summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/asmjit/src
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/asmjit/src')
-rw-r--r--3rdparty/asmjit/src/asmjit/a64.h28
-rw-r--r--3rdparty/asmjit/src/asmjit/arm.h44
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/a64archtraits_p.h7
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/a64assembler.cpp306
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/a64assembler.h15
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/a64builder.cpp10
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/a64builder.h2
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/a64compiler.cpp5
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/a64compiler.h117
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/a64emithelper.cpp14
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/a64emithelper_p.h8
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/a64emitter.h43
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/a64formatter.cpp247
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/a64formatter_p.h17
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/a64func.cpp29
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/a64func_p.h2
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/a64globals.h27
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/a64instapi.cpp86
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/a64instapi_p.h10
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/a64instdb.cpp2402
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/a64instdb.h12
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/a64instdb_p.h47
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/a64operand.cpp96
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/a64operand.h392
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/a64rapass.cpp12
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/a64rapass_p.h6
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/armformatter.cpp515
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/armformatter_p.h25
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/armglobals.h4
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/armoperand.h571
-rw-r--r--3rdparty/asmjit/src/asmjit/arm/armutils.h (renamed from 3rdparty/asmjit/src/asmjit/arm/a64utils.h)87
-rw-r--r--3rdparty/asmjit/src/asmjit/asmjit.h2
-rw-r--r--3rdparty/asmjit/src/asmjit/core.h312
-rw-r--r--3rdparty/asmjit/src/asmjit/core/api-build_p.h19
-rw-r--r--3rdparty/asmjit/src/asmjit/core/api-config.h317
-rw-r--r--3rdparty/asmjit/src/asmjit/core/archcommons.h194
-rw-r--r--3rdparty/asmjit/src/asmjit/core/archtraits.cpp1
-rw-r--r--3rdparty/asmjit/src/asmjit/core/archtraits.h45
-rw-r--r--3rdparty/asmjit/src/asmjit/core/assembler.h17
-rw-r--r--3rdparty/asmjit/src/asmjit/core/builder.cpp68
-rw-r--r--3rdparty/asmjit/src/asmjit/core/builder.h492
-rw-r--r--3rdparty/asmjit/src/asmjit/core/builder_p.h37
-rw-r--r--3rdparty/asmjit/src/asmjit/core/codebuffer.h30
-rw-r--r--3rdparty/asmjit/src/asmjit/core/codeholder.cpp41
-rw-r--r--3rdparty/asmjit/src/asmjit/core/codeholder.h304
-rw-r--r--3rdparty/asmjit/src/asmjit/core/codewriter.cpp105
-rw-r--r--3rdparty/asmjit/src/asmjit/core/compiler.cpp42
-rw-r--r--3rdparty/asmjit/src/asmjit/core/compiler.h116
-rw-r--r--3rdparty/asmjit/src/asmjit/core/compilerdefs.h54
-rw-r--r--3rdparty/asmjit/src/asmjit/core/constpool.cpp83
-rw-r--r--3rdparty/asmjit/src/asmjit/core/constpool.h45
-rw-r--r--3rdparty/asmjit/src/asmjit/core/cpuinfo.cpp1967
-rw-r--r--3rdparty/asmjit/src/asmjit/core/cpuinfo.h917
-rw-r--r--3rdparty/asmjit/src/asmjit/core/emithelper.cpp25
-rw-r--r--3rdparty/asmjit/src/asmjit/core/emithelper_p.h12
-rw-r--r--3rdparty/asmjit/src/asmjit/core/emitter.cpp82
-rw-r--r--3rdparty/asmjit/src/asmjit/core/emitter.h237
-rw-r--r--3rdparty/asmjit/src/asmjit/core/emitterutils.cpp8
-rw-r--r--3rdparty/asmjit/src/asmjit/core/emitterutils_p.h4
-rw-r--r--3rdparty/asmjit/src/asmjit/core/environment.h256
-rw-r--r--3rdparty/asmjit/src/asmjit/core/errorhandler.cpp4
-rw-r--r--3rdparty/asmjit/src/asmjit/core/errorhandler.h8
-rw-r--r--3rdparty/asmjit/src/asmjit/core/formatter.cpp62
-rw-r--r--3rdparty/asmjit/src/asmjit/core/formatter.h34
-rw-r--r--3rdparty/asmjit/src/asmjit/core/func.cpp20
-rw-r--r--3rdparty/asmjit/src/asmjit/core/func.h808
-rw-r--r--3rdparty/asmjit/src/asmjit/core/funcargscontext.cpp20
-rw-r--r--3rdparty/asmjit/src/asmjit/core/funcargscontext_p.h12
-rw-r--r--3rdparty/asmjit/src/asmjit/core/globals.cpp4
-rw-r--r--3rdparty/asmjit/src/asmjit/core/globals.h70
-rw-r--r--3rdparty/asmjit/src/asmjit/core/inst.cpp22
-rw-r--r--3rdparty/asmjit/src/asmjit/core/inst.h212
-rw-r--r--3rdparty/asmjit/src/asmjit/core/instdb.cpp101
-rw-r--r--3rdparty/asmjit/src/asmjit/core/instdb_p.h40
-rw-r--r--3rdparty/asmjit/src/asmjit/core/jitallocator.cpp727
-rw-r--r--3rdparty/asmjit/src/asmjit/core/jitallocator.h385
-rw-r--r--3rdparty/asmjit/src/asmjit/core/jitruntime.cpp31
-rw-r--r--3rdparty/asmjit/src/asmjit/core/jitruntime.h26
-rw-r--r--3rdparty/asmjit/src/asmjit/core/logger.cpp8
-rw-r--r--3rdparty/asmjit/src/asmjit/core/logger.h54
-rw-r--r--3rdparty/asmjit/src/asmjit/core/operand.cpp136
-rw-r--r--3rdparty/asmjit/src/asmjit/core/operand.h990
-rw-r--r--3rdparty/asmjit/src/asmjit/core/osutils.cpp82
-rw-r--r--3rdparty/asmjit/src/asmjit/core/osutils.h15
-rw-r--r--3rdparty/asmjit/src/asmjit/core/osutils_p.h40
-rw-r--r--3rdparty/asmjit/src/asmjit/core/raassignment_p.h18
-rw-r--r--3rdparty/asmjit/src/asmjit/core/rabuilders_p.h2
-rw-r--r--3rdparty/asmjit/src/asmjit/core/radefs_p.h364
-rw-r--r--3rdparty/asmjit/src/asmjit/core/ralocal.cpp23
-rw-r--r--3rdparty/asmjit/src/asmjit/core/ralocal_p.h65
-rw-r--r--3rdparty/asmjit/src/asmjit/core/rapass.cpp148
-rw-r--r--3rdparty/asmjit/src/asmjit/core/rapass_p.h294
-rw-r--r--3rdparty/asmjit/src/asmjit/core/rastack.cpp2
-rw-r--r--3rdparty/asmjit/src/asmjit/core/rastack_p.h31
-rw-r--r--3rdparty/asmjit/src/asmjit/core/string.cpp202
-rw-r--r--3rdparty/asmjit/src/asmjit/core/string.h95
-rw-r--r--3rdparty/asmjit/src/asmjit/core/support.cpp452
-rw-r--r--3rdparty/asmjit/src/asmjit/core/support.h661
-rw-r--r--3rdparty/asmjit/src/asmjit/core/support_p.h27
-rw-r--r--3rdparty/asmjit/src/asmjit/core/target.cpp4
-rw-r--r--3rdparty/asmjit/src/asmjit/core/target.h12
-rw-r--r--3rdparty/asmjit/src/asmjit/core/type.h114
-rw-r--r--3rdparty/asmjit/src/asmjit/core/virtmem.cpp886
-rw-r--r--3rdparty/asmjit/src/asmjit/core/virtmem.h147
-rw-r--r--3rdparty/asmjit/src/asmjit/core/zone.cpp12
-rw-r--r--3rdparty/asmjit/src/asmjit/core/zone.h56
-rw-r--r--3rdparty/asmjit/src/asmjit/core/zonehash.cpp8
-rw-r--r--3rdparty/asmjit/src/asmjit/core/zonehash.h16
-rw-r--r--3rdparty/asmjit/src/asmjit/core/zonelist.cpp180
-rw-r--r--3rdparty/asmjit/src/asmjit/core/zonelist.h37
-rw-r--r--3rdparty/asmjit/src/asmjit/core/zonestack.cpp58
-rw-r--r--3rdparty/asmjit/src/asmjit/core/zonestack.h44
-rw-r--r--3rdparty/asmjit/src/asmjit/core/zonestring.h16
-rw-r--r--3rdparty/asmjit/src/asmjit/core/zonetree.cpp17
-rw-r--r--3rdparty/asmjit/src/asmjit/core/zonetree.h62
-rw-r--r--3rdparty/asmjit/src/asmjit/core/zonevector.cpp183
-rw-r--r--3rdparty/asmjit/src/asmjit/core/zonevector.h188
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86assembler.cpp484
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86assembler.h68
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86builder.cpp9
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86builder.h11
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86compiler.cpp5
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86compiler.h329
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86emithelper.cpp105
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86emithelper_p.h4
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86emitter.h328
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86formatter.cpp142
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86func.cpp7
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86globals.h401
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86instapi.cpp528
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86instapi_p.h7
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86instdb.cpp9283
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86instdb.h166
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86instdb_p.h25
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86opcode_p.h66
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86operand.cpp332
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86operand.h555
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86rapass.cpp81
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86rapass_p.h12
139 files changed, 20096 insertions, 12205 deletions
diff --git a/3rdparty/asmjit/src/asmjit/a64.h b/3rdparty/asmjit/src/asmjit/a64.h
index ea4d304f058..e849eb3a8ca 100644
--- a/3rdparty/asmjit/src/asmjit/a64.h
+++ b/3rdparty/asmjit/src/asmjit/a64.h
@@ -18,25 +18,24 @@
//! ### Supported Instructions
//!
//! - Emitters:
-//! - \ref a64::EmitterExplicitT - Provides all instructions that use explicit
-//! operands, provides also utility functions. The member functions provided
-//! are part of all ARM/AArch64 emitters.
+//! - \ref a64::EmitterExplicitT - Provides all instructions that use explicit operands, provides also utility
+//! functions. The member functions provided are part of all AArch64 emitters.
//!
//! - Instruction representation:
//! - \ref a64::Inst::Id - instruction identifiers.
//!
//! ### Register Operands
//!
-//! - \ref arm::Reg - Base class for any AArch32/AArch64 register.
-//! - \ref arm::Gp - General purpose register:
-//! - \ref arm::GpW - 32-bit register.
-//! - \ref arm::GpX - 64-bit register.
-//! - \ref arm::Vec - Vector (SIMD) register:
-//! - \ref arm::VecB - 8-bit SIMD register (AArch64 only).
-//! - \ref arm::VecH - 16-bit SIMD register (AArch64 only).
-//! - \ref arm::VecS - 32-bit SIMD register.
-//! - \ref arm::VecD - 64-bit SIMD register.
-//! - \ref arm::VecV - 128-bit SIMD register.
+//! - \ref arm::Reg - Base class of all AArch32/AArch64 registers.
+//! - \ref a64::Gp - General purpose register (AArch64):
+//! - \ref a64::GpW - 32-bit general purpose register (AArch64).
+//! - \ref a64::GpX - 64-bit general purpose register (AArch64).
+//! - \ref a64::Vec - Vector (SIMD) register:
+//! - \ref a64::VecB - 8-bit SIMD register.
+//! - \ref a64::VecH - 16-bit SIMD register.
+//! - \ref a64::VecS - 32-bit SIMD register.
+//! - \ref a64::VecD - 64-bit SIMD register.
+//! - \ref a64::VecV - 128-bit SIMD register.
//!
//! ### Memory Operands
//!
@@ -46,7 +45,7 @@
//! ### Other
//!
//! - \ref arm::Shift - Shift operation and value.
-//! - \ref a64::Utils - Utilities that can help during code generation for AArch64.
+//! - \ref arm::Utils - Utilities that can help during code generation for AArch32 and AArch64.
#include "./arm.h"
#include "./arm/a64assembler.h"
@@ -56,7 +55,6 @@
#include "./arm/a64globals.h"
#include "./arm/a64instdb.h"
#include "./arm/a64operand.h"
-#include "./arm/a64utils.h"
#endif // ASMJIT_A64_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/arm.h b/3rdparty/asmjit/src/asmjit/arm.h
index 57ffa815b8c..e4a3e3d3ac5 100644
--- a/3rdparty/asmjit/src/asmjit/arm.h
+++ b/3rdparty/asmjit/src/asmjit/arm.h
@@ -11,11 +11,19 @@
//! ### Namespaces
//!
//! - \ref arm - arm namespace provides common functionality for both AArch32 and AArch64 backends.
+//! - \ref a32 - a32 namespace provides support for AArch32 architecture. In addition it includes
+//! \ref arm namespace, so you can only use a single namespace when targeting AArch32 architecture.
//! - \ref a64 - a64 namespace provides support for AArch64 architecture. In addition it includes
//! \ref arm namespace, so you can only use a single namespace when targeting AArch64 architecture.
//!
//! ### Emitters
//!
+//! - AArch32
+//! - \ref a32::Assembler - AArch32 assembler (must read, provides examples).
+//! - \ref a32::Builder - AArch32 builder.
+//! - \ref a32::Compiler - AArch32 compiler.
+//! - \ref a32::Emitter - AArch32 emitter (abstract).
+//!
//! - AArch64
//! - \ref a64::Assembler - AArch64 assembler (must read, provides examples).
//! - \ref a64::Builder - AArch64 builder.
@@ -24,6 +32,13 @@
//!
//! ### Supported Instructions
//!
+//! - AArch32:
+//! - Emitters:
+//! - \ref a32::EmitterExplicitT - Provides all instructions that use explicit operands, provides also
+//! utility functions. The member functions provided are part of all AArch32 emitters.
+//! - Instruction representation:
+//! - \ref a32::Inst::Id - instruction identifiers.
+//!
//! - AArch64:
//! - Emitters:
//! - \ref a64::EmitterExplicitT - Provides all instructions that use explicit operands, provides also
@@ -33,16 +48,22 @@
//!
//! ### Register Operands
//!
-//! - \ref arm::Reg - Base class for any AArch32/AArch64 register.
-//! - \ref arm::Gp - General purpose register:
-//! - \ref arm::GpW - 32-bit register.
-//! - \ref arm::GpX - 64-bit register.
-//! - \ref arm::Vec - Vector (SIMD) register:
-//! - \ref arm::VecB - 8-bit SIMD register (AArch64 only).
-//! - \ref arm::VecH - 16-bit SIMD register (AArch64 only).
-//! - \ref arm::VecS - 32-bit SIMD register.
-//! - \ref arm::VecD - 64-bit SIMD register.
-//! - \ref arm::VecV - 128-bit SIMD register.
+//! - \ref arm::Reg - Base class of all AArch32/AArch64 registers.
+//! - \ref a32::Gp - 32-bit general purpose register used by AArch32:
+//! - \ref a64::Gp - 32-bit or 64-bit general purpose register used by AArch64:
+//! - \ref a64::GpW - 32-bit register (AArch64).
+//! - \ref a64::GpX - 64-bit register (AArch64).
+//! - \ref arm::BaseVec - Base vector (SIMD) register.
+//! - \ref a32::Vec - Vector (SIMD) register (AArch32):
+//! - \ref a32::VecS - 32-bit SIMD register (AArch32).
+//! - \ref a32::VecD - 64-bit SIMD register (AArch32).
+//! - \ref a32::VecV - 128-bit SIMD register (AArch32).
+//! - \ref a64::Vec - Vector (SIMD) register (AArch64):
+//! - \ref a64::VecB - 8-bit SIMD register (AArch64).
+//! - \ref a64::VecH - 16-bit SIMD register (AArch64).
+//! - \ref a64::VecS - 32-bit SIMD register (AArch64).
+//! - \ref a64::VecD - 64-bit SIMD register (AArch64).
+//! - \ref a64::VecV - 128-bit SIMD register (AArch64).
//!
//! ### Memory Operands
//!
@@ -53,10 +74,11 @@
//!
//! - \ref arm::Shift - Shift operation and value (both AArch32 and AArch64).
//! - \ref arm::DataType - Data type that is part of an instruction in AArch32 mode.
-//! - \ref a64::Utils - Utilities that can help during code generation for AArch64.
+//! - \ref arm::Utils - Utilities that can help during code generation for AArch32 and AArch64.
#include "./core.h"
#include "./arm/armglobals.h"
#include "./arm/armoperand.h"
+#include "./arm/armutils.h"
#endif // ASMJIT_ARM_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64archtraits_p.h b/3rdparty/asmjit/src/asmjit/arm/a64archtraits_p.h
index 87559c71d5a..4b5bde68a9e 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64archtraits_p.h
+++ b/3rdparty/asmjit/src/asmjit/arm/a64archtraits_p.h
@@ -9,6 +9,7 @@
#include "../core/archtraits.h"
#include "../core/misc_p.h"
#include "../core/type.h"
+#include "../arm/a64globals.h"
#include "../arm/a64operand.h"
ASMJIT_BEGIN_SUB_NAMESPACE(a64)
@@ -24,7 +25,7 @@ static const constexpr ArchTraits a64ArchTraits = {
// Reserved.
{ 0, 0, 0 },
- // HW stack alignment (AArch64 requires stack aligned to 64 bytes).
+ // HW stack alignment (AArch64 requires stack aligned to 16 bytes at HW level).
16,
// Min/max stack offset - byte addressing is the worst, VecQ addressing the best.
@@ -39,12 +40,12 @@ static const constexpr ArchTraits a64ArchTraits = {
}},
// RegInfo.
- #define V(index) OperandSignature{arm::RegTraits<RegType(index)>::kSignature}
+ #define V(index) OperandSignature{RegTraits<RegType(index)>::kSignature}
{{ ASMJIT_LOOKUP_TABLE_32(V, 0) }},
#undef V
// RegTypeToTypeId.
- #define V(index) TypeId(arm::RegTraits<RegType(index)>::kTypeId)
+ #define V(index) TypeId(RegTraits<RegType(index)>::kTypeId)
{{ ASMJIT_LOOKUP_TABLE_32(V, 0) }},
#undef V
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64assembler.cpp b/3rdparty/asmjit/src/asmjit/arm/a64assembler.cpp
index 485f05f491f..32514b9bad9 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64assembler.cpp
+++ b/3rdparty/asmjit/src/asmjit/arm/a64assembler.cpp
@@ -14,19 +14,23 @@
#include "../core/misc_p.h"
#include "../core/support.h"
#include "../arm/armformatter_p.h"
+#include "../arm/armutils.h"
#include "../arm/a64assembler.h"
#include "../arm/a64emithelper_p.h"
#include "../arm/a64instdb_p.h"
-#include "../arm/a64utils.h"
ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+// a64::Assembler - Utils
+// ======================
+
+static ASMJIT_FORCE_INLINE constexpr uint32_t diff(RegType a, RegType b) noexcept { return uint32_t(a) - uint32_t(b); }
+static ASMJIT_FORCE_INLINE constexpr uint32_t diff(VecElementType elementType, VecElementType baseType) noexcept { return uint32_t(elementType) - uint32_t(baseType); }
+
// a64::Assembler - Cond
// =====================
-static inline uint32_t condCodeToOpcodeCond(uint32_t cond) noexcept {
- return (uint32_t(cond) - 2u) & 0xFu;
-}
+static inline uint32_t condCodeToOpcodeCond(uint32_t cond) noexcept { return (uint32_t(cond) - 2u) & 0xFu; }
// a64::Assembler - Bits
// =====================
@@ -49,8 +53,19 @@ static constexpr uint32_t kWX = InstDB::kWX;
static const uint8_t armShiftOpToLdStOptMap[] = { ASMJIT_LOOKUP_TABLE_16(VALUE, 0) };
#undef VALUE
-static inline constexpr uint32_t diff(RegType a, RegType b) noexcept {
- return uint32_t(a) - uint32_t(b);
+// a64::Assembler - ExtendOpToRegType
+// ==================================
+
+static inline RegType extendOptionToRegType(uint32_t option) noexcept {
+ uint32_t pred = (uint32_t(RegType::kARM_GpW) << (0x0 * 4)) | // 0b000 - UXTB.
+ (uint32_t(RegType::kARM_GpW) << (0x1 * 4)) | // 0b001 - UXTH.
+ (uint32_t(RegType::kARM_GpW) << (0x2 * 4)) | // 0b010 - UXTW.
+ (uint32_t(RegType::kARM_GpX) << (0x3 * 4)) | // 0b011 - UXTX|LSL.
+ (uint32_t(RegType::kARM_GpW) << (0x4 * 4)) | // 0b100 - SXTB.
+ (uint32_t(RegType::kARM_GpW) << (0x5 * 4)) | // 0b101 - SXTH.
+ (uint32_t(RegType::kARM_GpW) << (0x6 * 4)) | // 0b110 - SXTW.
+ (uint32_t(RegType::kARM_GpX) << (0x7 * 4)) ; // 0b111 - SXTX.
+ return RegType((pred >> (option * 4u)) & 0xFu);
}
// asmjit::a64::Assembler - SizeOp
@@ -118,25 +133,25 @@ struct SizeOpTable {
};
#define VALUE_BIN(x) { \
- x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeNone)) ? SizeOp::k00 : \
- x == (((uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeNone)) ? SizeOp::k00Q : \
- x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeB )) ? SizeOp::k00 : \
- x == (((uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeB )) ? SizeOp::k00Q : SizeOp::kInvalid \
+ x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kNone)) ? SizeOp::k00 : \
+ x == (((uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kNone)) ? SizeOp::k00Q : \
+ x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kB )) ? SizeOp::k00 : \
+ x == (((uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kB )) ? SizeOp::k00Q : SizeOp::kInvalid \
}
#define VALUE_ANY(x) { \
- x == (((uint32_t(RegType::kARM_VecB) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeNone)) ? SizeOp::k00S : \
- x == (((uint32_t(RegType::kARM_VecH) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeNone)) ? SizeOp::k01S : \
- x == (((uint32_t(RegType::kARM_VecS) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeNone)) ? SizeOp::k10S : \
- x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeNone)) ? SizeOp::k11S : \
- x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeB )) ? SizeOp::k00 : \
- x == (((uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeB )) ? SizeOp::k00Q : \
- x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeH )) ? SizeOp::k01 : \
- x == (((uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeH )) ? SizeOp::k01Q : \
- x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeS )) ? SizeOp::k10 : \
- x == (((uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeS )) ? SizeOp::k10Q : \
- x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeD )) ? SizeOp::k11S : \
- x == (((uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB)) << 3) | (Vec::kElementTypeD )) ? SizeOp::k11Q : SizeOp::kInvalid \
+ x == (((uint32_t(RegType::kARM_VecB) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kNone)) ? SizeOp::k00S : \
+ x == (((uint32_t(RegType::kARM_VecH) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kNone)) ? SizeOp::k01S : \
+ x == (((uint32_t(RegType::kARM_VecS) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kNone)) ? SizeOp::k10S : \
+ x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kNone)) ? SizeOp::k11S : \
+ x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kB )) ? SizeOp::k00 : \
+ x == (((uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kB )) ? SizeOp::k00Q : \
+ x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kH )) ? SizeOp::k01 : \
+ x == (((uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kH )) ? SizeOp::k01Q : \
+ x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kS )) ? SizeOp::k10 : \
+ x == (((uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kS )) ? SizeOp::k10Q : \
+ x == (((uint32_t(RegType::kARM_VecD) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kD )) ? SizeOp::k11S : \
+ x == (((uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB)) << 3) | uint32_t(VecElementType::kD )) ? SizeOp::k11Q : SizeOp::kInvalid \
}
static const SizeOpTable sizeOpTable[SizeOpTable::kCount] = {
@@ -254,16 +269,16 @@ static const Operand_& significantSimdOp(const Operand_& o0, const Operand_& o1,
return !(instFlags & InstDB::kInstFlagLong) ? o0 : o1;
}
-static inline SizeOp armElementTypeToSizeOp(uint32_t vecOpType, RegType regType, uint32_t elementType) noexcept {
+static inline SizeOp armElementTypeToSizeOp(uint32_t vecOpType, RegType regType, VecElementType elementType) noexcept {
// Instruction data or Assembler is wrong if this triggers an assertion failure.
ASMJIT_ASSERT(vecOpType < InstDB::kVO_Count);
// ElementType uses 3 bits in the operand signature, it should never overflow.
- ASMJIT_ASSERT(elementType <= 0x7u);
+ ASMJIT_ASSERT(uint32_t(elementType) <= 0x7u);
const SizeOpMap& map = sizeOpMap[vecOpType];
const SizeOpTable& table = sizeOpTable[map.tableId];
- size_t index = (Support::min<uint32_t>(diff(regType, RegType::kARM_VecB), diff(RegType::kARM_VecV, RegType::kARM_VecB) + 1) << 3) | elementType;
+ size_t index = (Support::min<uint32_t>(diff(regType, RegType::kARM_VecB), diff(RegType::kARM_VecV, RegType::kARM_VecB) + 1) << 3) | uint32_t(elementType);
SizeOp op = table.array[index];
SizeOp modifiedOp { uint8_t(op.value & map.sizeOpMask) };
@@ -398,14 +413,6 @@ static inline bool encodeLMH(uint32_t sizeField, uint32_t elementIndex, LMHImm*
return elementIndex <= maxElementIndex;
}
-// [.......A|B.......|.......C|D.......|.......E|F.......|.......G|H.......]
-static inline uint32_t encodeImm64ByteMaskToImm8(uint64_t imm) noexcept {
- return uint32_t(((imm >> (7 - 0)) & 0b00000011) | // [.......G|H.......]
- ((imm >> (23 - 2)) & 0b00001100) | // [.......E|F.......]
- ((imm >> (39 - 4)) & 0b00110000) | // [.......C|D.......]
- ((imm >> (55 - 6)) & 0b11000000)); // [.......A|B.......]
-}
-
// a64::Assembler - Opcode
// =======================
@@ -475,7 +482,7 @@ static inline bool matchSignature(const Operand_& o0, const Operand_& o1, const
}
static inline bool matchSignature(const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, uint32_t instFlags) noexcept {
- return matchSignature(o0, o1, instFlags) && o1.signature() == o2.signature() && o2.signature() == o3.signature();;
+ return matchSignature(o0, o1, instFlags) && o1.signature() == o2.signature() && o2.signature() == o3.signature();
}
// Memory must be either:
@@ -545,7 +552,7 @@ static inline bool pickFpOpcode(const Vec& reg, uint32_t sOp, uint32_t sHf, uint
else {
// Vector operation [HSD].
uint32_t q = diff(reg.type(), RegType::kARM_VecD);
- uint32_t sz = reg.elementType() - Vec::kElementTypeH;
+ uint32_t sz = diff(reg.elementType(), VecElementType::kH);
if (q > 1u || sz > 2u || !Support::bitTest(szBits[vHf].sizeMask, sz))
return false;
@@ -698,25 +705,25 @@ static const Support::Array<uint8_t, 32> commonHiRegIdOfType = {{
#undef V
static inline bool checkValidRegs(const Operand_& o0) noexcept {
- return ((o0.id() < 31) | (o0.id() == commonHiRegIdOfType[o0.as<Reg>().type()]));
+ return bool(unsigned(o0.id() < 31) | unsigned(o0.id() == commonHiRegIdOfType[o0.as<Reg>().type()]));
}
static inline bool checkValidRegs(const Operand_& o0, const Operand_& o1) noexcept {
- return ((o0.id() < 31) | (o0.id() == commonHiRegIdOfType[o0.as<Reg>().type()])) &
- ((o1.id() < 31) | (o1.id() == commonHiRegIdOfType[o1.as<Reg>().type()])) ;
+ return bool((unsigned(o0.id() < 31) | unsigned(o0.id() == commonHiRegIdOfType[o0.as<Reg>().type()])) &
+ (unsigned(o1.id() < 31) | unsigned(o1.id() == commonHiRegIdOfType[o1.as<Reg>().type()])));
}
static inline bool checkValidRegs(const Operand_& o0, const Operand_& o1, const Operand_& o2) noexcept {
- return ((o0.id() < 31) | (o0.id() == commonHiRegIdOfType[o0.as<Reg>().type()])) &
- ((o1.id() < 31) | (o1.id() == commonHiRegIdOfType[o1.as<Reg>().type()])) &
- ((o2.id() < 31) | (o2.id() == commonHiRegIdOfType[o2.as<Reg>().type()])) ;
+ return bool((unsigned(o0.id() < 31) | unsigned(o0.id() == commonHiRegIdOfType[o0.as<Reg>().type()])) &
+ (unsigned(o1.id() < 31) | unsigned(o1.id() == commonHiRegIdOfType[o1.as<Reg>().type()])) &
+ (unsigned(o2.id() < 31) | unsigned(o2.id() == commonHiRegIdOfType[o2.as<Reg>().type()])));
}
static inline bool checkValidRegs(const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) noexcept {
- return ((o0.id() < 31) | (o0.id() == commonHiRegIdOfType[o0.as<Reg>().type()])) &
- ((o1.id() < 31) | (o1.id() == commonHiRegIdOfType[o1.as<Reg>().type()])) &
- ((o2.id() < 31) | (o2.id() == commonHiRegIdOfType[o2.as<Reg>().type()])) &
- ((o3.id() < 31) | (o3.id() == commonHiRegIdOfType[o3.as<Reg>().type()])) ;
+ return bool((unsigned(o0.id() < 31) | unsigned(o0.id() == commonHiRegIdOfType[o0.as<Reg>().type()])) &
+ (unsigned(o1.id() < 31) | unsigned(o1.id() == commonHiRegIdOfType[o1.as<Reg>().type()])) &
+ (unsigned(o2.id() < 31) | unsigned(o2.id() == commonHiRegIdOfType[o2.as<Reg>().type()])) &
+ (unsigned(o3.id() < 31) | unsigned(o3.id() == commonHiRegIdOfType[o3.as<Reg>().type()])));
}
// a64::Assembler - Construction & Destruction
@@ -724,8 +731,6 @@ static inline bool checkValidRegs(const Operand_& o0, const Operand_& o1, const
Assembler::Assembler(CodeHolder* code) noexcept : BaseAssembler() {
_archMask = uint64_t(1) << uint32_t(Arch::kAArch64);
- assignEmitterFuncs(this);
-
if (code)
code->attach(this);
}
@@ -811,7 +816,7 @@ Error Assembler::_emit(InstId instId, const Operand_& o0, const Operand_& o1, co
Operand_ opArray[Globals::kMaxOpCount];
EmitterUtils::opArrayFromEmitArgs(opArray, o0, o1, o2, opExt);
- err = _funcs.validate(arch(), BaseInst(instId, options, _extraReg), opArray, Globals::kMaxOpCount, ValidationFlags::kNone);
+ err = _funcs.validate(BaseInst(instId, options, _extraReg), opArray, Globals::kMaxOpCount, ValidationFlags::kNone);
if (ASMJIT_UNLIKELY(err))
goto Failed;
}
@@ -1238,9 +1243,6 @@ Error Assembler::_emit(InstId instId, const Operand_& o0, const Operand_& o1, co
}
if (isign4 == ENC_OPS3(Reg, Reg, Reg) || isign4 == ENC_OPS4(Reg, Reg, Reg, Imm)) {
- if (!checkSignature(o1, o2))
- goto InvalidInstruction;
-
uint32_t opSize = x ? 64 : 32;
uint64_t shift = 0;
uint32_t sType = uint32_t(ShiftOp::kLSL);
@@ -1257,11 +1259,17 @@ Error Assembler::_emit(InstId instId, const Operand_& o0, const Operand_& o1, co
if (sType <= uint32_t(ShiftOp::kASR)) {
bool hasSP = o0.as<Gp>().isSP() || o1.as<Gp>().isSP();
if (!hasSP) {
- if (!checkGpId(o0, o1, kZR))
+ if (!checkSignature(o1, o2)) {
+ goto InvalidInstruction;
+ }
+
+ if (!checkGpId(o0, o1, kZR)) {
goto InvalidPhysId;
+ }
- if (shift >= opSize)
+ if (shift >= opSize) {
goto InvalidImmediate;
+ }
opcode.reset(uint32_t(opData.shiftedOp) << 21);
opcode.addImm(x, 31);
@@ -1274,8 +1282,10 @@ Error Assembler::_emit(InstId instId, const Operand_& o0, const Operand_& o1, co
}
// SP register can only be used with LSL or Extend.
- if (sType != uint32_t(ShiftOp::kLSL))
+ if (sType != uint32_t(ShiftOp::kLSL)) {
goto InvalidImmediate;
+ }
+
sType = x ? uint32_t(ShiftOp::kUXTX) : uint32_t(ShiftOp::kUXTW);
}
@@ -1283,8 +1293,9 @@ Error Assembler::_emit(InstId instId, const Operand_& o0, const Operand_& o1, co
opcode.reset(uint32_t(opData.extendedOp) << 21);
sType -= uint32_t(ShiftOp::kUXTB);
- if (sType > 7 || shift > 4)
+ if (sType > 7 || shift > 4) {
goto InvalidImmediate;
+ }
if (!(opcode.get() & B(29))) {
// ADD|SUB (extend) - ZR is not allowed.
@@ -1297,6 +1308,11 @@ Error Assembler::_emit(InstId instId, const Operand_& o0, const Operand_& o1, co
goto InvalidPhysId;
}
+ // Validate whether the register operands match extend option.
+ if (o2.as<Reg>().type() != extendOptionToRegType(sType) || o1.as<Reg>().type() < o2.as<Reg>().type()) {
+ goto InvalidInstruction;
+ }
+
opcode.addImm(x, 31);
opcode.addReg(o2, 16);
opcode.addImm(sType, 13);
@@ -1422,9 +1438,6 @@ Error Assembler::_emit(InstId instId, const Operand_& o0, const Operand_& o1, co
}
if (isign4 == ENC_OPS2(Reg, Reg) || isign4 == ENC_OPS3(Reg, Reg, Imm)) {
- if (!checkSignature(o0, o1))
- goto InvalidInstruction;
-
uint32_t opSize = x ? 64 : 32;
uint32_t sType = 0;
uint64_t shift = 0;
@@ -1439,8 +1452,13 @@ Error Assembler::_emit(InstId instId, const Operand_& o0, const Operand_& o1, co
// Shift operation - LSL, LSR, ASR.
if (sType <= uint32_t(ShiftOp::kASR)) {
if (!hasSP) {
- if (shift >= opSize)
+ if (!checkSignature(o0, o1)) {
+ goto InvalidInstruction;
+ }
+
+ if (shift >= opSize) {
goto InvalidImmediate;
+ }
opcode.reset(uint32_t(opData.shiftedOp) << 21);
opcode.addImm(x, 31);
@@ -1461,8 +1479,14 @@ Error Assembler::_emit(InstId instId, const Operand_& o0, const Operand_& o1, co
// Extend operation - UXTB, UXTH, UXTW, UXTX, SXTB, SXTH, SXTW, SXTX.
sType -= uint32_t(ShiftOp::kUXTB);
- if (sType > 7 || shift > 4)
+ if (sType > 7 || shift > 4) {
goto InvalidImmediate;
+ }
+
+ // Validate whether the register operands match extend option.
+ if (o1.as<Reg>().type() != extendOptionToRegType(sType) || o0.as<Reg>().type() < o1.as<Reg>().type()) {
+ goto InvalidInstruction;
+ }
opcode.reset(uint32_t(opData.extendedOp) << 21);
opcode.addImm(x, 31);
@@ -2250,6 +2274,86 @@ Error Assembler::_emit(InstId instId, const Operand_& o0, const Operand_& o1, co
}
// ------------------------------------------------------------------------
+ // [Base - Prefetch]
+ // ------------------------------------------------------------------------
+
+ case InstDB::kEncodingBasePrfm: {
+ const InstDB::EncodingData::BasePrfm& opData = InstDB::EncodingData::basePrfm[encodingIndex];
+
+ if (isign4 == ENC_OPS2(Imm, Mem)) {
+ const Mem& m = o1.as<Mem>();
+ rmRel = &m;
+
+ uint32_t immShift = 3u;
+
+ if (o0.as<Imm>().valueAs<uint64_t>() > 0x1Fu)
+ goto InvalidImmediate;
+
+ if (!armCheckMemBaseIndexRel(m))
+ goto InvalidAddress;
+
+ int64_t offset = m.offset();
+ uint32_t prfop = o0.as<Imm>().valueAs<uint32_t>();
+
+ if (m.hasBaseReg()) {
+ // [Base {Offset | Index}]
+ if (m.hasIndex()) {
+ uint32_t opt = armShiftOpToLdStOptMap[size_t(m.shiftOp())];
+ if (opt == 0xFF)
+ goto InvalidAddress;
+
+ uint32_t shift = m.shift();
+ uint32_t s = shift != 0;
+
+ if (s && shift != immShift)
+ goto InvalidAddressScale;
+
+ opcode.reset(uint32_t(opData.registerOp) << 21);
+ opcode.addImm(opt, 13);
+ opcode.addImm(s, 12);
+ opcode |= B(11);
+ opcode.addImm(prfop, 0);
+ goto EmitOp_MemBaseIndex_Rn5_Rm16;
+ }
+
+ if (!Support::isInt32(offset))
+ goto InvalidDisplacement;
+
+ int32_t offset32 = int32_t(offset);
+
+ if (m.isPreOrPost())
+ goto InvalidAddress;
+
+ uint32_t imm12 = uint32_t(offset32) >> immShift;
+
+ if (Support::isUInt12(imm12) && (imm12 << immShift) == uint32_t(offset32)) {
+ opcode.reset(uint32_t(opData.sOffsetOp) << 22);
+ opcode.addImm(imm12, 10);
+ opcode.addImm(prfop, 0);
+ goto EmitOp_MemBase_Rn5;
+ }
+
+ if (Support::isInt9(offset32)) {
+ opcode.reset(uint32_t(opData.uOffsetOp) << 21);
+ opcode.addImm(uint32_t(offset32) & 0x1FFu, 12);
+ opcode.addImm(prfop, 0);
+ goto EmitOp_MemBase_Rn5;
+ }
+
+ goto InvalidAddress;
+ }
+ else {
+ opcode.reset(uint32_t(opData.literalOp) << 24);
+ opcode.addImm(prfop, 0);
+ offsetFormat.resetToImmValue(OffsetType::kSignedOffset, 4, 5, 19, 2);
+ goto EmitOp_Rel;
+ }
+ }
+
+ break;
+ }
+
+ // ------------------------------------------------------------------------
// [Base - Load / Store]
// ------------------------------------------------------------------------
@@ -2280,7 +2384,7 @@ Error Assembler::_emit(InstId instId, const Operand_& o0, const Operand_& o1, co
if (m.hasBaseReg()) {
// [Base {Offset | Index}]
if (m.hasIndex()) {
- uint32_t opt = armShiftOpToLdStOptMap[m.predicate()];
+ uint32_t opt = armShiftOpToLdStOptMap[size_t(m.shiftOp())];
if (opt == 0xFF)
goto InvalidAddress;
@@ -2698,7 +2802,7 @@ Case_BaseLdurStur:
// hD, vS.{4|8}h (16-bit)
// sD, vS.4s (32-bit)
uint32_t sz = diff(o0.as<Reg>().type(), RegType::kARM_VecH);
- uint32_t elementSz = o1.as<Vec>().elementType() - Vec::kElementTypeH;
+ uint32_t elementSz = diff(o1.as<Vec>().elementType(), VecElementType::kH);
// Size greater than 1 means 64-bit elements, not supported.
if ((sz | elementSz) > 1 || sz != elementSz)
@@ -2820,7 +2924,7 @@ Case_BaseLdurStur:
if (q > 1)
goto InvalidInstruction;
- uint32_t sz = o0.as<Vec>().elementType() - Vec::kElementTypeB;
+ uint32_t sz = diff(o0.as<Vec>().elementType(), VecElementType::kB);
if (sz == 0 || sz > 3)
goto InvalidInstruction;
@@ -2912,7 +3016,7 @@ Case_BaseLdurStur:
if (q > 1)
goto InvalidInstruction;
- uint32_t sz = o0.as<Vec>().elementType() - Vec::kElementTypeB;
+ uint32_t sz = diff(o0.as<Vec>().elementType(), VecElementType::kB);
if (sz == 0 || sz > 3)
goto InvalidInstruction;
@@ -3094,11 +3198,11 @@ Case_BaseLdurStur:
if (uint32_t(opcode.hasQ()) != q)
goto InvalidInstruction;
- if (rL.isVecS4() && rN.elementType() == Vec::kElementTypeH && !opData.isCvtxn()) {
+ if (rL.isVecS4() && rN.elementType() == VecElementType::kH && !opData.isCvtxn()) {
goto EmitOp_Rd0_Rn5;
}
- if (rL.isVecD2() && rN.elementType() == Vec::kElementTypeS) {
+ if (rL.isVecD2() && rN.elementType() == VecElementType::kS) {
opcode |= B(22);
goto EmitOp_Rd0_Rn5;
}
@@ -3209,8 +3313,8 @@ Case_BaseLdurStur:
}
if (uint32_t(o0.as<Reg>().type()) != uint32_t(o1.as<Reg>().type()) + qIsOptional ||
- o0.as<Vec>().elementType() != opData.tA ||
- o1.as<Vec>().elementType() != opData.tB)
+ uint32_t(o0.as<Vec>().elementType()) != opData.tA ||
+ uint32_t(o1.as<Vec>().elementType()) != opData.tB)
goto InvalidInstruction;
if (!o2.as<Vec>().hasElementIndex()) {
@@ -3222,7 +3326,7 @@ Case_BaseLdurStur:
goto EmitOp_Rd0_Rn5_Rm16;
}
else {
- if (o2.as<Vec>().elementType() != opData.tElement)
+ if (uint32_t(o2.as<Vec>().elementType()) != opData.tElement)
goto InvalidInstruction;
if (o2.as<Reg>().id() > 15)
@@ -3372,7 +3476,7 @@ Case_BaseLdurStur:
}
else {
uint32_t q = diff(o0.as<Vec>().type(), RegType::kARM_VecD);
- uint32_t sz = o0.as<Vec>().elementType() - Vec::kElementTypeH;
+ uint32_t sz = diff(o0.as<Vec>().elementType(), VecElementType::kH);
if (q > 1 || sz > 2)
goto InvalidInstruction;
@@ -3426,7 +3530,7 @@ Case_BaseLdurStur:
if (q > 1)
goto InvalidInstruction;
- uint32_t sz = o0.as<Vec>().elementType() - Vec::kElementTypeH;
+ uint32_t sz = diff(o0.as<Vec>().elementType(), VecElementType::kH);
if (sz > 2)
goto InvalidInstruction;
@@ -3450,7 +3554,7 @@ Case_BaseLdurStur:
if (isign4 == ENC_OPS2(Reg, Reg)) {
// The first destination operand is scalar, which matches element-type of source vectors.
uint32_t L = (instFlags & InstDB::kInstFlagLong) != 0;
- if (diff(o0.as<Vec>().type(), RegType::kARM_VecB) != o1.as<Vec>().elementType() - Vec::kElementTypeB + L)
+ if (diff(o0.as<Vec>().type(), RegType::kARM_VecB) != diff(o1.as<Vec>().elementType(), VecElementType::kB) + L)
goto InvalidInstruction;
SizeOp sizeOp = armElementTypeToSizeOp(opData.vecOpType, o1.as<Reg>().type(), o1.as<Vec>().elementType());
@@ -3550,7 +3654,7 @@ Case_BaseLdurStur:
if (!sizeOp.isValid())
goto InvalidInstruction;
- if (!checkSignature(o0, o1) || !o0.as<Reg>().isVecV() || o0.as<Vec>().elementType() != o2.as<Vec>().elementType() + 1)
+ if (!checkSignature(o0, o1) || !o0.as<Reg>().isVecV() || uint32_t(o0.as<Vec>().elementType()) != uint32_t(o2.as<Vec>().elementType()) + 1u)
goto InvalidInstruction;
opcode.reset(opData.opcode());
@@ -3753,7 +3857,7 @@ Case_BaseLdurStur:
goto InvalidImmediate;
}
else if (imm) {
- shift = Support::ctz(imm) & 0x7u;
+ shift = Support::ctz(imm) & ~0x7u;
imm >>= shift;
if (imm > 0xFFu || shift > maxShift)
@@ -3835,9 +3939,9 @@ Case_BaseLdurStur:
if (o0.as<Reg>().type() != o1.as<Reg>().type() || o1.as<Reg>().type() != o2.as<Reg>().type())
goto InvalidInstruction;
- if (o0.as<Vec>().elementType() != opData.tA ||
- o1.as<Vec>().elementType() != opData.tB ||
- o2.as<Vec>().elementType() != opData.tB)
+ if (uint32_t(o0.as<Vec>().elementType()) != opData.tA ||
+ uint32_t(o1.as<Vec>().elementType()) != opData.tB ||
+ uint32_t(o2.as<Vec>().elementType()) != opData.tB)
goto InvalidInstruction;
opcode.reset(uint32_t(opData.vectorOp) << 10);
@@ -3851,9 +3955,9 @@ Case_BaseLdurStur:
if (o0.as<Reg>().type() != o1.as<Reg>().type() || !o2.as<Reg>().isVecV())
goto InvalidInstruction;
- if (o0.as<Vec>().elementType() != opData.tA ||
- o1.as<Vec>().elementType() != opData.tB ||
- o2.as<Vec>().elementType() != opData.tElement)
+ if (uint32_t(o0.as<Vec>().elementType()) != opData.tA ||
+ uint32_t(o1.as<Vec>().elementType()) != opData.tB ||
+ uint32_t(o2.as<Vec>().elementType()) != opData.tElement)
goto InvalidInstruction;
uint32_t elementIndex = o2.as<Vec>().elementIndex();
@@ -3879,13 +3983,13 @@ Case_BaseLdurStur:
case InstDB::kEncodingSimdDup: SimdDup: {
if (isign4 == ENC_OPS2(Reg, Reg)) {
// Truth table of valid encodings of `Q:1|ElementType:3`
- uint32_t kValidEncodings = B(Vec::kElementTypeB + 0) |
- B(Vec::kElementTypeH + 0) |
- B(Vec::kElementTypeS + 0) |
- B(Vec::kElementTypeB + 8) |
- B(Vec::kElementTypeH + 8) |
- B(Vec::kElementTypeS + 8) |
- B(Vec::kElementTypeD + 8) ;
+ uint32_t kValidEncodings = B(uint32_t(VecElementType::kB) + 0) |
+ B(uint32_t(VecElementType::kH) + 0) |
+ B(uint32_t(VecElementType::kS) + 0) |
+ B(uint32_t(VecElementType::kB) + 8) |
+ B(uint32_t(VecElementType::kH) + 8) |
+ B(uint32_t(VecElementType::kS) + 8) |
+ B(uint32_t(VecElementType::kD) + 8) ;
uint32_t q = diff(o0.as<Reg>().type(), RegType::kARM_VecD);
@@ -3894,7 +3998,7 @@ Case_BaseLdurStur:
//
// NOTE: This is only scalar for `dup d, x` case, otherwise the value
// would be duplicated across all vector elements (1, 2, 4, 8, or 16).
- uint32_t elementType = o0.as<Vec>().elementType();
+ uint32_t elementType = uint32_t(o0.as<Vec>().elementType());
if (q > 1 || !Support::bitTest(kValidEncodings, (q << 3) | elementType))
goto InvalidInstruction;
@@ -3915,7 +4019,7 @@ Case_BaseLdurStur:
// DUP - Vec (scalar) <- Vec[N].
uint32_t lsbIndex = diff(o0.as<Reg>().type(), RegType::kARM_VecB);
- if (lsbIndex != o1.as<Vec>().elementType() - Vec::kElementTypeB || lsbIndex > 3)
+ if (lsbIndex != diff(o1.as<Vec>().elementType(), VecElementType::kB) || lsbIndex > 3)
goto InvalidInstruction;
uint32_t imm5 = ((dstIndex << 1) | 1u) << lsbIndex;
@@ -3928,7 +4032,7 @@ Case_BaseLdurStur:
}
else {
// DUP - Vec (all) <- Vec[N].
- uint32_t elementType = o0.as<Vec>().elementType();
+ uint32_t elementType = uint32_t(o0.as<Vec>().elementType());
if (q > 1 || !Support::bitTest(kValidEncodings, (q << 3) | elementType))
goto InvalidInstruction;
@@ -3953,7 +4057,7 @@ Case_BaseLdurStur:
if (!o0.as<Vec>().hasElementIndex())
goto InvalidInstruction;
- uint32_t elementType = o0.as<Vec>().elementType();
+ uint32_t elementType = uint32_t(o0.as<Vec>().elementType());
uint32_t dstIndex = o0.as<Vec>().elementIndex();
uint32_t lsbIndex = elementType - 1u;
@@ -4056,7 +4160,7 @@ Case_BaseLdurStur:
goto InvalidImmediate;
if (Utils::isByteMaskImm8(imm64)) {
- imm8 = encodeImm64ByteMaskToImm8(imm64);
+ imm8 = Utils::encodeImm64ByteMaskToImm8(imm64);
}
else {
// Change from D to S and from 64-bit imm to 32-bit imm if this
@@ -4122,7 +4226,6 @@ Case_BaseLdurStur:
if (inverted) {
imm8 = ~imm8 & 0xFFu;
- inverted = 0;
}
cmode = B(3) | B(2) | B(1);
@@ -4155,7 +4258,6 @@ Case_BaseLdurStur:
case 3:
if (inverted) {
imm8 = ~imm8 & 0xFFu;
- inverted = 0;
}
op = 1;
@@ -4443,7 +4545,7 @@ Case_BaseLdurStur:
if (m.hasBaseReg()) {
// [Base {Offset | Index}]
if (m.hasIndex()) {
- uint32_t opt = armShiftOpToLdStOptMap[m.predicate()];
+ uint32_t opt = armShiftOpToLdStOptMap[size_t(m.shiftOp())];
if (opt == 0xFFu)
goto InvalidAddress;
@@ -4667,7 +4769,7 @@ Case_SimdLdurStur:
uint32_t q = 0;
uint32_t rm = 0;
uint32_t rn = m.baseId();
- uint32_t sz = v.elementType() - Vec::kElementTypeB;
+ uint32_t sz = diff(v.elementType(), VecElementType::kB);
uint32_t opcSsize = sz;
uint32_t offsetPossibility = 0;
@@ -4997,9 +5099,7 @@ EmitDone:
#endif
}
- resetExtraReg();
- resetInstOptions();
- resetInlineComment();
+ resetState();
writer.done(this);
return kErrorOk;
@@ -5025,9 +5125,7 @@ Failed:
#ifndef ASMJIT_NO_LOGGING
return EmitterUtils::logInstructionFailed(this, err, instId, options, o0, o1, o2, opExt);
#else
- resetExtraReg();
- resetInstOptions();
- resetInlineComment();
+ resetState();
return reportError(err);
#endif
}
@@ -5103,6 +5201,10 @@ Error Assembler::align(AlignMode alignMode, uint32_t alignment) {
Error Assembler::onAttach(CodeHolder* code) noexcept {
ASMJIT_PROPAGATE(Base::onAttach(code));
+
+ _instructionAlignment = uint8_t(4);
+ assignEmitterFuncs(this);
+
return kErrorOk;
}
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64assembler.h b/3rdparty/asmjit/src/asmjit/arm/a64assembler.h
index f1ac72b8d56..319321576d8 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64assembler.h
+++ b/3rdparty/asmjit/src/asmjit/arm/a64assembler.h
@@ -23,22 +23,11 @@ class ASMJIT_VIRTAPI Assembler
public:
typedef BaseAssembler Base;
- //! \name Construction / Destruction
+ //! \name Construction & Destruction
//! \{
ASMJIT_API Assembler(CodeHolder* code = nullptr) noexcept;
- ASMJIT_API virtual ~Assembler() noexcept;
-
- //! \}
-
- //! \name Accessors
- //! \{
-
- //! Gets whether the current ARM mode is THUMB (alternative to 32-bit ARM encoding).
- inline bool isInThumbMode() const noexcept { return _environment.isArchThumb(); }
-
- //! Gets the current code alignment of the current mode (ARM vs THUMB).
- inline uint32_t codeAlignment() const noexcept { return isInThumbMode() ? 2 : 4; }
+ ASMJIT_API ~Assembler() noexcept override;
//! \}
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64builder.cpp b/3rdparty/asmjit/src/asmjit/arm/a64builder.cpp
index 3a52b2a578c..d29b0a498b9 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64builder.cpp
+++ b/3rdparty/asmjit/src/asmjit/arm/a64builder.cpp
@@ -17,8 +17,6 @@ ASMJIT_BEGIN_SUB_NAMESPACE(a64)
Builder::Builder(CodeHolder* code) noexcept : BaseBuilder() {
_archMask = uint64_t(1) << uint32_t(Arch::kAArch64);
- assignEmitterFuncs(this);
-
if (code)
code->attach(this);
}
@@ -28,13 +26,19 @@ Builder::~Builder() noexcept {}
// =====================
Error Builder::onAttach(CodeHolder* code) noexcept {
- return Base::onAttach(code);
+ ASMJIT_PROPAGATE(Base::onAttach(code));
+
+ _instructionAlignment = uint8_t(4);
+ assignEmitterFuncs(this);
+
+ return kErrorOk;
}
Error Builder::onDetach(CodeHolder* code) noexcept {
return Base::onDetach(code);
}
+
// a64::Builder - Finalize
// =======================
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64builder.h b/3rdparty/asmjit/src/asmjit/arm/a64builder.h
index adc99aafc8c..cab1083172b 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64builder.h
+++ b/3rdparty/asmjit/src/asmjit/arm/a64builder.h
@@ -29,7 +29,7 @@ public:
//! \{
ASMJIT_API explicit Builder(CodeHolder* code = nullptr) noexcept;
- ASMJIT_API virtual ~Builder() noexcept;
+ ASMJIT_API ~Builder() noexcept override;
//! \}
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64compiler.cpp b/3rdparty/asmjit/src/asmjit/arm/a64compiler.cpp
index d6c4ed28ff2..765fd4b9dee 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64compiler.cpp
+++ b/3rdparty/asmjit/src/asmjit/arm/a64compiler.cpp
@@ -18,8 +18,6 @@ ASMJIT_BEGIN_SUB_NAMESPACE(a64)
Compiler::Compiler(CodeHolder* code) noexcept : BaseCompiler() {
_archMask = uint64_t(1) << uint32_t(Arch::kAArch64);
- assignEmitterFuncs(this);
-
if (code)
code->attach(this);
}
@@ -37,6 +35,9 @@ Error Compiler::onAttach(CodeHolder* code) noexcept {
return err;
}
+ _instructionAlignment = uint8_t(4);
+ assignEmitterFuncs(this);
+
return kErrorOk;
}
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64compiler.h b/3rdparty/asmjit/src/asmjit/arm/a64compiler.h
index bed408a98fd..64f82f62538 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64compiler.h
+++ b/3rdparty/asmjit/src/asmjit/arm/a64compiler.h
@@ -3,8 +3,8 @@
// See asmjit.h or LICENSE.md for license and copyright information
// SPDX-License-Identifier: Zlib
-#ifndef ASMJIT_ARM_ARMCOMPILER_H_INCLUDED
-#define ASMJIT_ARM_ARMCOMPILER_H_INCLUDED
+#ifndef ASMJIT_ARM_A64COMPILER_H_INCLUDED
+#define ASMJIT_ARM_A64COMPILER_H_INCLUDED
#include "../core/api-config.h"
#ifndef ASMJIT_NO_COMPILER
@@ -30,7 +30,7 @@ public:
//! \{
ASMJIT_API explicit Compiler(CodeHolder* code = nullptr) noexcept;
- ASMJIT_API virtual ~Compiler() noexcept;
+ ASMJIT_API ~Compiler() noexcept override;
//! \}
@@ -39,74 +39,81 @@ public:
//! \cond INTERNAL
template<typename RegT, typename Type>
- inline RegT _newRegInternal(const Type& type) {
+ ASMJIT_INLINE_NODEBUG RegT _newRegInternal(const Type& type) {
RegT reg(Globals::NoInit);
_newReg(&reg, type, nullptr);
return reg;
}
- template<typename RegT, typename Type, typename... Args>
- inline RegT _newRegInternal(const Type& type, const char* s, Args&&... args) {
+ template<typename RegT, typename Type>
+ ASMJIT_INLINE_NODEBUG RegT _newRegInternal(const Type& type, const char* s) {
#ifndef ASMJIT_NO_LOGGING
RegT reg(Globals::NoInit);
- if (sizeof...(Args) == 0)
- _newReg(&reg, type, s);
- else
- _newRegFmt(&reg, type, s, std::forward<Args>(args)...);
+ _newReg(&reg, type, s);
return reg;
#else
- DebugUtils::unused(std::forward<Args>(args)...);
+ DebugUtils::unused(s);
+ return _newRegInternal<RegT>(type);
+#endif
+ }
+
+ template<typename RegT, typename Type, typename... Args>
+ ASMJIT_INLINE_NODEBUG RegT _newRegInternal(const Type& type, const char* s, Args&&... args) {
+#ifndef ASMJIT_NO_LOGGING
RegT reg(Globals::NoInit);
- _newReg(&reg, type, nullptr);
+ _newRegFmt(&reg, type, s, std::forward<Args>(args)...);
return reg;
+#else
+ DebugUtils::unused(s, std::forward<Args>(args)...);
+ return _newRegInternal<RegT>(type);
#endif
}
//! \endcond
template<typename RegT, typename... Args>
- inline RegT newSimilarReg(const RegT& ref, Args&&... args) {
+ ASMJIT_INLINE_NODEBUG RegT newSimilarReg(const RegT& ref, Args&&... args) {
return _newRegInternal<RegT>(ref, std::forward<Args>(args)...);
}
template<typename... Args>
- inline Reg newReg(TypeId typeId, Args&&... args) { return _newRegInternal<Reg>(typeId, std::forward<Args>(args)...); }
+ ASMJIT_INLINE_NODEBUG Reg newReg(TypeId typeId, Args&&... args) { return _newRegInternal<Reg>(typeId, std::forward<Args>(args)...); }
template<typename... Args>
- inline Gp newGp(TypeId typeId, Args&&... args) { return _newRegInternal<Gp>(typeId, std::forward<Args>(args)...); }
+ ASMJIT_INLINE_NODEBUG Gp newGp(TypeId typeId, Args&&... args) { return _newRegInternal<Gp>(typeId, std::forward<Args>(args)...); }
template<typename... Args>
- inline Vec newVec(TypeId typeId, Args&&... args) { return _newRegInternal<Vec>(typeId, std::forward<Args>(args)...); }
+ ASMJIT_INLINE_NODEBUG Vec newVec(TypeId typeId, Args&&... args) { return _newRegInternal<Vec>(typeId, std::forward<Args>(args)...); }
template<typename... Args>
- inline Gp newInt32(Args&&... args) { return _newRegInternal<Gp>(TypeId::kInt32, std::forward<Args>(args)...); }
+ ASMJIT_INLINE_NODEBUG Gp newInt32(Args&&... args) { return _newRegInternal<Gp>(TypeId::kInt32, std::forward<Args>(args)...); }
template<typename... Args>
- inline Gp newUInt32(Args&&... args) { return _newRegInternal<Gp>(TypeId::kUInt32, std::forward<Args>(args)...); }
+ ASMJIT_INLINE_NODEBUG Gp newUInt32(Args&&... args) { return _newRegInternal<Gp>(TypeId::kUInt32, std::forward<Args>(args)...); }
template<typename... Args>
- inline Gp newInt64(Args&&... args) { return _newRegInternal<Gp>(TypeId::kInt64, std::forward<Args>(args)...); }
+ ASMJIT_INLINE_NODEBUG Gp newInt64(Args&&... args) { return _newRegInternal<Gp>(TypeId::kInt64, std::forward<Args>(args)...); }
template<typename... Args>
- inline Gp newUInt64(Args&&... args) { return _newRegInternal<Gp>(TypeId::kUInt64, std::forward<Args>(args)...); }
+ ASMJIT_INLINE_NODEBUG Gp newUInt64(Args&&... args) { return _newRegInternal<Gp>(TypeId::kUInt64, std::forward<Args>(args)...); }
template<typename... Args>
- inline Gp newIntPtr(Args&&... args) { return _newRegInternal<Gp>(TypeId::kIntPtr, std::forward<Args>(args)...); }
+ ASMJIT_INLINE_NODEBUG Gp newIntPtr(Args&&... args) { return _newRegInternal<Gp>(TypeId::kIntPtr, std::forward<Args>(args)...); }
template<typename... Args>
- inline Gp newUIntPtr(Args&&... args) { return _newRegInternal<Gp>(TypeId::kUIntPtr, std::forward<Args>(args)...); }
+ ASMJIT_INLINE_NODEBUG Gp newUIntPtr(Args&&... args) { return _newRegInternal<Gp>(TypeId::kUIntPtr, std::forward<Args>(args)...); }
template<typename... Args>
- inline Gp newGpw(Args&&... args) { return _newRegInternal<Gp>(TypeId::kUInt32, std::forward<Args>(args)...); }
+ ASMJIT_INLINE_NODEBUG Gp newGpw(Args&&... args) { return _newRegInternal<Gp>(TypeId::kUInt32, std::forward<Args>(args)...); }
template<typename... Args>
- inline Gp newGpx(Args&&... args) { return _newRegInternal<Gp>(TypeId::kUInt64, std::forward<Args>(args)...); }
+ ASMJIT_INLINE_NODEBUG Gp newGpx(Args&&... args) { return _newRegInternal<Gp>(TypeId::kUInt64, std::forward<Args>(args)...); }
template<typename... Args>
- inline Gp newGpz(Args&&... args) { return _newRegInternal<Gp>(TypeId::kUIntPtr, std::forward<Args>(args)...); }
+ ASMJIT_INLINE_NODEBUG Gp newGpz(Args&&... args) { return _newRegInternal<Gp>(TypeId::kUIntPtr, std::forward<Args>(args)...); }
template<typename... Args>
- inline Vec newVecS(Args&&... args) { return _newRegInternal<Vec>(TypeId::kFloat32, std::forward<Args>(args)...); }
+ ASMJIT_INLINE_NODEBUG Vec newVecS(Args&&... args) { return _newRegInternal<Vec>(TypeId::kFloat32, std::forward<Args>(args)...); }
template<typename... Args>
- inline Vec newVecD(Args&&... args) { return _newRegInternal<Vec>(TypeId::kFloat64, std::forward<Args>(args)...); }
+ ASMJIT_INLINE_NODEBUG Vec newVecD(Args&&... args) { return _newRegInternal<Vec>(TypeId::kFloat64, std::forward<Args>(args)...); }
template<typename... Args>
- inline Vec newVecQ(Args&&... args) { return _newRegInternal<Vec>(TypeId::kUInt8x16, std::forward<Args>(args)...); }
+ ASMJIT_INLINE_NODEBUG Vec newVecQ(Args&&... args) { return _newRegInternal<Vec>(TypeId::kUInt8x16, std::forward<Args>(args)...); }
//! \}
@@ -114,7 +121,7 @@ public:
//! \{
//! Creates a new memory chunk allocated on the current function's stack.
- inline Mem newStack(uint32_t size, uint32_t alignment, const char* name = nullptr) {
+ ASMJIT_INLINE_NODEBUG Mem newStack(uint32_t size, uint32_t alignment, const char* name = nullptr) {
Mem m(Globals::NoInit);
_newStack(&m, size, alignment, name);
return m;
@@ -126,38 +133,38 @@ public:
//! \{
//! Put data to a constant-pool and get a memory reference to it.
- inline Mem newConst(ConstPoolScope scope, const void* data, size_t size) {
+ ASMJIT_INLINE_NODEBUG 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 (8 bits).
- inline Mem newByteConst(ConstPoolScope scope, uint8_t val) noexcept { return newConst(scope, &val, 1); }
+ ASMJIT_INLINE_NODEBUG Mem newByteConst(ConstPoolScope scope, uint8_t val) noexcept { return newConst(scope, &val, 1); }
//! Put a HWORD `val` to a constant-pool (16 bits).
- inline Mem newHWordConst(ConstPoolScope scope, uint16_t val) noexcept { return newConst(scope, &val, 2); }
+ ASMJIT_INLINE_NODEBUG Mem newHWordConst(ConstPoolScope scope, uint16_t val) noexcept { return newConst(scope, &val, 2); }
//! Put a WORD `val` to a constant-pool (32 bits).
- inline Mem newWordConst(ConstPoolScope scope, uint32_t val) noexcept { return newConst(scope, &val, 4); }
+ ASMJIT_INLINE_NODEBUG Mem newWordConst(ConstPoolScope scope, uint32_t val) noexcept { return newConst(scope, &val, 4); }
//! Put a DWORD `val` to a constant-pool (64 bits).
- inline Mem newDWordConst(ConstPoolScope scope, uint64_t val) noexcept { return newConst(scope, &val, 8); }
+ ASMJIT_INLINE_NODEBUG Mem newDWordConst(ConstPoolScope scope, uint64_t val) noexcept { return newConst(scope, &val, 8); }
//! Put a WORD `val` to a constant-pool.
- inline Mem newInt16Const(ConstPoolScope scope, int16_t val) noexcept { return newConst(scope, &val, 2); }
+ ASMJIT_INLINE_NODEBUG Mem newInt16Const(ConstPoolScope scope, int16_t val) noexcept { return newConst(scope, &val, 2); }
//! Put a WORD `val` to a constant-pool.
- inline Mem newUInt16Const(ConstPoolScope scope, uint16_t val) noexcept { return newConst(scope, &val, 2); }
+ ASMJIT_INLINE_NODEBUG Mem newUInt16Const(ConstPoolScope scope, uint16_t val) noexcept { return newConst(scope, &val, 2); }
//! Put a DWORD `val` to a constant-pool.
- inline Mem newInt32Const(ConstPoolScope scope, int32_t val) noexcept { return newConst(scope, &val, 4); }
+ ASMJIT_INLINE_NODEBUG Mem newInt32Const(ConstPoolScope scope, int32_t val) noexcept { return newConst(scope, &val, 4); }
//! Put a DWORD `val` to a constant-pool.
- inline Mem newUInt32Const(ConstPoolScope scope, uint32_t val) noexcept { return newConst(scope, &val, 4); }
+ ASMJIT_INLINE_NODEBUG Mem newUInt32Const(ConstPoolScope scope, uint32_t val) noexcept { return newConst(scope, &val, 4); }
//! Put a QWORD `val` to a constant-pool.
- inline Mem newInt64Const(ConstPoolScope scope, int64_t val) noexcept { return newConst(scope, &val, 8); }
+ ASMJIT_INLINE_NODEBUG Mem newInt64Const(ConstPoolScope scope, int64_t val) noexcept { return newConst(scope, &val, 8); }
//! Put a QWORD `val` to a constant-pool.
- inline Mem newUInt64Const(ConstPoolScope scope, uint64_t val) noexcept { return newConst(scope, &val, 8); }
+ ASMJIT_INLINE_NODEBUG 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(ConstPoolScope scope, float val) noexcept { return newConst(scope, &val, 4); }
+ ASMJIT_INLINE_NODEBUG Mem newFloatConst(ConstPoolScope scope, float val) noexcept { return newConst(scope, &val, 4); }
//! Put a DP-FP `val` to a constant-pool.
- inline Mem newDoubleConst(ConstPoolScope scope, double val) noexcept { return newConst(scope, &val, 8); }
+ ASMJIT_INLINE_NODEBUG Mem newDoubleConst(ConstPoolScope scope, double val) noexcept { return newConst(scope, &val, 8); }
//! \}
@@ -165,7 +172,7 @@ public:
//! \{
//! Force the compiler to not follow the conditional or unconditional jump.
- inline Compiler& unfollow() noexcept { _instOptions |= InstOptions::kUnfollow; return *this; }
+ ASMJIT_INLINE_NODEBUG Compiler& unfollow() noexcept { _instOptions |= InstOptions::kUnfollow; return *this; }
//! \}
@@ -177,7 +184,7 @@ public:
//! \note At the moment this instruction is only useful to load a stack allocated address into a GP register
//! for further use. It makes very little sense to use it for anything else. The semantics of this instruction
//! is the same as X86 `LEA` (load effective address) instruction.
- inline Error loadAddressOf(const Gp& o0, const Mem& o1) { return _emitter()->_emitI(Inst::kIdAdr, o0, o1); }
+ ASMJIT_INLINE_NODEBUG Error loadAddressOf(const Gp& o0, const Mem& o1) { return _emitter()->_emitI(Inst::kIdAdr, o0, o1); }
//! \}
@@ -185,7 +192,7 @@ public:
//! \{
//! Invoke a function call without `target` type enforcement.
- inline Error invoke_(InvokeNode** out, const Operand_& target, const FuncSignature& signature) {
+ ASMJIT_INLINE_NODEBUG Error invoke_(InvokeNode** out, const Operand_& target, const FuncSignature& signature) {
return addInvokeNode(out, Inst::kIdBlr, target, signature);
}
@@ -194,22 +201,22 @@ public:
//! 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); }
+ ASMJIT_INLINE_NODEBUG Error invoke(InvokeNode** out, const Gp& target, const FuncSignature& signature) { return invoke_(out, target, signature); }
//! \overload
- inline Error invoke(InvokeNode** out, const Mem& target, const FuncSignature& signature) { return invoke_(out, target, signature); }
+ ASMJIT_INLINE_NODEBUG Error invoke(InvokeNode** out, const Mem& target, const FuncSignature& signature) { return invoke_(out, target, signature); }
//! \overload
- inline Error invoke(InvokeNode** out, const Label& target, const FuncSignature& signature) { return invoke_(out, target, signature); }
+ ASMJIT_INLINE_NODEBUG Error invoke(InvokeNode** out, const Label& target, const FuncSignature& signature) { return invoke_(out, target, signature); }
//! \overload
- inline Error invoke(InvokeNode** out, const Imm& target, const FuncSignature& signature) { return invoke_(out, target, signature); }
+ ASMJIT_INLINE_NODEBUG Error invoke(InvokeNode** out, const Imm& target, const FuncSignature& signature) { return invoke_(out, target, signature); }
//! \overload
- inline Error invoke(InvokeNode** out, uint64_t target, const FuncSignature& signature) { return invoke_(out, Imm(int64_t(target)), signature); }
+ ASMJIT_INLINE_NODEBUG Error invoke(InvokeNode** out, uint64_t target, const FuncSignature& signature) { return invoke_(out, Imm(int64_t(target)), signature); }
//! Return.
- inline Error ret() { return addRet(Operand(), Operand()); }
+ ASMJIT_INLINE_NODEBUG Error ret() { return addRet(Operand(), Operand()); }
//! \overload
- inline Error ret(const BaseReg& o0) { return addRet(o0, Operand()); }
+ ASMJIT_INLINE_NODEBUG Error ret(const BaseReg& o0) { return addRet(o0, Operand()); }
//! \overload
- inline Error ret(const BaseReg& o0, const BaseReg& o1) { return addRet(o0, o1); }
+ ASMJIT_INLINE_NODEBUG Error ret(const BaseReg& o0, const BaseReg& o1) { return addRet(o0, o1); }
//! \}
@@ -219,7 +226,7 @@ public:
using EmitterExplicitT<Compiler>::br;
//! Adds a jump to the given `target` with the provided jump `annotation`.
- inline Error br(const BaseReg& target, JumpAnnotation* annotation) { return emitAnnotatedJump(Inst::kIdBr, target, annotation); }
+ ASMJIT_INLINE_NODEBUG Error br(const BaseReg& target, JumpAnnotation* annotation) { return emitAnnotatedJump(Inst::kIdBr, target, annotation); }
//! \}
@@ -244,4 +251,4 @@ public:
ASMJIT_END_SUB_NAMESPACE
#endif // !ASMJIT_NO_COMPILER
-#endif // ASMJIT_ARM_ARMCOMPILER_H_INCLUDED
+#endif // ASMJIT_ARM_A64COMPILER_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64emithelper.cpp b/3rdparty/asmjit/src/asmjit/arm/a64emithelper.cpp
index 1e8da619a6b..0cf098250a3 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64emithelper.cpp
+++ b/3rdparty/asmjit/src/asmjit/arm/a64emithelper.cpp
@@ -169,7 +169,7 @@ Error EmitHelper::emitArgMove(
if (TypeUtils::isInt(dstTypeId)) {
if (TypeUtils::isInt(srcTypeId)) {
- uint32_t x = dstSize == 8;
+ uint32_t x = uint32_t(dstSize == 8);
dst.setSignature(OperandSignature{x ? uint32_t(GpX::kSignature) : uint32_t(GpW::kSignature)});
_emitter->setInlineComment(comment);
@@ -186,7 +186,7 @@ Error EmitHelper::emitArgMove(
case TypeId::kInt16: instId = Inst::kIdLdrsh; break;
case TypeId::kUInt16: instId = Inst::kIdLdrh; break;
case TypeId::kInt32: instId = x ? Inst::kIdLdrsw : Inst::kIdLdr; break;
- case TypeId::kUInt32: instId = Inst::kIdLdr; x = 0; break;
+ case TypeId::kUInt32: instId = Inst::kIdLdr; break;
case TypeId::kInt64: instId = Inst::kIdLdr; break;
case TypeId::kUInt64: instId = Inst::kIdLdr; break;
default:
@@ -312,6 +312,12 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitProlog(const FuncFrame& frame) {
{ Inst::kIdStr_v, Inst::kIdStp_v }
}};
+ // Emit: 'bti' (indirect branch protection).
+ if (frame.hasIndirectBranchProtection()) {
+ // TODO: The instruction is not available at the moment (would be ABI break).
+ // ASMJIT_PROPAGATE(emitter->bti());
+ }
+
uint32_t adjustInitialOffset = pei.sizeTotal;
for (RegGroup group : Support::EnumValues<RegGroup, RegGroup::kGp, RegGroup::kVec>{}) {
@@ -339,7 +345,7 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitProlog(const FuncFrame& frame) {
else
ASMJIT_PROPAGATE(emitter->emit(insts.pairInstId, regs[0], regs[1], mem));
- mem.resetToFixedOffset();
+ mem.resetOffsetMode();
if (i == 0 && frame.hasPreservedFP()) {
ASMJIT_PROPAGATE(emitter->mov(x29, sp));
@@ -421,7 +427,7 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitEpilog(const FuncFrame& frame) {
else
ASMJIT_PROPAGATE(emitter->emit(insts.pairInstId, regs[0], regs[1], mem));
- mem.resetToFixedOffset();
+ mem.resetOffsetMode();
}
}
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64emithelper_p.h b/3rdparty/asmjit/src/asmjit/arm/a64emithelper_p.h
index b1ba1a92960..6e10f9eaabe 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64emithelper_p.h
+++ b/3rdparty/asmjit/src/asmjit/arm/a64emithelper_p.h
@@ -3,8 +3,8 @@
// See asmjit.h or LICENSE.md for license and copyright information
// SPDX-License-Identifier: Zlib
-#ifndef ASMJIT_ARM_ARMEMITHELPER_P_H_INCLUDED
-#define ASMJIT_ARM_ARMEMITHELPER_P_H_INCLUDED
+#ifndef ASMJIT_ARM_A64EMITHELPER_P_H_INCLUDED
+#define ASMJIT_ARM_A64EMITHELPER_P_H_INCLUDED
#include "../core/api-config.h"
@@ -21,7 +21,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(a64)
class EmitHelper : public BaseEmitHelper {
public:
- inline explicit EmitHelper(BaseEmitter* emitter = nullptr) noexcept
+ ASMJIT_INLINE_NODEBUG explicit EmitHelper(BaseEmitter* emitter = nullptr) noexcept
: BaseEmitHelper(emitter) {}
Error emitRegMove(
@@ -47,4 +47,4 @@ void assignEmitterFuncs(BaseEmitter* emitter);
ASMJIT_END_SUB_NAMESPACE
-#endif // ASMJIT_ARM_ARMEMITHELPER_P_H_INCLUDED
+#endif // ASMJIT_ARM_A64EMITHELPER_P_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64emitter.h b/3rdparty/asmjit/src/asmjit/arm/a64emitter.h
index 54354eaca84..15c91e0ba4a 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64emitter.h
+++ b/3rdparty/asmjit/src/asmjit/arm/a64emitter.h
@@ -11,6 +11,14 @@
#include "../arm/a64instdb.h"
#include "../arm/a64operand.h"
+// MSVC targeting AArch64 defines a lot of macros without underscores clashing
+// with AArch64 instruction names. We have to workaround until it's fixed in SDK.
+#if defined(_MSC_VER) && defined(mvn)
+ #define ASMJIT_RESTORE_MSVC_AARCH64_MACROS
+ #pragma push_macro("mvn")
+ #undef mvn
+#endif
+
ASMJIT_BEGIN_SUB_NAMESPACE(a64)
#define ASMJIT_INST_0x(NAME, ID) \
@@ -63,7 +71,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(a64)
//! ARM emitter.
//!
//! NOTE: This class cannot be instantiated, you can only cast to it and use it as emitter that emits to either
-//! \ref Assembler, \ref Builder, or \ref Compiler (use withcaution with \ref Compiler as it expects virtual
+//! \ref Assembler, \ref Builder, or \ref Compiler (use with caution with \ref Compiler as it expects virtual
//! registers to be used).
template<typename This>
struct EmitterExplicitT {
@@ -71,22 +79,22 @@ struct EmitterExplicitT {
// 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); }
+ ASMJIT_ATTRIBUTE_NO_SANITIZE_UNDEF ASMJIT_INLINE_NODEBUG This* _emitter() noexcept { return static_cast<This*>(this); }
+ ASMJIT_ATTRIBUTE_NO_SANITIZE_UNDEF ASMJIT_INLINE_NODEBUG const This* _emitter() const noexcept { return static_cast<const This*>(this); }
//! \endcond
- // --------------------------------------------------------------------------
- // [Options]
- // --------------------------------------------------------------------------
-protected:
- inline This& _addInstOptions(InstOptions options) noexcept {
- static_cast<This*>(this)->addInstOptions(options);
- return *static_cast<This*>(this);
- }
+ //! \name Native Registers
+ //! \{
+
+ //! Returns either 32-bit or 64-bit GP register of the given `id` depending on the emitter's architecture.
+ inline Gp gpz(uint32_t id) const noexcept { return Gp(_emitter()->_gpSignature, id); }
+ //! Clones the given `reg` to either 32-bit or 64-bit GP register depending on the emitter's architecture.
+ inline Gp gpz(const Gp& reg) const noexcept { return Gp(_emitter()->_gpSignature, reg.id()); }
+
+ //! \}
-public:
//! \name General Purpose Instructions
//! \{
@@ -517,6 +525,8 @@ public:
ASMJIT_INST_2x(ldxrb, Ldxrb, Gp, Mem)
ASMJIT_INST_2x(ldxrh, Ldxrh, Gp, Mem)
+ ASMJIT_INST_2x(prfm, Prfm, Imm, Mem)
+
ASMJIT_INST_2x(stadd, Stadd, Gp, Mem)
ASMJIT_INST_2x(staddb, Staddb, Gp, Mem)
ASMJIT_INST_2x(staddh, Staddh, Gp, Mem)
@@ -1111,14 +1121,14 @@ public:
//! \}
- //! \name FJCVTZS Instruction (ARMv8.3-A)
+ //! \name JSCVT Instruction (ARMv8.3-A)
//! \{
ASMJIT_INST_2x(fjcvtzs, Fjcvtzs_v, Gp, Vec);
//! \}
- //! \name FP16FML Instructions (ARMv8.4-A, optional in ARMv8.2-A)
+ //! \name FHM Instructions
//! \{
ASMJIT_INST_3x(fmlal, Fmlal_v, Vec, Vec, Vec);
@@ -1225,4 +1235,9 @@ class Emitter : public BaseEmitter, public EmitterExplicitT<Emitter> {
ASMJIT_END_SUB_NAMESPACE
+// Restore undefined MSVC AArch64 macros.
+#if defined(ASMJIT_RESTORE_MSVC_AARCH64_MACROS)
+ #pragma pop_macro("mvn")
+#endif
+
#endif // ASMJIT_ARM_A64EMITTER_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64formatter.cpp b/3rdparty/asmjit/src/asmjit/arm/a64formatter.cpp
index bccb68b99b0..94ef3ee59e9 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64formatter.cpp
+++ b/3rdparty/asmjit/src/asmjit/arm/a64formatter.cpp
@@ -4,7 +4,7 @@
// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
-#ifndef ASMJIT_NO_LOGGING
+#if !defined(ASMJIT_NO_AARCH64) && !defined(ASMJIT_NO_LOGGING)
#include "../core/misc_p.h"
#include "../core/support.h"
@@ -19,243 +19,6 @@
ASMJIT_BEGIN_SUB_NAMESPACE(a64)
-// a64::FormatterInternal - Format Register
-// ========================================
-
-ASMJIT_FAVOR_SIZE Error FormatterInternal::formatRegister(
- String& sb,
- FormatFlags flags,
- const BaseEmitter* emitter,
- Arch arch,
- RegType regType,
- uint32_t rId,
- uint32_t elementType,
- uint32_t elementIndex) noexcept {
-
- DebugUtils::unused(flags);
- DebugUtils::unused(arch);
-
- static const char bhsdq[] = "bhsdq";
-
- bool virtRegFormatted = false;
-
-#ifndef ASMJIT_NO_COMPILER
- if (Operand::isVirtId(rId)) {
- if (emitter && emitter->isCompiler()) {
- const BaseCompiler* cc = static_cast<const BaseCompiler*>(emitter);
- if (cc->isVirtIdValid(rId)) {
- VirtReg* vReg = cc->virtRegById(rId);
- 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))));
-
- virtRegFormatted = true;
- }
- }
- }
-#else
- DebugUtils::unused(emitter, flags);
-#endif
-
- if (!virtRegFormatted) {
- char letter = '\0';
- switch (regType) {
- case RegType::kARM_GpW:
- if (rId == Gp::kIdZr)
- return sb.append("wzr");
- if (rId == Gp::kIdSp)
- return sb.append("wsp");
-
- letter = 'w';
- break;
-
- case RegType::kARM_GpX:
- if (rId == Gp::kIdZr)
- return sb.append("xzr");
- if (rId == Gp::kIdSp)
- return sb.append("sp");
-
- letter = 'x';
- break;
-
- case RegType::kARM_VecB:
- case RegType::kARM_VecH:
- case RegType::kARM_VecS:
- case RegType::kARM_VecD:
- case RegType::kARM_VecV:
- letter = bhsdq[uint32_t(regType) - uint32_t(RegType::kARM_VecB)];
- if (elementType)
- letter = 'v';
- break;
-
- default:
- ASMJIT_PROPAGATE(sb.appendFormat("<Reg-%u>?$u", uint32_t(regType), rId));
- break;
- }
-
- if (letter)
- ASMJIT_PROPAGATE(sb.appendFormat("%c%u", letter, rId));
- }
-
- if (elementType) {
- char elementLetter = '\0';
- uint32_t elementCount = 0;
-
- switch (elementType) {
- case Vec::kElementTypeB:
- elementLetter = 'b';
- elementCount = 16;
- break;
-
- case Vec::kElementTypeH:
- elementLetter = 'h';
- elementCount = 8;
- break;
-
- case Vec::kElementTypeS:
- elementLetter = 's';
- elementCount = 4;
- break;
-
- case Vec::kElementTypeD:
- elementLetter = 'd';
- elementCount = 2;
- break;
-
- default:
- return sb.append(".<Unknown>");
- }
-
- if (elementLetter) {
- if (elementIndex == 0xFFFFFFFFu) {
- if (regType == RegType::kARM_VecD)
- elementCount /= 2u;
- ASMJIT_PROPAGATE(sb.appendFormat(".%u%c", elementCount, elementLetter));
- }
- else {
- ASMJIT_PROPAGATE(sb.appendFormat(".%c[%u]", elementLetter, elementIndex));
- }
- }
- }
-
- return kErrorOk;
-}
-
-// a64::FormatterInternal - Format Operand
-// =======================================
-
-ASMJIT_FAVOR_SIZE Error FormatterInternal::formatOperand(
- String& sb,
- FormatFlags flags,
- const BaseEmitter* emitter,
- Arch arch,
- const Operand_& op) noexcept {
-
- if (op.isReg()) {
- const BaseReg& reg = op.as<BaseReg>();
-
- uint32_t elementType = op.as<Vec>().elementType();
- uint32_t elementIndex = op.as<Vec>().elementIndex();
-
- if (!op.as<Vec>().hasElementIndex())
- elementIndex = 0xFFFFFFFFu;
-
- return formatRegister(sb, flags, emitter, arch, reg.type(), reg.id(), elementType, elementIndex);
- }
-
- if (op.isMem()) {
- const Mem& m = op.as<Mem>();
- ASMJIT_PROPAGATE(sb.append('['));
-
- if (m.hasBase()) {
- if (m.hasBaseLabel()) {
- ASMJIT_PROPAGATE(Formatter::formatLabel(sb, flags, emitter, m.baseId()));
- }
- else {
- FormatFlags modifiedFlags = flags;
- if (m.isRegHome()) {
- ASMJIT_PROPAGATE(sb.append('&'));
- modifiedFlags &= ~FormatFlags::kRegCasts;
- }
- ASMJIT_PROPAGATE(formatRegister(sb, modifiedFlags, emitter, arch, m.baseType(), m.baseId()));
- }
- }
- else {
- // ARM really requires base.
- if (m.hasIndex() || m.hasOffset()) {
- ASMJIT_PROPAGATE(sb.append("<None>"));
- }
- }
-
- // The post index makes it look like there was another operand, but it's
- // still the part of AsmJit's `arm::Mem` operand so it's consistent with
- // other architectures.
- if (m.isPostIndex())
- ASMJIT_PROPAGATE(sb.append(']'));
-
- if (m.hasIndex()) {
- ASMJIT_PROPAGATE(sb.append(", "));
- ASMJIT_PROPAGATE(formatRegister(sb, flags, emitter, arch, m.indexType(), m.indexId()));
- }
-
- if (m.hasOffset()) {
- ASMJIT_PROPAGATE(sb.append(", "));
-
- int64_t off = int64_t(m.offset());
- uint32_t base = 10;
-
- if (Support::test(flags, FormatFlags::kHexOffsets) && uint64_t(off) > 9)
- base = 16;
-
- if (base == 10) {
- ASMJIT_PROPAGATE(sb.appendInt(off, base));
- }
- else {
- ASMJIT_PROPAGATE(sb.append("0x"));
- ASMJIT_PROPAGATE(sb.appendUInt(uint64_t(off), base));
- }
- }
-
- if (m.hasShift()) {
- ASMJIT_PROPAGATE(sb.append(' '));
- if (!m.isPreOrPost())
- ASMJIT_PROPAGATE(formatShiftOp(sb, (ShiftOp)m.predicate()));
- ASMJIT_PROPAGATE(sb.appendFormat(" %u", m.shift()));
- }
-
- if (!m.isPostIndex())
- ASMJIT_PROPAGATE(sb.append(']'));
-
- if (m.isPreIndex())
- ASMJIT_PROPAGATE(sb.append('!'));
-
- return kErrorOk;
- }
-
- if (op.isImm()) {
- const Imm& i = op.as<Imm>();
- int64_t val = i.value();
-
- if (Support::test(flags, FormatFlags::kHexImms) && uint64_t(val) > 9) {
- ASMJIT_PROPAGATE(sb.append("0x"));
- return sb.appendUInt(uint64_t(val), 16);
- }
- else {
- return sb.appendInt(val, 10);
- }
- }
-
- if (op.isLabel()) {
- return Formatter::formatLabel(sb, flags, emitter, op.id());
- }
-
- return sb.append("<None>");
-}
-
// a64::FormatterInternal - Format Instruction
// ===========================================
@@ -266,12 +29,10 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatInstruction(
Arch arch,
const BaseInst& inst, const Operand_* operands, size_t opCount) noexcept {
- DebugUtils::unused(arch);
-
// Format instruction options and instruction mnemonic.
InstId instId = inst.realId();
- if (instId < Inst::_kIdCount)
- ASMJIT_PROPAGATE(InstInternal::instIdToString(arch, instId, sb));
+ if (instId != Inst::kIdNone && instId < Inst::_kIdCount)
+ ASMJIT_PROPAGATE(InstInternal::instIdToString(instId, sb));
else
ASMJIT_PROPAGATE(sb.appendFormat("[InstId=#%u]", unsigned(instId)));
@@ -295,4 +56,4 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatInstruction(
ASMJIT_END_SUB_NAMESPACE
-#endif // !ASMJIT_NO_LOGGING
+#endif // !ASMJIT_NO_AARCH64 && !ASMJIT_NO_LOGGING
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64formatter_p.h b/3rdparty/asmjit/src/asmjit/arm/a64formatter_p.h
index bd7a1440cb0..d0adde3ce0d 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64formatter_p.h
+++ b/3rdparty/asmjit/src/asmjit/arm/a64formatter_p.h
@@ -24,23 +24,6 @@ namespace FormatterInternal {
using namespace arm::FormatterInternal;
-Error ASMJIT_CDECL formatRegister(
- String& sb,
- FormatFlags flags,
- const BaseEmitter* emitter,
- Arch arch,
- RegType regType,
- uint32_t regId,
- uint32_t elementType = 0,
- uint32_t elementIndex = 0xFFFFFFFFu) noexcept;
-
-Error ASMJIT_CDECL formatOperand(
- String& sb,
- FormatFlags flags,
- const BaseEmitter* emitter,
- Arch arch,
- const Operand_& op) noexcept;
-
Error ASMJIT_CDECL formatInstruction(
String& sb,
FormatFlags flags,
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64func.cpp b/3rdparty/asmjit/src/asmjit/arm/a64func.cpp
index 55e3f2e71ec..a33a2f2d9d7 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64func.cpp
+++ b/3rdparty/asmjit/src/asmjit/arm/a64func.cpp
@@ -13,7 +13,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(a64)
namespace FuncInternal {
-static inline bool shouldThreatAsCDecl(CallConvId ccId) noexcept {
+static inline bool shouldTreatAsCDecl(CallConvId ccId) noexcept {
return ccId == CallConvId::kCDecl ||
ccId == CallConvId::kStdCall ||
ccId == CallConvId::kFastCall ||
@@ -41,18 +41,19 @@ static RegType regTypeFromFpOrVecTypeId(TypeId typeId) noexcept {
ASMJIT_FAVOR_SIZE Error initCallConv(CallConv& cc, CallConvId ccId, const Environment& environment) noexcept {
cc.setArch(environment.arch());
+ cc.setStrategy(environment.isDarwin() ? CallConvStrategy::kAArch64Apple : CallConvStrategy::kDefault);
cc.setSaveRestoreRegSize(RegGroup::kGp, 8);
cc.setSaveRestoreRegSize(RegGroup::kVec, 8);
cc.setSaveRestoreAlignment(RegGroup::kGp, 16);
cc.setSaveRestoreAlignment(RegGroup::kVec, 16);
- cc.setSaveRestoreAlignment(RegGroup::kExtraVirt2, 1);
+ cc.setSaveRestoreAlignment(RegGroup::kMask, 1);
cc.setSaveRestoreAlignment(RegGroup::kExtraVirt3, 1);
cc.setPassedOrder(RegGroup::kGp, 0, 1, 2, 3, 4, 5, 6, 7);
cc.setPassedOrder(RegGroup::kVec, 0, 1, 2, 3, 4, 5, 6, 7);
cc.setNaturalStackAlignment(16);
- if (shouldThreatAsCDecl(ccId)) {
+ if (shouldTreatAsCDecl(ccId)) {
// ARM doesn't have that many calling conventions as we can find in X86 world, treat most conventions as __cdecl.
cc.setId(CallConvId::kCDecl);
cc.setPreservedRegs(RegGroup::kGp, Support::bitMask(Gp::kIdOs, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30));
@@ -68,7 +69,7 @@ ASMJIT_FAVOR_SIZE Error initCallConv(CallConv& cc, CallConvId ccId, const Enviro
return kErrorOk;
}
-ASMJIT_FAVOR_SIZE Error initFuncDetail(FuncDetail& func, const FuncSignature& signature, uint32_t registerSize) noexcept {
+ASMJIT_FAVOR_SIZE Error initFuncDetail(FuncDetail& func, const FuncSignature& signature) noexcept {
DebugUtils::unused(signature);
const CallConv& cc = func.callConv();
@@ -77,6 +78,13 @@ ASMJIT_FAVOR_SIZE Error initFuncDetail(FuncDetail& func, const FuncSignature& si
uint32_t i;
uint32_t argCount = func.argCount();
+ // Minimum stack size of a single argument passed via stack. The standard AArch64 calling convention
+ // specifies 8 bytes, so each function argument would occupy at least 8 bytes even if it needs less.
+ // However, Apple has decided to not follow this rule and function argument can occupy less, for
+ // example two consecutive 32-bit arguments would occupy 8 bytes total, instead of 16 as specified
+ // by ARM.
+ uint32_t minStackArgSize = cc.strategy() == CallConvStrategy::kAArch64Apple ? 4u : 8u;
+
if (func.hasRet()) {
for (uint32_t valueIndex = 0; valueIndex < Globals::kMaxValuePack; valueIndex++) {
TypeId typeId = func._rets[valueIndex].typeId();
@@ -119,7 +127,8 @@ ASMJIT_FAVOR_SIZE Error initFuncDetail(FuncDetail& func, const FuncSignature& si
}
switch (cc.strategy()) {
- case CallConvStrategy::kDefault: {
+ case CallConvStrategy::kDefault:
+ case CallConvStrategy::kAArch64Apple: {
uint32_t gpzPos = 0;
uint32_t vecPos = 0;
@@ -140,7 +149,9 @@ ASMJIT_FAVOR_SIZE Error initFuncDetail(FuncDetail& func, const FuncSignature& si
gpzPos++;
}
else {
- uint32_t size = Support::max<uint32_t>(TypeUtils::sizeOf(typeId), registerSize);
+ uint32_t size = Support::max<uint32_t>(TypeUtils::sizeOf(typeId), minStackArgSize);
+ if (size >= 8)
+ stackOffset = Support::alignUp(stackOffset, 8);
arg.assignStackOffset(int32_t(stackOffset));
stackOffset += size;
}
@@ -164,7 +175,9 @@ ASMJIT_FAVOR_SIZE Error initFuncDetail(FuncDetail& func, const FuncSignature& si
vecPos++;
}
else {
- uint32_t size = TypeUtils::sizeOf(typeId);
+ uint32_t size = Support::max<uint32_t>(TypeUtils::sizeOf(typeId), minStackArgSize);
+ if (size >= 8)
+ stackOffset = Support::alignUp(stackOffset, 8);
arg.assignStackOffset(int32_t(stackOffset));
stackOffset += size;
}
@@ -178,7 +191,7 @@ ASMJIT_FAVOR_SIZE Error initFuncDetail(FuncDetail& func, const FuncSignature& si
return DebugUtils::errored(kErrorInvalidState);
}
- func._argStackSize = stackOffset;
+ func._argStackSize = Support::alignUp(stackOffset, 8u);
return kErrorOk;
}
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64func_p.h b/3rdparty/asmjit/src/asmjit/arm/a64func_p.h
index 9f531fc5a23..7f2221c7059 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64func_p.h
+++ b/3rdparty/asmjit/src/asmjit/arm/a64func_p.h
@@ -21,7 +21,7 @@ namespace FuncInternal {
Error initCallConv(CallConv& cc, CallConvId ccId, const Environment& environment) noexcept;
//! Initialize `FuncDetail` (AArch64 specific).
-Error initFuncDetail(FuncDetail& func, const FuncSignature& signature, uint32_t registerSize) noexcept;
+Error initFuncDetail(FuncDetail& func, const FuncSignature& signature) noexcept;
} // {FuncInternal}
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64globals.h b/3rdparty/asmjit/src/asmjit/arm/a64globals.h
index 2b6b6f0ce91..720b6f151ce 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64globals.h
+++ b/3rdparty/asmjit/src/asmjit/arm/a64globals.h
@@ -15,16 +15,13 @@
ASMJIT_BEGIN_SUB_NAMESPACE(a64)
-// a64 uses everything from arm namespace and adds into it.
-using namespace arm;
-
//! \addtogroup asmjit_a64
//! \{
//! AArch64 instruction.
//!
//! \note Only used to hold ARM-specific enumerations and static functions.
-struct Inst {
+namespace Inst {
//! Instruction id.
enum Id : uint32_t {
// ${InstId:Begin}
@@ -293,6 +290,7 @@ struct Inst {
kIdPacdza, //!< Instruction 'pacdza'.
kIdPacdzb, //!< Instruction 'pacdzb'.
kIdPacga, //!< Instruction 'pacga'.
+ kIdPrfm, //!< Instruction 'prfm'.
kIdPssbb, //!< Instruction 'pssbb'.
kIdRbit, //!< Instruction 'rbit'.
kIdRet, //!< Instruction 'ret'.
@@ -797,14 +795,14 @@ struct Inst {
};
//! Tests whether the `instId` is defined (counts also Inst::kIdNone, which must be zero).
- static inline bool isDefinedId(InstId instId) noexcept { return (instId & uint32_t(InstIdParts::kRealId)) < _kIdCount; }
+ static ASMJIT_INLINE_NODEBUG bool isDefinedId(InstId instId) noexcept { return (instId & uint32_t(InstIdParts::kRealId)) < _kIdCount; }
};
namespace Predicate {
//! Address translate options (AT).
namespace AT {
- static inline constexpr uint32_t encode(uint32_t op1, uint32_t cRn, uint32_t cRm, uint32_t op2) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr uint32_t encode(uint32_t op1, uint32_t cRn, uint32_t cRm, uint32_t op2) noexcept {
return (op1 << 11) | (cRn << 7) | (cRm << 3) | (op2 << 0);
}
@@ -862,7 +860,7 @@ namespace DB {
//! Data cache maintenance options.
namespace DC {
- static inline constexpr uint32_t encode(uint32_t op1, uint32_t cRn, uint32_t cRm, uint32_t op2) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr uint32_t encode(uint32_t op1, uint32_t cRn, uint32_t cRm, uint32_t op2) noexcept {
return (op1 << 11) | (cRn << 7) | (cRm << 3) | (op2 << 0);
}
@@ -901,7 +899,7 @@ namespace DC {
//! Instruction cache maintenance options.
namespace IC {
- static inline constexpr uint32_t encode(uint32_t op1, uint32_t cRn, uint32_t cRm, uint32_t op2) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr uint32_t encode(uint32_t op1, uint32_t cRn, uint32_t cRm, uint32_t op2) noexcept {
return (op1 << 11) | (cRn << 7) | (cRm << 3) | (op2 << 0);
}
@@ -955,7 +953,7 @@ namespace PSB {
}
namespace TLBI {
- static inline constexpr uint32_t encode(uint32_t op1, uint32_t cRn, uint32_t cRm, uint32_t op2) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr uint32_t encode(uint32_t op1, uint32_t cRn, uint32_t cRm, uint32_t op2) noexcept {
return (op1 << 11) | (cRn << 7) | (cRm << 3) | (op2 << 0);
}
@@ -1054,7 +1052,7 @@ namespace TSB {
//! Processor state access through MSR.
namespace PState {
//! Encodes a pstate from `op0` and `op1`.
- static inline constexpr uint32_t encode(uint32_t op0, uint32_t op1) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr uint32_t encode(uint32_t op0, uint32_t op1) noexcept {
return (op0 << 3) | (op1 << 0);
}
@@ -1083,17 +1081,17 @@ namespace SysReg {
};
//! Encodes a system register from `op0`, `op1`, `cRn`, `cRm`, and `op2` fields.
- static inline constexpr uint32_t encode(uint32_t op0, uint32_t op1, uint32_t cRn, uint32_t cRm, uint32_t op2) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr uint32_t encode(uint32_t op0, uint32_t op1, uint32_t cRn, uint32_t cRm, uint32_t op2) noexcept {
return (op0 << 14) | (op1 << 11) | (cRn << 7) | (cRm << 3) | (op2 << 0);
}
//! Encodes a system register from `fields`.
- static inline constexpr uint32_t encode(const Fields& fields) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr uint32_t encode(const Fields& fields) noexcept {
return encode(fields.op0, fields.op1, fields.cRn, fields.cRm, fields.op2);
}
//! Decodes a system register to \ref Fields.
- static inline constexpr Fields decode(uint32_t id) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr Fields decode(uint32_t id) noexcept {
return Fields {
uint8_t((id >> 14) & 0x3u),
uint8_t((id >> 11) & 0x7u),
@@ -1417,9 +1415,12 @@ namespace SysReg {
kID_AA64DFR1_EL1 = encode(0b11, 0b000, 0b0000, 0b0101, 0b001), // RO
kID_AA64ISAR0_EL1 = encode(0b11, 0b000, 0b0000, 0b0110, 0b000), // RO
kID_AA64ISAR1_EL1 = encode(0b11, 0b000, 0b0000, 0b0110, 0b001), // RO
+ kID_AA64ISAR2_EL1 = encode(0b11, 0b000, 0b0000, 0b0110, 0b010), // RO
kID_AA64MMFR0_EL1 = encode(0b11, 0b000, 0b0000, 0b0111, 0b000), // RO
kID_AA64MMFR1_EL1 = encode(0b11, 0b000, 0b0000, 0b0111, 0b001), // RO
kID_AA64MMFR2_EL1 = encode(0b11, 0b000, 0b0000, 0b0111, 0b010), // RO
+ kID_AA64MMFR3_EL1 = encode(0b11, 0b000, 0b0000, 0b0111, 0b011), // RO
+ kID_AA64MMFR4_EL1 = encode(0b11, 0b000, 0b0000, 0b0111, 0b100), // RO
kID_AA64PFR0_EL1 = encode(0b11, 0b000, 0b0000, 0b0100, 0b000), // RO
kID_AA64PFR1_EL1 = encode(0b11, 0b000, 0b0000, 0b0100, 0b001), // RO
kID_AA64ZFR0_EL1 = encode(0b11, 0b000, 0b0000, 0b0100, 0b100), // RO
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64instapi.cpp b/3rdparty/asmjit/src/asmjit/arm/a64instapi.cpp
index d933d4bd7f7..023be05573e 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64instapi.cpp
+++ b/3rdparty/asmjit/src/asmjit/arm/a64instapi.cpp
@@ -8,71 +8,29 @@
#include "../core/cpuinfo.h"
#include "../core/misc_p.h"
-#include "../core/support.h"
+#include "../core/support_p.h"
#include "../arm/a64instapi_p.h"
#include "../arm/a64instdb_p.h"
#include "../arm/a64operand.h"
ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+namespace InstInternal {
+
// a64::InstInternal - Text
// ========================
#ifndef ASMJIT_NO_TEXT
-Error InstInternal::instIdToString(Arch arch, InstId instId, String& output) noexcept {
+Error instIdToString(InstId instId, String& output) noexcept {
uint32_t realId = instId & uint32_t(InstIdParts::kRealId);
- DebugUtils::unused(arch);
-
if (ASMJIT_UNLIKELY(!Inst::isDefinedId(realId)))
return DebugUtils::errored(kErrorInvalidInstruction);
- const InstDB::InstInfo& info = InstDB::infoById(realId);
- return output.append(InstDB::_nameData + info._nameDataIndex);
+ return InstNameUtils::decode(output, InstDB::_instNameIndexTable[realId], InstDB::_instNameStringTable);
}
-InstId InstInternal::stringToInstId(Arch arch, const char* s, size_t len) noexcept {
- DebugUtils::unused(arch);
-
- if (ASMJIT_UNLIKELY(!s))
- return Inst::kIdNone;
-
- if (len == SIZE_MAX)
- len = strlen(s);
-
- if (ASMJIT_UNLIKELY(len == 0 || len > InstDB::kMaxNameSize))
- return Inst::kIdNone;
-
- uint32_t prefix = uint32_t(s[0]) - 'a';
- if (ASMJIT_UNLIKELY(prefix > 'z' - 'a'))
- return Inst::kIdNone;
-
- uint32_t index = InstDB::instNameIndex[prefix].start;
- if (ASMJIT_UNLIKELY(!index))
- return Inst::kIdNone;
-
- const char* nameData = InstDB::_nameData;
- const InstDB::InstInfo* table = InstDB::_instInfoTable;
-
- const InstDB::InstInfo* base = table + index;
- const InstDB::InstInfo* end = table + InstDB::instNameIndex[prefix].end;
-
- for (size_t lim = (size_t)(end - base); lim != 0; lim >>= 1) {
- const InstDB::InstInfo* cur = base + (lim >> 1);
- int result = Support::cmpInstName(nameData + cur[0]._nameDataIndex, s, len);
-
- if (result < 0) {
- base = cur + 1;
- lim--;
- continue;
- }
-
- if (result > 0)
- continue;
-
- return uint32_t((size_t)(cur - table));
- }
-
- return Inst::kIdNone;
+InstId stringToInstId(const char* s, size_t len) noexcept {
+ return InstNameUtils::find(s, len, InstDB::instNameIndex, InstDB::_instNameIndexTable, InstDB::_instNameStringTable);
}
#endif // !ASMJIT_NO_TEXT
@@ -80,9 +38,9 @@ InstId InstInternal::stringToInstId(Arch arch, const char* s, size_t len) noexce
// ============================
#ifndef ASMJIT_NO_VALIDATION
-ASMJIT_FAVOR_SIZE Error InstInternal::validate(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, ValidationFlags validationFlags) noexcept {
+ASMJIT_FAVOR_SIZE Error validate(const BaseInst& inst, const Operand_* operands, size_t opCount, ValidationFlags validationFlags) noexcept {
// TODO:
- DebugUtils::unused(arch, inst, operands, opCount, validationFlags);
+ DebugUtils::unused(inst, operands, opCount, validationFlags);
return kErrorOk;
}
#endif // !ASMJIT_NO_VALIDATION
@@ -126,13 +84,7 @@ static const InstRWInfoData instRWInfoData[] = {
static const uint8_t elementTypeSize[8] = { 0, 1, 2, 4, 8, 4, 4, 0 };
-Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, InstRWInfo* out) noexcept {
- // Unused in Release configuration as the assert is not compiled in.
- DebugUtils::unused(arch);
-
- // Only called when `arch` matches X86 family.
- ASMJIT_ASSERT(Environment::isFamilyARM(arch));
-
+Error queryRWInfo(const BaseInst& inst, const Operand_* operands, size_t opCount, InstRWInfo* out) noexcept {
// Get the instruction data.
uint32_t realId = inst.id() & uint32_t(InstIdParts::kRealId);
@@ -185,11 +137,13 @@ Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_*
if (memOp.hasBase()) {
op.addOpFlags(OpRWFlags::kMemBaseRead);
+ if ((memOp.hasIndex() || memOp.hasOffset()) && memOp.isPreOrPost()) {
+ op.addOpFlags(OpRWFlags::kMemBaseWrite);
+ }
}
if (memOp.hasIndex()) {
op.addOpFlags(OpRWFlags::kMemIndexRead);
- op.addOpFlags(memOp.isPreOrPost() ? OpRWFlags::kMemIndexWrite : OpRWFlags::kNone);
}
}
}
@@ -222,10 +176,10 @@ Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_*
if (srcOp.isReg()) {
if (srcOp.as<Vec>().hasElementIndex()) {
// Only part of the vector is accessed if element index [] is used.
- uint32_t elementType = srcOp.as<Vec>().elementType();
+ VecElementType elementType = srcOp.as<Vec>().elementType();
uint32_t elementIndex = srcOp.as<Vec>().elementIndex();
- uint32_t elementSize = elementTypeSize[elementType];
+ uint32_t elementSize = elementTypeSize[size_t(elementType)];
uint64_t accessMask = uint64_t(Support::lsbMask<uint32_t>(elementSize)) << (elementIndex * elementSize);
op._readByteMask &= accessMask;
@@ -239,11 +193,13 @@ Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_*
if (memOp.hasBase()) {
op.addOpFlags(OpRWFlags::kMemBaseRead);
+ if ((memOp.hasIndex() || memOp.hasOffset()) && memOp.isPreOrPost()) {
+ op.addOpFlags(OpRWFlags::kMemBaseWrite);
+ }
}
if (memOp.hasIndex()) {
op.addOpFlags(OpRWFlags::kMemIndexRead);
- op.addOpFlags(memOp.isPreOrPost() ? OpRWFlags::kMemIndexWrite : OpRWFlags::kNone);
}
}
}
@@ -257,13 +213,15 @@ Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_*
// =================================
#ifndef ASMJIT_NO_INTROSPECTION
-Error InstInternal::queryFeatures(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, CpuFeatures* out) noexcept {
+Error queryFeatures(const BaseInst& inst, const Operand_* operands, size_t opCount, CpuFeatures* out) noexcept {
// TODO: [ARM] QueryFeatures not implemented yet.
- DebugUtils::unused(arch, inst, operands, opCount, out);
+ DebugUtils::unused(inst, operands, opCount, out);
return kErrorOk;
}
#endif // !ASMJIT_NO_INTROSPECTION
+} // {InstInternal}
+
// a64::InstInternal - Unit
// ========================
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64instapi_p.h b/3rdparty/asmjit/src/asmjit/arm/a64instapi_p.h
index 320a3e881d9..535e4bd71f8 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64instapi_p.h
+++ b/3rdparty/asmjit/src/asmjit/arm/a64instapi_p.h
@@ -18,17 +18,17 @@ ASMJIT_BEGIN_SUB_NAMESPACE(a64)
namespace InstInternal {
#ifndef ASMJIT_NO_TEXT
-Error ASMJIT_CDECL instIdToString(Arch arch, InstId instId, String& output) noexcept;
-InstId ASMJIT_CDECL stringToInstId(Arch arch, const char* s, size_t len) noexcept;
+Error ASMJIT_CDECL instIdToString(InstId instId, String& output) noexcept;
+InstId ASMJIT_CDECL stringToInstId(const char* s, size_t len) noexcept;
#endif // !ASMJIT_NO_TEXT
#ifndef ASMJIT_NO_VALIDATION
-Error ASMJIT_CDECL validate(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, ValidationFlags validationFlags) noexcept;
+Error ASMJIT_CDECL validate(const BaseInst& inst, const Operand_* operands, size_t opCount, ValidationFlags validationFlags) noexcept;
#endif // !ASMJIT_NO_VALIDATION
#ifndef ASMJIT_NO_INTROSPECTION
-Error ASMJIT_CDECL queryRWInfo(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, InstRWInfo* out) noexcept;
-Error ASMJIT_CDECL queryFeatures(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, CpuFeatures* out) noexcept;
+Error ASMJIT_CDECL queryRWInfo(const BaseInst& inst, const Operand_* operands, size_t opCount, InstRWInfo* out) noexcept;
+Error ASMJIT_CDECL queryFeatures(const BaseInst& inst, const Operand_* operands, size_t opCount, CpuFeatures* out) noexcept;
#endif // !ASMJIT_NO_INTROSPECTION
} // {InstInternal}
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64instdb.cpp b/3rdparty/asmjit/src/asmjit/arm/a64instdb.cpp
index 64709b5db03..bc6646e895e 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64instdb.cpp
+++ b/3rdparty/asmjit/src/asmjit/arm/a64instdb.cpp
@@ -18,20 +18,11 @@ namespace InstDB {
// a64::InstDB - InstInfoTable
// ===========================
-// Don't store `_nameDataIndex` if instruction names are disabled. Since some
-// APIs can use `_nameDataIndex` it's much safer if it's zero if it's not used.
-#if defined(ASMJIT_NO_TEXT)
- #define NAME_DATA_INDEX(x) 0
-#else
- #define NAME_DATA_INDEX(x) x
-#endif
-
// Defines an ARM/AArch64 instruction.
-#define INST(id, opcodeEncoding, opcodeData, rwInfoIndex, flags, opcodeDataIndex, nameDataIndex) { \
+#define INST(id, opcodeEncoding, opcodeData, rwInfoIndex, flags, opcodeDataIndex) { \
uint32_t(kEncoding##opcodeEncoding), \
uint32_t(opcodeDataIndex), \
0, \
- uint32_t(NAME_DATA_INDEX(nameDataIndex)), \
uint16_t(rwInfoIndex), \
uint16_t(flags) \
}
@@ -63,774 +54,775 @@ IRG: Insert Random Tag.
INST_(Irg , BaseRRR , (0b1001101011000000000100, kX , kSP, kX , kSP, kX , kZR, true) , kRWI_W , 0 , 0 , 1 ), // #1
*/
const InstInfo _instInfoTable[] = {
- // +------------------+---------------------+--------------------------------------------------------------------------------------+-----------+---------------------------+----+-----+
- // | Instruction Id | Encoding | Opcode Data | RW Info | Instruction Flags |DatX|NameX|
- // +------------------+---------------------+--------------------------------------------------------------------------------------+-----------+---------------------------+----+-----+
+ // +------------------+---------------------+--------------------------------------------------------------------------------------+-----------+---------------------------+----+
+ // | Instruction Id | Encoding | Opcode Data | RW Info | Instruction Flags |DatX|
+ // +------------------+---------------------+--------------------------------------------------------------------------------------+-----------+---------------------------+----+
// ${InstInfo:Begin}
- INST(None , None , (_) , 0 , 0 , 0 , 0 ), // #0
- INST(Adc , BaseRRR , (0b0001101000000000000000, kWX, kZR, kWX, kZR, kWX, kZR, true) , kRWI_W , 0 , 0 , 1 ), // #1
- INST(Adcs , BaseRRR , (0b0011101000000000000000, kWX, kZR, kWX, kZR, kWX, kZR, true) , kRWI_W , 0 , 1 , 5 ), // #2
- INST(Add , BaseAddSub , (0b0001011000, 0b0001011001, 0b0010001) , kRWI_W , 0 , 0 , 978 ), // #3
- INST(Addg , BaseRRII , (0b1001000110000000000000, kX, kSP, kX, kSP, 6, 4, 16, 4, 0, 10) , kRWI_W , 0 , 0 , 10 ), // #4
- INST(Adds , BaseAddSub , (0b0101011000, 0b0101011001, 0b0110001) , kRWI_W , 0 , 1 , 15 ), // #5
- INST(Adr , BaseAdr , (0b0001000000000000000000, OffsetType::kAArch64_ADR) , kRWI_W , 0 , 0 , 25 ), // #6
- INST(Adrp , BaseAdr , (0b1001000000000000000000, OffsetType::kAArch64_ADRP) , kRWI_W , 0 , 1 , 29 ), // #7
- INST(And , BaseLogical , (0b0001010000, 0b00100100, 0) , kRWI_W , 0 , 0 , 57 ), // #8
- INST(Ands , BaseLogical , (0b1101010000, 0b11100100, 0) , kRWI_W , 0 , 1 , 61 ), // #9
- INST(Asr , BaseShift , (0b0001101011000000001010, 0b0001001100000000011111, 0) , kRWI_W , 0 , 0 , 66 ), // #10
- INST(Asrv , BaseShift , (0b0001101011000000001010, 0b0000000000000000000000, 0) , kRWI_W , 0 , 1 , 70 ), // #11
- INST(At , BaseAtDcIcTlbi , (0b00011111110000, 0b00001111000000, true) , kRWI_RX , 0 , 0 , 75 ), // #12
- INST(Autda , BaseRR , (0b11011010110000010001100000000000, kX, kZR, 0, kX, kSP, 5, true) , kRWI_X , 0 , 0 , 78 ), // #13
- INST(Autdza , BaseR , (0b11011010110000010011101111100000, kX, kZR, 0) , kRWI_X , 0 , 0 , 90 ), // #14
- INST(Autdb , BaseRR , (0b11011010110000010001110000000000, kX, kZR, 0, kX, kSP, 5, true) , kRWI_X , 0 , 1 , 84 ), // #15
- INST(Autdzb , BaseR , (0b11011010110000010011111111100000, kX, kZR, 0) , kRWI_X , 0 , 1 , 97 ), // #16
- INST(Autia , BaseRR , (0b11011010110000010001000000000000, kX, kZR, 0, kX, kSP, 5, true) , kRWI_X , 0 , 2 , 104 ), // #17
- INST(Autia1716 , BaseOp , (0b11010101000000110010000110011111) , 0 , 0 , 0 , 110 ), // #18
- INST(Autiasp , BaseOp , (0b11010101000000110010001110111111) , 0 , 0 , 1 , 120 ), // #19
- INST(Autiaz , BaseOp , (0b11010101000000110010001110011111) , 0 , 0 , 2 , 128 ), // #20
- INST(Autib , BaseRR , (0b11011010110000010001010000000000, kX, kZR, 0, kX, kSP, 5, true) , kRWI_X , 0 , 3 , 135 ), // #21
- INST(Autib1716 , BaseOp , (0b11010101000000110010000111011111) , 0 , 0 , 3 , 141 ), // #22
- INST(Autibsp , BaseOp , (0b11010101000000110010001111111111) , 0 , 0 , 4 , 151 ), // #23
- INST(Autibz , BaseOp , (0b11010101000000110010001111011111) , 0 , 0 , 5 , 159 ), // #24
- INST(Autiza , BaseR , (0b11011010110000010011001111100000, kX, kZR, 0) , kRWI_X , 0 , 2 , 166 ), // #25
- INST(Autizb , BaseR , (0b11011010110000010011011111100000, kX, kZR, 0) , kRWI_X , 0 , 3 , 173 ), // #26
- INST(Axflag , BaseOp , (0b11010101000000000100000001011111) , 0 , 0 , 6 , 180 ), // #27
- INST(B , BaseBranchRel , (0b00010100000000000000000000000000) , 0 , F(Cond) , 0 , 1738), // #28
- INST(Bfc , BaseBfc , (0b00110011000000000000001111100000) , kRWI_X , 0 , 0 , 192 ), // #29
- INST(Bfi , BaseBfi , (0b00110011000000000000000000000000) , kRWI_X , 0 , 0 , 223 ), // #30
- INST(Bfm , BaseBfm , (0b00110011000000000000000000000000) , kRWI_X , 0 , 0 , 2514), // #31
- INST(Bfxil , BaseBfx , (0b00110011000000000000000000000000) , kRWI_X , 0 , 0 , 250 ), // #32
- INST(Bic , BaseLogical , (0b0001010001, 0b00100100, 1) , kRWI_W , 0 , 2 , 256 ), // #33
- INST(Bics , BaseLogical , (0b1101010001, 0b11100100, 1) , kRWI_W , 0 , 3 , 260 ), // #34
- INST(Bl , BaseBranchRel , (0b10010100000000000000000000000000) , 0 , 0 , 1 , 2831), // #35
- INST(Blr , BaseBranchReg , (0b11010110001111110000000000000000) , kRWI_R , 0 , 0 , 269 ), // #36
- INST(Br , BaseBranchReg , (0b11010110000111110000000000000000) , kRWI_R , 0 , 1 , 273 ), // #37
- INST(Brk , BaseOpImm , (0b11010100001000000000000000000000, 16, 5) , 0 , 0 , 0 , 276 ), // #38
- INST(Cas , BaseAtomicOp , (0b1000100010100000011111, kWX, 30, 0) , kRWI_XRX , 0 , 0 , 284 ), // #39
- INST(Casa , BaseAtomicOp , (0b1000100011100000011111, kWX, 30, 1) , kRWI_XRX , 0 , 1 , 288 ), // #40
- INST(Casab , BaseAtomicOp , (0b0000100011100000011111, kW , 0 , 1) , kRWI_XRX , 0 , 2 , 293 ), // #41
- INST(Casah , BaseAtomicOp , (0b0100100011100000011111, kW , 0 , 1) , kRWI_XRX , 0 , 3 , 299 ), // #42
- INST(Casal , BaseAtomicOp , (0b1000100011100000111111, kWX, 30, 1) , kRWI_XRX , 0 , 4 , 305 ), // #43
- INST(Casalb , BaseAtomicOp , (0b0000100011100000111111, kW , 0 , 1) , kRWI_XRX , 0 , 5 , 311 ), // #44
- INST(Casalh , BaseAtomicOp , (0b0100100011100000111111, kW , 0 , 1) , kRWI_XRX , 0 , 6 , 318 ), // #45
- INST(Casb , BaseAtomicOp , (0b0000100010100000011111, kW , 0 , 0) , kRWI_XRX , 0 , 7 , 325 ), // #46
- INST(Cash , BaseAtomicOp , (0b0100100010100000011111, kW , 0 , 0) , kRWI_XRX , 0 , 8 , 330 ), // #47
- INST(Casl , BaseAtomicOp , (0b1000100010100000111111, kWX, 30, 0) , kRWI_XRX , 0 , 9 , 335 ), // #48
- INST(Caslb , BaseAtomicOp , (0b0000100010100000111111, kW , 0 , 0) , kRWI_XRX , 0 , 10 , 340 ), // #49
- INST(Caslh , BaseAtomicOp , (0b0100100010100000111111, kW , 0 , 0) , kRWI_XRX , 0 , 11 , 346 ), // #50
- INST(Casp , BaseAtomicCasp , (0b0000100000100000011111, kWX, 30) , kRWI_XXRRX, 0 , 0 , 352 ), // #51
- INST(Caspa , BaseAtomicCasp , (0b0000100001100000011111, kWX, 30) , kRWI_XXRRX, 0 , 1 , 357 ), // #52
- INST(Caspal , BaseAtomicCasp , (0b0000100001100000111111, kWX, 30) , kRWI_XXRRX, 0 , 2 , 363 ), // #53
- INST(Caspl , BaseAtomicCasp , (0b0000100000100000111111, kWX, 30) , kRWI_XXRRX, 0 , 3 , 370 ), // #54
- INST(Cbnz , BaseBranchCmp , (0b00110101000000000000000000000000) , kRWI_R , 0 , 0 , 376 ), // #55
- INST(Cbz , BaseBranchCmp , (0b00110100000000000000000000000000) , kRWI_R , 0 , 1 , 381 ), // #56
- INST(Ccmn , BaseCCmp , (0b00111010010000000000000000000000) , kRWI_R , 0 , 0 , 385 ), // #57
- INST(Ccmp , BaseCCmp , (0b01111010010000000000000000000000) , kRWI_R , 0 , 1 , 650 ), // #58
- INST(Cfinv , BaseOp , (0b11010101000000000100000000011111) , 0 , 0 , 7 , 390 ), // #59
- INST(Cinc , BaseCInc , (0b00011010100000000000010000000000) , kRWI_W , 0 , 0 , 396 ), // #60
- INST(Cinv , BaseCInc , (0b01011010100000000000000000000000) , kRWI_W , 0 , 1 , 401 ), // #61
- INST(Clrex , BaseOpImm , (0b11010101000000110011000001011111, 4, 8) , 0 , 0 , 1 , 406 ), // #62
- INST(Cls , BaseRR , (0b01011010110000000001010000000000, kWX, kZR, 0, kWX, kZR, 5, true) , kRWI_W , 0 , 4 , 412 ), // #63
- INST(Clz , BaseRR , (0b01011010110000000001000000000000, kWX, kZR, 0, kWX, kZR, 5, true) , kRWI_W , 0 , 5 , 416 ), // #64
- INST(Cmn , BaseCmpCmn , (0b0101011000, 0b0101011001, 0b0110001) , kRWI_R , 0 , 0 , 386 ), // #65
- INST(Cmp , BaseCmpCmn , (0b1101011000, 0b1101011001, 0b1110001) , kRWI_R , 0 , 1 , 651 ), // #66
- INST(Cmpp , BaseRR , (0b10111010110000000000000000011111, kX, kSP, 5, kX, kSP, 16, true) , kRWI_R , 0 , 6 , 430 ), // #67
- INST(Cneg , BaseCInc , (0b01011010100000000000010000000000) , kRWI_W , 0 , 2 , 441 ), // #68
- INST(Crc32b , BaseRRR , (0b0001101011000000010000, kW, kZR, kW, kZR, kW, kZR, false) , kRWI_W , 0 , 2 , 450 ), // #69
- INST(Crc32cb , BaseRRR , (0b0001101011000000010100, kW, kZR, kW, kZR, kW, kZR, false) , kRWI_W , 0 , 3 , 457 ), // #70
- INST(Crc32ch , BaseRRR , (0b0001101011000000010101, kW, kZR, kW, kZR, kW, kZR, false) , kRWI_W , 0 , 4 , 465 ), // #71
- INST(Crc32cw , BaseRRR , (0b0001101011000000010110, kW, kZR, kW, kZR, kW, kZR, false) , kRWI_W , 0 , 5 , 473 ), // #72
- INST(Crc32cx , BaseRRR , (0b1001101011000000010111, kW, kZR, kW, kZR, kX, kZR, false) , kRWI_W , 0 , 6 , 481 ), // #73
- INST(Crc32h , BaseRRR , (0b0001101011000000010001, kW, kZR, kW, kZR, kW, kZR, false) , kRWI_W , 0 , 7 , 489 ), // #74
- INST(Crc32w , BaseRRR , (0b0001101011000000010010, kW, kZR, kW, kZR, kW, kZR, false) , kRWI_W , 0 , 8 , 496 ), // #75
- INST(Crc32x , BaseRRR , (0b1001101011000000010011, kW, kZR, kW, kZR, kX, kZR, false) , kRWI_W , 0 , 9 , 503 ), // #76
- INST(Csdb , BaseOp , (0b11010101000000110010001010011111) , 0 , 0 , 8 , 510 ), // #77
- INST(Csel , BaseCSel , (0b00011010100000000000000000000000) , kRWI_W , 0 , 0 , 710 ), // #78
- INST(Cset , BaseCSet , (0b00011010100111110000011111100000) , kRWI_W , 0 , 0 , 515 ), // #79
- INST(Csetm , BaseCSet , (0b01011010100111110000001111100000) , kRWI_W , 0 , 1 , 520 ), // #80
- INST(Csinc , BaseCSel , (0b00011010100000000000010000000000) , kRWI_W , 0 , 1 , 526 ), // #81
- INST(Csinv , BaseCSel , (0b01011010100000000000000000000000) , kRWI_W , 0 , 2 , 532 ), // #82
- INST(Csneg , BaseCSel , (0b01011010100000000000010000000000) , kRWI_W , 0 , 3 , 538 ), // #83
- INST(Dc , BaseAtDcIcTlbi , (0b00011110000000, 0b00001110000000, true) , kRWI_RX , 0 , 1 , 2 ), // #84
- INST(Dcps1 , BaseOpImm , (0b11010100101000000000000000000001, 16, 5) , 0 , 0 , 2 , 544 ), // #85
- INST(Dcps2 , BaseOpImm , (0b11010100101000000000000000000010, 16, 5) , 0 , 0 , 3 , 550 ), // #86
- INST(Dcps3 , BaseOpImm , (0b11010100101000000000000000000011, 16, 5) , 0 , 0 , 4 , 556 ), // #87
- INST(Dgh , BaseOp , (0b11010101000000110010000011011111) , 0 , 0 , 9 , 562 ), // #88
- INST(Dmb , BaseOpImm , (0b11010101000000110011000010111111, 4, 8) , 0 , 0 , 5 , 566 ), // #89
- INST(Drps , BaseOp , (0b11010110101111110000001111100000) , 0 , 0 , 10 , 570 ), // #90
- INST(Dsb , BaseOpImm , (0b11010101000000110011000010011111, 4, 8) , 0 , 0 , 6 , 575 ), // #91
- INST(Eon , BaseLogical , (0b1001010001, 0b10100100, 1) , kRWI_W , 0 , 4 , 583 ), // #92
- INST(Eor , BaseLogical , (0b1001010000, 0b10100100, 0) , kRWI_W , 0 , 5 , 1418), // #93
- INST(Esb , BaseOp , (0b11010101000000110010001000011111) , 0 , 0 , 11 , 597 ), // #94
- INST(Extr , BaseExtract , (0b00010011100000000000000000000000) , kRWI_W , 0 , 0 , 605 ), // #95
- INST(Eret , BaseOp , (0b11010110100111110000001111100000) , 0 , 0 , 12 , 592 ), // #96
- INST(Gmi , BaseRRR , (0b1001101011000000000101, kX , kZR, kX , kSP, kX , kZR, true) , kRWI_W , 0 , 10 , 1128), // #97
- INST(Hint , BaseOpImm , (0b11010101000000110010000000011111, 7, 5) , 0 , 0 , 7 , 1132), // #98
- INST(Hlt , BaseOpImm , (0b11010100010000000000000000000000, 16, 5) , 0 , 0 , 8 , 1137), // #99
- INST(Hvc , BaseOpImm , (0b11010100000000000000000000000010, 16, 5) , 0 , 0 , 9 , 1141), // #100
- INST(Ic , BaseAtDcIcTlbi , (0b00011110000000, 0b00001110000000, false) , kRWI_RX , 0 , 2 , 257 ), // #101
- INST(Isb , BaseOpImm , (0b11010101000000110011000011011111, 4, 8) , 0 , 0 , 10 , 1149), // #102
- INST(Ldadd , BaseAtomicOp , (0b1011100000100000000000, kWX, 30, 0) , kRWI_WRX , 0 , 12 , 1189), // #103
- INST(Ldadda , BaseAtomicOp , (0b1011100010100000000000, kWX, 30, 1) , kRWI_WRX , 0 , 13 , 1195), // #104
- INST(Ldaddab , BaseAtomicOp , (0b0011100010100000000000, kW , 0 , 1) , kRWI_WRX , 0 , 14 , 1202), // #105
- INST(Ldaddah , BaseAtomicOp , (0b0111100010100000000000, kW , 0 , 1) , kRWI_WRX , 0 , 15 , 1210), // #106
- INST(Ldaddal , BaseAtomicOp , (0b1011100011100000000000, kWX, 30, 1) , kRWI_WRX , 0 , 16 , 1218), // #107
- INST(Ldaddalb , BaseAtomicOp , (0b0011100011100000000000, kW , 0 , 1) , kRWI_WRX , 0 , 17 , 1226), // #108
- INST(Ldaddalh , BaseAtomicOp , (0b0111100011100000000000, kW , 0 , 1) , kRWI_WRX , 0 , 18 , 1235), // #109
- INST(Ldaddb , BaseAtomicOp , (0b0011100000100000000000, kW , 0 , 0) , kRWI_WRX , 0 , 19 , 1244), // #110
- INST(Ldaddh , BaseAtomicOp , (0b0111100000100000000000, kW , 0 , 0) , kRWI_WRX , 0 , 20 , 1251), // #111
- INST(Ldaddl , BaseAtomicOp , (0b1011100001100000000000, kWX, 30, 0) , kRWI_WRX , 0 , 21 , 1258), // #112
- INST(Ldaddlb , BaseAtomicOp , (0b0011100001100000000000, kW , 0 , 0) , kRWI_WRX , 0 , 22 , 1265), // #113
- INST(Ldaddlh , BaseAtomicOp , (0b0111100001100000000000, kW , 0 , 0) , kRWI_WRX , 0 , 23 , 1273), // #114
- INST(Ldar , BaseRM_NoImm , (0b1000100011011111111111, kWX, kZR, 30) , kRWI_W , 0 , 0 , 1281), // #115
- INST(Ldarb , BaseRM_NoImm , (0b0000100011011111111111, kW , kZR, 0 ) , kRWI_W , 0 , 1 , 1286), // #116
- INST(Ldarh , BaseRM_NoImm , (0b0100100011011111111111, kW , kZR, 0 ) , kRWI_W , 0 , 2 , 1292), // #117
- INST(Ldaxp , BaseLdxp , (0b1000100001111111100000, kWX, 30) , kRWI_WW , 0 , 0 , 1298), // #118
- INST(Ldaxr , BaseRM_NoImm , (0b1000100001011111111111, kWX, kZR, 30) , kRWI_W , 0 , 3 , 1304), // #119
- INST(Ldaxrb , BaseRM_NoImm , (0b0000100001011111111111, kW , kZR, 0 ) , kRWI_W , 0 , 4 , 1310), // #120
- INST(Ldaxrh , BaseRM_NoImm , (0b0100100001011111111111, kW , kZR, 0 ) , kRWI_W , 0 , 5 , 1317), // #121
- INST(Ldclr , BaseAtomicOp , (0b1011100000100000000100, kWX, 30, 0) , kRWI_WRX , 0 , 24 , 1324), // #122
- INST(Ldclra , BaseAtomicOp , (0b1011100010100000000100, kWX, 30, 1) , kRWI_WRX , 0 , 25 , 1330), // #123
- INST(Ldclrab , BaseAtomicOp , (0b0011100010100000000100, kW , 0 , 1) , kRWI_WRX , 0 , 26 , 1337), // #124
- INST(Ldclrah , BaseAtomicOp , (0b0111100010100000000100, kW , 0 , 1) , kRWI_WRX , 0 , 27 , 1345), // #125
- INST(Ldclral , BaseAtomicOp , (0b1011100011100000000100, kWX, 30, 1) , kRWI_WRX , 0 , 28 , 1353), // #126
- INST(Ldclralb , BaseAtomicOp , (0b0011100011100000000100, kW , 0 , 1) , kRWI_WRX , 0 , 29 , 1361), // #127
- INST(Ldclralh , BaseAtomicOp , (0b0111100011100000000100, kW , 0 , 1) , kRWI_WRX , 0 , 30 , 1370), // #128
- INST(Ldclrb , BaseAtomicOp , (0b0011100000100000000100, kW , 0 , 0) , kRWI_WRX , 0 , 31 , 1379), // #129
- INST(Ldclrh , BaseAtomicOp , (0b0111100000100000000100, kW , 0 , 0) , kRWI_WRX , 0 , 32 , 1386), // #130
- INST(Ldclrl , BaseAtomicOp , (0b1011100001100000000100, kWX, 30, 0) , kRWI_WRX , 0 , 33 , 1393), // #131
- INST(Ldclrlb , BaseAtomicOp , (0b0011100001100000000100, kW , 0 , 0) , kRWI_WRX , 0 , 34 , 1400), // #132
- INST(Ldclrlh , BaseAtomicOp , (0b0111100001100000000100, kW , 0 , 0) , kRWI_WRX , 0 , 35 , 1408), // #133
- INST(Ldeor , BaseAtomicOp , (0b1011100000100000001000, kWX, 30, 0) , kRWI_WRX , 0 , 36 , 1416), // #134
- INST(Ldeora , BaseAtomicOp , (0b1011100010100000001000, kWX, 30, 1) , kRWI_WRX , 0 , 37 , 1422), // #135
- INST(Ldeorab , BaseAtomicOp , (0b0011100010100000001000, kW , 0 , 1) , kRWI_WRX , 0 , 38 , 1429), // #136
- INST(Ldeorah , BaseAtomicOp , (0b0111100010100000001000, kW , 0 , 1) , kRWI_WRX , 0 , 39 , 1437), // #137
- INST(Ldeoral , BaseAtomicOp , (0b1011100011100000001000, kWX, 30, 1) , kRWI_WRX , 0 , 40 , 1445), // #138
- INST(Ldeoralb , BaseAtomicOp , (0b0011100011100000001000, kW , 0 , 1) , kRWI_WRX , 0 , 41 , 1453), // #139
- INST(Ldeoralh , BaseAtomicOp , (0b0111100011100000001000, kW , 0 , 1) , kRWI_WRX , 0 , 42 , 1462), // #140
- INST(Ldeorb , BaseAtomicOp , (0b0011100000100000001000, kW , 0 , 0) , kRWI_WRX , 0 , 43 , 1471), // #141
- INST(Ldeorh , BaseAtomicOp , (0b0111100000100000001000, kW , 0 , 0) , kRWI_WRX , 0 , 44 , 1478), // #142
- INST(Ldeorl , BaseAtomicOp , (0b1011100001100000001000, kWX, 30, 0) , kRWI_WRX , 0 , 45 , 1485), // #143
- INST(Ldeorlb , BaseAtomicOp , (0b0011100001100000001000, kW , 0 , 0) , kRWI_WRX , 0 , 46 , 1492), // #144
- INST(Ldeorlh , BaseAtomicOp , (0b0111100001100000001000, kW , 0 , 0) , kRWI_WRX , 0 , 47 , 1500), // #145
- INST(Ldg , BaseRM_SImm9 , (0b1101100101100000000000, 0b0000000000000000000000, kX , kZR, 0, 4) , kRWI_W , 0 , 0 , 1508), // #146
- INST(Ldgm , BaseRM_NoImm , (0b1101100111100000000000, kX , kZR, 0 ) , kRWI_W , 0 , 6 , 1512), // #147
- INST(Ldlar , BaseRM_NoImm , (0b1000100011011111011111, kWX, kZR, 30) , kRWI_W , 0 , 7 , 1517), // #148
- INST(Ldlarb , BaseRM_NoImm , (0b0000100011011111011111, kW , kZR, 0 ) , kRWI_W , 0 , 8 , 1523), // #149
- INST(Ldlarh , BaseRM_NoImm , (0b0100100011011111011111, kW , kZR, 0 ) , kRWI_W , 0 , 9 , 1530), // #150
- INST(Ldnp , BaseLdpStp , (0b0010100001, 0 , kWX, 31, 2) , kRWI_WW , 0 , 0 , 1537), // #151
- INST(Ldp , BaseLdpStp , (0b0010100101, 0b0010100011, kWX, 31, 2) , kRWI_W , 0 , 1 , 1542), // #152
- INST(Ldpsw , BaseLdpStp , (0b0110100101, 0b0110100011, kX , 0 , 2) , kRWI_WW , 0 , 2 , 1546), // #153
- INST(Ldr , BaseLdSt , (0b1011100101, 0b10111000010, 0b10111000011, 0b00011000, kWX, 30, 2, Inst::kIdLdur) , kRWI_W , 0 , 0 , 1552), // #154
- INST(Ldraa , BaseRM_SImm10 , (0b1111100000100000000001, kX , kZR, 0, 3) , kRWI_W , 0 , 0 , 1556), // #155
- INST(Ldrab , BaseRM_SImm10 , (0b1111100010100000000001, kX , kZR, 0, 3) , kRWI_W , 0 , 1 , 1562), // #156
- INST(Ldrb , BaseLdSt , (0b0011100101, 0b00111000010, 0b00111000011, 0 , kW , 0 , 0, Inst::kIdLdurb) , kRWI_W , 0 , 1 , 1568), // #157
- INST(Ldrh , BaseLdSt , (0b0111100101, 0b01111000010, 0b01111000011, 0 , kW , 0 , 1, Inst::kIdLdurh) , kRWI_W , 0 , 2 , 1573), // #158
- INST(Ldrsb , BaseLdSt , (0b0011100111, 0b00111000100, 0b00111000101, 0 , kWX, 22, 0, Inst::kIdLdursb) , kRWI_W , 0 , 3 , 1578), // #159
- INST(Ldrsh , BaseLdSt , (0b0111100110, 0b01111000100, 0b01111000101, 0 , kWX, 22, 1, Inst::kIdLdursh) , kRWI_W , 0 , 4 , 1584), // #160
- INST(Ldrsw , BaseLdSt , (0b1011100110, 0b10111000100, 0b10111000101, 0b10011000, kX , 0 , 2, Inst::kIdLdursw) , kRWI_W , 0 , 5 , 1590), // #161
- INST(Ldset , BaseAtomicOp , (0b1011100000100000001100, kWX, 30, 0) , kRWI_WRX , 0 , 48 , 1596), // #162
- INST(Ldseta , BaseAtomicOp , (0b1011100010100000001100, kWX, 30, 1) , kRWI_WRX , 0 , 49 , 1602), // #163
- INST(Ldsetab , BaseAtomicOp , (0b0011100010100000001100, kW , 0 , 1) , kRWI_WRX , 0 , 50 , 1609), // #164
- INST(Ldsetah , BaseAtomicOp , (0b0111100010100000001100, kW , 0 , 1) , kRWI_WRX , 0 , 51 , 1617), // #165
- INST(Ldsetal , BaseAtomicOp , (0b1011100011100000001100, kWX, 30, 1) , kRWI_WRX , 0 , 52 , 1625), // #166
- INST(Ldsetalb , BaseAtomicOp , (0b0011100011100000001100, kW , 0 , 1) , kRWI_WRX , 0 , 53 , 1633), // #167
- INST(Ldsetalh , BaseAtomicOp , (0b0111100011100000001100, kW , 0 , 1) , kRWI_WRX , 0 , 54 , 1642), // #168
- INST(Ldsetb , BaseAtomicOp , (0b0011100000100000001100, kW , 0 , 0) , kRWI_WRX , 0 , 55 , 1651), // #169
- INST(Ldseth , BaseAtomicOp , (0b0111100000100000001100, kW , 0 , 0) , kRWI_WRX , 0 , 56 , 1658), // #170
- INST(Ldsetl , BaseAtomicOp , (0b1011100001100000001100, kWX, 30, 0) , kRWI_WRX , 0 , 57 , 1665), // #171
- INST(Ldsetlb , BaseAtomicOp , (0b0011100001100000001100, kW , 0 , 0) , kRWI_WRX , 0 , 58 , 1672), // #172
- INST(Ldsetlh , BaseAtomicOp , (0b0111100001100000001100, kW , 0 , 0) , kRWI_WRX , 0 , 59 , 1680), // #173
- INST(Ldsmax , BaseAtomicOp , (0b1011100000100000010000, kWX, 30, 0) , kRWI_WRX , 0 , 60 , 1688), // #174
- INST(Ldsmaxa , BaseAtomicOp , (0b1011100010100000010000, kWX, 30, 1) , kRWI_WRX , 0 , 61 , 1695), // #175
- INST(Ldsmaxab , BaseAtomicOp , (0b0011100010100000010000, kW , 0 , 1) , kRWI_WRX , 0 , 62 , 1703), // #176
- INST(Ldsmaxah , BaseAtomicOp , (0b0111100010100000010000, kW , 0 , 1) , kRWI_WRX , 0 , 63 , 1712), // #177
- INST(Ldsmaxal , BaseAtomicOp , (0b1011100011100000010000, kWX, 30, 1) , kRWI_WRX , 0 , 64 , 1721), // #178
- INST(Ldsmaxalb , BaseAtomicOp , (0b0011100011100000010000, kW , 0 , 1) , kRWI_WRX , 0 , 65 , 1730), // #179
- INST(Ldsmaxalh , BaseAtomicOp , (0b0111100011100000010000, kW , 0 , 1) , kRWI_WRX , 0 , 66 , 1740), // #180
- INST(Ldsmaxb , BaseAtomicOp , (0b0011100000100000010000, kW , 0 , 0) , kRWI_WRX , 0 , 67 , 1750), // #181
- INST(Ldsmaxh , BaseAtomicOp , (0b0111100000100000010000, kW , 0 , 0) , kRWI_WRX , 0 , 68 , 1758), // #182
- INST(Ldsmaxl , BaseAtomicOp , (0b1011100001100000010000, kWX, 30, 0) , kRWI_WRX , 0 , 69 , 1766), // #183
- INST(Ldsmaxlb , BaseAtomicOp , (0b0011100001100000010000, kW , 0 , 0) , kRWI_WRX , 0 , 70 , 1774), // #184
- INST(Ldsmaxlh , BaseAtomicOp , (0b0111100001100000010000, kW , 0 , 0) , kRWI_WRX , 0 , 71 , 1783), // #185
- INST(Ldsmin , BaseAtomicOp , (0b1011100000100000010100, kWX, 30, 0) , kRWI_WRX , 0 , 72 , 1792), // #186
- INST(Ldsmina , BaseAtomicOp , (0b1011100010100000010100, kWX, 30, 1) , kRWI_WRX , 0 , 73 , 1799), // #187
- INST(Ldsminab , BaseAtomicOp , (0b0011100010100000010100, kW , 0 , 1) , kRWI_WRX , 0 , 74 , 1807), // #188
- INST(Ldsminah , BaseAtomicOp , (0b0111100010100000010100, kW , 0 , 1) , kRWI_WRX , 0 , 75 , 1816), // #189
- INST(Ldsminal , BaseAtomicOp , (0b1011100011100000010100, kWX, 30, 1) , kRWI_WRX , 0 , 76 , 1825), // #190
- INST(Ldsminalb , BaseAtomicOp , (0b0011100011100000010100, kW , 0 , 1) , kRWI_WRX , 0 , 77 , 1834), // #191
- INST(Ldsminalh , BaseAtomicOp , (0b0111100011100000010100, kW , 0 , 1) , kRWI_WRX , 0 , 78 , 1844), // #192
- INST(Ldsminb , BaseAtomicOp , (0b0011100000100000010100, kW , 0 , 0) , kRWI_WRX , 0 , 79 , 1854), // #193
- INST(Ldsminh , BaseAtomicOp , (0b0111100000100000010100, kW , 0 , 0) , kRWI_WRX , 0 , 80 , 1862), // #194
- INST(Ldsminl , BaseAtomicOp , (0b1011100001100000010100, kWX, 30, 0) , kRWI_WRX , 0 , 81 , 1870), // #195
- INST(Ldsminlb , BaseAtomicOp , (0b0011100001100000010100, kW , 0 , 0) , kRWI_WRX , 0 , 82 , 1878), // #196
- INST(Ldsminlh , BaseAtomicOp , (0b0111100001100000010100, kW , 0 , 0) , kRWI_WRX , 0 , 83 , 1887), // #197
- INST(Ldtr , BaseRM_SImm9 , (0b1011100001000000000010, 0b0000000000000000000000, kWX, kZR, 30, 0) , kRWI_W , 0 , 1 , 1896), // #198
- INST(Ldtrb , BaseRM_SImm9 , (0b0011100001000000000010, 0b0000000000000000000000, kW , kZR, 0 , 0) , kRWI_W , 0 , 2 , 1901), // #199
- INST(Ldtrh , BaseRM_SImm9 , (0b0111100001000000000010, 0b0000000000000000000000, kW , kZR, 0 , 0) , kRWI_W , 0 , 3 , 1907), // #200
- INST(Ldtrsb , BaseRM_SImm9 , (0b0011100011000000000010, 0b0000000000000000000000, kWX, kZR, 22, 0) , kRWI_W , 0 , 4 , 1913), // #201
- INST(Ldtrsh , BaseRM_SImm9 , (0b0111100011000000000010, 0b0000000000000000000000, kWX, kZR, 22, 0) , kRWI_W , 0 , 5 , 1920), // #202
- INST(Ldtrsw , BaseRM_SImm9 , (0b1011100010000000000010, 0b0000000000000000000000, kX , kZR, 0 , 0) , kRWI_W , 0 , 6 , 1927), // #203
- INST(Ldumax , BaseAtomicOp , (0b1011100000100000011000, kWX, 30, 0) , kRWI_WRX , 0 , 84 , 1934), // #204
- INST(Ldumaxa , BaseAtomicOp , (0b1011100010100000011000, kWX, 30, 1) , kRWI_WRX , 0 , 85 , 1941), // #205
- INST(Ldumaxab , BaseAtomicOp , (0b0011100010100000011000, kW , 0 , 1) , kRWI_WRX , 0 , 86 , 1949), // #206
- INST(Ldumaxah , BaseAtomicOp , (0b0111100010100000011000, kW , 0 , 1) , kRWI_WRX , 0 , 87 , 1958), // #207
- INST(Ldumaxal , BaseAtomicOp , (0b1011100011100000011000, kWX, 30, 1) , kRWI_WRX , 0 , 88 , 1967), // #208
- INST(Ldumaxalb , BaseAtomicOp , (0b0011100011100000011000, kW , 0 , 1) , kRWI_WRX , 0 , 89 , 1976), // #209
- INST(Ldumaxalh , BaseAtomicOp , (0b0111100011100000011000, kW , 0 , 1) , kRWI_WRX , 0 , 90 , 1986), // #210
- INST(Ldumaxb , BaseAtomicOp , (0b0011100000100000011000, kW , 0 , 0) , kRWI_WRX , 0 , 91 , 1996), // #211
- INST(Ldumaxh , BaseAtomicOp , (0b0111100000100000011000, kW , 0 , 0) , kRWI_WRX , 0 , 92 , 2004), // #212
- INST(Ldumaxl , BaseAtomicOp , (0b1011100001100000011000, kWX, 30, 0) , kRWI_WRX , 0 , 93 , 2012), // #213
- INST(Ldumaxlb , BaseAtomicOp , (0b0011100001100000011000, kW , 0 , 0) , kRWI_WRX , 0 , 94 , 2020), // #214
- INST(Ldumaxlh , BaseAtomicOp , (0b0111100001100000011000, kW , 0 , 0) , kRWI_WRX , 0 , 95 , 2029), // #215
- INST(Ldumin , BaseAtomicOp , (0b1011100000100000011100, kWX, 30, 0) , kRWI_WRX , 0 , 96 , 2038), // #216
- INST(Ldumina , BaseAtomicOp , (0b1011100010100000011100, kWX, 30, 1) , kRWI_WRX , 0 , 97 , 2045), // #217
- INST(Lduminab , BaseAtomicOp , (0b0011100010100000011100, kW , 0 , 1) , kRWI_WRX , 0 , 98 , 2053), // #218
- INST(Lduminah , BaseAtomicOp , (0b0111100010100000011100, kW , 0 , 1) , kRWI_WRX , 0 , 99 , 2062), // #219
- INST(Lduminal , BaseAtomicOp , (0b1011100011100000011100, kWX, 30, 1) , kRWI_WRX , 0 , 100, 2071), // #220
- INST(Lduminalb , BaseAtomicOp , (0b0011100011100000011100, kW , 0 , 1) , kRWI_WRX , 0 , 101, 2080), // #221
- INST(Lduminalh , BaseAtomicOp , (0b0111100011100000011100, kW , 0 , 1) , kRWI_WRX , 0 , 102, 2090), // #222
- INST(Lduminb , BaseAtomicOp , (0b0011100000100000011100, kW , 0 , 0) , kRWI_WRX , 0 , 103, 2100), // #223
- INST(Lduminh , BaseAtomicOp , (0b0111100000100000011100, kW , 0 , 0) , kRWI_WRX , 0 , 104, 2108), // #224
- INST(Lduminl , BaseAtomicOp , (0b1011100001100000011100, kWX, 30, 0) , kRWI_WRX , 0 , 105, 2116), // #225
- INST(Lduminlb , BaseAtomicOp , (0b0011100001100000011100, kW , 0 , 0) , kRWI_WRX , 0 , 106, 2124), // #226
- INST(Lduminlh , BaseAtomicOp , (0b0111100001100000011100, kW , 0 , 0) , kRWI_WRX , 0 , 107, 2133), // #227
- INST(Ldur , BaseRM_SImm9 , (0b1011100001000000000000, 0b0000000000000000000000, kWX, kZR, 30, 0) , kRWI_W , 0 , 7 , 2142), // #228
- INST(Ldurb , BaseRM_SImm9 , (0b0011100001000000000000, 0b0000000000000000000000, kW , kZR, 0 , 0) , kRWI_W , 0 , 8 , 2147), // #229
- INST(Ldurh , BaseRM_SImm9 , (0b0111100001000000000000, 0b0000000000000000000000, kW , kZR, 0 , 0) , kRWI_W , 0 , 9 , 2153), // #230
- INST(Ldursb , BaseRM_SImm9 , (0b0011100011000000000000, 0b0000000000000000000000, kWX, kZR, 22, 0) , kRWI_W , 0 , 10 , 2159), // #231
- INST(Ldursh , BaseRM_SImm9 , (0b0111100011000000000000, 0b0000000000000000000000, kWX, kZR, 22, 0) , kRWI_W , 0 , 11 , 2166), // #232
- INST(Ldursw , BaseRM_SImm9 , (0b1011100010000000000000, 0b0000000000000000000000, kWX, kZR, 0 , 0) , kRWI_W , 0 , 12 , 2173), // #233
- INST(Ldxp , BaseLdxp , (0b1000100001111111000000, kWX, 30) , kRWI_WW , 0 , 1 , 2180), // #234
- INST(Ldxr , BaseRM_NoImm , (0b1000100001011111011111, kWX, kZR, 30) , kRWI_W , 0 , 10 , 2185), // #235
- INST(Ldxrb , BaseRM_NoImm , (0b0000100001011111011111, kW , kZR, 0 ) , kRWI_W , 0 , 11 , 2190), // #236
- INST(Ldxrh , BaseRM_NoImm , (0b0100100001011111011111, kW , kZR, 0 ) , kRWI_W , 0 , 12 , 2196), // #237
- INST(Lsl , BaseShift , (0b0001101011000000001000, 0b0101001100000000000000, 0) , kRWI_W , 0 , 2 , 2880), // #238
- INST(Lslv , BaseShift , (0b0001101011000000001000, 0b0000000000000000000000, 0) , kRWI_W , 0 , 3 , 2202), // #239
- INST(Lsr , BaseShift , (0b0001101011000000001001, 0b0101001100000000011111, 0) , kRWI_W , 0 , 4 , 2207), // #240
- INST(Lsrv , BaseShift , (0b0001101011000000001001, 0b0000000000000000000000, 0) , kRWI_W , 0 , 5 , 2211), // #241
- INST(Madd , BaseRRRR , (0b0001101100000000000000, kWX, kZR, kWX, kZR, kWX, kZR, kWX, kZR, true) , kRWI_W , 0 , 0 , 977 ), // #242
- INST(Mneg , BaseRRR , (0b0001101100000000111111, kWX, kZR, kWX, kZR, kWX, kZR, true) , kRWI_W , 0 , 11 , 2216), // #243
- INST(Mov , BaseMov , (_) , kRWI_W , 0 , 0 , 949 ), // #244
- INST(Movk , BaseMovKNZ , (0b01110010100000000000000000000000) , kRWI_X , 0 , 0 , 2226), // #245
- INST(Movn , BaseMovKNZ , (0b00010010100000000000000000000000) , kRWI_W , 0 , 1 , 2231), // #246
- INST(Movz , BaseMovKNZ , (0b01010010100000000000000000000000) , kRWI_W , 0 , 2 , 2236), // #247
- INST(Mrs , BaseMrs , (_) , kRWI_W , 0 , 0 , 2241), // #248
- INST(Msr , BaseMsr , (_) , kRWI_W , 0 , 0 , 2245), // #249
- INST(Msub , BaseRRRR , (0b0001101100000000100000, kWX, kZR, kWX, kZR, kWX, kZR, kWX, kZR, true) , kRWI_W , 0 , 1 , 984 ), // #250
- INST(Mul , BaseRRR , (0b0001101100000000011111, kWX, kZR, kWX, kZR, kWX, kZR, true) , kRWI_W , 0 , 12 , 991 ), // #251
- INST(Mvn , BaseMvnNeg , (0b00101010001000000000001111100000) , kRWI_W , 0 , 0 , 2249), // #252
- INST(Neg , BaseMvnNeg , (0b01001011000000000000001111100000) , kRWI_W , 0 , 1 , 540 ), // #253
- INST(Negs , BaseMvnNeg , (0b01101011000000000000001111100000) , kRWI_W , 0 , 2 , 2258), // #254
- INST(Ngc , BaseRR , (0b01011010000000000000001111100000, kWX, kZR, 0, kWX, kZR, 16, true) , kRWI_W , 0 , 7 , 2263), // #255
- INST(Ngcs , BaseRR , (0b01111010000000000000001111100000, kWX, kZR, 0, kWX, kZR, 16, true) , kRWI_W , 0 , 8 , 2267), // #256
- INST(Nop , BaseOp , (0b11010101000000110010000000011111) , 0 , 0 , 13 , 2272), // #257
- INST(Orn , BaseLogical , (0b0101010001, 0b01100100, 1) , kRWI_W , 0 , 6 , 2280), // #258
- INST(Orr , BaseLogical , (0b0101010000, 0b01100100, 0) , kRWI_W , 0 , 7 , 2284), // #259
- INST(Pacda , BaseRR , (0b11011010110000010000100000000000, kX, kZR, 0, kX, kSP, 5, true) , kRWI_X , 0 , 9 , 2288), // #260
- INST(Pacdb , BaseRR , (0b11011010110000010000110000000000, kX, kZR, 0, kX, kSP, 5, true) , kRWI_X , 0 , 10 , 2294), // #261
- INST(Pacdza , BaseR , (0b11011010110000010010101111100000, kX, kZR, 0) , kRWI_X , 0 , 4 , 2300), // #262
- INST(Pacdzb , BaseR , (0b11011010110000010010111111100000, kX, kZR, 0) , kRWI_X , 0 , 5 , 2307), // #263
- INST(Pacga , BaseRRR , (0b1001101011000000001100, kX, kZR, kX, kZR, kX, kSP, false) , kRWI_W , 0 , 13 , 2314), // #264
- INST(Pssbb , BaseOp , (0b11010101000000110011010010011111) , 0 , 0 , 14 , 2338), // #265
- INST(Rbit , BaseRR , (0b01011010110000000000000000000000, kWX, kZR, 0, kWX, kZR, 5, true) , kRWI_W , 0 , 11 , 2364), // #266
- INST(Ret , BaseBranchReg , (0b11010110010111110000000000000000) , kRWI_R , 0 , 2 , 593 ), // #267
- INST(Rev , BaseRev , (_) , kRWI_W , 0 , 0 , 2369), // #268
- INST(Rev16 , BaseRR , (0b01011010110000000000010000000000, kWX, kZR, 0, kWX, kZR, 5, true) , kRWI_W , 0 , 12 , 2373), // #269
- INST(Rev32 , BaseRR , (0b11011010110000000000100000000000, kWX, kZR, 0, kWX, kZR, 5, true) , kRWI_W , 0 , 13 , 2379), // #270
- INST(Rev64 , BaseRR , (0b11011010110000000000110000000000, kWX, kZR, 0, kWX, kZR, 5, true) , kRWI_W , 0 , 14 , 2385), // #271
- INST(Ror , BaseShift , (0b0001101011000000001011, 0b0001001110000000000000, 1) , kRWI_W , 0 , 6 , 2391), // #272
- INST(Rorv , BaseShift , (0b0001101011000000001011, 0b0000000000000000000000, 1) , kRWI_W , 0 , 7 , 2395), // #273
- INST(Sbc , BaseRRR , (0b0101101000000000000000, kWX, kZR, kWX, kZR, kWX, kZR, true) , kRWI_W , 0 , 14 , 2498), // #274
- INST(Sbcs , BaseRRR , (0b0111101000000000000000, kWX, kZR, kWX, kZR, kWX, kZR, true) , kRWI_W , 0 , 15 , 2502), // #275
- INST(Sbfiz , BaseBfi , (0b00010011000000000000000000000000) , kRWI_W , 0 , 1 , 2507), // #276
- INST(Sbfm , BaseBfm , (0b00010011000000000000000000000000) , kRWI_W , 0 , 1 , 2513), // #277
- INST(Sbfx , BaseBfx , (0b00010011000000000000000000000000) , kRWI_W , 0 , 1 , 2518), // #278
- INST(Sdiv , BaseRRR , (0b0001101011000000000011, kWX, kZR, kWX, kZR, kWX, kZR, true) , kRWI_W , 0 , 16 , 2529), // #279
- INST(Setf8 , BaseR , (0b00111010000000000000100000001101, kW, kZR, 5) , 0 , 0 , 6 , 2541), // #280
- INST(Setf16 , BaseR , (0b00111010000000000100100000001101, kW, kZR, 5) , 0 , 0 , 7 , 2534), // #281
- INST(Sev , BaseOp , (0b11010101000000110010000010011111) , 0 , 0 , 15 , 2547), // #282
- INST(Sevl , BaseOp , (0b11010101000000110010000010111111) , 0 , 0 , 16 , 2551), // #283
- INST(Smaddl , BaseRRRR , (0b1001101100100000000000, kX , kZR, kW , kZR, kW , kZR, kX , kZR, false) , kRWI_W , 0 , 2 , 2758), // #284
- INST(Smc , BaseOpImm , (0b11010100000000000000000000000011, 16, 5) , 0 , 0 , 11 , 53 ), // #285
- INST(Smnegl , BaseRRR , (0b1001101100100000111111, kX , kZR, kW , kZR, kW , kZR, false) , kRWI_W , 0 , 17 , 2815), // #286
- INST(Smsubl , BaseRRRR , (0b1001101100100000100000, kX , kZR, kW , kZR, kW , kZR, kX , kZR, false) , kRWI_W , 0 , 3 , 2827), // #287
- INST(Smulh , BaseRRR , (0b1001101101000000011111, kX , kZR, kX , kZR, kX , kZR, true) , kRWI_W , 0 , 18 , 2834), // #288
- INST(Smull , BaseRRR , (0b1001101100100000011111, kX , kZR, kW , kZR, kW , kZR, false) , kRWI_W , 0 , 19 , 2840), // #289
- INST(Ssbb , BaseOp , (0b11010101000000110011000010011111) , 0 , 0 , 17 , 2339), // #290
- INST(St2g , BaseRM_SImm9 , (0b1101100110100000000010, 0b1101100110100000000001, kX, kSP, 0, 4) , kRWI_RW , 0 , 13 , 3164), // #291
- INST(Stadd , BaseAtomicSt , (0b1011100000100000000000, kWX, 30) , kRWI_RX , 0 , 0 , 3177), // #292
- INST(Staddl , BaseAtomicSt , (0b1011100001100000000000, kWX, 30) , kRWI_RX , 0 , 1 , 3197), // #293
- INST(Staddb , BaseAtomicSt , (0b0011100000100000000000, kW , 0 ) , kRWI_RX , 0 , 2 , 3183), // #294
- INST(Staddlb , BaseAtomicSt , (0b0011100001100000000000, kW , 0 ) , kRWI_RX , 0 , 3 , 3204), // #295
- INST(Staddh , BaseAtomicSt , (0b0111100000100000000000, kW , 0 ) , kRWI_RX , 0 , 4 , 3190), // #296
- INST(Staddlh , BaseAtomicSt , (0b0111100001100000000000, kW , 0 ) , kRWI_RX , 0 , 5 , 3212), // #297
- INST(Stclr , BaseAtomicSt , (0b1011100000100000000100, kWX, 30) , kRWI_RX , 0 , 6 , 3220), // #298
- INST(Stclrl , BaseAtomicSt , (0b1011100001100000000100, kWX, 30) , kRWI_RX , 0 , 7 , 3240), // #299
- INST(Stclrb , BaseAtomicSt , (0b0011100000100000000100, kW , 0 ) , kRWI_RX , 0 , 8 , 3226), // #300
- INST(Stclrlb , BaseAtomicSt , (0b0011100001100000000100, kW , 0 ) , kRWI_RX , 0 , 9 , 3247), // #301
- INST(Stclrh , BaseAtomicSt , (0b0111100000100000000100, kW , 0 ) , kRWI_RX , 0 , 10 , 3233), // #302
- INST(Stclrlh , BaseAtomicSt , (0b0111100001100000000100, kW , 0 ) , kRWI_RX , 0 , 11 , 3255), // #303
- INST(Steor , BaseAtomicSt , (0b1011100000100000001000, kWX, 30) , kRWI_RX , 0 , 12 , 3263), // #304
- INST(Steorl , BaseAtomicSt , (0b1011100001100000001000, kWX, 30) , kRWI_RX , 0 , 13 , 3283), // #305
- INST(Steorb , BaseAtomicSt , (0b0011100000100000001000, kW , 0 ) , kRWI_RX , 0 , 14 , 3269), // #306
- INST(Steorlb , BaseAtomicSt , (0b0011100001100000001000, kW , 0 ) , kRWI_RX , 0 , 15 , 3290), // #307
- INST(Steorh , BaseAtomicSt , (0b0111100000100000001000, kW , 0 ) , kRWI_RX , 0 , 16 , 3276), // #308
- INST(Steorlh , BaseAtomicSt , (0b0111100001100000001000, kW , 0 ) , kRWI_RX , 0 , 17 , 3298), // #309
- INST(Stg , BaseRM_SImm9 , (0b1101100100100000000010, 0b1101100100100000000001, kX, kSP, 0, 4) , kRWI_RW , 0 , 14 , 3306), // #310
- INST(Stgm , BaseRM_NoImm , (0b1101100110100000000000, kX , kZR, 0 ) , kRWI_RW , 0 , 13 , 3310), // #311
- INST(Stgp , BaseLdpStp , (0b0110100100, 0b0110100010, kX, 0, 4) , kRWI_RRW , 0 , 3 , 3315), // #312
- INST(Stllr , BaseRM_NoImm , (0b1000100010011111011111, kWX, kZR, 30) , kRWI_RW , 0 , 14 , 3320), // #313
- INST(Stllrb , BaseRM_NoImm , (0b0000100010011111011111, kW , kZR, 0 ) , kRWI_RW , 0 , 15 , 3326), // #314
- INST(Stllrh , BaseRM_NoImm , (0b0100100010011111011111, kW , kZR, 0 ) , kRWI_RW , 0 , 16 , 3333), // #315
- INST(Stlr , BaseRM_NoImm , (0b1000100010011111111111, kWX, kZR, 30) , kRWI_RW , 0 , 17 , 3340), // #316
- INST(Stlrb , BaseRM_NoImm , (0b0000100010011111111111, kW , kZR, 0 ) , kRWI_RW , 0 , 18 , 3345), // #317
- INST(Stlrh , BaseRM_NoImm , (0b0100100010011111111111, kW , kZR, 0 ) , kRWI_RW , 0 , 19 , 3351), // #318
- INST(Stlxp , BaseStxp , (0b1000100000100000100000, kWX, 30) , kRWI_WRRX , 0 , 0 , 3357), // #319
- INST(Stlxr , BaseAtomicOp , (0b1000100000000000111111, kWX, 30, 1) , kRWI_WRX , 0 , 108, 3363), // #320
- INST(Stlxrb , BaseAtomicOp , (0b0000100000000000111111, kW , 0 , 1) , kRWI_WRX , 0 , 109, 3369), // #321
- INST(Stlxrh , BaseAtomicOp , (0b0100100000000000111111, kW , 0 , 1) , kRWI_WRX , 0 , 110, 3376), // #322
- INST(Stnp , BaseLdpStp , (0b0010100000, 0 , kWX, 31, 2) , kRWI_RRW , 0 , 4 , 3383), // #323
- INST(Stp , BaseLdpStp , (0b0010100100, 0b0010100010, kWX, 31, 2) , kRWI_RRW , 0 , 5 , 3388), // #324
- INST(Str , BaseLdSt , (0b1011100100, 0b10111000000, 0b10111000001, 0 , kWX, 30, 2, Inst::kIdStur) , kRWI_RW , 0 , 6 , 3392), // #325
- INST(Strb , BaseLdSt , (0b0011100100, 0b00111000000, 0b00111000001, 0 , kW , 30, 0, Inst::kIdSturb) , kRWI_RW , 0 , 7 , 3396), // #326
- INST(Strh , BaseLdSt , (0b0111100100, 0b01111000000, 0b01111000001, 0 , kWX, 30, 1, Inst::kIdSturh) , kRWI_RW , 0 , 8 , 3401), // #327
- INST(Stset , BaseAtomicSt , (0b1011100000100000001100, kWX, 30) , kRWI_RX , 0 , 18 , 3406), // #328
- INST(Stsetl , BaseAtomicSt , (0b1011100001100000001100, kWX, 30) , kRWI_RX , 0 , 19 , 3426), // #329
- INST(Stsetb , BaseAtomicSt , (0b0011100000100000001100, kW , 0 ) , kRWI_RX , 0 , 20 , 3412), // #330
- INST(Stsetlb , BaseAtomicSt , (0b0011100001100000001100, kW , 0 ) , kRWI_RX , 0 , 21 , 3433), // #331
- INST(Stseth , BaseAtomicSt , (0b0111100000100000001100, kW , 0 ) , kRWI_RX , 0 , 22 , 3419), // #332
- INST(Stsetlh , BaseAtomicSt , (0b0111100001100000001100, kW , 0 ) , kRWI_RX , 0 , 23 , 3441), // #333
- INST(Stsmax , BaseAtomicSt , (0b1011100000100000010000, kWX, 30) , kRWI_RX , 0 , 24 , 3449), // #334
- INST(Stsmaxl , BaseAtomicSt , (0b1011100001100000010000, kWX, 30) , kRWI_RX , 0 , 25 , 3472), // #335
- INST(Stsmaxb , BaseAtomicSt , (0b0011100000100000010000, kW , 0 ) , kRWI_RX , 0 , 26 , 3456), // #336
- INST(Stsmaxlb , BaseAtomicSt , (0b0011100001100000010000, kW , 0 ) , kRWI_RX , 0 , 27 , 3480), // #337
- INST(Stsmaxh , BaseAtomicSt , (0b0111100000100000010000, kW , 0 ) , kRWI_RX , 0 , 28 , 3464), // #338
- INST(Stsmaxlh , BaseAtomicSt , (0b0111100001100000010000, kW , 0 ) , kRWI_RX , 0 , 29 , 3489), // #339
- INST(Stsmin , BaseAtomicSt , (0b1011100000100000010100, kWX, 30) , kRWI_RX , 0 , 30 , 3498), // #340
- INST(Stsminl , BaseAtomicSt , (0b1011100001100000010100, kWX, 30) , kRWI_RX , 0 , 31 , 3521), // #341
- INST(Stsminb , BaseAtomicSt , (0b0011100000100000010100, kW , 0 ) , kRWI_RX , 0 , 32 , 3505), // #342
- INST(Stsminlb , BaseAtomicSt , (0b0011100001100000010100, kW , 0 ) , kRWI_RX , 0 , 33 , 3529), // #343
- INST(Stsminh , BaseAtomicSt , (0b0111100000100000010100, kW , 0 ) , kRWI_RX , 0 , 34 , 3513), // #344
- INST(Stsminlh , BaseAtomicSt , (0b0111100001100000010100, kW , 0 ) , kRWI_RX , 0 , 35 , 3538), // #345
- INST(Sttr , BaseRM_SImm9 , (0b1011100000000000000010, 0b0000000000000000000000, kWX, kZR, 30, 0) , kRWI_RW , 0 , 15 , 3547), // #346
- INST(Sttrb , BaseRM_SImm9 , (0b0011100000000000000010, 0b0000000000000000000000, kW , kZR, 0 , 0) , kRWI_RW , 0 , 16 , 3552), // #347
- INST(Sttrh , BaseRM_SImm9 , (0b0111100000000000000010, 0b0000000000000000000000, kW , kZR, 0 , 0) , kRWI_RW , 0 , 17 , 3558), // #348
- INST(Stumax , BaseAtomicSt , (0b1011100000100000011000, kWX, 30) , kRWI_RX , 0 , 36 , 3564), // #349
- INST(Stumaxl , BaseAtomicSt , (0b1011100001100000011000, kWX, 30) , kRWI_RX , 0 , 37 , 3587), // #350
- INST(Stumaxb , BaseAtomicSt , (0b0011100000100000011000, kW , 0 ) , kRWI_RX , 0 , 38 , 3571), // #351
- INST(Stumaxlb , BaseAtomicSt , (0b0011100001100000011000, kW , 0 ) , kRWI_RX , 0 , 39 , 3595), // #352
- INST(Stumaxh , BaseAtomicSt , (0b0111100000100000011000, kW , 0 ) , kRWI_RX , 0 , 40 , 3579), // #353
- INST(Stumaxlh , BaseAtomicSt , (0b0111100001100000011000, kW , 0 ) , kRWI_RX , 0 , 41 , 3604), // #354
- INST(Stumin , BaseAtomicSt , (0b1011100000100000011100, kWX, 30) , kRWI_RX , 0 , 42 , 3613), // #355
- INST(Stuminl , BaseAtomicSt , (0b1011100001100000011100, kWX, 30) , kRWI_RX , 0 , 43 , 3636), // #356
- INST(Stuminb , BaseAtomicSt , (0b0011100000100000011100, kW , 0 ) , kRWI_RX , 0 , 44 , 3620), // #357
- INST(Stuminlb , BaseAtomicSt , (0b0011100001100000011100, kW , 0 ) , kRWI_RX , 0 , 45 , 3644), // #358
- INST(Stuminh , BaseAtomicSt , (0b0111100000100000011100, kW , 0 ) , kRWI_RX , 0 , 46 , 3628), // #359
- INST(Stuminlh , BaseAtomicSt , (0b0111100001100000011100, kW , 0 ) , kRWI_RX , 0 , 47 , 3653), // #360
- INST(Stur , BaseRM_SImm9 , (0b1011100000000000000000, 0b0000000000000000000000, kWX, kZR, 30, 0) , kRWI_RW , 0 , 18 , 3662), // #361
- INST(Sturb , BaseRM_SImm9 , (0b0011100000000000000000, 0b0000000000000000000000, kW , kZR, 0 , 0) , kRWI_RW , 0 , 19 , 3667), // #362
- INST(Sturh , BaseRM_SImm9 , (0b0111100000000000000000, 0b0000000000000000000000, kW , kZR, 0 , 0) , kRWI_RW , 0 , 20 , 3673), // #363
- INST(Stxp , BaseStxp , (0b1000100000100000000000, kWX, 30) , kRWI_WRRW , 0 , 1 , 3679), // #364
- INST(Stxr , BaseStx , (0b1000100000000000011111, kWX, 30) , kRWI_WRW , 0 , 0 , 3684), // #365
- INST(Stxrb , BaseStx , (0b0000100000000000011111, kW , 0 ) , kRWI_WRW , 0 , 1 , 3689), // #366
- INST(Stxrh , BaseStx , (0b0100100000000000011111, kW , 0 ) , kRWI_WRW , 0 , 2 , 3695), // #367
- INST(Stz2g , BaseRM_SImm9 , (0b1101100111100000000010, 0b1101100111100000000001, kX , kSP, 0, 4) , kRWI_RW , 0 , 21 , 3701), // #368
- INST(Stzg , BaseRM_SImm9 , (0b1101100101100000000010, 0b1101100101100000000001, kX , kSP, 0, 4) , kRWI_RW , 0 , 22 , 3707), // #369
- INST(Stzgm , BaseRM_NoImm , (0b1101100100100000000000, kX , kZR, 0) , kRWI_RW , 0 , 20 , 3712), // #370
- INST(Sub , BaseAddSub , (0b1001011000, 0b1001011001, 0b1010001) , kRWI_X , 0 , 2 , 985 ), // #371
- INST(Subg , BaseRRII , (0b1101000110000000000000, kX, kSP, kX, kSP, 6, 4, 16, 4, 0, 10) , kRWI_W , 0 , 1 , 3718), // #372
- INST(Subp , BaseRRR , (0b1001101011000000000000, kX, kZR, kX, kSP, kX, kSP, false) , kRWI_W , 0 , 20 , 3723), // #373
- INST(Subps , BaseRRR , (0b1011101011000000000000, kX, kZR, kX, kSP, kX, kSP, false) , kRWI_W , 0 , 21 , 3728), // #374
- INST(Subs , BaseAddSub , (0b1101011000, 0b1101011001, 0b1110001) , kRWI_X , 0 , 3 , 3734), // #375
- INST(Svc , BaseOpImm , (0b11010100000000000000000000000001, 16, 5) , 0 , 0 , 12 , 3752), // #376
- INST(Swp , BaseAtomicOp , (0b1011100000100000100000, kWX, 30, 1) , kRWI_RWX , 0 , 111, 3756), // #377
- INST(Swpa , BaseAtomicOp , (0b1011100010100000100000, kWX, 30, 1) , kRWI_RWX , 0 , 112, 3760), // #378
- INST(Swpab , BaseAtomicOp , (0b0011100010100000100000, kW , 0 , 1) , kRWI_RWX , 0 , 113, 3765), // #379
- INST(Swpah , BaseAtomicOp , (0b0111100010100000100000, kW , 0 , 1) , kRWI_RWX , 0 , 114, 3771), // #380
- INST(Swpal , BaseAtomicOp , (0b1011100011100000100000, kWX, 30, 1) , kRWI_RWX , 0 , 115, 3777), // #381
- INST(Swpalb , BaseAtomicOp , (0b0011100011100000100000, kW , 0 , 1) , kRWI_RWX , 0 , 116, 3783), // #382
- INST(Swpalh , BaseAtomicOp , (0b0111100011100000100000, kW , 0 , 1) , kRWI_RWX , 0 , 117, 3790), // #383
- INST(Swpb , BaseAtomicOp , (0b0011100000100000100000, kW , 0 , 1) , kRWI_RWX , 0 , 118, 3797), // #384
- INST(Swph , BaseAtomicOp , (0b0111100000100000100000, kW , 0 , 1) , kRWI_RWX , 0 , 119, 3802), // #385
- INST(Swpl , BaseAtomicOp , (0b1011100001100000100000, kWX, 30, 1) , kRWI_RWX , 0 , 120, 3807), // #386
- INST(Swplb , BaseAtomicOp , (0b0011100001100000100000, kW , 0 , 1) , kRWI_RWX , 0 , 121, 3812), // #387
- INST(Swplh , BaseAtomicOp , (0b0111100001100000100000, kW , 0 , 1) , kRWI_RWX , 0 , 122, 3818), // #388
- INST(Sxtb , BaseExtend , (0b0001001100000000000111, kWX, 0) , kRWI_W , 0 , 0 , 3824), // #389
- INST(Sxth , BaseExtend , (0b0001001100000000001111, kWX, 0) , kRWI_W , 0 , 1 , 3829), // #390
- INST(Sxtw , BaseExtend , (0b1001001101000000011111, kX , 0) , kRWI_W , 0 , 2 , 3845), // #391
- INST(Sys , BaseSys , (_) , kRWI_W , 0 , 0 , 3850), // #392
- INST(Tlbi , BaseAtDcIcTlbi , (0b00011110000000, 0b00010000000000, false) , kRWI_RX , 0 , 3 , 3871), // #393
- INST(Tst , BaseTst , (0b1101010000, 0b111001000) , kRWI_R , 0 , 0 , 437 ), // #394
- INST(Tbnz , BaseBranchTst , (0b00110111000000000000000000000000) , kRWI_R , 0 , 0 , 3858), // #395
- INST(Tbz , BaseBranchTst , (0b00110110000000000000000000000000) , kRWI_R , 0 , 1 , 3867), // #396
- INST(Ubfiz , BaseBfi , (0b01010011000000000000000000000000) , kRWI_W , 0 , 2 , 3969), // #397
- INST(Ubfm , BaseBfm , (0b01010011000000000000000000000000) , kRWI_W , 0 , 2 , 3975), // #398
- INST(Ubfx , BaseBfx , (0b01010011000000000000000000000000) , kRWI_W , 0 , 2 , 3980), // #399
- INST(Udf , BaseOpImm , (0b00000000000000000000000000000000, 16, 0) , 0 , 0 , 13 , 3991), // #400
- INST(Udiv , BaseRRR , (0b0001101011000000000010, kWX, kZR, kWX, kZR, kWX, kZR, true) , kRWI_W , 0 , 22 , 3995), // #401
- INST(Umaddl , BaseRRRR , (0b1001101110100000000000, kX , kZR, kW , kZR, kW , kZR, kX , kZR, false) , kRWI_W , 0 , 4 , 4012), // #402
- INST(Umnegl , BaseRRR , (0b1001101110100000111111, kX , kZR, kW , kZR, kW , kZR, false) , kRWI_W , 0 , 23 , 4075), // #403
- INST(Umull , BaseRRR , (0b1001101110100000011111, kX , kZR, kW , kZR, kW , kZR, false) , kRWI_W , 0 , 24 , 4100), // #404
- INST(Umulh , BaseRRR , (0b1001101111000000011111, kX , kZR, kX , kZR, kX , kZR, false) , kRWI_W , 0 , 25 , 4094), // #405
- INST(Umsubl , BaseRRRR , (0b1001101110100000100000, kX , kZR, kW , kZR, kW , kZR, kX , kZR, false) , kRWI_W , 0 , 5 , 4087), // #406
- INST(Uxtb , BaseExtend , (0b0101001100000000000111, kW, 1) , kRWI_W , 0 , 3 , 4291), // #407
- INST(Uxth , BaseExtend , (0b0101001100000000001111, kW, 1) , kRWI_W , 0 , 4 , 4296), // #408
- INST(Wfe , BaseOp , (0b11010101000000110010000001011111) , 0 , 0 , 18 , 4322), // #409
- INST(Wfi , BaseOp , (0b11010101000000110010000001111111) , 0 , 0 , 19 , 4326), // #410
- INST(Xaflag , BaseOp , (0b11010101000000000100000000111111) , 0 , 0 , 20 , 4330), // #411
- INST(Xpacd , BaseR , (0b11011010110000010100011111100000, kX, kZR, 0) , kRWI_X , 0 , 8 , 4341), // #412
- INST(Xpaci , BaseR , (0b11011010110000010100001111100000, kX, kZR, 0) , kRWI_X , 0 , 9 , 4347), // #413
- INST(Xpaclri , BaseOp , (0b11010101000000110010000011111111) , kRWI_X , 0 , 21 , 4353), // #414
- INST(Yield , BaseOp , (0b11010101000000110010000000111111) , 0 , 0 , 22 , 4361), // #415
- INST(Abs_v , ISimdVV , (0b0000111000100000101110, kVO_V_Any) , kRWI_W , 0 , 0 , 2855), // #416
- INST(Add_v , ISimdVVV , (0b0000111000100000100001, kVO_V_Any) , kRWI_W , 0 , 0 , 978 ), // #417
- INST(Addhn_v , ISimdVVV , (0b0000111000100000010000, kVO_V_B8H4S2) , kRWI_W , F(Narrow) , 1 , 2345), // #418
- INST(Addhn2_v , ISimdVVV , (0b0100111000100000010000, kVO_V_B16H8S4) , kRWI_W , F(Narrow) , 2 , 2352), // #419
- INST(Addp_v , ISimdPair , (0b0101111000110001101110, 0b0000111000100000101111, kVO_V_Any) , kRWI_W , F(Pair) , 0 , 638 ), // #420
- INST(Addv_v , ISimdSV , (0b0000111000110001101110, kVO_V_BH_4S) , kRWI_W , 0 , 0 , 20 ), // #421
- INST(Aesd_v , ISimdVVx , (0b0100111000101000010110, kOp_V16B, kOp_V16B) , kRWI_X , 0 , 0 , 34 ), // #422
- INST(Aese_v , ISimdVVx , (0b0100111000101000010010, kOp_V16B, kOp_V16B) , kRWI_X , 0 , 1 , 39 ), // #423
- INST(Aesimc_v , ISimdVVx , (0b0100111000101000011110, kOp_V16B, kOp_V16B) , kRWI_W , 0 , 2 , 44 ), // #424
- INST(Aesmc_v , ISimdVVx , (0b0100111000101000011010, kOp_V16B, kOp_V16B) , kRWI_W , 0 , 3 , 51 ), // #425
- INST(And_v , ISimdVVV , (0b0000111000100000000111, kVO_V_B) , kRWI_W , 0 , 3 , 57 ), // #426
- INST(Bcax_v , ISimdVVVV , (0b1100111000100000000000, kVO_V_B16) , kRWI_W , 0 , 0 , 187 ), // #427
- INST(Bfcvt_v , ISimdVVx , (0b0001111001100011010000, kOp_H, kOp_S) , kRWI_W , 0 , 4 , 196 ), // #428
- INST(Bfcvtn_v , ISimdVVx , (0b0000111010100001011010, kOp_V4H, kOp_V4S) , kRWI_W , F(Narrow) , 5 , 202 ), // #429
- INST(Bfcvtn2_v , ISimdVVx , (0b0100111010100001011010, kOp_V8H, kOp_V4S) , kRWI_W , F(Narrow) , 6 , 209 ), // #430
- INST(Bfdot_v , SimdDot , (0b0010111001000000111111, 0b0000111101000000111100, kET_S, kET_H, kET_2H) , kRWI_X , 0 , 0 , 217 ), // #431
- INST(Bfmlalb_v , SimdFmlal , (0b0010111011000000111111, 0b0000111111000000111100, 0, kET_S, kET_H, kET_H) , kRWI_X , F(VH0_15) , 0 , 227 ), // #432
- INST(Bfmlalt_v , SimdFmlal , (0b0110111011000000111111, 0b0100111111000000111100, 0, kET_S, kET_H, kET_H) , kRWI_X , F(VH0_15) , 1 , 235 ), // #433
- INST(Bfmmla_v , ISimdVVVx , (0b0110111001000000111011, kOp_V4S, kOp_V8H, kOp_V8H) , kRWI_X , F(Long) , 0 , 243 ), // #434
- INST(Bic_v , SimdBicOrr , (0b0000111001100000000111, 0b0010111100000000000001) , kRWI_W , 0 , 0 , 256 ), // #435
- INST(Bif_v , ISimdVVV , (0b0010111011100000000111, kVO_V_B) , kRWI_X , 0 , 4 , 265 ), // #436
- INST(Bit_v , ISimdVVV , (0b0010111010100000000111, kVO_V_B) , kRWI_X , 0 , 5 , 2365), // #437
- INST(Bsl_v , ISimdVVV , (0b0010111001100000000111, kVO_V_B) , kRWI_X , 0 , 6 , 280 ), // #438
- INST(Cls_v , ISimdVV , (0b0000111000100000010010, kVO_V_BHS) , kRWI_W , 0 , 1 , 412 ), // #439
- INST(Clz_v , ISimdVV , (0b0010111000100000010010, kVO_V_BHS) , kRWI_W , 0 , 2 , 416 ), // #440
- INST(Cmeq_v , SimdCmp , (0b0010111000100000100011, 0b0000111000100000100110, kVO_V_Any) , kRWI_W , 0 , 0 , 663 ), // #441
- INST(Cmge_v , SimdCmp , (0b0000111000100000001111, 0b0010111000100000100010, kVO_V_Any) , kRWI_W , 0 , 1 , 669 ), // #442
- INST(Cmgt_v , SimdCmp , (0b0000111000100000001101, 0b0000111000100000100010, kVO_V_Any) , kRWI_W , 0 , 2 , 675 ), // #443
- INST(Cmhi_v , SimdCmp , (0b0010111000100000001101, 0b0000000000000000000000, kVO_V_Any) , kRWI_W , 0 , 3 , 420 ), // #444
- INST(Cmhs_v , SimdCmp , (0b0010111000100000001111, 0b0000000000000000000000, kVO_V_Any) , kRWI_W , 0 , 4 , 425 ), // #445
- INST(Cmle_v , SimdCmp , (0b0000000000000000000000, 0b0010111000100000100110, kVO_V_Any) , kRWI_W , 0 , 5 , 687 ), // #446
- INST(Cmlt_v , SimdCmp , (0b0000000000000000000000, 0b0000111000100000101010, kVO_V_Any) , kRWI_W , 0 , 6 , 693 ), // #447
- INST(Cmtst_v , ISimdVVV , (0b0000111000100000100011, kVO_V_Any) , kRWI_W , 0 , 7 , 435 ), // #448
- INST(Cnt_v , ISimdVV , (0b0000111000100000010110, kVO_V_B) , kRWI_W , 0 , 3 , 446 ), // #449
- INST(Dup_v , SimdDup , (_) , kRWI_W , 0 , 0 , 579 ), // #450
- INST(Eor_v , ISimdVVV , (0b0010111000100000000111, kVO_V_B) , kRWI_W , 0 , 8 , 1418), // #451
- INST(Eor3_v , ISimdVVVV , (0b1100111000000000000000, kVO_V_B16) , kRWI_W , 0 , 1 , 587 ), // #452
- INST(Ext_v , ISimdVVVI , (0b0010111000000000000000, kVO_V_B, 4, 11, 1) , kRWI_W , 0 , 0 , 601 ), // #453
- INST(Fabd_v , FSimdVVV , (0b0111111010100000110101, kHF_C, 0b0010111010100000110101, kHF_C) , kRWI_W , 0 , 0 , 610 ), // #454
- INST(Fabs_v , FSimdVV , (0b0001111000100000110000, kHF_A, 0b0000111010100000111110, kHF_B) , kRWI_W , 0 , 0 , 615 ), // #455
- INST(Facge_v , FSimdVVV , (0b0111111000100000111011, kHF_C, 0b0010111000100000111011, kHF_C) , kRWI_W , 0 , 1 , 620 ), // #456
- INST(Facgt_v , FSimdVVV , (0b0111111010100000111011, kHF_C, 0b0010111010100000111011, kHF_C) , kRWI_W , 0 , 2 , 626 ), // #457
- INST(Fadd_v , FSimdVVV , (0b0001111000100000001010, kHF_A, 0b0000111000100000110101, kHF_C) , kRWI_W , 0 , 3 , 632 ), // #458
- INST(Faddp_v , FSimdPair , (0b0111111000110000110110, 0b0010111000100000110101) , kRWI_W , 0 , 0 , 637 ), // #459
- INST(Fcadd_v , SimdFcadd , (0b0010111000000000111001) , kRWI_W , 0 , 0 , 643 ), // #460
- INST(Fccmp_v , SimdFccmpFccmpe , (0b00011110001000000000010000000000) , kRWI_R , 0 , 0 , 649 ), // #461
- INST(Fccmpe_v , SimdFccmpFccmpe , (0b00011110001000000000010000010000) , kRWI_R , 0 , 1 , 655 ), // #462
- INST(Fcmeq_v , SimdFcm , (0b0000111000100000111001, kHF_C, 0b0000111010100000110110) , kRWI_W , 0 , 0 , 662 ), // #463
- INST(Fcmge_v , SimdFcm , (0b0010111000100000111001, kHF_C, 0b0010111010100000110010) , kRWI_W , 0 , 1 , 668 ), // #464
- INST(Fcmgt_v , SimdFcm , (0b0010111010100000111001, kHF_C, 0b0000111010100000110010) , kRWI_W , 0 , 2 , 674 ), // #465
- INST(Fcmla_v , SimdFcmla , (0b0010111000000000110001, 0b0010111100000000000100) , kRWI_X , 0 , 0 , 680 ), // #466
- INST(Fcmle_v , SimdFcm , (0b0000000000000000000000, kHF_C, 0b0010111010100000110110) , kRWI_W , 0 , 3 , 686 ), // #467
- INST(Fcmlt_v , SimdFcm , (0b0000000000000000000000, kHF_C, 0b0000111010100000111010) , kRWI_W , 0 , 4 , 692 ), // #468
- INST(Fcmp_v , SimdFcmpFcmpe , (0b00011110001000000010000000000000) , kRWI_R , 0 , 0 , 698 ), // #469
- INST(Fcmpe_v , SimdFcmpFcmpe , (0b00011110001000000010000000010000) , kRWI_R , 0 , 1 , 703 ), // #470
- INST(Fcsel_v , SimdFcsel , (_) , kRWI_W , 0 , 0 , 709 ), // #471
- INST(Fcvt_v , SimdFcvt , (_) , kRWI_W , 0 , 0 , 197 ), // #472
- INST(Fcvtas_v , SimdFcvtSV , (0b0000111000100001110010, 0b0000000000000000000000, 0b0001111000100100000000, 1) , kRWI_W , 0 , 0 , 715 ), // #473
- INST(Fcvtau_v , SimdFcvtSV , (0b0010111000100001110010, 0b0000000000000000000000, 0b0001111000100101000000, 1) , kRWI_W , 0 , 1 , 722 ), // #474
- INST(Fcvtl_v , SimdFcvtLN , (0b0000111000100001011110, 0, 0) , kRWI_W , F(Long) , 0 , 729 ), // #475
- INST(Fcvtl2_v , SimdFcvtLN , (0b0100111000100001011110, 0, 0) , kRWI_W , F(Long) , 1 , 735 ), // #476
- INST(Fcvtms_v , SimdFcvtSV , (0b0000111000100001101110, 0b0000000000000000000000, 0b0001111000110000000000, 1) , kRWI_W , 0 , 2 , 742 ), // #477
- INST(Fcvtmu_v , SimdFcvtSV , (0b0010111000100001101110, 0b0000000000000000000000, 0b0001111000110001000000, 1) , kRWI_W , 0 , 3 , 749 ), // #478
- INST(Fcvtn_v , SimdFcvtLN , (0b0000111000100001011010, 0, 0) , kRWI_W , F(Narrow) , 2 , 203 ), // #479
- INST(Fcvtn2_v , SimdFcvtLN , (0b0100111000100001011010, 0, 0) , kRWI_X , F(Narrow) , 3 , 210 ), // #480
- INST(Fcvtns_v , SimdFcvtSV , (0b0000111000100001101010, 0b0000000000000000000000, 0b0001111000100000000000, 1) , kRWI_W , 0 , 4 , 756 ), // #481
- INST(Fcvtnu_v , SimdFcvtSV , (0b0010111000100001101010, 0b0000000000000000000000, 0b0001111000100001000000, 1) , kRWI_W , 0 , 5 , 763 ), // #482
- INST(Fcvtps_v , SimdFcvtSV , (0b0000111010100001101010, 0b0000000000000000000000, 0b0001111000101000000000, 1) , kRWI_W , 0 , 6 , 770 ), // #483
- INST(Fcvtpu_v , SimdFcvtSV , (0b0010111010100001101010, 0b0000000000000000000000, 0b0001111000101001000000, 1) , kRWI_W , 0 , 7 , 777 ), // #484
- INST(Fcvtxn_v , SimdFcvtLN , (0b0010111000100001011010, 1, 1) , kRWI_W , F(Narrow) , 4 , 784 ), // #485
- INST(Fcvtxn2_v , SimdFcvtLN , (0b0110111000100001011010, 1, 0) , kRWI_X , F(Narrow) , 5 , 791 ), // #486
- INST(Fcvtzs_v , SimdFcvtSV , (0b0000111010100001101110, 0b0000111100000000111111, 0b0001111000111000000000, 1) , kRWI_W , 0 , 8 , 799 ), // #487
- INST(Fcvtzu_v , SimdFcvtSV , (0b0010111010100001101110, 0b0010111100000000111111, 0b0001111000111001000000, 1) , kRWI_W , 0 , 9 , 806 ), // #488
- INST(Fdiv_v , FSimdVVV , (0b0001111000100000000110, kHF_A, 0b0010111000100000111111, kHF_C) , kRWI_W , 0 , 4 , 813 ), // #489
- INST(Fjcvtzs_v , ISimdVVx , (0b0001111001111110000000, kOp_GpW, kOp_D) , kRWI_W , 0 , 7 , 818 ), // #490
- INST(Fmadd_v , FSimdVVVV , (0b0001111100000000000000, kHF_A, 0b0000000000000000000000, kHF_N) , kRWI_W , 0 , 0 , 826 ), // #491
- INST(Fmax_v , FSimdVVV , (0b0001111000100000010010, kHF_A, 0b0000111000100000111101, kHF_C) , kRWI_W , 0 , 5 , 832 ), // #492
- INST(Fmaxnm_v , FSimdVVV , (0b0001111000100000011010, kHF_A, 0b0000111000100000110001, kHF_C) , kRWI_W , 0 , 6 , 837 ), // #493
- INST(Fmaxnmp_v , FSimdPair , (0b0111111000110000110010, 0b0010111000100000110001) , kRWI_W , 0 , 1 , 844 ), // #494
- INST(Fmaxnmv_v , FSimdSV , (0b0010111000110000110010) , kRWI_W , 0 , 0 , 852 ), // #495
- INST(Fmaxp_v , FSimdPair , (0b0111111000110000111110, 0b0010111000100000111101) , kRWI_W , 0 , 2 , 860 ), // #496
- INST(Fmaxv_v , FSimdSV , (0b0010111000110000111110) , kRWI_W , 0 , 1 , 866 ), // #497
- INST(Fmin_v , FSimdVVV , (0b0001111000100000010110, kHF_A, 0b0000111010100000111101, kHF_C) , kRWI_W , 0 , 7 , 872 ), // #498
- INST(Fminnm_v , FSimdVVV , (0b0001111000100000011110, kHF_A, 0b0000111010100000110001, kHF_C) , kRWI_W , 0 , 8 , 877 ), // #499
- INST(Fminnmp_v , FSimdPair , (0b0111111010110000110010, 0b0010111010100000110001) , kRWI_W , 0 , 3 , 884 ), // #500
- INST(Fminnmv_v , FSimdSV , (0b0010111010110000110010) , kRWI_W , 0 , 2 , 892 ), // #501
- INST(Fminp_v , FSimdPair , (0b0111111010110000111110, 0b0010111010100000111101) , kRWI_W , 0 , 4 , 900 ), // #502
- INST(Fminv_v , FSimdSV , (0b0010111010110000111110) , kRWI_W , 0 , 3 , 906 ), // #503
- INST(Fmla_v , FSimdVVVe , (0b0000000000000000000000, kHF_N, 0b0000111000100000110011, 0b0000111110000000000100) , kRWI_X , F(VH0_15) , 0 , 912 ), // #504
- INST(Fmlal_v , SimdFmlal , (0b0000111000100000111011, 0b0000111110000000000000, 1, kET_S, kET_H, kET_H) , kRWI_X , F(VH0_15) , 2 , 917 ), // #505
- INST(Fmlal2_v , SimdFmlal , (0b0010111000100000110011, 0b0010111110000000100000, 1, kET_S, kET_H, kET_H) , kRWI_X , F(VH0_15) , 3 , 923 ), // #506
- INST(Fmls_v , FSimdVVVe , (0b0000000000000000000000, kHF_N, 0b0000111010100000110011, 0b0000111110000000010100) , kRWI_X , F(VH0_15) , 1 , 930 ), // #507
- INST(Fmlsl_v , SimdFmlal , (0b0000111010100000111011, 0b0000111110000000010000, 1, kET_S, kET_H, kET_H) , kRWI_X , F(VH0_15) , 4 , 935 ), // #508
- INST(Fmlsl2_v , SimdFmlal , (0b0010111010100000110011, 0b0010111110000000110000, 1, kET_S, kET_H, kET_H) , kRWI_X , F(VH0_15) , 5 , 941 ), // #509
- INST(Fmov_v , SimdFmov , (_) , kRWI_W , 0 , 0 , 948 ), // #510
- INST(Fmsub_v , FSimdVVVV , (0b0001111100000000100000, kHF_A, 0b0000000000000000000000, kHF_N) , kRWI_W , 0 , 1 , 953 ), // #511
- INST(Fmul_v , FSimdVVVe , (0b0001111000100000000010, kHF_A, 0b0010111000100000110111, 0b0000111110000000100100) , kRWI_W , F(VH0_15) , 2 , 959 ), // #512
- INST(Fmulx_v , FSimdVVVe , (0b0101111000100000110111, kHF_C, 0b0000111000100000110111, 0b0010111110000000100100) , kRWI_W , F(VH0_15) , 3 , 964 ), // #513
- INST(Fneg_v , FSimdVV , (0b0001111000100001010000, kHF_A, 0b0010111010100000111110, kHF_B) , kRWI_W , 0 , 1 , 970 ), // #514
- INST(Fnmadd_v , FSimdVVVV , (0b0001111100100000000000, kHF_A, 0b0000000000000000000000, kHF_N) , kRWI_W , 0 , 2 , 975 ), // #515
- INST(Fnmsub_v , FSimdVVVV , (0b0001111100100000100000, kHF_A, 0b0000000000000000000000, kHF_N) , kRWI_W , 0 , 3 , 982 ), // #516
- INST(Fnmul_v , FSimdVVV , (0b0001111000100000100010, kHF_A, 0b0000000000000000000000, kHF_N) , kRWI_W , 0 , 9 , 989 ), // #517
- INST(Frecpe_v , FSimdVV , (0b0101111010100001110110, kHF_B, 0b0000111010100001110110, kHF_B) , kRWI_W , 0 , 2 , 995 ), // #518
- INST(Frecps_v , FSimdVVV , (0b0101111000100000111111, kHF_C, 0b0000111000100000111111, kHF_C) , kRWI_W , 0 , 10 , 1002), // #519
- INST(Frecpx_v , FSimdVV , (0b0101111010100001111110, kHF_B, 0b0000000000000000000000, kHF_N) , kRWI_W , 0 , 3 , 1009), // #520
- INST(Frint32x_v , FSimdVV , (0b0001111000101000110000, kHF_N, 0b0010111000100001111010, kHF_N) , kRWI_W , 0 , 4 , 1016), // #521
- INST(Frint32z_v , FSimdVV , (0b0001111000101000010000, kHF_N, 0b0000111000100001111010, kHF_N) , kRWI_W , 0 , 5 , 1025), // #522
- INST(Frint64x_v , FSimdVV , (0b0001111000101001110000, kHF_N, 0b0010111000100001111110, kHF_N) , kRWI_W , 0 , 6 , 1034), // #523
- INST(Frint64z_v , FSimdVV , (0b0001111000101001010000, kHF_N, 0b0000111000100001111110, kHF_N) , kRWI_W , 0 , 7 , 1043), // #524
- INST(Frinta_v , FSimdVV , (0b0001111000100110010000, kHF_A, 0b0010111000100001100010, kHF_B) , kRWI_W , 0 , 8 , 1052), // #525
- INST(Frinti_v , FSimdVV , (0b0001111000100111110000, kHF_A, 0b0010111010100001100110, kHF_B) , kRWI_W , 0 , 9 , 1059), // #526
- INST(Frintm_v , FSimdVV , (0b0001111000100101010000, kHF_A, 0b0000111000100001100110, kHF_B) , kRWI_W , 0 , 10 , 1066), // #527
- INST(Frintn_v , FSimdVV , (0b0001111000100100010000, kHF_A, 0b0000111000100001100010, kHF_B) , kRWI_W , 0 , 11 , 1073), // #528
- INST(Frintp_v , FSimdVV , (0b0001111000100100110000, kHF_A, 0b0000111010100001100010, kHF_B) , kRWI_W , 0 , 12 , 1080), // #529
- INST(Frintx_v , FSimdVV , (0b0001111000100111010000, kHF_A, 0b0010111000100001100110, kHF_B) , kRWI_W , 0 , 13 , 1087), // #530
- INST(Frintz_v , FSimdVV , (0b0001111000100101110000, kHF_A, 0b0000111010100001100110, kHF_B) , kRWI_W , 0 , 14 , 1094), // #531
- INST(Frsqrte_v , FSimdVV , (0b0111111010100001110110, kHF_B, 0b0010111010100001110110, kHF_B) , kRWI_W , 0 , 15 , 1101), // #532
- INST(Frsqrts_v , FSimdVVV , (0b0101111010100000111111, kHF_C, 0b0000111010100000111111, kHF_C) , kRWI_W , 0 , 11 , 1109), // #533
- INST(Fsqrt_v , FSimdVV , (0b0001111000100001110000, kHF_A, 0b0010111010100001111110, kHF_B) , kRWI_W , 0 , 16 , 1117), // #534
- INST(Fsub_v , FSimdVVV , (0b0001111000100000001110, kHF_A, 0b0000111010100000110101, kHF_C) , kRWI_W , 0 , 12 , 1123), // #535
- INST(Ins_v , SimdIns , (_) , kRWI_X , 0 , 0 , 1145), // #536
- INST(Ld1_v , SimdLdNStN , (0b0000110101000000000000, 0b0000110001000000001000, 1, 0) , kRWI_LDn , F(Consecutive) , 0 , 1153), // #537
- INST(Ld1r_v , SimdLdNStN , (0b0000110101000000110000, 0b0000000000000000000000, 1, 1) , kRWI_LDn , F(Consecutive) , 1 , 1157), // #538
- INST(Ld2_v , SimdLdNStN , (0b0000110101100000000000, 0b0000110001000000100000, 2, 0) , kRWI_LDn , F(Consecutive) , 2 , 1162), // #539
- INST(Ld2r_v , SimdLdNStN , (0b0000110101100000110000, 0b0000000000000000000000, 2, 1) , kRWI_LDn , F(Consecutive) , 3 , 1166), // #540
- INST(Ld3_v , SimdLdNStN , (0b0000110101000000001000, 0b0000110001000000010000, 3, 0) , kRWI_LDn , F(Consecutive) , 4 , 1171), // #541
- INST(Ld3r_v , SimdLdNStN , (0b0000110101000000111000, 0b0000000000000000000000, 3, 1) , kRWI_LDn , F(Consecutive) , 5 , 1175), // #542
- INST(Ld4_v , SimdLdNStN , (0b0000110101100000001000, 0b0000110001000000000000, 4, 0) , kRWI_LDn , F(Consecutive) , 6 , 1180), // #543
- INST(Ld4r_v , SimdLdNStN , (0b0000110101100000111000, 0b0000000000000000000000, 4, 1) , kRWI_LDn , F(Consecutive) , 7 , 1184), // #544
- INST(Ldnp_v , SimdLdpStp , (0b0010110001, 0b0000000000) , kRWI_WW , 0 , 0 , 1537), // #545
- INST(Ldp_v , SimdLdpStp , (0b0010110101, 0b0010110011) , kRWI_WW , 0 , 1 , 1542), // #546
- INST(Ldr_v , SimdLdSt , (0b0011110101, 0b00111100010, 0b00111100011, 0b00011100, Inst::kIdLdur_v) , kRWI_W , 0 , 0 , 1552), // #547
- INST(Ldur_v , SimdLdurStur , (0b0011110001000000000000) , kRWI_W , 0 , 0 , 2142), // #548
- INST(Mla_v , ISimdVVVe , (0b0000111000100000100101, kVO_V_BHS, 0b0010111100000000000000, kVO_V_HS) , kRWI_X , F(VH0_15) , 0 , 246 ), // #549
- INST(Mls_v , ISimdVVVe , (0b0010111000100000100101, kVO_V_BHS, 0b0010111100000000010000, kVO_V_HS) , kRWI_X , F(VH0_15) , 1 , 931 ), // #550
- INST(Mov_v , SimdMov , (_) , kRWI_W , 0 , 0 , 949 ), // #551
- INST(Movi_v , SimdMoviMvni , (0b0000111100000000000001, 0) , kRWI_W , 0 , 0 , 2221), // #552
- INST(Mul_v , ISimdVVVe , (0b0000111000100000100111, kVO_V_BHS, 0b0000111100000000100000, kVO_V_HS) , kRWI_W , F(VH0_15) , 2 , 991 ), // #553
- INST(Mvn_v , ISimdVV , (0b0010111000100000010110, kVO_V_B) , kRWI_W , 0 , 4 , 2249), // #554
- INST(Mvni_v , SimdMoviMvni , (0b0000111100000000000001, 1) , kRWI_W , 0 , 1 , 2253), // #555
- INST(Neg_v , ISimdVV , (0b0010111000100000101110, kVO_V_Any) , kRWI_W , 0 , 5 , 540 ), // #556
- INST(Not_v , ISimdVV , (0b0010111000100000010110, kVO_V_B) , kRWI_W , 0 , 6 , 2276), // #557
- INST(Orn_v , ISimdVVV , (0b0000111011100000000111, kVO_V_B) , kRWI_W , 0 , 9 , 2280), // #558
- INST(Orr_v , SimdBicOrr , (0b0000111010100000000111, 0b0000111100000000000001) , kRWI_W , 0 , 1 , 2284), // #559
- INST(Pmul_v , ISimdVVV , (0b0010111000100000100111, kVO_V_B) , kRWI_W , 0 , 10 , 2320), // #560
- INST(Pmull_v , ISimdVVV , (0b0000111000100000111000, kVO_V_B8D1) , kRWI_W , F(Long) , 11 , 2325), // #561
- INST(Pmull2_v , ISimdVVV , (0b0100111000100000111000, kVO_V_B16D2) , kRWI_W , F(Long) , 12 , 2331), // #562
- INST(Raddhn_v , ISimdVVV , (0b0010111000100000010000, kVO_V_B8H4S2) , kRWI_W , F(Narrow) , 13 , 2344), // #563
- INST(Raddhn2_v , ISimdVVV , (0b0110111000100000010000, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 14 , 2351), // #564
- INST(Rax1_v , ISimdVVV , (0b1100111001100000100011, kVO_V_D2) , kRWI_W , 0 , 15 , 2359), // #565
- INST(Rbit_v , ISimdVV , (0b0010111001100000010110, kVO_V_B) , kRWI_W , 0 , 7 , 2364), // #566
- INST(Rev16_v , ISimdVV , (0b0000111000100000000110, kVO_V_B) , kRWI_W , 0 , 8 , 2373), // #567
- INST(Rev32_v , ISimdVV , (0b0010111000100000000010, kVO_V_BH) , kRWI_W , 0 , 9 , 2379), // #568
- INST(Rev64_v , ISimdVV , (0b0000111000100000000010, kVO_V_BHS) , kRWI_W , 0 , 10 , 2385), // #569
- INST(Rshrn_v , SimdShift , (0b0000000000000000000000, 0b0000111100000000100011, 1, kVO_V_B8H4S2) , kRWI_W , F(Narrow) , 0 , 2960), // #570
- INST(Rshrn2_v , SimdShift , (0b0000000000000000000000, 0b0100111100000000100011, 1, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 1 , 2968), // #571
- INST(Rsubhn_v , ISimdVVV , (0b0010111000100000011000, kVO_V_B8H4S2) , kRWI_W , F(Narrow) , 16 , 2400), // #572
- INST(Rsubhn2_v , ISimdVVV , (0b0110111000100000011000, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 17 , 2407), // #573
- INST(Saba_v , ISimdVVV , (0b0000111000100000011111, kVO_V_BHS) , kRWI_X , 0 , 18 , 2415), // #574
- INST(Sabal_v , ISimdVVV , (0b0000111000100000010100, kVO_V_B8H4S2) , kRWI_X , F(Long) , 19 , 2420), // #575
- INST(Sabal2_v , ISimdVVV , (0b0100111000100000010100, kVO_V_B16H8S4) , kRWI_X , F(Long) , 20 , 2426), // #576
- INST(Sabd_v , ISimdVVV , (0b0000111000100000011101, kVO_V_BHS) , kRWI_W , 0 , 21 , 2433), // #577
- INST(Sabdl_v , ISimdVVV , (0b0000111000100000011100, kVO_V_B8H4S2) , kRWI_W , F(Long) , 22 , 2438), // #578
- INST(Sabdl2_v , ISimdVVV , (0b0100111000100000011100, kVO_V_B16H8S4) , kRWI_W , F(Long) , 23 , 2444), // #579
- INST(Sadalp_v , ISimdVV , (0b0000111000100000011010, kVO_V_BHS) , kRWI_X , F(Long) | F(Pair) , 11 , 2451), // #580
- INST(Saddl_v , ISimdVVV , (0b0000111000100000000000, kVO_V_B8H4S2) , kRWI_W , F(Long) , 24 , 2458), // #581
- INST(Saddl2_v , ISimdVVV , (0b0100111000100000000000, kVO_V_B16H8S4) , kRWI_W , F(Long) , 25 , 2464), // #582
- INST(Saddlp_v , ISimdVV , (0b0000111000100000001010, kVO_V_BHS) , kRWI_W , F(Long) | F(Pair) , 12 , 2471), // #583
- INST(Saddlv_v , ISimdSV , (0b0000111000110000001110, kVO_V_BH_4S) , kRWI_W , F(Long) , 1 , 2478), // #584
- INST(Saddw_v , ISimdWWV , (0b0000111000100000000100, kVO_V_B8H4S2) , kRWI_W , 0 , 0 , 2485), // #585
- INST(Saddw2_v , ISimdWWV , (0b0000111000100000000100, kVO_V_B16H8S4) , kRWI_W , 0 , 1 , 2491), // #586
- INST(Scvtf_v , SimdFcvtSV , (0b0000111000100001110110, 0b0000111100000000111001, 0b0001111000100010000000, 0) , kRWI_W , 0 , 10 , 2523), // #587
- INST(Sdot_v , SimdDot , (0b0000111010000000100101, 0b0000111110000000111000, kET_S, kET_B, kET_4B) , kRWI_X , 0 , 1 , 4218), // #588
- INST(Sha1c_v , ISimdVVVx , (0b0101111000000000000000, kOp_Q, kOp_S, kOp_V4S) , kRWI_X , 0 , 1 , 2556), // #589
- INST(Sha1h_v , ISimdVVx , (0b0101111000101000000010, kOp_S, kOp_S) , kRWI_W , 0 , 8 , 2562), // #590
- INST(Sha1m_v , ISimdVVVx , (0b0101111000000000001000, kOp_Q, kOp_S, kOp_V4S) , kRWI_X , 0 , 2 , 2568), // #591
- INST(Sha1p_v , ISimdVVVx , (0b0101111000000000000100, kOp_Q, kOp_S, kOp_V4S) , kRWI_X , 0 , 3 , 2574), // #592
- INST(Sha1su0_v , ISimdVVVx , (0b0101111000000000001100, kOp_V4S, kOp_V4S, kOp_V4S) , kRWI_X , 0 , 4 , 2580), // #593
- INST(Sha1su1_v , ISimdVVx , (0b0101111000101000000110, kOp_V4S, kOp_V4S) , kRWI_X , 0 , 9 , 2588), // #594
- INST(Sha256h_v , ISimdVVVx , (0b0101111000000000010000, kOp_Q, kOp_Q, kOp_V4S) , kRWI_X , 0 , 5 , 2596), // #595
- INST(Sha256h2_v , ISimdVVVx , (0b0101111000000000010100, kOp_Q, kOp_Q, kOp_V4S) , kRWI_X , 0 , 6 , 2604), // #596
- INST(Sha256su0_v , ISimdVVx , (0b0101111000101000001010, kOp_V4S, kOp_V4S) , kRWI_X , 0 , 10 , 2613), // #597
- INST(Sha256su1_v , ISimdVVVx , (0b0101111000000000011000, kOp_V4S, kOp_V4S, kOp_V4S) , kRWI_X , 0 , 7 , 2623), // #598
- INST(Sha512h_v , ISimdVVVx , (0b1100111001100000100000, kOp_Q, kOp_Q, kOp_V2D) , kRWI_X , 0 , 8 , 2633), // #599
- INST(Sha512h2_v , ISimdVVVx , (0b1100111001100000100001, kOp_Q, kOp_Q, kOp_V2D) , kRWI_X , 0 , 9 , 2641), // #600
- INST(Sha512su0_v , ISimdVVx , (0b1100111011000000100000, kOp_V2D, kOp_V2D) , kRWI_X , 0 , 11 , 2650), // #601
- INST(Sha512su1_v , ISimdVVVx , (0b1100111001100000100010, kOp_V2D, kOp_V2D, kOp_V2D) , kRWI_X , 0 , 10 , 2660), // #602
- INST(Shadd_v , ISimdVVV , (0b0000111000100000000001, kVO_V_BHS) , kRWI_W , 0 , 26 , 2670), // #603
- INST(Shl_v , SimdShift , (0b0000000000000000000000, 0b0000111100000000010101, 0, kVO_V_Any) , kRWI_W , 0 , 2 , 2954), // #604
- INST(Shll_v , SimdShiftES , (0b0010111000100001001110, kVO_V_B8H4S2) , kRWI_W , F(Long) , 0 , 3108), // #605
- INST(Shll2_v , SimdShiftES , (0b0110111000100001001110, kVO_V_B16H8S4) , kRWI_W , F(Long) , 1 , 3114), // #606
- INST(Shrn_v , SimdShift , (0b0000000000000000000000, 0b0000111100000000100001, 1, kVO_V_B8H4S2) , kRWI_W , F(Narrow) , 3 , 2961), // #607
- INST(Shrn2_v , SimdShift , (0b0000000000000000000000, 0b0100111100000000100001, 1, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 4 , 2969), // #608
- INST(Shsub_v , ISimdVVV , (0b0000111000100000001001, kVO_V_BHS) , kRWI_W , 0 , 27 , 2676), // #609
- INST(Sli_v , SimdShift , (0b0000000000000000000000, 0b0010111100000000010101, 0, kVO_V_Any) , kRWI_X , 0 , 5 , 2682), // #610
- INST(Sm3partw1_v , ISimdVVVx , (0b1100111001100000110000, kOp_V4S, kOp_V4S, kOp_V4S) , kRWI_X , 0 , 11 , 2686), // #611
- INST(Sm3partw2_v , ISimdVVVx , (0b1100111001100000110001, kOp_V4S, kOp_V4S, kOp_V4S) , kRWI_X , 0 , 12 , 2696), // #612
- INST(Sm3ss1_v , ISimdVVVVx , (0b1100111001000000000000, kOp_V4S, kOp_V4S, kOp_V4S, kOp_V4S) , kRWI_W , 0 , 0 , 2706), // #613
- INST(Sm3tt1a_v , SimdSm3tt , (0b1100111001000000100000) , kRWI_X , 0 , 0 , 2713), // #614
- INST(Sm3tt1b_v , SimdSm3tt , (0b1100111001000000100001) , kRWI_X , 0 , 1 , 2721), // #615
- INST(Sm3tt2a_v , SimdSm3tt , (0b1100111001000000100010) , kRWI_X , 0 , 2 , 2729), // #616
- INST(Sm3tt2b_v , SimdSm3tt , (0b1100111001000000100011) , kRWI_X , 0 , 3 , 2737), // #617
- INST(Sm4e_v , ISimdVVx , (0b1100111011000000100001, kOp_V4S, kOp_V4S) , kRWI_X , 0 , 12 , 2745), // #618
- INST(Sm4ekey_v , ISimdVVVx , (0b1100111001100000110010, kOp_V4S, kOp_V4S, kOp_V4S) , kRWI_X , 0 , 13 , 2750), // #619
- INST(Smax_v , ISimdVVV , (0b0000111000100000011001, kVO_V_BHS) , kRWI_W , 0 , 28 , 1690), // #620
- INST(Smaxp_v , ISimdVVV , (0b0000111000100000101001, kVO_V_BHS) , kRWI_W , 0 , 29 , 2765), // #621
- INST(Smaxv_v , ISimdSV , (0b0000111000110000101010, kVO_V_BH_4S) , kRWI_W , 0 , 2 , 2771), // #622
- INST(Smin_v , ISimdVVV , (0b0000111000100000011011, kVO_V_BHS) , kRWI_W , 0 , 30 , 1794), // #623
- INST(Sminp_v , ISimdVVV , (0b0000111000100000101011, kVO_V_BHS) , kRWI_W , 0 , 31 , 2777), // #624
- INST(Sminv_v , ISimdSV , (0b0000111000110001101010, kVO_V_BH_4S) , kRWI_W , 0 , 3 , 2783), // #625
- INST(Smlal_v , ISimdVVVe , (0b0000111000100000100000, kVO_V_B8H4S2, 0b0000111100000000001000, kVO_V_H4S2) , kRWI_X , F(Long) | F(VH0_15) , 3 , 2789), // #626
- INST(Smlal2_v , ISimdVVVe , (0b0100111000100000100000, kVO_V_B16H8S4, 0b0100111100000000001000, kVO_V_H8S4) , kRWI_X , F(Long) | F(VH0_15) , 4 , 2795), // #627
- INST(Smlsl_v , ISimdVVVe , (0b0000111000100000101000, kVO_V_B8H4S2, 0b0000111100000000011000, kVO_V_H4S2) , kRWI_X , F(Long) | F(VH0_15) , 5 , 2802), // #628
- INST(Smlsl2_v , ISimdVVVe , (0b0100111000100000101000, kVO_V_B16H8S4, 0b0100111100000000011000, kVO_V_H8S4) , kRWI_X , F(Long) | F(VH0_15) , 6 , 2808), // #629
- INST(Smmla_v , ISimdVVVx , (0b0100111010000000101001, kOp_V4S, kOp_V16B, kOp_V16B) , kRWI_X , 0 , 14 , 4247), // #630
- INST(Smov_v , SimdSmovUmov , (0b0000111000000000001011, kVO_V_BHS, 1) , kRWI_W , 0 , 0 , 2822), // #631
- INST(Smull_v , ISimdVVVe , (0b0000111000100000110000, kVO_V_B8H4S2, 0b0000111100000000101000, kVO_V_H4S2) , kRWI_W , F(Long) | F(VH0_15) , 7 , 2840), // #632
- INST(Smull2_v , ISimdVVVe , (0b0100111000100000110000, kVO_V_B16H8S4, 0b0100111100000000101000, kVO_V_H8S4) , kRWI_W , F(Long) | F(VH0_15) , 8 , 2846), // #633
- INST(Sqabs_v , ISimdVV , (0b0000111000100000011110, kVO_SV_Any) , kRWI_W , 0 , 13 , 2853), // #634
- INST(Sqadd_v , ISimdVVV , (0b0000111000100000000011, kVO_SV_Any) , kRWI_W , 0 , 32 , 4254), // #635
- INST(Sqdmlal_v , ISimdVVVe , (0b0000111000100000100100, kVO_SV_BHS, 0b0000111100000000001100, kVO_V_H4S2) , kRWI_X , F(Long) | F(VH0_15) , 9 , 2859), // #636
- INST(Sqdmlal2_v , ISimdVVVe , (0b0100111000100000100100, kVO_V_B16H8S4, 0b0100111100000000001100, kVO_V_H8S4) , kRWI_X , F(Long) | F(VH0_15) , 10 , 2867), // #637
- INST(Sqdmlsl_v , ISimdVVVe , (0b0000111000100000101100, kVO_SV_BHS, 0b0000111100000000011100, kVO_V_H4S2) , kRWI_X , F(Long) | F(VH0_15) , 11 , 2876), // #638
- INST(Sqdmlsl2_v , ISimdVVVe , (0b0100111000100000101100, kVO_V_B16H8S4, 0b0100111100000000011100, kVO_V_H8S4) , kRWI_X , F(Long) | F(VH0_15) , 12 , 2884), // #639
- INST(Sqdmulh_v , ISimdVVVe , (0b0000111000100000101101, kVO_SV_HS, 0b0000111100000000110000, kVO_SV_HS) , kRWI_W , F(VH0_15) , 13 , 2893), // #640
- INST(Sqdmull_v , ISimdVVVe , (0b0000111000100000110100, kVO_SV_BHS, 0b0000111100000000101100, kVO_V_H4S2) , kRWI_W , F(Long) | F(VH0_15) , 14 , 2901), // #641
- INST(Sqdmull2_v , ISimdVVVe , (0b0100111000100000110100, kVO_V_B16H8S4, 0b0100111100000000101100, kVO_V_H8S4) , kRWI_W , F(Long) | F(VH0_15) , 15 , 2909), // #642
- INST(Sqneg_v , ISimdVV , (0b0010111000100000011110, kVO_SV_Any) , kRWI_W , 0 , 14 , 2918), // #643
- INST(Sqrdmlah_v , ISimdVVVe , (0b0010111000000000100001, kVO_SV_HS, 0b0010111100000000110100, kVO_SV_HS) , kRWI_X , F(VH0_15) , 16 , 2924), // #644
- INST(Sqrdmlsh_v , ISimdVVVe , (0b0010111000000000100011, kVO_SV_HS, 0b0010111100000000111100, kVO_SV_HS) , kRWI_X , F(VH0_15) , 17 , 2933), // #645
- INST(Sqrdmulh_v , ISimdVVVe , (0b0010111000100000101101, kVO_SV_HS, 0b0000111100000000110100, kVO_SV_HS) , kRWI_W , F(VH0_15) , 18 , 2942), // #646
- INST(Sqrshl_v , SimdShift , (0b0000111000100000010111, 0b0000000000000000000000, 1, kVO_SV_Any) , kRWI_W , 0 , 6 , 2951), // #647
- INST(Sqrshrn_v , SimdShift , (0b0000000000000000000000, 0b0000111100000000100111, 1, kVO_SV_B8H4S2) , kRWI_W , F(Narrow) , 7 , 2958), // #648
- INST(Sqrshrn2_v , SimdShift , (0b0000000000000000000000, 0b0100111100000000100111, 1, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 8 , 2966), // #649
- INST(Sqrshrun_v , SimdShift , (0b0000000000000000000000, 0b0010111100000000100011, 1, kVO_SV_B8H4S2) , kRWI_W , F(Narrow) , 9 , 2975), // #650
- INST(Sqrshrun2_v , SimdShift , (0b0000000000000000000000, 0b0110111100000000100011, 1, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 10 , 2984), // #651
- INST(Sqshl_v , SimdShift , (0b0000111000100000010011, 0b0000111100000000011101, 0, kVO_SV_Any) , kRWI_W , 0 , 11 , 2994), // #652
- INST(Sqshlu_v , SimdShift , (0b0000000000000000000000, 0b0010111100000000011001, 0, kVO_SV_Any) , kRWI_W , 0 , 12 , 3000), // #653
- INST(Sqshrn_v , SimdShift , (0b0000000000000000000000, 0b0000111100000000100101, 1, kVO_SV_B8H4S2) , kRWI_W , F(Narrow) , 13 , 3007), // #654
- INST(Sqshrn2_v , SimdShift , (0b0000000000000000000000, 0b0100111100000000100101, 1, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 14 , 3014), // #655
- INST(Sqshrun_v , SimdShift , (0b0000000000000000000000, 0b0010111100000000100001, 1, kVO_SV_B8H4S2) , kRWI_W , F(Narrow) , 15 , 3022), // #656
- INST(Sqshrun2_v , SimdShift , (0b0000000000000000000000, 0b0110111100000000100001, 1, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 16 , 3030), // #657
- INST(Sqsub_v , ISimdVVV , (0b0000111000100000001011, kVO_SV_Any) , kRWI_W , 0 , 33 , 3039), // #658
- INST(Sqxtn_v , ISimdVV , (0b0000111000100001010010, kVO_SV_B8H4S2) , kRWI_W , F(Narrow) , 15 , 3045), // #659
- INST(Sqxtn2_v , ISimdVV , (0b0100111000100001010010, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 16 , 3051), // #660
- INST(Sqxtun_v , ISimdVV , (0b0010111000100001001010, kVO_SV_B8H4S2) , kRWI_W , F(Narrow) , 17 , 3058), // #661
- INST(Sqxtun2_v , ISimdVV , (0b0110111000100001001010, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 18 , 3065), // #662
- INST(Srhadd_v , ISimdVVV , (0b0000111000100000000101, kVO_V_BHS) , kRWI_W , 0 , 34 , 3073), // #663
- INST(Sri_v , SimdShift , (0b0000000000000000000000, 0b0010111100000000010001, 1, kVO_V_Any) , kRWI_W , 0 , 17 , 3080), // #664
- INST(Srshl_v , SimdShift , (0b0000111000100000010101, 0b0000000000000000000000, 0, kVO_V_Any) , kRWI_W , 0 , 18 , 3084), // #665
- INST(Srshr_v , SimdShift , (0b0000000000000000000000, 0b0000111100000000001001, 1, kVO_V_Any) , kRWI_W , 0 , 19 , 3090), // #666
- INST(Srsra_v , SimdShift , (0b0000000000000000000000, 0b0000111100000000001101, 1, kVO_V_Any) , kRWI_X , 0 , 20 , 3096), // #667
- INST(Sshl_v , SimdShift , (0b0000111000100000010001, 0b0000000000000000000000, 0, kVO_V_Any) , kRWI_W , 0 , 21 , 3102), // #668
- INST(Sshll_v , SimdShift , (0b0000000000000000000000, 0b0000111100000000101001, 0, kVO_V_B8H4S2) , kRWI_W , F(Long) , 22 , 3107), // #669
- INST(Sshll2_v , SimdShift , (0b0000000000000000000000, 0b0100111100000000101001, 0, kVO_V_B16H8S4) , kRWI_W , F(Long) , 23 , 3113), // #670
- INST(Sshr_v , SimdShift , (0b0000000000000000000000, 0b0000111100000000000001, 1, kVO_V_Any) , kRWI_W , 0 , 24 , 3120), // #671
- INST(Ssra_v , SimdShift , (0b0000000000000000000000, 0b0000111100000000000101, 1, kVO_V_Any) , kRWI_X , 0 , 25 , 3125), // #672
- INST(Ssubl_v , ISimdVVV , (0b0000111000100000001000, kVO_V_B8H4S2) , kRWI_W , F(Long) , 35 , 3130), // #673
- INST(Ssubl2_v , ISimdVVV , (0b0100111000100000001000, kVO_V_B16H8S4) , kRWI_W , F(Long) , 36 , 3136), // #674
- INST(Ssubw_v , ISimdWWV , (0b0000111000100000001100, kVO_V_B8H4S2) , kRWI_W , 0 , 2 , 3143), // #675
- INST(Ssubw2_v , ISimdWWV , (0b0000111000100000001100, kVO_V_B16H8S4) , kRWI_X , 0 , 3 , 3149), // #676
- INST(St1_v , SimdLdNStN , (0b0000110100000000000000, 0b0000110000000000001000, 1, 0) , kRWI_STn , F(Consecutive) , 8 , 3156), // #677
- INST(St2_v , SimdLdNStN , (0b0000110100100000000000, 0b0000110000000000100000, 2, 0) , kRWI_STn , F(Consecutive) , 9 , 3160), // #678
- INST(St3_v , SimdLdNStN , (0b0000110100000000001000, 0b0000110000000000010000, 3, 0) , kRWI_STn , F(Consecutive) , 10 , 3169), // #679
- INST(St4_v , SimdLdNStN , (0b0000110100100000001000, 0b0000110000000000000000, 4, 0) , kRWI_STn , F(Consecutive) , 11 , 3173), // #680
- INST(Stnp_v , SimdLdpStp , (0b0010110000, 0b0000000000) , kRWI_RRW , 0 , 2 , 3383), // #681
- INST(Stp_v , SimdLdpStp , (0b0010110100, 0b0010110010) , kRWI_RRW , 0 , 3 , 3388), // #682
- INST(Str_v , SimdLdSt , (0b0011110100, 0b00111100000, 0b00111100001, 0b00000000, Inst::kIdStur_v) , kRWI_RW , 0 , 1 , 3392), // #683
- INST(Stur_v , SimdLdurStur , (0b0011110000000000000000) , kRWI_RW , 0 , 1 , 3662), // #684
- INST(Sub_v , ISimdVVV , (0b0010111000100000100001, kVO_V_Any) , kRWI_W , 0 , 37 , 985 ), // #685
- INST(Subhn_v , ISimdVVV , (0b0000111000100000011000, kVO_V_B8H4S2) , kRWI_W , F(Narrow) , 38 , 2401), // #686
- INST(Subhn2_v , ISimdVVV , (0b0000111000100000011000, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 39 , 2408), // #687
- INST(Sudot_v , SimdDot , (0b0000000000000000000000, 0b0000111100000000111100, kET_S, kET_B, kET_4B) , kRWI_X , 0 , 2 , 3739), // #688
- INST(Suqadd_v , ISimdVV , (0b0000111000100000001110, kVO_SV_Any) , kRWI_X , 0 , 19 , 3745), // #689
- INST(Sxtl_v , SimdSxtlUxtl , (0b0000111100000000101001, kVO_V_B8H4S2) , kRWI_W , F(Long) , 0 , 3834), // #690
- INST(Sxtl2_v , SimdSxtlUxtl , (0b0100111100000000101001, kVO_V_B16H8S4) , kRWI_W , F(Long) , 1 , 3839), // #691
- INST(Tbl_v , SimdTblTbx , (0b0000111000000000000000) , kRWI_W , 0 , 0 , 3854), // #692
- INST(Tbx_v , SimdTblTbx , (0b0000111000000000000100) , kRWI_W , 0 , 1 , 3863), // #693
- INST(Trn1_v , ISimdVVV , (0b0000111000000000001010, kVO_V_BHS_D2) , kRWI_W , 0 , 40 , 3876), // #694
- INST(Trn2_v , ISimdVVV , (0b0000111000000000011010, kVO_V_BHS_D2) , kRWI_W , 0 , 41 , 3881), // #695
- INST(Uaba_v , ISimdVVV , (0b0010111000100000011111, kVO_V_BHS) , kRWI_X , 0 , 42 , 3886), // #696
- INST(Uabal_v , ISimdVVV , (0b0010111000100000010100, kVO_V_B8H4S2) , kRWI_X , F(Long) , 43 , 3891), // #697
- INST(Uabal2_v , ISimdVVV , (0b0110111000100000010100, kVO_V_B16H8S4) , kRWI_X , F(Long) , 44 , 3897), // #698
- INST(Uabd_v , ISimdVVV , (0b0010111000100000011101, kVO_V_BHS) , kRWI_W , 0 , 45 , 3904), // #699
- INST(Uabdl_v , ISimdVVV , (0b0010111000100000011100, kVO_V_B8H4S2) , kRWI_W , F(Long) , 46 , 3909), // #700
- INST(Uabdl2_v , ISimdVVV , (0b0110111000100000011100, kVO_V_B16H8S4) , kRWI_W , F(Long) , 47 , 3915), // #701
- INST(Uadalp_v , ISimdVV , (0b0010111000100000011010, kVO_V_BHS) , kRWI_X , F(Long) | F(Pair) , 20 , 3922), // #702
- INST(Uaddl_v , ISimdVVV , (0b0010111000100000000000, kVO_V_B8H4S2) , kRWI_W , F(Long) , 48 , 3929), // #703
- INST(Uaddl2_v , ISimdVVV , (0b0110111000100000000000, kVO_V_B16H8S4) , kRWI_W , F(Long) , 49 , 3935), // #704
- INST(Uaddlp_v , ISimdVV , (0b0010111000100000001010, kVO_V_BHS) , kRWI_W , F(Long) | F(Pair) , 21 , 3942), // #705
- INST(Uaddlv_v , ISimdSV , (0b0010111000110000001110, kVO_V_BH_4S) , kRWI_W , F(Long) , 4 , 3949), // #706
- INST(Uaddw_v , ISimdWWV , (0b0010111000100000000100, kVO_V_B8H4S2) , kRWI_W , 0 , 4 , 3956), // #707
- INST(Uaddw2_v , ISimdWWV , (0b0010111000100000000100, kVO_V_B16H8S4) , kRWI_W , 0 , 5 , 3962), // #708
- INST(Ucvtf_v , SimdFcvtSV , (0b0010111000100001110110, 0b0010111100000000111001, 0b0001111000100011000000, 0) , kRWI_W , 0 , 11 , 3985), // #709
- INST(Udot_v , SimdDot , (0b0010111010000000100101, 0b0010111110000000111000, kET_S, kET_B, kET_4B) , kRWI_X , 0 , 3 , 3740), // #710
- INST(Uhadd_v , ISimdVVV , (0b0010111000100000000001, kVO_V_BHS) , kRWI_W , 0 , 50 , 4000), // #711
- INST(Uhsub_v , ISimdVVV , (0b0010111000100000001001, kVO_V_BHS) , kRWI_W , 0 , 51 , 4006), // #712
- INST(Umax_v , ISimdVVV , (0b0010111000100000011001, kVO_V_BHS) , kRWI_W , 0 , 52 , 1936), // #713
- INST(Umaxp_v , ISimdVVV , (0b0010111000100000101001, kVO_V_BHS) , kRWI_W , 0 , 53 , 4019), // #714
- INST(Umaxv_v , ISimdSV , (0b0010111000110000101010, kVO_V_BH_4S) , kRWI_W , 0 , 5 , 4025), // #715
- INST(Umin_v , ISimdVVV , (0b0010111000100000011011, kVO_V_BHS) , kRWI_W , 0 , 54 , 2040), // #716
- INST(Uminp_v , ISimdVVV , (0b0010111000100000101011, kVO_V_BHS) , kRWI_W , 0 , 55 , 4031), // #717
- INST(Uminv_v , ISimdSV , (0b0010111000110001101010, kVO_V_BH_4S) , kRWI_W , 0 , 6 , 4037), // #718
- INST(Umlal_v , ISimdVVVe , (0b0010111000100000100000, kVO_V_B8H4S2, 0b0010111100000000001000, kVO_V_H4S2) , kRWI_X , F(Long) | F(VH0_15) , 19 , 4043), // #719
- INST(Umlal2_v , ISimdVVVe , (0b0110111000100000100000, kVO_V_B16H8S4, 0b0010111100000000001000, kVO_V_H8S4) , kRWI_X , F(Long) | F(VH0_15) , 20 , 4049), // #720
- INST(Umlsl_v , ISimdVVVe , (0b0010111000100000101000, kVO_V_B8H4S2, 0b0010111100000000011000, kVO_V_H4S2) , kRWI_X , F(Long) | F(VH0_15) , 21 , 4056), // #721
- INST(Umlsl2_v , ISimdVVVe , (0b0110111000100000101000, kVO_V_B16H8S4, 0b0110111100000000011000, kVO_V_H8S4) , kRWI_X , F(Long) | F(VH0_15) , 22 , 4062), // #722
- INST(Ummla_v , ISimdVVVx , (0b0110111010000000101001, kOp_V4S, kOp_V16B, kOp_V16B) , kRWI_X , 0 , 15 , 4069), // #723
- INST(Umov_v , SimdSmovUmov , (0b0000111000000000001111, kVO_V_Any, 0) , kRWI_W , 0 , 1 , 4082), // #724
- INST(Umull_v , ISimdVVVe , (0b0010111000100000110000, kVO_V_B8H4S2, 0b0010111100000000101000, kVO_V_H4S2) , kRWI_W , F(Long) | F(VH0_15) , 23 , 4100), // #725
- INST(Umull2_v , ISimdVVVe , (0b0110111000100000110000, kVO_V_B16H8S4, 0b0110111100000000101000, kVO_V_H8S4) , kRWI_W , F(Long) | F(VH0_15) , 24 , 4106), // #726
- INST(Uqadd_v , ISimdVVV , (0b0010111000100000000011, kVO_SV_Any) , kRWI_W , 0 , 56 , 3746), // #727
- INST(Uqrshl_v , SimdShift , (0b0010111000100000010111, 0b0000000000000000000000, 0, kVO_SV_Any) , kRWI_W , 0 , 26 , 4113), // #728
- INST(Uqrshrn_v , SimdShift , (0b0000000000000000000000, 0b0010111100000000100111, 1, kVO_SV_B8H4S2) , kRWI_W , F(Narrow) , 27 , 4120), // #729
- INST(Uqrshrn2_v , SimdShift , (0b0000000000000000000000, 0b0110111100000000100111, 1, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 28 , 4128), // #730
- INST(Uqshl_v , SimdShift , (0b0010111000100000010011, 0b0010111100000000011101, 0, kVO_SV_Any) , kRWI_W , 0 , 29 , 4137), // #731
- INST(Uqshrn_v , SimdShift , (0b0000000000000000000000, 0b0010111100000000100101, 1, kVO_SV_B8H4S2) , kRWI_W , F(Narrow) , 30 , 4143), // #732
- INST(Uqshrn2_v , SimdShift , (0b0000000000000000000000, 0b0110111100000000100101, 1, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 31 , 4150), // #733
- INST(Uqsub_v , ISimdVVV , (0b0010111000100000001011, kVO_SV_Any) , kRWI_W , 0 , 57 , 4158), // #734
- INST(Uqxtn_v , ISimdVV , (0b0010111000100001010010, kVO_SV_B8H4S2) , kRWI_W , F(Narrow) , 22 , 4164), // #735
- INST(Uqxtn2_v , ISimdVV , (0b0110111000100001010010, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 23 , 4170), // #736
- INST(Urecpe_v , ISimdVV , (0b0000111010100001110010, kVO_V_S) , kRWI_W , 0 , 24 , 4177), // #737
- INST(Urhadd_v , ISimdVVV , (0b0010111000100000000101, kVO_V_BHS) , kRWI_W , 0 , 58 , 4184), // #738
- INST(Urshl_v , SimdShift , (0b0010111000100000010101, 0b0000000000000000000000, 0, kVO_V_Any) , kRWI_W , 0 , 32 , 4191), // #739
- INST(Urshr_v , SimdShift , (0b0000000000000000000000, 0b0010111100000000001001, 1, kVO_V_Any) , kRWI_W , 0 , 33 , 4197), // #740
- INST(Ursqrte_v , ISimdVV , (0b0010111010100001110010, kVO_V_S) , kRWI_W , 0 , 25 , 4203), // #741
- INST(Ursra_v , SimdShift , (0b0000000000000000000000, 0b0010111100000000001101, 1, kVO_V_Any) , kRWI_X , 0 , 34 , 4211), // #742
- INST(Usdot_v , SimdDot , (0b0000111010000000100111, 0b0000111110000000111100, kET_S, kET_B, kET_4B) , kRWI_X , 0 , 4 , 4217), // #743
- INST(Ushl_v , SimdShift , (0b0010111000100000010001, 0b0000000000000000000000, 0, kVO_V_Any) , kRWI_W , 0 , 35 , 4223), // #744
- INST(Ushll_v , SimdShift , (0b0000000000000000000000, 0b0010111100000000101001, 0, kVO_V_B8H4S2) , kRWI_W , F(Long) , 36 , 4228), // #745
- INST(Ushll2_v , SimdShift , (0b0000000000000000000000, 0b0110111100000000101001, 0, kVO_V_B16H8S4) , kRWI_W , F(Long) , 37 , 4234), // #746
- INST(Ushr_v , SimdShift , (0b0000000000000000000000, 0b0010111100000000000001, 1, kVO_V_Any) , kRWI_W , 0 , 38 , 4241), // #747
- INST(Usmmla_v , ISimdVVVx , (0b0100111010000000101011, kOp_V4S, kOp_V16B, kOp_V16B) , kRWI_X , 0 , 16 , 4246), // #748
- INST(Usqadd_v , ISimdVV , (0b0010111000100000001110, kVO_SV_Any) , kRWI_X , 0 , 26 , 4253), // #749
- INST(Usra_v , SimdShift , (0b0000000000000000000000, 0b0010111100000000000101, 1, kVO_V_Any) , kRWI_X , 0 , 39 , 4260), // #750
- INST(Usubl_v , ISimdVVV , (0b0010111000100000001000, kVO_V_B8H4S2) , kRWI_W , F(Long) , 59 , 4265), // #751
- INST(Usubl2_v , ISimdVVV , (0b0110111000100000001000, kVO_V_B16H8S4) , kRWI_W , F(Long) , 60 , 4271), // #752
- INST(Usubw_v , ISimdWWV , (0b0010111000100000001100, kVO_V_B8H4S2) , kRWI_W , 0 , 6 , 4278), // #753
- INST(Usubw2_v , ISimdWWV , (0b0010111000100000001100, kVO_V_B16H8S4) , kRWI_W , 0 , 7 , 4284), // #754
- INST(Uxtl_v , SimdSxtlUxtl , (0b0010111100000000101001, kVO_V_B8H4S2) , kRWI_W , F(Long) , 2 , 4301), // #755
- INST(Uxtl2_v , SimdSxtlUxtl , (0b0110111100000000101001, kVO_V_B16H8S4) , kRWI_W , F(Long) , 3 , 4306), // #756
- INST(Uzp1_v , ISimdVVV , (0b0000111000000000000110, kVO_V_BHS_D2) , kRWI_W , 0 , 61 , 4312), // #757
- INST(Uzp2_v , ISimdVVV , (0b0000111000000000010110, kVO_V_BHS_D2) , kRWI_W , 0 , 62 , 4317), // #758
- INST(Xar_v , ISimdVVVI , (0b1100111001100000100011, kVO_V_D2, 6, 10, 0) , kRWI_W , 0 , 1 , 4337), // #759
- INST(Xtn_v , ISimdVV , (0b0000111000100001001010, kVO_V_B8H4S2) , kRWI_W , F(Narrow) , 27 , 3047), // #760
- INST(Xtn2_v , ISimdVV , (0b0100111000100001001010, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 28 , 3053), // #761
- INST(Zip1_v , ISimdVVV , (0b0000111000000000001110, kVO_V_BHS_D2) , kRWI_W , 0 , 63 , 4367), // #762
- INST(Zip2_v , ISimdVVV , (0b0000111000000000011110, kVO_V_BHS_D2) , kRWI_W , 0 , 64 , 4372) // #763
+ INST(None , None , (_) , 0 , 0 , 0 ), // #0
+ INST(Adc , BaseRRR , (0b0001101000000000000000, kWX, kZR, kWX, kZR, kWX, kZR, true) , kRWI_W , 0 , 0 ), // #1
+ INST(Adcs , BaseRRR , (0b0011101000000000000000, kWX, kZR, kWX, kZR, kWX, kZR, true) , kRWI_W , 0 , 1 ), // #2
+ INST(Add , BaseAddSub , (0b0001011000, 0b0001011001, 0b0010001) , kRWI_W , 0 , 0 ), // #3
+ INST(Addg , BaseRRII , (0b1001000110000000000000, kX, kSP, kX, kSP, 6, 4, 16, 4, 0, 10) , kRWI_W , 0 , 0 ), // #4
+ INST(Adds , BaseAddSub , (0b0101011000, 0b0101011001, 0b0110001) , kRWI_W , 0 , 1 ), // #5
+ INST(Adr , BaseAdr , (0b0001000000000000000000, OffsetType::kAArch64_ADR) , kRWI_W , 0 , 0 ), // #6
+ INST(Adrp , BaseAdr , (0b1001000000000000000000, OffsetType::kAArch64_ADRP) , kRWI_W , 0 , 1 ), // #7
+ INST(And , BaseLogical , (0b0001010000, 0b00100100, 0) , kRWI_W , 0 , 0 ), // #8
+ INST(Ands , BaseLogical , (0b1101010000, 0b11100100, 0) , kRWI_W , 0 , 1 ), // #9
+ INST(Asr , BaseShift , (0b0001101011000000001010, 0b0001001100000000011111, 0) , kRWI_W , 0 , 0 ), // #10
+ INST(Asrv , BaseShift , (0b0001101011000000001010, 0b0000000000000000000000, 0) , kRWI_W , 0 , 1 ), // #11
+ INST(At , BaseAtDcIcTlbi , (0b00011111110000, 0b00001111000000, true) , kRWI_RX , 0 , 0 ), // #12
+ INST(Autda , BaseRR , (0b11011010110000010001100000000000, kX, kZR, 0, kX, kSP, 5, true) , kRWI_X , 0 , 0 ), // #13
+ INST(Autdza , BaseR , (0b11011010110000010011101111100000, kX, kZR, 0) , kRWI_X , 0 , 0 ), // #14
+ INST(Autdb , BaseRR , (0b11011010110000010001110000000000, kX, kZR, 0, kX, kSP, 5, true) , kRWI_X , 0 , 1 ), // #15
+ INST(Autdzb , BaseR , (0b11011010110000010011111111100000, kX, kZR, 0) , kRWI_X , 0 , 1 ), // #16
+ INST(Autia , BaseRR , (0b11011010110000010001000000000000, kX, kZR, 0, kX, kSP, 5, true) , kRWI_X , 0 , 2 ), // #17
+ INST(Autia1716 , BaseOp , (0b11010101000000110010000110011111) , 0 , 0 , 0 ), // #18
+ INST(Autiasp , BaseOp , (0b11010101000000110010001110111111) , 0 , 0 , 1 ), // #19
+ INST(Autiaz , BaseOp , (0b11010101000000110010001110011111) , 0 , 0 , 2 ), // #20
+ INST(Autib , BaseRR , (0b11011010110000010001010000000000, kX, kZR, 0, kX, kSP, 5, true) , kRWI_X , 0 , 3 ), // #21
+ INST(Autib1716 , BaseOp , (0b11010101000000110010000111011111) , 0 , 0 , 3 ), // #22
+ INST(Autibsp , BaseOp , (0b11010101000000110010001111111111) , 0 , 0 , 4 ), // #23
+ INST(Autibz , BaseOp , (0b11010101000000110010001111011111) , 0 , 0 , 5 ), // #24
+ INST(Autiza , BaseR , (0b11011010110000010011001111100000, kX, kZR, 0) , kRWI_X , 0 , 2 ), // #25
+ INST(Autizb , BaseR , (0b11011010110000010011011111100000, kX, kZR, 0) , kRWI_X , 0 , 3 ), // #26
+ INST(Axflag , BaseOp , (0b11010101000000000100000001011111) , 0 , 0 , 6 ), // #27
+ INST(B , BaseBranchRel , (0b00010100000000000000000000000000) , 0 , F(Cond) , 0 ), // #28
+ INST(Bfc , BaseBfc , (0b00110011000000000000001111100000) , kRWI_X , 0 , 0 ), // #29
+ INST(Bfi , BaseBfi , (0b00110011000000000000000000000000) , kRWI_X , 0 , 0 ), // #30
+ INST(Bfm , BaseBfm , (0b00110011000000000000000000000000) , kRWI_X , 0 , 0 ), // #31
+ INST(Bfxil , BaseBfx , (0b00110011000000000000000000000000) , kRWI_X , 0 , 0 ), // #32
+ INST(Bic , BaseLogical , (0b0001010001, 0b00100100, 1) , kRWI_W , 0 , 2 ), // #33
+ INST(Bics , BaseLogical , (0b1101010001, 0b11100100, 1) , kRWI_W , 0 , 3 ), // #34
+ INST(Bl , BaseBranchRel , (0b10010100000000000000000000000000) , 0 , 0 , 1 ), // #35
+ INST(Blr , BaseBranchReg , (0b11010110001111110000000000000000) , kRWI_R , 0 , 0 ), // #36
+ INST(Br , BaseBranchReg , (0b11010110000111110000000000000000) , kRWI_R , 0 , 1 ), // #37
+ INST(Brk , BaseOpImm , (0b11010100001000000000000000000000, 16, 5) , 0 , 0 , 0 ), // #38
+ INST(Cas , BaseAtomicOp , (0b1000100010100000011111, kWX, 30, 0) , kRWI_XRX , 0 , 0 ), // #39
+ INST(Casa , BaseAtomicOp , (0b1000100011100000011111, kWX, 30, 1) , kRWI_XRX , 0 , 1 ), // #40
+ INST(Casab , BaseAtomicOp , (0b0000100011100000011111, kW , 0 , 1) , kRWI_XRX , 0 , 2 ), // #41
+ INST(Casah , BaseAtomicOp , (0b0100100011100000011111, kW , 0 , 1) , kRWI_XRX , 0 , 3 ), // #42
+ INST(Casal , BaseAtomicOp , (0b1000100011100000111111, kWX, 30, 1) , kRWI_XRX , 0 , 4 ), // #43
+ INST(Casalb , BaseAtomicOp , (0b0000100011100000111111, kW , 0 , 1) , kRWI_XRX , 0 , 5 ), // #44
+ INST(Casalh , BaseAtomicOp , (0b0100100011100000111111, kW , 0 , 1) , kRWI_XRX , 0 , 6 ), // #45
+ INST(Casb , BaseAtomicOp , (0b0000100010100000011111, kW , 0 , 0) , kRWI_XRX , 0 , 7 ), // #46
+ INST(Cash , BaseAtomicOp , (0b0100100010100000011111, kW , 0 , 0) , kRWI_XRX , 0 , 8 ), // #47
+ INST(Casl , BaseAtomicOp , (0b1000100010100000111111, kWX, 30, 0) , kRWI_XRX , 0 , 9 ), // #48
+ INST(Caslb , BaseAtomicOp , (0b0000100010100000111111, kW , 0 , 0) , kRWI_XRX , 0 , 10 ), // #49
+ INST(Caslh , BaseAtomicOp , (0b0100100010100000111111, kW , 0 , 0) , kRWI_XRX , 0 , 11 ), // #50
+ INST(Casp , BaseAtomicCasp , (0b0000100000100000011111, kWX, 30) , kRWI_XXRRX, 0 , 0 ), // #51
+ INST(Caspa , BaseAtomicCasp , (0b0000100001100000011111, kWX, 30) , kRWI_XXRRX, 0 , 1 ), // #52
+ INST(Caspal , BaseAtomicCasp , (0b0000100001100000111111, kWX, 30) , kRWI_XXRRX, 0 , 2 ), // #53
+ INST(Caspl , BaseAtomicCasp , (0b0000100000100000111111, kWX, 30) , kRWI_XXRRX, 0 , 3 ), // #54
+ INST(Cbnz , BaseBranchCmp , (0b00110101000000000000000000000000) , kRWI_R , 0 , 0 ), // #55
+ INST(Cbz , BaseBranchCmp , (0b00110100000000000000000000000000) , kRWI_R , 0 , 1 ), // #56
+ INST(Ccmn , BaseCCmp , (0b00111010010000000000000000000000) , kRWI_R , 0 , 0 ), // #57
+ INST(Ccmp , BaseCCmp , (0b01111010010000000000000000000000) , kRWI_R , 0 , 1 ), // #58
+ INST(Cfinv , BaseOp , (0b11010101000000000100000000011111) , 0 , 0 , 7 ), // #59
+ INST(Cinc , BaseCInc , (0b00011010100000000000010000000000) , kRWI_W , 0 , 0 ), // #60
+ INST(Cinv , BaseCInc , (0b01011010100000000000000000000000) , kRWI_W , 0 , 1 ), // #61
+ INST(Clrex , BaseOpImm , (0b11010101000000110011000001011111, 4, 8) , 0 , 0 , 1 ), // #62
+ INST(Cls , BaseRR , (0b01011010110000000001010000000000, kWX, kZR, 0, kWX, kZR, 5, true) , kRWI_W , 0 , 4 ), // #63
+ INST(Clz , BaseRR , (0b01011010110000000001000000000000, kWX, kZR, 0, kWX, kZR, 5, true) , kRWI_W , 0 , 5 ), // #64
+ INST(Cmn , BaseCmpCmn , (0b0101011000, 0b0101011001, 0b0110001) , kRWI_R , 0 , 0 ), // #65
+ INST(Cmp , BaseCmpCmn , (0b1101011000, 0b1101011001, 0b1110001) , kRWI_R , 0 , 1 ), // #66
+ INST(Cmpp , BaseRR , (0b10111010110000000000000000011111, kX, kSP, 5, kX, kSP, 16, true) , kRWI_R , 0 , 6 ), // #67
+ INST(Cneg , BaseCInc , (0b01011010100000000000010000000000) , kRWI_W , 0 , 2 ), // #68
+ INST(Crc32b , BaseRRR , (0b0001101011000000010000, kW, kZR, kW, kZR, kW, kZR, false) , kRWI_W , 0 , 2 ), // #69
+ INST(Crc32cb , BaseRRR , (0b0001101011000000010100, kW, kZR, kW, kZR, kW, kZR, false) , kRWI_W , 0 , 3 ), // #70
+ INST(Crc32ch , BaseRRR , (0b0001101011000000010101, kW, kZR, kW, kZR, kW, kZR, false) , kRWI_W , 0 , 4 ), // #71
+ INST(Crc32cw , BaseRRR , (0b0001101011000000010110, kW, kZR, kW, kZR, kW, kZR, false) , kRWI_W , 0 , 5 ), // #72
+ INST(Crc32cx , BaseRRR , (0b1001101011000000010111, kW, kZR, kW, kZR, kX, kZR, false) , kRWI_W , 0 , 6 ), // #73
+ INST(Crc32h , BaseRRR , (0b0001101011000000010001, kW, kZR, kW, kZR, kW, kZR, false) , kRWI_W , 0 , 7 ), // #74
+ INST(Crc32w , BaseRRR , (0b0001101011000000010010, kW, kZR, kW, kZR, kW, kZR, false) , kRWI_W , 0 , 8 ), // #75
+ INST(Crc32x , BaseRRR , (0b1001101011000000010011, kW, kZR, kW, kZR, kX, kZR, false) , kRWI_W , 0 , 9 ), // #76
+ INST(Csdb , BaseOp , (0b11010101000000110010001010011111) , 0 , 0 , 8 ), // #77
+ INST(Csel , BaseCSel , (0b00011010100000000000000000000000) , kRWI_W , 0 , 0 ), // #78
+ INST(Cset , BaseCSet , (0b00011010100111110000011111100000) , kRWI_W , 0 , 0 ), // #79
+ INST(Csetm , BaseCSet , (0b01011010100111110000001111100000) , kRWI_W , 0 , 1 ), // #80
+ INST(Csinc , BaseCSel , (0b00011010100000000000010000000000) , kRWI_W , 0 , 1 ), // #81
+ INST(Csinv , BaseCSel , (0b01011010100000000000000000000000) , kRWI_W , 0 , 2 ), // #82
+ INST(Csneg , BaseCSel , (0b01011010100000000000010000000000) , kRWI_W , 0 , 3 ), // #83
+ INST(Dc , BaseAtDcIcTlbi , (0b00011110000000, 0b00001110000000, true) , kRWI_RX , 0 , 1 ), // #84
+ INST(Dcps1 , BaseOpImm , (0b11010100101000000000000000000001, 16, 5) , 0 , 0 , 2 ), // #85
+ INST(Dcps2 , BaseOpImm , (0b11010100101000000000000000000010, 16, 5) , 0 , 0 , 3 ), // #86
+ INST(Dcps3 , BaseOpImm , (0b11010100101000000000000000000011, 16, 5) , 0 , 0 , 4 ), // #87
+ INST(Dgh , BaseOp , (0b11010101000000110010000011011111) , 0 , 0 , 9 ), // #88
+ INST(Dmb , BaseOpImm , (0b11010101000000110011000010111111, 4, 8) , 0 , 0 , 5 ), // #89
+ INST(Drps , BaseOp , (0b11010110101111110000001111100000) , 0 , 0 , 10 ), // #90
+ INST(Dsb , BaseOpImm , (0b11010101000000110011000010011111, 4, 8) , 0 , 0 , 6 ), // #91
+ INST(Eon , BaseLogical , (0b1001010001, 0b10100100, 1) , kRWI_W , 0 , 4 ), // #92
+ INST(Eor , BaseLogical , (0b1001010000, 0b10100100, 0) , kRWI_W , 0 , 5 ), // #93
+ INST(Esb , BaseOp , (0b11010101000000110010001000011111) , 0 , 0 , 11 ), // #94
+ INST(Extr , BaseExtract , (0b00010011100000000000000000000000) , kRWI_W , 0 , 0 ), // #95
+ INST(Eret , BaseOp , (0b11010110100111110000001111100000) , 0 , 0 , 12 ), // #96
+ INST(Gmi , BaseRRR , (0b1001101011000000000101, kX , kZR, kX , kSP, kX , kZR, true) , kRWI_W , 0 , 10 ), // #97
+ INST(Hint , BaseOpImm , (0b11010101000000110010000000011111, 7, 5) , 0 , 0 , 7 ), // #98
+ INST(Hlt , BaseOpImm , (0b11010100010000000000000000000000, 16, 5) , 0 , 0 , 8 ), // #99
+ INST(Hvc , BaseOpImm , (0b11010100000000000000000000000010, 16, 5) , 0 , 0 , 9 ), // #100
+ INST(Ic , BaseAtDcIcTlbi , (0b00011110000000, 0b00001110000000, false) , kRWI_RX , 0 , 2 ), // #101
+ INST(Isb , BaseOpImm , (0b11010101000000110011000011011111, 4, 8) , 0 , 0 , 10 ), // #102
+ INST(Ldadd , BaseAtomicOp , (0b1011100000100000000000, kWX, 30, 0) , kRWI_WRX , 0 , 12 ), // #103
+ INST(Ldadda , BaseAtomicOp , (0b1011100010100000000000, kWX, 30, 1) , kRWI_WRX , 0 , 13 ), // #104
+ INST(Ldaddab , BaseAtomicOp , (0b0011100010100000000000, kW , 0 , 1) , kRWI_WRX , 0 , 14 ), // #105
+ INST(Ldaddah , BaseAtomicOp , (0b0111100010100000000000, kW , 0 , 1) , kRWI_WRX , 0 , 15 ), // #106
+ INST(Ldaddal , BaseAtomicOp , (0b1011100011100000000000, kWX, 30, 1) , kRWI_WRX , 0 , 16 ), // #107
+ INST(Ldaddalb , BaseAtomicOp , (0b0011100011100000000000, kW , 0 , 1) , kRWI_WRX , 0 , 17 ), // #108
+ INST(Ldaddalh , BaseAtomicOp , (0b0111100011100000000000, kW , 0 , 1) , kRWI_WRX , 0 , 18 ), // #109
+ INST(Ldaddb , BaseAtomicOp , (0b0011100000100000000000, kW , 0 , 0) , kRWI_WRX , 0 , 19 ), // #110
+ INST(Ldaddh , BaseAtomicOp , (0b0111100000100000000000, kW , 0 , 0) , kRWI_WRX , 0 , 20 ), // #111
+ INST(Ldaddl , BaseAtomicOp , (0b1011100001100000000000, kWX, 30, 0) , kRWI_WRX , 0 , 21 ), // #112
+ INST(Ldaddlb , BaseAtomicOp , (0b0011100001100000000000, kW , 0 , 0) , kRWI_WRX , 0 , 22 ), // #113
+ INST(Ldaddlh , BaseAtomicOp , (0b0111100001100000000000, kW , 0 , 0) , kRWI_WRX , 0 , 23 ), // #114
+ INST(Ldar , BaseRM_NoImm , (0b1000100011011111111111, kWX, kZR, 30) , kRWI_W , 0 , 0 ), // #115
+ INST(Ldarb , BaseRM_NoImm , (0b0000100011011111111111, kW , kZR, 0 ) , kRWI_W , 0 , 1 ), // #116
+ INST(Ldarh , BaseRM_NoImm , (0b0100100011011111111111, kW , kZR, 0 ) , kRWI_W , 0 , 2 ), // #117
+ INST(Ldaxp , BaseLdxp , (0b1000100001111111100000, kWX, 30) , kRWI_WW , 0 , 0 ), // #118
+ INST(Ldaxr , BaseRM_NoImm , (0b1000100001011111111111, kWX, kZR, 30) , kRWI_W , 0 , 3 ), // #119
+ INST(Ldaxrb , BaseRM_NoImm , (0b0000100001011111111111, kW , kZR, 0 ) , kRWI_W , 0 , 4 ), // #120
+ INST(Ldaxrh , BaseRM_NoImm , (0b0100100001011111111111, kW , kZR, 0 ) , kRWI_W , 0 , 5 ), // #121
+ INST(Ldclr , BaseAtomicOp , (0b1011100000100000000100, kWX, 30, 0) , kRWI_WRX , 0 , 24 ), // #122
+ INST(Ldclra , BaseAtomicOp , (0b1011100010100000000100, kWX, 30, 1) , kRWI_WRX , 0 , 25 ), // #123
+ INST(Ldclrab , BaseAtomicOp , (0b0011100010100000000100, kW , 0 , 1) , kRWI_WRX , 0 , 26 ), // #124
+ INST(Ldclrah , BaseAtomicOp , (0b0111100010100000000100, kW , 0 , 1) , kRWI_WRX , 0 , 27 ), // #125
+ INST(Ldclral , BaseAtomicOp , (0b1011100011100000000100, kWX, 30, 1) , kRWI_WRX , 0 , 28 ), // #126
+ INST(Ldclralb , BaseAtomicOp , (0b0011100011100000000100, kW , 0 , 1) , kRWI_WRX , 0 , 29 ), // #127
+ INST(Ldclralh , BaseAtomicOp , (0b0111100011100000000100, kW , 0 , 1) , kRWI_WRX , 0 , 30 ), // #128
+ INST(Ldclrb , BaseAtomicOp , (0b0011100000100000000100, kW , 0 , 0) , kRWI_WRX , 0 , 31 ), // #129
+ INST(Ldclrh , BaseAtomicOp , (0b0111100000100000000100, kW , 0 , 0) , kRWI_WRX , 0 , 32 ), // #130
+ INST(Ldclrl , BaseAtomicOp , (0b1011100001100000000100, kWX, 30, 0) , kRWI_WRX , 0 , 33 ), // #131
+ INST(Ldclrlb , BaseAtomicOp , (0b0011100001100000000100, kW , 0 , 0) , kRWI_WRX , 0 , 34 ), // #132
+ INST(Ldclrlh , BaseAtomicOp , (0b0111100001100000000100, kW , 0 , 0) , kRWI_WRX , 0 , 35 ), // #133
+ INST(Ldeor , BaseAtomicOp , (0b1011100000100000001000, kWX, 30, 0) , kRWI_WRX , 0 , 36 ), // #134
+ INST(Ldeora , BaseAtomicOp , (0b1011100010100000001000, kWX, 30, 1) , kRWI_WRX , 0 , 37 ), // #135
+ INST(Ldeorab , BaseAtomicOp , (0b0011100010100000001000, kW , 0 , 1) , kRWI_WRX , 0 , 38 ), // #136
+ INST(Ldeorah , BaseAtomicOp , (0b0111100010100000001000, kW , 0 , 1) , kRWI_WRX , 0 , 39 ), // #137
+ INST(Ldeoral , BaseAtomicOp , (0b1011100011100000001000, kWX, 30, 1) , kRWI_WRX , 0 , 40 ), // #138
+ INST(Ldeoralb , BaseAtomicOp , (0b0011100011100000001000, kW , 0 , 1) , kRWI_WRX , 0 , 41 ), // #139
+ INST(Ldeoralh , BaseAtomicOp , (0b0111100011100000001000, kW , 0 , 1) , kRWI_WRX , 0 , 42 ), // #140
+ INST(Ldeorb , BaseAtomicOp , (0b0011100000100000001000, kW , 0 , 0) , kRWI_WRX , 0 , 43 ), // #141
+ INST(Ldeorh , BaseAtomicOp , (0b0111100000100000001000, kW , 0 , 0) , kRWI_WRX , 0 , 44 ), // #142
+ INST(Ldeorl , BaseAtomicOp , (0b1011100001100000001000, kWX, 30, 0) , kRWI_WRX , 0 , 45 ), // #143
+ INST(Ldeorlb , BaseAtomicOp , (0b0011100001100000001000, kW , 0 , 0) , kRWI_WRX , 0 , 46 ), // #144
+ INST(Ldeorlh , BaseAtomicOp , (0b0111100001100000001000, kW , 0 , 0) , kRWI_WRX , 0 , 47 ), // #145
+ INST(Ldg , BaseRM_SImm9 , (0b1101100101100000000000, 0b0000000000000000000000, kX , kZR, 0, 4) , kRWI_W , 0 , 0 ), // #146
+ INST(Ldgm , BaseRM_NoImm , (0b1101100111100000000000, kX , kZR, 0 ) , kRWI_W , 0 , 6 ), // #147
+ INST(Ldlar , BaseRM_NoImm , (0b1000100011011111011111, kWX, kZR, 30) , kRWI_W , 0 , 7 ), // #148
+ INST(Ldlarb , BaseRM_NoImm , (0b0000100011011111011111, kW , kZR, 0 ) , kRWI_W , 0 , 8 ), // #149
+ INST(Ldlarh , BaseRM_NoImm , (0b0100100011011111011111, kW , kZR, 0 ) , kRWI_W , 0 , 9 ), // #150
+ INST(Ldnp , BaseLdpStp , (0b0010100001, 0 , kWX, 31, 2) , kRWI_WW , 0 , 0 ), // #151
+ INST(Ldp , BaseLdpStp , (0b0010100101, 0b0010100011, kWX, 31, 2) , kRWI_WW , 0 , 1 ), // #152
+ INST(Ldpsw , BaseLdpStp , (0b0110100101, 0b0110100011, kX , 0 , 2) , kRWI_WW , 0 , 2 ), // #153
+ INST(Ldr , BaseLdSt , (0b1011100101, 0b10111000010, 0b10111000011, 0b00011000, kWX, 30, 2, Inst::kIdLdur) , kRWI_W , 0 , 0 ), // #154
+ INST(Ldraa , BaseRM_SImm10 , (0b1111100000100000000001, kX , kZR, 0, 3) , kRWI_W , 0 , 0 ), // #155
+ INST(Ldrab , BaseRM_SImm10 , (0b1111100010100000000001, kX , kZR, 0, 3) , kRWI_W , 0 , 1 ), // #156
+ INST(Ldrb , BaseLdSt , (0b0011100101, 0b00111000010, 0b00111000011, 0 , kW , 0 , 0, Inst::kIdLdurb) , kRWI_W , 0 , 1 ), // #157
+ INST(Ldrh , BaseLdSt , (0b0111100101, 0b01111000010, 0b01111000011, 0 , kW , 0 , 1, Inst::kIdLdurh) , kRWI_W , 0 , 2 ), // #158
+ INST(Ldrsb , BaseLdSt , (0b0011100111, 0b00111000100, 0b00111000111, 0 , kWX, 22, 0, Inst::kIdLdursb) , kRWI_W , 0 , 3 ), // #159
+ INST(Ldrsh , BaseLdSt , (0b0111100111, 0b01111000100, 0b01111000111, 0 , kWX, 22, 1, Inst::kIdLdursh) , kRWI_W , 0 , 4 ), // #160
+ INST(Ldrsw , BaseLdSt , (0b1011100110, 0b10111000100, 0b10111000101, 0b10011000, kX , 0 , 2, Inst::kIdLdursw) , kRWI_W , 0 , 5 ), // #161
+ INST(Ldset , BaseAtomicOp , (0b1011100000100000001100, kWX, 30, 0) , kRWI_WRX , 0 , 48 ), // #162
+ INST(Ldseta , BaseAtomicOp , (0b1011100010100000001100, kWX, 30, 1) , kRWI_WRX , 0 , 49 ), // #163
+ INST(Ldsetab , BaseAtomicOp , (0b0011100010100000001100, kW , 0 , 1) , kRWI_WRX , 0 , 50 ), // #164
+ INST(Ldsetah , BaseAtomicOp , (0b0111100010100000001100, kW , 0 , 1) , kRWI_WRX , 0 , 51 ), // #165
+ INST(Ldsetal , BaseAtomicOp , (0b1011100011100000001100, kWX, 30, 1) , kRWI_WRX , 0 , 52 ), // #166
+ INST(Ldsetalb , BaseAtomicOp , (0b0011100011100000001100, kW , 0 , 1) , kRWI_WRX , 0 , 53 ), // #167
+ INST(Ldsetalh , BaseAtomicOp , (0b0111100011100000001100, kW , 0 , 1) , kRWI_WRX , 0 , 54 ), // #168
+ INST(Ldsetb , BaseAtomicOp , (0b0011100000100000001100, kW , 0 , 0) , kRWI_WRX , 0 , 55 ), // #169
+ INST(Ldseth , BaseAtomicOp , (0b0111100000100000001100, kW , 0 , 0) , kRWI_WRX , 0 , 56 ), // #170
+ INST(Ldsetl , BaseAtomicOp , (0b1011100001100000001100, kWX, 30, 0) , kRWI_WRX , 0 , 57 ), // #171
+ INST(Ldsetlb , BaseAtomicOp , (0b0011100001100000001100, kW , 0 , 0) , kRWI_WRX , 0 , 58 ), // #172
+ INST(Ldsetlh , BaseAtomicOp , (0b0111100001100000001100, kW , 0 , 0) , kRWI_WRX , 0 , 59 ), // #173
+ INST(Ldsmax , BaseAtomicOp , (0b1011100000100000010000, kWX, 30, 0) , kRWI_WRX , 0 , 60 ), // #174
+ INST(Ldsmaxa , BaseAtomicOp , (0b1011100010100000010000, kWX, 30, 1) , kRWI_WRX , 0 , 61 ), // #175
+ INST(Ldsmaxab , BaseAtomicOp , (0b0011100010100000010000, kW , 0 , 1) , kRWI_WRX , 0 , 62 ), // #176
+ INST(Ldsmaxah , BaseAtomicOp , (0b0111100010100000010000, kW , 0 , 1) , kRWI_WRX , 0 , 63 ), // #177
+ INST(Ldsmaxal , BaseAtomicOp , (0b1011100011100000010000, kWX, 30, 1) , kRWI_WRX , 0 , 64 ), // #178
+ INST(Ldsmaxalb , BaseAtomicOp , (0b0011100011100000010000, kW , 0 , 1) , kRWI_WRX , 0 , 65 ), // #179
+ INST(Ldsmaxalh , BaseAtomicOp , (0b0111100011100000010000, kW , 0 , 1) , kRWI_WRX , 0 , 66 ), // #180
+ INST(Ldsmaxb , BaseAtomicOp , (0b0011100000100000010000, kW , 0 , 0) , kRWI_WRX , 0 , 67 ), // #181
+ INST(Ldsmaxh , BaseAtomicOp , (0b0111100000100000010000, kW , 0 , 0) , kRWI_WRX , 0 , 68 ), // #182
+ INST(Ldsmaxl , BaseAtomicOp , (0b1011100001100000010000, kWX, 30, 0) , kRWI_WRX , 0 , 69 ), // #183
+ INST(Ldsmaxlb , BaseAtomicOp , (0b0011100001100000010000, kW , 0 , 0) , kRWI_WRX , 0 , 70 ), // #184
+ INST(Ldsmaxlh , BaseAtomicOp , (0b0111100001100000010000, kW , 0 , 0) , kRWI_WRX , 0 , 71 ), // #185
+ INST(Ldsmin , BaseAtomicOp , (0b1011100000100000010100, kWX, 30, 0) , kRWI_WRX , 0 , 72 ), // #186
+ INST(Ldsmina , BaseAtomicOp , (0b1011100010100000010100, kWX, 30, 1) , kRWI_WRX , 0 , 73 ), // #187
+ INST(Ldsminab , BaseAtomicOp , (0b0011100010100000010100, kW , 0 , 1) , kRWI_WRX , 0 , 74 ), // #188
+ INST(Ldsminah , BaseAtomicOp , (0b0111100010100000010100, kW , 0 , 1) , kRWI_WRX , 0 , 75 ), // #189
+ INST(Ldsminal , BaseAtomicOp , (0b1011100011100000010100, kWX, 30, 1) , kRWI_WRX , 0 , 76 ), // #190
+ INST(Ldsminalb , BaseAtomicOp , (0b0011100011100000010100, kW , 0 , 1) , kRWI_WRX , 0 , 77 ), // #191
+ INST(Ldsminalh , BaseAtomicOp , (0b0111100011100000010100, kW , 0 , 1) , kRWI_WRX , 0 , 78 ), // #192
+ INST(Ldsminb , BaseAtomicOp , (0b0011100000100000010100, kW , 0 , 0) , kRWI_WRX , 0 , 79 ), // #193
+ INST(Ldsminh , BaseAtomicOp , (0b0111100000100000010100, kW , 0 , 0) , kRWI_WRX , 0 , 80 ), // #194
+ INST(Ldsminl , BaseAtomicOp , (0b1011100001100000010100, kWX, 30, 0) , kRWI_WRX , 0 , 81 ), // #195
+ INST(Ldsminlb , BaseAtomicOp , (0b0011100001100000010100, kW , 0 , 0) , kRWI_WRX , 0 , 82 ), // #196
+ INST(Ldsminlh , BaseAtomicOp , (0b0111100001100000010100, kW , 0 , 0) , kRWI_WRX , 0 , 83 ), // #197
+ INST(Ldtr , BaseRM_SImm9 , (0b1011100001000000000010, 0b0000000000000000000000, kWX, kZR, 30, 0) , kRWI_W , 0 , 1 ), // #198
+ INST(Ldtrb , BaseRM_SImm9 , (0b0011100001000000000010, 0b0000000000000000000000, kW , kZR, 0 , 0) , kRWI_W , 0 , 2 ), // #199
+ INST(Ldtrh , BaseRM_SImm9 , (0b0111100001000000000010, 0b0000000000000000000000, kW , kZR, 0 , 0) , kRWI_W , 0 , 3 ), // #200
+ INST(Ldtrsb , BaseRM_SImm9 , (0b0011100011000000000010, 0b0000000000000000000000, kWX, kZR, 22, 0) , kRWI_W , 0 , 4 ), // #201
+ INST(Ldtrsh , BaseRM_SImm9 , (0b0111100011000000000010, 0b0000000000000000000000, kWX, kZR, 22, 0) , kRWI_W , 0 , 5 ), // #202
+ INST(Ldtrsw , BaseRM_SImm9 , (0b1011100010000000000010, 0b0000000000000000000000, kX , kZR, 0 , 0) , kRWI_W , 0 , 6 ), // #203
+ INST(Ldumax , BaseAtomicOp , (0b1011100000100000011000, kWX, 30, 0) , kRWI_WRX , 0 , 84 ), // #204
+ INST(Ldumaxa , BaseAtomicOp , (0b1011100010100000011000, kWX, 30, 1) , kRWI_WRX , 0 , 85 ), // #205
+ INST(Ldumaxab , BaseAtomicOp , (0b0011100010100000011000, kW , 0 , 1) , kRWI_WRX , 0 , 86 ), // #206
+ INST(Ldumaxah , BaseAtomicOp , (0b0111100010100000011000, kW , 0 , 1) , kRWI_WRX , 0 , 87 ), // #207
+ INST(Ldumaxal , BaseAtomicOp , (0b1011100011100000011000, kWX, 30, 1) , kRWI_WRX , 0 , 88 ), // #208
+ INST(Ldumaxalb , BaseAtomicOp , (0b0011100011100000011000, kW , 0 , 1) , kRWI_WRX , 0 , 89 ), // #209
+ INST(Ldumaxalh , BaseAtomicOp , (0b0111100011100000011000, kW , 0 , 1) , kRWI_WRX , 0 , 90 ), // #210
+ INST(Ldumaxb , BaseAtomicOp , (0b0011100000100000011000, kW , 0 , 0) , kRWI_WRX , 0 , 91 ), // #211
+ INST(Ldumaxh , BaseAtomicOp , (0b0111100000100000011000, kW , 0 , 0) , kRWI_WRX , 0 , 92 ), // #212
+ INST(Ldumaxl , BaseAtomicOp , (0b1011100001100000011000, kWX, 30, 0) , kRWI_WRX , 0 , 93 ), // #213
+ INST(Ldumaxlb , BaseAtomicOp , (0b0011100001100000011000, kW , 0 , 0) , kRWI_WRX , 0 , 94 ), // #214
+ INST(Ldumaxlh , BaseAtomicOp , (0b0111100001100000011000, kW , 0 , 0) , kRWI_WRX , 0 , 95 ), // #215
+ INST(Ldumin , BaseAtomicOp , (0b1011100000100000011100, kWX, 30, 0) , kRWI_WRX , 0 , 96 ), // #216
+ INST(Ldumina , BaseAtomicOp , (0b1011100010100000011100, kWX, 30, 1) , kRWI_WRX , 0 , 97 ), // #217
+ INST(Lduminab , BaseAtomicOp , (0b0011100010100000011100, kW , 0 , 1) , kRWI_WRX , 0 , 98 ), // #218
+ INST(Lduminah , BaseAtomicOp , (0b0111100010100000011100, kW , 0 , 1) , kRWI_WRX , 0 , 99 ), // #219
+ INST(Lduminal , BaseAtomicOp , (0b1011100011100000011100, kWX, 30, 1) , kRWI_WRX , 0 , 100), // #220
+ INST(Lduminalb , BaseAtomicOp , (0b0011100011100000011100, kW , 0 , 1) , kRWI_WRX , 0 , 101), // #221
+ INST(Lduminalh , BaseAtomicOp , (0b0111100011100000011100, kW , 0 , 1) , kRWI_WRX , 0 , 102), // #222
+ INST(Lduminb , BaseAtomicOp , (0b0011100000100000011100, kW , 0 , 0) , kRWI_WRX , 0 , 103), // #223
+ INST(Lduminh , BaseAtomicOp , (0b0111100000100000011100, kW , 0 , 0) , kRWI_WRX , 0 , 104), // #224
+ INST(Lduminl , BaseAtomicOp , (0b1011100001100000011100, kWX, 30, 0) , kRWI_WRX , 0 , 105), // #225
+ INST(Lduminlb , BaseAtomicOp , (0b0011100001100000011100, kW , 0 , 0) , kRWI_WRX , 0 , 106), // #226
+ INST(Lduminlh , BaseAtomicOp , (0b0111100001100000011100, kW , 0 , 0) , kRWI_WRX , 0 , 107), // #227
+ INST(Ldur , BaseRM_SImm9 , (0b1011100001000000000000, 0b0000000000000000000000, kWX, kZR, 30, 0) , kRWI_W , 0 , 7 ), // #228
+ INST(Ldurb , BaseRM_SImm9 , (0b0011100001000000000000, 0b0000000000000000000000, kW , kZR, 0 , 0) , kRWI_W , 0 , 8 ), // #229
+ INST(Ldurh , BaseRM_SImm9 , (0b0111100001000000000000, 0b0000000000000000000000, kW , kZR, 0 , 0) , kRWI_W , 0 , 9 ), // #230
+ INST(Ldursb , BaseRM_SImm9 , (0b0011100011000000000000, 0b0000000000000000000000, kWX, kZR, 22, 0) , kRWI_W , 0 , 10 ), // #231
+ INST(Ldursh , BaseRM_SImm9 , (0b0111100011000000000000, 0b0000000000000000000000, kWX, kZR, 22, 0) , kRWI_W , 0 , 11 ), // #232
+ INST(Ldursw , BaseRM_SImm9 , (0b1011100010000000000000, 0b0000000000000000000000, kX , kZR, 0 , 0) , kRWI_W , 0 , 12 ), // #233
+ INST(Ldxp , BaseLdxp , (0b1000100001111111000000, kWX, 30) , kRWI_WW , 0 , 1 ), // #234
+ INST(Ldxr , BaseRM_NoImm , (0b1000100001011111011111, kWX, kZR, 30) , kRWI_W , 0 , 10 ), // #235
+ INST(Ldxrb , BaseRM_NoImm , (0b0000100001011111011111, kW , kZR, 0 ) , kRWI_W , 0 , 11 ), // #236
+ INST(Ldxrh , BaseRM_NoImm , (0b0100100001011111011111, kW , kZR, 0 ) , kRWI_W , 0 , 12 ), // #237
+ INST(Lsl , BaseShift , (0b0001101011000000001000, 0b0101001100000000000000, 0) , kRWI_W , 0 , 2 ), // #238
+ INST(Lslv , BaseShift , (0b0001101011000000001000, 0b0000000000000000000000, 0) , kRWI_W , 0 , 3 ), // #239
+ INST(Lsr , BaseShift , (0b0001101011000000001001, 0b0101001100000000011111, 0) , kRWI_W , 0 , 4 ), // #240
+ INST(Lsrv , BaseShift , (0b0001101011000000001001, 0b0000000000000000000000, 0) , kRWI_W , 0 , 5 ), // #241
+ INST(Madd , BaseRRRR , (0b0001101100000000000000, kWX, kZR, kWX, kZR, kWX, kZR, kWX, kZR, true) , kRWI_W , 0 , 0 ), // #242
+ INST(Mneg , BaseRRR , (0b0001101100000000111111, kWX, kZR, kWX, kZR, kWX, kZR, true) , kRWI_W , 0 , 11 ), // #243
+ INST(Mov , BaseMov , (_) , kRWI_W , 0 , 0 ), // #244
+ INST(Movk , BaseMovKNZ , (0b01110010100000000000000000000000) , kRWI_X , 0 , 0 ), // #245
+ INST(Movn , BaseMovKNZ , (0b00010010100000000000000000000000) , kRWI_W , 0 , 1 ), // #246
+ INST(Movz , BaseMovKNZ , (0b01010010100000000000000000000000) , kRWI_W , 0 , 2 ), // #247
+ INST(Mrs , BaseMrs , (_) , kRWI_W , 0 , 0 ), // #248
+ INST(Msr , BaseMsr , (_) , kRWI_W , 0 , 0 ), // #249
+ INST(Msub , BaseRRRR , (0b0001101100000000100000, kWX, kZR, kWX, kZR, kWX, kZR, kWX, kZR, true) , kRWI_W , 0 , 1 ), // #250
+ INST(Mul , BaseRRR , (0b0001101100000000011111, kWX, kZR, kWX, kZR, kWX, kZR, true) , kRWI_W , 0 , 12 ), // #251
+ INST(Mvn , BaseMvnNeg , (0b00101010001000000000001111100000) , kRWI_W , 0 , 0 ), // #252
+ INST(Neg , BaseMvnNeg , (0b01001011000000000000001111100000) , kRWI_W , 0 , 1 ), // #253
+ INST(Negs , BaseMvnNeg , (0b01101011000000000000001111100000) , kRWI_W , 0 , 2 ), // #254
+ INST(Ngc , BaseRR , (0b01011010000000000000001111100000, kWX, kZR, 0, kWX, kZR, 16, true) , kRWI_W , 0 , 7 ), // #255
+ INST(Ngcs , BaseRR , (0b01111010000000000000001111100000, kWX, kZR, 0, kWX, kZR, 16, true) , kRWI_W , 0 , 8 ), // #256
+ INST(Nop , BaseOp , (0b11010101000000110010000000011111) , 0 , 0 , 13 ), // #257
+ INST(Orn , BaseLogical , (0b0101010001, 0b01100100, 1) , kRWI_W , 0 , 6 ), // #258
+ INST(Orr , BaseLogical , (0b0101010000, 0b01100100, 0) , kRWI_W , 0 , 7 ), // #259
+ INST(Pacda , BaseRR , (0b11011010110000010000100000000000, kX, kZR, 0, kX, kSP, 5, true) , kRWI_X , 0 , 9 ), // #260
+ INST(Pacdb , BaseRR , (0b11011010110000010000110000000000, kX, kZR, 0, kX, kSP, 5, true) , kRWI_X , 0 , 10 ), // #261
+ INST(Pacdza , BaseR , (0b11011010110000010010101111100000, kX, kZR, 0) , kRWI_X , 0 , 4 ), // #262
+ INST(Pacdzb , BaseR , (0b11011010110000010010111111100000, kX, kZR, 0) , kRWI_X , 0 , 5 ), // #263
+ INST(Pacga , BaseRRR , (0b1001101011000000001100, kX, kZR, kX, kZR, kX, kSP, false) , kRWI_W , 0 , 13 ), // #264
+ INST(Prfm , BasePrfm , (0b11111000101, 0b1111100110, 0b11111000100, 0b11011000) , kRWI_R , 0 , 0 ), // #265
+ INST(Pssbb , BaseOp , (0b11010101000000110011010010011111) , 0 , 0 , 14 ), // #266
+ INST(Rbit , BaseRR , (0b01011010110000000000000000000000, kWX, kZR, 0, kWX, kZR, 5, true) , kRWI_W , 0 , 11 ), // #267
+ INST(Ret , BaseBranchReg , (0b11010110010111110000000000000000) , kRWI_R , 0 , 2 ), // #268
+ INST(Rev , BaseRev , (_) , kRWI_W , 0 , 0 ), // #269
+ INST(Rev16 , BaseRR , (0b01011010110000000000010000000000, kWX, kZR, 0, kWX, kZR, 5, true) , kRWI_W , 0 , 12 ), // #270
+ INST(Rev32 , BaseRR , (0b11011010110000000000100000000000, kWX, kZR, 0, kWX, kZR, 5, true) , kRWI_W , 0 , 13 ), // #271
+ INST(Rev64 , BaseRR , (0b11011010110000000000110000000000, kWX, kZR, 0, kWX, kZR, 5, true) , kRWI_W , 0 , 14 ), // #272
+ INST(Ror , BaseShift , (0b0001101011000000001011, 0b0001001110000000000000, 1) , kRWI_W , 0 , 6 ), // #273
+ INST(Rorv , BaseShift , (0b0001101011000000001011, 0b0000000000000000000000, 1) , kRWI_W , 0 , 7 ), // #274
+ INST(Sbc , BaseRRR , (0b0101101000000000000000, kWX, kZR, kWX, kZR, kWX, kZR, true) , kRWI_W , 0 , 14 ), // #275
+ INST(Sbcs , BaseRRR , (0b0111101000000000000000, kWX, kZR, kWX, kZR, kWX, kZR, true) , kRWI_W , 0 , 15 ), // #276
+ INST(Sbfiz , BaseBfi , (0b00010011000000000000000000000000) , kRWI_W , 0 , 1 ), // #277
+ INST(Sbfm , BaseBfm , (0b00010011000000000000000000000000) , kRWI_W , 0 , 1 ), // #278
+ INST(Sbfx , BaseBfx , (0b00010011000000000000000000000000) , kRWI_W , 0 , 1 ), // #279
+ INST(Sdiv , BaseRRR , (0b0001101011000000000011, kWX, kZR, kWX, kZR, kWX, kZR, true) , kRWI_W , 0 , 16 ), // #280
+ INST(Setf8 , BaseR , (0b00111010000000000000100000001101, kW, kZR, 5) , 0 , 0 , 6 ), // #281
+ INST(Setf16 , BaseR , (0b00111010000000000100100000001101, kW, kZR, 5) , 0 , 0 , 7 ), // #282
+ INST(Sev , BaseOp , (0b11010101000000110010000010011111) , 0 , 0 , 15 ), // #283
+ INST(Sevl , BaseOp , (0b11010101000000110010000010111111) , 0 , 0 , 16 ), // #284
+ INST(Smaddl , BaseRRRR , (0b1001101100100000000000, kX , kZR, kW , kZR, kW , kZR, kX , kZR, false) , kRWI_W , 0 , 2 ), // #285
+ INST(Smc , BaseOpImm , (0b11010100000000000000000000000011, 16, 5) , 0 , 0 , 11 ), // #286
+ INST(Smnegl , BaseRRR , (0b1001101100100000111111, kX , kZR, kW , kZR, kW , kZR, false) , kRWI_W , 0 , 17 ), // #287
+ INST(Smsubl , BaseRRRR , (0b1001101100100000100000, kX , kZR, kW , kZR, kW , kZR, kX , kZR, false) , kRWI_W , 0 , 3 ), // #288
+ INST(Smulh , BaseRRR , (0b1001101101000000011111, kX , kZR, kX , kZR, kX , kZR, true) , kRWI_W , 0 , 18 ), // #289
+ INST(Smull , BaseRRR , (0b1001101100100000011111, kX , kZR, kW , kZR, kW , kZR, false) , kRWI_W , 0 , 19 ), // #290
+ INST(Ssbb , BaseOp , (0b11010101000000110011000010011111) , 0 , 0 , 17 ), // #291
+ INST(St2g , BaseRM_SImm9 , (0b1101100110100000000010, 0b1101100110100000000001, kX, kSP, 0, 4) , kRWI_RW , 0 , 13 ), // #292
+ INST(Stadd , BaseAtomicSt , (0b1011100000100000000000, kWX, 30) , kRWI_RX , 0 , 0 ), // #293
+ INST(Staddl , BaseAtomicSt , (0b1011100001100000000000, kWX, 30) , kRWI_RX , 0 , 1 ), // #294
+ INST(Staddb , BaseAtomicSt , (0b0011100000100000000000, kW , 0 ) , kRWI_RX , 0 , 2 ), // #295
+ INST(Staddlb , BaseAtomicSt , (0b0011100001100000000000, kW , 0 ) , kRWI_RX , 0 , 3 ), // #296
+ INST(Staddh , BaseAtomicSt , (0b0111100000100000000000, kW , 0 ) , kRWI_RX , 0 , 4 ), // #297
+ INST(Staddlh , BaseAtomicSt , (0b0111100001100000000000, kW , 0 ) , kRWI_RX , 0 , 5 ), // #298
+ INST(Stclr , BaseAtomicSt , (0b1011100000100000000100, kWX, 30) , kRWI_RX , 0 , 6 ), // #299
+ INST(Stclrl , BaseAtomicSt , (0b1011100001100000000100, kWX, 30) , kRWI_RX , 0 , 7 ), // #300
+ INST(Stclrb , BaseAtomicSt , (0b0011100000100000000100, kW , 0 ) , kRWI_RX , 0 , 8 ), // #301
+ INST(Stclrlb , BaseAtomicSt , (0b0011100001100000000100, kW , 0 ) , kRWI_RX , 0 , 9 ), // #302
+ INST(Stclrh , BaseAtomicSt , (0b0111100000100000000100, kW , 0 ) , kRWI_RX , 0 , 10 ), // #303
+ INST(Stclrlh , BaseAtomicSt , (0b0111100001100000000100, kW , 0 ) , kRWI_RX , 0 , 11 ), // #304
+ INST(Steor , BaseAtomicSt , (0b1011100000100000001000, kWX, 30) , kRWI_RX , 0 , 12 ), // #305
+ INST(Steorl , BaseAtomicSt , (0b1011100001100000001000, kWX, 30) , kRWI_RX , 0 , 13 ), // #306
+ INST(Steorb , BaseAtomicSt , (0b0011100000100000001000, kW , 0 ) , kRWI_RX , 0 , 14 ), // #307
+ INST(Steorlb , BaseAtomicSt , (0b0011100001100000001000, kW , 0 ) , kRWI_RX , 0 , 15 ), // #308
+ INST(Steorh , BaseAtomicSt , (0b0111100000100000001000, kW , 0 ) , kRWI_RX , 0 , 16 ), // #309
+ INST(Steorlh , BaseAtomicSt , (0b0111100001100000001000, kW , 0 ) , kRWI_RX , 0 , 17 ), // #310
+ INST(Stg , BaseRM_SImm9 , (0b1101100100100000000010, 0b1101100100100000000001, kX, kSP, 0, 4) , kRWI_RW , 0 , 14 ), // #311
+ INST(Stgm , BaseRM_NoImm , (0b1101100110100000000000, kX , kZR, 0 ) , kRWI_RW , 0 , 13 ), // #312
+ INST(Stgp , BaseLdpStp , (0b0110100100, 0b0110100010, kX, 0, 4) , kRWI_RRW , 0 , 3 ), // #313
+ INST(Stllr , BaseRM_NoImm , (0b1000100010011111011111, kWX, kZR, 30) , kRWI_RW , 0 , 14 ), // #314
+ INST(Stllrb , BaseRM_NoImm , (0b0000100010011111011111, kW , kZR, 0 ) , kRWI_RW , 0 , 15 ), // #315
+ INST(Stllrh , BaseRM_NoImm , (0b0100100010011111011111, kW , kZR, 0 ) , kRWI_RW , 0 , 16 ), // #316
+ INST(Stlr , BaseRM_NoImm , (0b1000100010011111111111, kWX, kZR, 30) , kRWI_RW , 0 , 17 ), // #317
+ INST(Stlrb , BaseRM_NoImm , (0b0000100010011111111111, kW , kZR, 0 ) , kRWI_RW , 0 , 18 ), // #318
+ INST(Stlrh , BaseRM_NoImm , (0b0100100010011111111111, kW , kZR, 0 ) , kRWI_RW , 0 , 19 ), // #319
+ INST(Stlxp , BaseStxp , (0b1000100000100000100000, kWX, 30) , kRWI_WRRX , 0 , 0 ), // #320
+ INST(Stlxr , BaseAtomicOp , (0b1000100000000000111111, kWX, 30, 1) , kRWI_WRX , 0 , 108), // #321
+ INST(Stlxrb , BaseAtomicOp , (0b0000100000000000111111, kW , 0 , 1) , kRWI_WRX , 0 , 109), // #322
+ INST(Stlxrh , BaseAtomicOp , (0b0100100000000000111111, kW , 0 , 1) , kRWI_WRX , 0 , 110), // #323
+ INST(Stnp , BaseLdpStp , (0b0010100000, 0 , kWX, 31, 2) , kRWI_RRW , 0 , 4 ), // #324
+ INST(Stp , BaseLdpStp , (0b0010100100, 0b0010100010, kWX, 31, 2) , kRWI_RRW , 0 , 5 ), // #325
+ INST(Str , BaseLdSt , (0b1011100100, 0b10111000000, 0b10111000001, 0 , kWX, 30, 2, Inst::kIdStur) , kRWI_RW , 0 , 6 ), // #326
+ INST(Strb , BaseLdSt , (0b0011100100, 0b00111000000, 0b00111000001, 0 , kW , 30, 0, Inst::kIdSturb) , kRWI_RW , 0 , 7 ), // #327
+ INST(Strh , BaseLdSt , (0b0111100100, 0b01111000000, 0b01111000001, 0 , kWX, 30, 1, Inst::kIdSturh) , kRWI_RW , 0 , 8 ), // #328
+ INST(Stset , BaseAtomicSt , (0b1011100000100000001100, kWX, 30) , kRWI_RX , 0 , 18 ), // #329
+ INST(Stsetl , BaseAtomicSt , (0b1011100001100000001100, kWX, 30) , kRWI_RX , 0 , 19 ), // #330
+ INST(Stsetb , BaseAtomicSt , (0b0011100000100000001100, kW , 0 ) , kRWI_RX , 0 , 20 ), // #331
+ INST(Stsetlb , BaseAtomicSt , (0b0011100001100000001100, kW , 0 ) , kRWI_RX , 0 , 21 ), // #332
+ INST(Stseth , BaseAtomicSt , (0b0111100000100000001100, kW , 0 ) , kRWI_RX , 0 , 22 ), // #333
+ INST(Stsetlh , BaseAtomicSt , (0b0111100001100000001100, kW , 0 ) , kRWI_RX , 0 , 23 ), // #334
+ INST(Stsmax , BaseAtomicSt , (0b1011100000100000010000, kWX, 30) , kRWI_RX , 0 , 24 ), // #335
+ INST(Stsmaxl , BaseAtomicSt , (0b1011100001100000010000, kWX, 30) , kRWI_RX , 0 , 25 ), // #336
+ INST(Stsmaxb , BaseAtomicSt , (0b0011100000100000010000, kW , 0 ) , kRWI_RX , 0 , 26 ), // #337
+ INST(Stsmaxlb , BaseAtomicSt , (0b0011100001100000010000, kW , 0 ) , kRWI_RX , 0 , 27 ), // #338
+ INST(Stsmaxh , BaseAtomicSt , (0b0111100000100000010000, kW , 0 ) , kRWI_RX , 0 , 28 ), // #339
+ INST(Stsmaxlh , BaseAtomicSt , (0b0111100001100000010000, kW , 0 ) , kRWI_RX , 0 , 29 ), // #340
+ INST(Stsmin , BaseAtomicSt , (0b1011100000100000010100, kWX, 30) , kRWI_RX , 0 , 30 ), // #341
+ INST(Stsminl , BaseAtomicSt , (0b1011100001100000010100, kWX, 30) , kRWI_RX , 0 , 31 ), // #342
+ INST(Stsminb , BaseAtomicSt , (0b0011100000100000010100, kW , 0 ) , kRWI_RX , 0 , 32 ), // #343
+ INST(Stsminlb , BaseAtomicSt , (0b0011100001100000010100, kW , 0 ) , kRWI_RX , 0 , 33 ), // #344
+ INST(Stsminh , BaseAtomicSt , (0b0111100000100000010100, kW , 0 ) , kRWI_RX , 0 , 34 ), // #345
+ INST(Stsminlh , BaseAtomicSt , (0b0111100001100000010100, kW , 0 ) , kRWI_RX , 0 , 35 ), // #346
+ INST(Sttr , BaseRM_SImm9 , (0b1011100000000000000010, 0b0000000000000000000000, kWX, kZR, 30, 0) , kRWI_RW , 0 , 15 ), // #347
+ INST(Sttrb , BaseRM_SImm9 , (0b0011100000000000000010, 0b0000000000000000000000, kW , kZR, 0 , 0) , kRWI_RW , 0 , 16 ), // #348
+ INST(Sttrh , BaseRM_SImm9 , (0b0111100000000000000010, 0b0000000000000000000000, kW , kZR, 0 , 0) , kRWI_RW , 0 , 17 ), // #349
+ INST(Stumax , BaseAtomicSt , (0b1011100000100000011000, kWX, 30) , kRWI_RX , 0 , 36 ), // #350
+ INST(Stumaxl , BaseAtomicSt , (0b1011100001100000011000, kWX, 30) , kRWI_RX , 0 , 37 ), // #351
+ INST(Stumaxb , BaseAtomicSt , (0b0011100000100000011000, kW , 0 ) , kRWI_RX , 0 , 38 ), // #352
+ INST(Stumaxlb , BaseAtomicSt , (0b0011100001100000011000, kW , 0 ) , kRWI_RX , 0 , 39 ), // #353
+ INST(Stumaxh , BaseAtomicSt , (0b0111100000100000011000, kW , 0 ) , kRWI_RX , 0 , 40 ), // #354
+ INST(Stumaxlh , BaseAtomicSt , (0b0111100001100000011000, kW , 0 ) , kRWI_RX , 0 , 41 ), // #355
+ INST(Stumin , BaseAtomicSt , (0b1011100000100000011100, kWX, 30) , kRWI_RX , 0 , 42 ), // #356
+ INST(Stuminl , BaseAtomicSt , (0b1011100001100000011100, kWX, 30) , kRWI_RX , 0 , 43 ), // #357
+ INST(Stuminb , BaseAtomicSt , (0b0011100000100000011100, kW , 0 ) , kRWI_RX , 0 , 44 ), // #358
+ INST(Stuminlb , BaseAtomicSt , (0b0011100001100000011100, kW , 0 ) , kRWI_RX , 0 , 45 ), // #359
+ INST(Stuminh , BaseAtomicSt , (0b0111100000100000011100, kW , 0 ) , kRWI_RX , 0 , 46 ), // #360
+ INST(Stuminlh , BaseAtomicSt , (0b0111100001100000011100, kW , 0 ) , kRWI_RX , 0 , 47 ), // #361
+ INST(Stur , BaseRM_SImm9 , (0b1011100000000000000000, 0b0000000000000000000000, kWX, kZR, 30, 0) , kRWI_RW , 0 , 18 ), // #362
+ INST(Sturb , BaseRM_SImm9 , (0b0011100000000000000000, 0b0000000000000000000000, kW , kZR, 0 , 0) , kRWI_RW , 0 , 19 ), // #363
+ INST(Sturh , BaseRM_SImm9 , (0b0111100000000000000000, 0b0000000000000000000000, kW , kZR, 0 , 0) , kRWI_RW , 0 , 20 ), // #364
+ INST(Stxp , BaseStxp , (0b1000100000100000000000, kWX, 30) , kRWI_WRRW , 0 , 1 ), // #365
+ INST(Stxr , BaseStx , (0b1000100000000000011111, kWX, 30) , kRWI_WRW , 0 , 0 ), // #366
+ INST(Stxrb , BaseStx , (0b0000100000000000011111, kW , 0 ) , kRWI_WRW , 0 , 1 ), // #367
+ INST(Stxrh , BaseStx , (0b0100100000000000011111, kW , 0 ) , kRWI_WRW , 0 , 2 ), // #368
+ INST(Stz2g , BaseRM_SImm9 , (0b1101100111100000000010, 0b1101100111100000000001, kX , kSP, 0, 4) , kRWI_RW , 0 , 21 ), // #369
+ INST(Stzg , BaseRM_SImm9 , (0b1101100101100000000010, 0b1101100101100000000001, kX , kSP, 0, 4) , kRWI_RW , 0 , 22 ), // #370
+ INST(Stzgm , BaseRM_NoImm , (0b1101100100100000000000, kX , kZR, 0) , kRWI_RW , 0 , 20 ), // #371
+ INST(Sub , BaseAddSub , (0b1001011000, 0b1001011001, 0b1010001) , kRWI_W , 0 , 2 ), // #372
+ INST(Subg , BaseRRII , (0b1101000110000000000000, kX, kSP, kX, kSP, 6, 4, 16, 4, 0, 10) , kRWI_W , 0 , 1 ), // #373
+ INST(Subp , BaseRRR , (0b1001101011000000000000, kX, kZR, kX, kSP, kX, kSP, false) , kRWI_W , 0 , 20 ), // #374
+ INST(Subps , BaseRRR , (0b1011101011000000000000, kX, kZR, kX, kSP, kX, kSP, false) , kRWI_W , 0 , 21 ), // #375
+ INST(Subs , BaseAddSub , (0b1101011000, 0b1101011001, 0b1110001) , kRWI_W , 0 , 3 ), // #376
+ INST(Svc , BaseOpImm , (0b11010100000000000000000000000001, 16, 5) , 0 , 0 , 12 ), // #377
+ INST(Swp , BaseAtomicOp , (0b1011100000100000100000, kWX, 30, 1) , kRWI_RWX , 0 , 111), // #378
+ INST(Swpa , BaseAtomicOp , (0b1011100010100000100000, kWX, 30, 1) , kRWI_RWX , 0 , 112), // #379
+ INST(Swpab , BaseAtomicOp , (0b0011100010100000100000, kW , 0 , 1) , kRWI_RWX , 0 , 113), // #380
+ INST(Swpah , BaseAtomicOp , (0b0111100010100000100000, kW , 0 , 1) , kRWI_RWX , 0 , 114), // #381
+ INST(Swpal , BaseAtomicOp , (0b1011100011100000100000, kWX, 30, 1) , kRWI_RWX , 0 , 115), // #382
+ INST(Swpalb , BaseAtomicOp , (0b0011100011100000100000, kW , 0 , 1) , kRWI_RWX , 0 , 116), // #383
+ INST(Swpalh , BaseAtomicOp , (0b0111100011100000100000, kW , 0 , 1) , kRWI_RWX , 0 , 117), // #384
+ INST(Swpb , BaseAtomicOp , (0b0011100000100000100000, kW , 0 , 1) , kRWI_RWX , 0 , 118), // #385
+ INST(Swph , BaseAtomicOp , (0b0111100000100000100000, kW , 0 , 1) , kRWI_RWX , 0 , 119), // #386
+ INST(Swpl , BaseAtomicOp , (0b1011100001100000100000, kWX, 30, 1) , kRWI_RWX , 0 , 120), // #387
+ INST(Swplb , BaseAtomicOp , (0b0011100001100000100000, kW , 0 , 1) , kRWI_RWX , 0 , 121), // #388
+ INST(Swplh , BaseAtomicOp , (0b0111100001100000100000, kW , 0 , 1) , kRWI_RWX , 0 , 122), // #389
+ INST(Sxtb , BaseExtend , (0b0001001100000000000111, kWX, 0) , kRWI_W , 0 , 0 ), // #390
+ INST(Sxth , BaseExtend , (0b0001001100000000001111, kWX, 0) , kRWI_W , 0 , 1 ), // #391
+ INST(Sxtw , BaseExtend , (0b1001001101000000011111, kX , 0) , kRWI_W , 0 , 2 ), // #392
+ INST(Sys , BaseSys , (_) , kRWI_W , 0 , 0 ), // #393
+ INST(Tlbi , BaseAtDcIcTlbi , (0b00011110000000, 0b00010000000000, false) , kRWI_RX , 0 , 3 ), // #394
+ INST(Tst , BaseTst , (0b1101010000, 0b111001000) , kRWI_R , 0 , 0 ), // #395
+ INST(Tbnz , BaseBranchTst , (0b00110111000000000000000000000000) , kRWI_R , 0 , 0 ), // #396
+ INST(Tbz , BaseBranchTst , (0b00110110000000000000000000000000) , kRWI_R , 0 , 1 ), // #397
+ INST(Ubfiz , BaseBfi , (0b01010011000000000000000000000000) , kRWI_W , 0 , 2 ), // #398
+ INST(Ubfm , BaseBfm , (0b01010011000000000000000000000000) , kRWI_W , 0 , 2 ), // #399
+ INST(Ubfx , BaseBfx , (0b01010011000000000000000000000000) , kRWI_W , 0 , 2 ), // #400
+ INST(Udf , BaseOpImm , (0b00000000000000000000000000000000, 16, 0) , 0 , 0 , 13 ), // #401
+ INST(Udiv , BaseRRR , (0b0001101011000000000010, kWX, kZR, kWX, kZR, kWX, kZR, true) , kRWI_W , 0 , 22 ), // #402
+ INST(Umaddl , BaseRRRR , (0b1001101110100000000000, kX , kZR, kW , kZR, kW , kZR, kX , kZR, false) , kRWI_W , 0 , 4 ), // #403
+ INST(Umnegl , BaseRRR , (0b1001101110100000111111, kX , kZR, kW , kZR, kW , kZR, false) , kRWI_W , 0 , 23 ), // #404
+ INST(Umull , BaseRRR , (0b1001101110100000011111, kX , kZR, kW , kZR, kW , kZR, false) , kRWI_W , 0 , 24 ), // #405
+ INST(Umulh , BaseRRR , (0b1001101111000000011111, kX , kZR, kX , kZR, kX , kZR, false) , kRWI_W , 0 , 25 ), // #406
+ INST(Umsubl , BaseRRRR , (0b1001101110100000100000, kX , kZR, kW , kZR, kW , kZR, kX , kZR, false) , kRWI_W , 0 , 5 ), // #407
+ INST(Uxtb , BaseExtend , (0b0101001100000000000111, kW, 1) , kRWI_W , 0 , 3 ), // #408
+ INST(Uxth , BaseExtend , (0b0101001100000000001111, kW, 1) , kRWI_W , 0 , 4 ), // #409
+ INST(Wfe , BaseOp , (0b11010101000000110010000001011111) , 0 , 0 , 18 ), // #410
+ INST(Wfi , BaseOp , (0b11010101000000110010000001111111) , 0 , 0 , 19 ), // #411
+ INST(Xaflag , BaseOp , (0b11010101000000000100000000111111) , 0 , 0 , 20 ), // #412
+ INST(Xpacd , BaseR , (0b11011010110000010100011111100000, kX, kZR, 0) , kRWI_X , 0 , 8 ), // #413
+ INST(Xpaci , BaseR , (0b11011010110000010100001111100000, kX, kZR, 0) , kRWI_X , 0 , 9 ), // #414
+ INST(Xpaclri , BaseOp , (0b11010101000000110010000011111111) , kRWI_X , 0 , 21 ), // #415
+ INST(Yield , BaseOp , (0b11010101000000110010000000111111) , 0 , 0 , 22 ), // #416
+ INST(Abs_v , ISimdVV , (0b0000111000100000101110, kVO_V_Any) , kRWI_W , 0 , 0 ), // #417
+ INST(Add_v , ISimdVVV , (0b0000111000100000100001, kVO_V_Any) , kRWI_W , 0 , 0 ), // #418
+ INST(Addhn_v , ISimdVVV , (0b0000111000100000010000, kVO_V_B8H4S2) , kRWI_W , F(Narrow) , 1 ), // #419
+ INST(Addhn2_v , ISimdVVV , (0b0100111000100000010000, kVO_V_B16H8S4) , kRWI_W , F(Narrow) , 2 ), // #420
+ INST(Addp_v , ISimdPair , (0b0101111000110001101110, 0b0000111000100000101111, kVO_V_Any) , kRWI_W , F(Pair) , 0 ), // #421
+ INST(Addv_v , ISimdSV , (0b0000111000110001101110, kVO_V_BH_4S) , kRWI_W , 0 , 0 ), // #422
+ INST(Aesd_v , ISimdVVx , (0b0100111000101000010110, kOp_V16B, kOp_V16B) , kRWI_X , 0 , 0 ), // #423
+ INST(Aese_v , ISimdVVx , (0b0100111000101000010010, kOp_V16B, kOp_V16B) , kRWI_X , 0 , 1 ), // #424
+ INST(Aesimc_v , ISimdVVx , (0b0100111000101000011110, kOp_V16B, kOp_V16B) , kRWI_W , 0 , 2 ), // #425
+ INST(Aesmc_v , ISimdVVx , (0b0100111000101000011010, kOp_V16B, kOp_V16B) , kRWI_W , 0 , 3 ), // #426
+ INST(And_v , ISimdVVV , (0b0000111000100000000111, kVO_V_B) , kRWI_W , 0 , 3 ), // #427
+ INST(Bcax_v , ISimdVVVV , (0b1100111000100000000000, kVO_V_B16) , kRWI_W , 0 , 0 ), // #428
+ INST(Bfcvt_v , ISimdVVx , (0b0001111001100011010000, kOp_H, kOp_S) , kRWI_W , 0 , 4 ), // #429
+ INST(Bfcvtn_v , ISimdVVx , (0b0000111010100001011010, kOp_V4H, kOp_V4S) , kRWI_W , F(Narrow) , 5 ), // #430
+ INST(Bfcvtn2_v , ISimdVVx , (0b0100111010100001011010, kOp_V8H, kOp_V4S) , kRWI_W , F(Narrow) , 6 ), // #431
+ INST(Bfdot_v , SimdDot , (0b0010111001000000111111, 0b0000111101000000111100, kET_S, kET_H, kET_2H) , kRWI_X , 0 , 0 ), // #432
+ INST(Bfmlalb_v , SimdFmlal , (0b0010111011000000111111, 0b0000111111000000111100, 0, kET_S, kET_H, kET_H) , kRWI_X , F(VH0_15) , 0 ), // #433
+ INST(Bfmlalt_v , SimdFmlal , (0b0110111011000000111111, 0b0100111111000000111100, 0, kET_S, kET_H, kET_H) , kRWI_X , F(VH0_15) , 1 ), // #434
+ INST(Bfmmla_v , ISimdVVVx , (0b0110111001000000111011, kOp_V4S, kOp_V8H, kOp_V8H) , kRWI_X , F(Long) , 0 ), // #435
+ INST(Bic_v , SimdBicOrr , (0b0000111001100000000111, 0b0010111100000000000001) , kRWI_W , 0 , 0 ), // #436
+ INST(Bif_v , ISimdVVV , (0b0010111011100000000111, kVO_V_B) , kRWI_X , 0 , 4 ), // #437
+ INST(Bit_v , ISimdVVV , (0b0010111010100000000111, kVO_V_B) , kRWI_X , 0 , 5 ), // #438
+ INST(Bsl_v , ISimdVVV , (0b0010111001100000000111, kVO_V_B) , kRWI_X , 0 , 6 ), // #439
+ INST(Cls_v , ISimdVV , (0b0000111000100000010010, kVO_V_BHS) , kRWI_W , 0 , 1 ), // #440
+ INST(Clz_v , ISimdVV , (0b0010111000100000010010, kVO_V_BHS) , kRWI_W , 0 , 2 ), // #441
+ INST(Cmeq_v , SimdCmp , (0b0010111000100000100011, 0b0000111000100000100110, kVO_V_Any) , kRWI_W , 0 , 0 ), // #442
+ INST(Cmge_v , SimdCmp , (0b0000111000100000001111, 0b0010111000100000100010, kVO_V_Any) , kRWI_W , 0 , 1 ), // #443
+ INST(Cmgt_v , SimdCmp , (0b0000111000100000001101, 0b0000111000100000100010, kVO_V_Any) , kRWI_W , 0 , 2 ), // #444
+ INST(Cmhi_v , SimdCmp , (0b0010111000100000001101, 0b0000000000000000000000, kVO_V_Any) , kRWI_W , 0 , 3 ), // #445
+ INST(Cmhs_v , SimdCmp , (0b0010111000100000001111, 0b0000000000000000000000, kVO_V_Any) , kRWI_W , 0 , 4 ), // #446
+ INST(Cmle_v , SimdCmp , (0b0000000000000000000000, 0b0010111000100000100110, kVO_V_Any) , kRWI_W , 0 , 5 ), // #447
+ INST(Cmlt_v , SimdCmp , (0b0000000000000000000000, 0b0000111000100000101010, kVO_V_Any) , kRWI_W , 0 , 6 ), // #448
+ INST(Cmtst_v , ISimdVVV , (0b0000111000100000100011, kVO_V_Any) , kRWI_W , 0 , 7 ), // #449
+ INST(Cnt_v , ISimdVV , (0b0000111000100000010110, kVO_V_B) , kRWI_W , 0 , 3 ), // #450
+ INST(Dup_v , SimdDup , (_) , kRWI_W , 0 , 0 ), // #451
+ INST(Eor_v , ISimdVVV , (0b0010111000100000000111, kVO_V_B) , kRWI_W , 0 , 8 ), // #452
+ INST(Eor3_v , ISimdVVVV , (0b1100111000000000000000, kVO_V_B16) , kRWI_W , 0 , 1 ), // #453
+ INST(Ext_v , ISimdVVVI , (0b0010111000000000000000, kVO_V_B, 4, 11, 1) , kRWI_W , 0 , 0 ), // #454
+ INST(Fabd_v , FSimdVVV , (0b0111111010100000110101, kHF_C, 0b0010111010100000110101, kHF_C) , kRWI_W , 0 , 0 ), // #455
+ INST(Fabs_v , FSimdVV , (0b0001111000100000110000, kHF_A, 0b0000111010100000111110, kHF_B) , kRWI_W , 0 , 0 ), // #456
+ INST(Facge_v , FSimdVVV , (0b0111111000100000111011, kHF_C, 0b0010111000100000111011, kHF_C) , kRWI_W , 0 , 1 ), // #457
+ INST(Facgt_v , FSimdVVV , (0b0111111010100000111011, kHF_C, 0b0010111010100000111011, kHF_C) , kRWI_W , 0 , 2 ), // #458
+ INST(Fadd_v , FSimdVVV , (0b0001111000100000001010, kHF_A, 0b0000111000100000110101, kHF_C) , kRWI_W , 0 , 3 ), // #459
+ INST(Faddp_v , FSimdPair , (0b0111111000110000110110, 0b0010111000100000110101) , kRWI_W , 0 , 0 ), // #460
+ INST(Fcadd_v , SimdFcadd , (0b0010111000000000111001) , kRWI_W , 0 , 0 ), // #461
+ INST(Fccmp_v , SimdFccmpFccmpe , (0b00011110001000000000010000000000) , kRWI_R , 0 , 0 ), // #462
+ INST(Fccmpe_v , SimdFccmpFccmpe , (0b00011110001000000000010000010000) , kRWI_R , 0 , 1 ), // #463
+ INST(Fcmeq_v , SimdFcm , (0b0000111000100000111001, kHF_C, 0b0000111010100000110110) , kRWI_W , 0 , 0 ), // #464
+ INST(Fcmge_v , SimdFcm , (0b0010111000100000111001, kHF_C, 0b0010111010100000110010) , kRWI_W , 0 , 1 ), // #465
+ INST(Fcmgt_v , SimdFcm , (0b0010111010100000111001, kHF_C, 0b0000111010100000110010) , kRWI_W , 0 , 2 ), // #466
+ INST(Fcmla_v , SimdFcmla , (0b0010111000000000110001, 0b0010111100000000000100) , kRWI_X , 0 , 0 ), // #467
+ INST(Fcmle_v , SimdFcm , (0b0000000000000000000000, kHF_C, 0b0010111010100000110110) , kRWI_W , 0 , 3 ), // #468
+ INST(Fcmlt_v , SimdFcm , (0b0000000000000000000000, kHF_C, 0b0000111010100000111010) , kRWI_W , 0 , 4 ), // #469
+ INST(Fcmp_v , SimdFcmpFcmpe , (0b00011110001000000010000000000000) , kRWI_R , 0 , 0 ), // #470
+ INST(Fcmpe_v , SimdFcmpFcmpe , (0b00011110001000000010000000010000) , kRWI_R , 0 , 1 ), // #471
+ INST(Fcsel_v , SimdFcsel , (_) , kRWI_W , 0 , 0 ), // #472
+ INST(Fcvt_v , SimdFcvt , (_) , kRWI_W , 0 , 0 ), // #473
+ INST(Fcvtas_v , SimdFcvtSV , (0b0000111000100001110010, 0b0000000000000000000000, 0b0001111000100100000000, 1) , kRWI_W , 0 , 0 ), // #474
+ INST(Fcvtau_v , SimdFcvtSV , (0b0010111000100001110010, 0b0000000000000000000000, 0b0001111000100101000000, 1) , kRWI_W , 0 , 1 ), // #475
+ INST(Fcvtl_v , SimdFcvtLN , (0b0000111000100001011110, 0, 0) , kRWI_W , F(Long) , 0 ), // #476
+ INST(Fcvtl2_v , SimdFcvtLN , (0b0100111000100001011110, 0, 0) , kRWI_W , F(Long) , 1 ), // #477
+ INST(Fcvtms_v , SimdFcvtSV , (0b0000111000100001101110, 0b0000000000000000000000, 0b0001111000110000000000, 1) , kRWI_W , 0 , 2 ), // #478
+ INST(Fcvtmu_v , SimdFcvtSV , (0b0010111000100001101110, 0b0000000000000000000000, 0b0001111000110001000000, 1) , kRWI_W , 0 , 3 ), // #479
+ INST(Fcvtn_v , SimdFcvtLN , (0b0000111000100001011010, 0, 0) , kRWI_W , F(Narrow) , 2 ), // #480
+ INST(Fcvtn2_v , SimdFcvtLN , (0b0100111000100001011010, 0, 0) , kRWI_X , F(Narrow) , 3 ), // #481
+ INST(Fcvtns_v , SimdFcvtSV , (0b0000111000100001101010, 0b0000000000000000000000, 0b0001111000100000000000, 1) , kRWI_W , 0 , 4 ), // #482
+ INST(Fcvtnu_v , SimdFcvtSV , (0b0010111000100001101010, 0b0000000000000000000000, 0b0001111000100001000000, 1) , kRWI_W , 0 , 5 ), // #483
+ INST(Fcvtps_v , SimdFcvtSV , (0b0000111010100001101010, 0b0000000000000000000000, 0b0001111000101000000000, 1) , kRWI_W , 0 , 6 ), // #484
+ INST(Fcvtpu_v , SimdFcvtSV , (0b0010111010100001101010, 0b0000000000000000000000, 0b0001111000101001000000, 1) , kRWI_W , 0 , 7 ), // #485
+ INST(Fcvtxn_v , SimdFcvtLN , (0b0010111000100001011010, 1, 1) , kRWI_W , F(Narrow) , 4 ), // #486
+ INST(Fcvtxn2_v , SimdFcvtLN , (0b0110111000100001011010, 1, 0) , kRWI_X , F(Narrow) , 5 ), // #487
+ INST(Fcvtzs_v , SimdFcvtSV , (0b0000111010100001101110, 0b0000111100000000111111, 0b0001111000111000000000, 1) , kRWI_W , 0 , 8 ), // #488
+ INST(Fcvtzu_v , SimdFcvtSV , (0b0010111010100001101110, 0b0010111100000000111111, 0b0001111000111001000000, 1) , kRWI_W , 0 , 9 ), // #489
+ INST(Fdiv_v , FSimdVVV , (0b0001111000100000000110, kHF_A, 0b0010111000100000111111, kHF_C) , kRWI_W , 0 , 4 ), // #490
+ INST(Fjcvtzs_v , ISimdVVx , (0b0001111001111110000000, kOp_GpW, kOp_D) , kRWI_W , 0 , 7 ), // #491
+ INST(Fmadd_v , FSimdVVVV , (0b0001111100000000000000, kHF_A, 0b0000000000000000000000, kHF_N) , kRWI_W , 0 , 0 ), // #492
+ INST(Fmax_v , FSimdVVV , (0b0001111000100000010010, kHF_A, 0b0000111000100000111101, kHF_C) , kRWI_W , 0 , 5 ), // #493
+ INST(Fmaxnm_v , FSimdVVV , (0b0001111000100000011010, kHF_A, 0b0000111000100000110001, kHF_C) , kRWI_W , 0 , 6 ), // #494
+ INST(Fmaxnmp_v , FSimdPair , (0b0111111000110000110010, 0b0010111000100000110001) , kRWI_W , 0 , 1 ), // #495
+ INST(Fmaxnmv_v , FSimdSV , (0b0010111000110000110010) , kRWI_W , 0 , 0 ), // #496
+ INST(Fmaxp_v , FSimdPair , (0b0111111000110000111110, 0b0010111000100000111101) , kRWI_W , 0 , 2 ), // #497
+ INST(Fmaxv_v , FSimdSV , (0b0010111000110000111110) , kRWI_W , 0 , 1 ), // #498
+ INST(Fmin_v , FSimdVVV , (0b0001111000100000010110, kHF_A, 0b0000111010100000111101, kHF_C) , kRWI_W , 0 , 7 ), // #499
+ INST(Fminnm_v , FSimdVVV , (0b0001111000100000011110, kHF_A, 0b0000111010100000110001, kHF_C) , kRWI_W , 0 , 8 ), // #500
+ INST(Fminnmp_v , FSimdPair , (0b0111111010110000110010, 0b0010111010100000110001) , kRWI_W , 0 , 3 ), // #501
+ INST(Fminnmv_v , FSimdSV , (0b0010111010110000110010) , kRWI_W , 0 , 2 ), // #502
+ INST(Fminp_v , FSimdPair , (0b0111111010110000111110, 0b0010111010100000111101) , kRWI_W , 0 , 4 ), // #503
+ INST(Fminv_v , FSimdSV , (0b0010111010110000111110) , kRWI_W , 0 , 3 ), // #504
+ INST(Fmla_v , FSimdVVVe , (0b0000000000000000000000, kHF_N, 0b0000111000100000110011, 0b0000111110000000000100) , kRWI_X , F(VH0_15) , 0 ), // #505
+ INST(Fmlal_v , SimdFmlal , (0b0000111000100000111011, 0b0000111110000000000000, 1, kET_S, kET_H, kET_H) , kRWI_X , F(VH0_15) , 2 ), // #506
+ INST(Fmlal2_v , SimdFmlal , (0b0010111000100000110011, 0b0010111110000000100000, 1, kET_S, kET_H, kET_H) , kRWI_X , F(VH0_15) , 3 ), // #507
+ INST(Fmls_v , FSimdVVVe , (0b0000000000000000000000, kHF_N, 0b0000111010100000110011, 0b0000111110000000010100) , kRWI_X , F(VH0_15) , 1 ), // #508
+ INST(Fmlsl_v , SimdFmlal , (0b0000111010100000111011, 0b0000111110000000010000, 1, kET_S, kET_H, kET_H) , kRWI_X , F(VH0_15) , 4 ), // #509
+ INST(Fmlsl2_v , SimdFmlal , (0b0010111010100000110011, 0b0010111110000000110000, 1, kET_S, kET_H, kET_H) , kRWI_X , F(VH0_15) , 5 ), // #510
+ INST(Fmov_v , SimdFmov , (_) , kRWI_W , 0 , 0 ), // #511
+ INST(Fmsub_v , FSimdVVVV , (0b0001111100000000100000, kHF_A, 0b0000000000000000000000, kHF_N) , kRWI_W , 0 , 1 ), // #512
+ INST(Fmul_v , FSimdVVVe , (0b0001111000100000000010, kHF_A, 0b0010111000100000110111, 0b0000111110000000100100) , kRWI_W , F(VH0_15) , 2 ), // #513
+ INST(Fmulx_v , FSimdVVVe , (0b0101111000100000110111, kHF_C, 0b0000111000100000110111, 0b0010111110000000100100) , kRWI_W , F(VH0_15) , 3 ), // #514
+ INST(Fneg_v , FSimdVV , (0b0001111000100001010000, kHF_A, 0b0010111010100000111110, kHF_B) , kRWI_W , 0 , 1 ), // #515
+ INST(Fnmadd_v , FSimdVVVV , (0b0001111100100000000000, kHF_A, 0b0000000000000000000000, kHF_N) , kRWI_W , 0 , 2 ), // #516
+ INST(Fnmsub_v , FSimdVVVV , (0b0001111100100000100000, kHF_A, 0b0000000000000000000000, kHF_N) , kRWI_W , 0 , 3 ), // #517
+ INST(Fnmul_v , FSimdVVV , (0b0001111000100000100010, kHF_A, 0b0000000000000000000000, kHF_N) , kRWI_W , 0 , 9 ), // #518
+ INST(Frecpe_v , FSimdVV , (0b0101111010100001110110, kHF_B, 0b0000111010100001110110, kHF_B) , kRWI_W , 0 , 2 ), // #519
+ INST(Frecps_v , FSimdVVV , (0b0101111000100000111111, kHF_C, 0b0000111000100000111111, kHF_C) , kRWI_W , 0 , 10 ), // #520
+ INST(Frecpx_v , FSimdVV , (0b0101111010100001111110, kHF_B, 0b0000000000000000000000, kHF_N) , kRWI_W , 0 , 3 ), // #521
+ INST(Frint32x_v , FSimdVV , (0b0001111000101000110000, kHF_N, 0b0010111000100001111010, kHF_N) , kRWI_W , 0 , 4 ), // #522
+ INST(Frint32z_v , FSimdVV , (0b0001111000101000010000, kHF_N, 0b0000111000100001111010, kHF_N) , kRWI_W , 0 , 5 ), // #523
+ INST(Frint64x_v , FSimdVV , (0b0001111000101001110000, kHF_N, 0b0010111000100001111110, kHF_N) , kRWI_W , 0 , 6 ), // #524
+ INST(Frint64z_v , FSimdVV , (0b0001111000101001010000, kHF_N, 0b0000111000100001111110, kHF_N) , kRWI_W , 0 , 7 ), // #525
+ INST(Frinta_v , FSimdVV , (0b0001111000100110010000, kHF_A, 0b0010111000100001100010, kHF_B) , kRWI_W , 0 , 8 ), // #526
+ INST(Frinti_v , FSimdVV , (0b0001111000100111110000, kHF_A, 0b0010111010100001100110, kHF_B) , kRWI_W , 0 , 9 ), // #527
+ INST(Frintm_v , FSimdVV , (0b0001111000100101010000, kHF_A, 0b0000111000100001100110, kHF_B) , kRWI_W , 0 , 10 ), // #528
+ INST(Frintn_v , FSimdVV , (0b0001111000100100010000, kHF_A, 0b0000111000100001100010, kHF_B) , kRWI_W , 0 , 11 ), // #529
+ INST(Frintp_v , FSimdVV , (0b0001111000100100110000, kHF_A, 0b0000111010100001100010, kHF_B) , kRWI_W , 0 , 12 ), // #530
+ INST(Frintx_v , FSimdVV , (0b0001111000100111010000, kHF_A, 0b0010111000100001100110, kHF_B) , kRWI_W , 0 , 13 ), // #531
+ INST(Frintz_v , FSimdVV , (0b0001111000100101110000, kHF_A, 0b0000111010100001100110, kHF_B) , kRWI_W , 0 , 14 ), // #532
+ INST(Frsqrte_v , FSimdVV , (0b0111111010100001110110, kHF_B, 0b0010111010100001110110, kHF_B) , kRWI_W , 0 , 15 ), // #533
+ INST(Frsqrts_v , FSimdVVV , (0b0101111010100000111111, kHF_C, 0b0000111010100000111111, kHF_C) , kRWI_W , 0 , 11 ), // #534
+ INST(Fsqrt_v , FSimdVV , (0b0001111000100001110000, kHF_A, 0b0010111010100001111110, kHF_B) , kRWI_W , 0 , 16 ), // #535
+ INST(Fsub_v , FSimdVVV , (0b0001111000100000001110, kHF_A, 0b0000111010100000110101, kHF_C) , kRWI_W , 0 , 12 ), // #536
+ INST(Ins_v , SimdIns , (_) , kRWI_X , 0 , 0 ), // #537
+ INST(Ld1_v , SimdLdNStN , (0b0000110101000000000000, 0b0000110001000000001000, 1, 0) , kRWI_LDn , F(Consecutive) , 0 ), // #538
+ INST(Ld1r_v , SimdLdNStN , (0b0000110101000000110000, 0b0000000000000000000000, 1, 1) , kRWI_LDn , F(Consecutive) , 1 ), // #539
+ INST(Ld2_v , SimdLdNStN , (0b0000110101100000000000, 0b0000110001000000100000, 2, 0) , kRWI_LDn , F(Consecutive) , 2 ), // #540
+ INST(Ld2r_v , SimdLdNStN , (0b0000110101100000110000, 0b0000000000000000000000, 2, 1) , kRWI_LDn , F(Consecutive) , 3 ), // #541
+ INST(Ld3_v , SimdLdNStN , (0b0000110101000000001000, 0b0000110001000000010000, 3, 0) , kRWI_LDn , F(Consecutive) , 4 ), // #542
+ INST(Ld3r_v , SimdLdNStN , (0b0000110101000000111000, 0b0000000000000000000000, 3, 1) , kRWI_LDn , F(Consecutive) , 5 ), // #543
+ INST(Ld4_v , SimdLdNStN , (0b0000110101100000001000, 0b0000110001000000000000, 4, 0) , kRWI_LDn , F(Consecutive) , 6 ), // #544
+ INST(Ld4r_v , SimdLdNStN , (0b0000110101100000111000, 0b0000000000000000000000, 4, 1) , kRWI_LDn , F(Consecutive) , 7 ), // #545
+ INST(Ldnp_v , SimdLdpStp , (0b0010110001, 0b0000000000) , kRWI_WW , 0 , 0 ), // #546
+ INST(Ldp_v , SimdLdpStp , (0b0010110101, 0b0010110011) , kRWI_WW , 0 , 1 ), // #547
+ INST(Ldr_v , SimdLdSt , (0b0011110101, 0b00111100010, 0b00111100011, 0b00011100, Inst::kIdLdur_v) , kRWI_W , 0 , 0 ), // #548
+ INST(Ldur_v , SimdLdurStur , (0b0011110001000000000000) , kRWI_W , 0 , 0 ), // #549
+ INST(Mla_v , ISimdVVVe , (0b0000111000100000100101, kVO_V_BHS, 0b0010111100000000000000, kVO_V_HS) , kRWI_X , F(VH0_15) , 0 ), // #550
+ INST(Mls_v , ISimdVVVe , (0b0010111000100000100101, kVO_V_BHS, 0b0010111100000000010000, kVO_V_HS) , kRWI_X , F(VH0_15) , 1 ), // #551
+ INST(Mov_v , SimdMov , (_) , kRWI_W , 0 , 0 ), // #552
+ INST(Movi_v , SimdMoviMvni , (0b0000111100000000000001, 0) , kRWI_W , 0 , 0 ), // #553
+ INST(Mul_v , ISimdVVVe , (0b0000111000100000100111, kVO_V_BHS, 0b0000111100000000100000, kVO_V_HS) , kRWI_W , F(VH0_15) , 2 ), // #554
+ INST(Mvn_v , ISimdVV , (0b0010111000100000010110, kVO_V_B) , kRWI_W , 0 , 4 ), // #555
+ INST(Mvni_v , SimdMoviMvni , (0b0000111100000000000001, 1) , kRWI_W , 0 , 1 ), // #556
+ INST(Neg_v , ISimdVV , (0b0010111000100000101110, kVO_V_Any) , kRWI_W , 0 , 5 ), // #557
+ INST(Not_v , ISimdVV , (0b0010111000100000010110, kVO_V_B) , kRWI_W , 0 , 6 ), // #558
+ INST(Orn_v , ISimdVVV , (0b0000111011100000000111, kVO_V_B) , kRWI_W , 0 , 9 ), // #559
+ INST(Orr_v , SimdBicOrr , (0b0000111010100000000111, 0b0000111100000000000001) , kRWI_W , 0 , 1 ), // #560
+ INST(Pmul_v , ISimdVVV , (0b0010111000100000100111, kVO_V_B) , kRWI_W , 0 , 10 ), // #561
+ INST(Pmull_v , ISimdVVV , (0b0000111000100000111000, kVO_V_B8D1) , kRWI_W , F(Long) , 11 ), // #562
+ INST(Pmull2_v , ISimdVVV , (0b0100111000100000111000, kVO_V_B16D2) , kRWI_W , F(Long) , 12 ), // #563
+ INST(Raddhn_v , ISimdVVV , (0b0010111000100000010000, kVO_V_B8H4S2) , kRWI_W , F(Narrow) , 13 ), // #564
+ INST(Raddhn2_v , ISimdVVV , (0b0110111000100000010000, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 14 ), // #565
+ INST(Rax1_v , ISimdVVV , (0b1100111001100000100011, kVO_V_D2) , kRWI_W , 0 , 15 ), // #566
+ INST(Rbit_v , ISimdVV , (0b0010111001100000010110, kVO_V_B) , kRWI_W , 0 , 7 ), // #567
+ INST(Rev16_v , ISimdVV , (0b0000111000100000000110, kVO_V_B) , kRWI_W , 0 , 8 ), // #568
+ INST(Rev32_v , ISimdVV , (0b0010111000100000000010, kVO_V_BH) , kRWI_W , 0 , 9 ), // #569
+ INST(Rev64_v , ISimdVV , (0b0000111000100000000010, kVO_V_BHS) , kRWI_W , 0 , 10 ), // #570
+ INST(Rshrn_v , SimdShift , (0b0000000000000000000000, 0b0000111100000000100011, 1, kVO_V_B8H4S2) , kRWI_W , F(Narrow) , 0 ), // #571
+ INST(Rshrn2_v , SimdShift , (0b0000000000000000000000, 0b0100111100000000100011, 1, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 1 ), // #572
+ INST(Rsubhn_v , ISimdVVV , (0b0010111000100000011000, kVO_V_B8H4S2) , kRWI_W , F(Narrow) , 16 ), // #573
+ INST(Rsubhn2_v , ISimdVVV , (0b0110111000100000011000, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 17 ), // #574
+ INST(Saba_v , ISimdVVV , (0b0000111000100000011111, kVO_V_BHS) , kRWI_X , 0 , 18 ), // #575
+ INST(Sabal_v , ISimdVVV , (0b0000111000100000010100, kVO_V_B8H4S2) , kRWI_X , F(Long) , 19 ), // #576
+ INST(Sabal2_v , ISimdVVV , (0b0100111000100000010100, kVO_V_B16H8S4) , kRWI_X , F(Long) , 20 ), // #577
+ INST(Sabd_v , ISimdVVV , (0b0000111000100000011101, kVO_V_BHS) , kRWI_W , 0 , 21 ), // #578
+ INST(Sabdl_v , ISimdVVV , (0b0000111000100000011100, kVO_V_B8H4S2) , kRWI_W , F(Long) , 22 ), // #579
+ INST(Sabdl2_v , ISimdVVV , (0b0100111000100000011100, kVO_V_B16H8S4) , kRWI_W , F(Long) , 23 ), // #580
+ INST(Sadalp_v , ISimdVV , (0b0000111000100000011010, kVO_V_BHS) , kRWI_X , F(Long) | F(Pair) , 11 ), // #581
+ INST(Saddl_v , ISimdVVV , (0b0000111000100000000000, kVO_V_B8H4S2) , kRWI_W , F(Long) , 24 ), // #582
+ INST(Saddl2_v , ISimdVVV , (0b0100111000100000000000, kVO_V_B16H8S4) , kRWI_W , F(Long) , 25 ), // #583
+ INST(Saddlp_v , ISimdVV , (0b0000111000100000001010, kVO_V_BHS) , kRWI_W , F(Long) | F(Pair) , 12 ), // #584
+ INST(Saddlv_v , ISimdSV , (0b0000111000110000001110, kVO_V_BH_4S) , kRWI_W , F(Long) , 1 ), // #585
+ INST(Saddw_v , ISimdWWV , (0b0000111000100000000100, kVO_V_B8H4S2) , kRWI_W , 0 , 0 ), // #586
+ INST(Saddw2_v , ISimdWWV , (0b0000111000100000000100, kVO_V_B16H8S4) , kRWI_W , 0 , 1 ), // #587
+ INST(Scvtf_v , SimdFcvtSV , (0b0000111000100001110110, 0b0000111100000000111001, 0b0001111000100010000000, 0) , kRWI_W , 0 , 10 ), // #588
+ INST(Sdot_v , SimdDot , (0b0000111010000000100101, 0b0000111110000000111000, kET_S, kET_B, kET_4B) , kRWI_X , 0 , 1 ), // #589
+ INST(Sha1c_v , ISimdVVVx , (0b0101111000000000000000, kOp_Q, kOp_S, kOp_V4S) , kRWI_X , 0 , 1 ), // #590
+ INST(Sha1h_v , ISimdVVx , (0b0101111000101000000010, kOp_S, kOp_S) , kRWI_W , 0 , 8 ), // #591
+ INST(Sha1m_v , ISimdVVVx , (0b0101111000000000001000, kOp_Q, kOp_S, kOp_V4S) , kRWI_X , 0 , 2 ), // #592
+ INST(Sha1p_v , ISimdVVVx , (0b0101111000000000000100, kOp_Q, kOp_S, kOp_V4S) , kRWI_X , 0 , 3 ), // #593
+ INST(Sha1su0_v , ISimdVVVx , (0b0101111000000000001100, kOp_V4S, kOp_V4S, kOp_V4S) , kRWI_X , 0 , 4 ), // #594
+ INST(Sha1su1_v , ISimdVVx , (0b0101111000101000000110, kOp_V4S, kOp_V4S) , kRWI_X , 0 , 9 ), // #595
+ INST(Sha256h_v , ISimdVVVx , (0b0101111000000000010000, kOp_Q, kOp_Q, kOp_V4S) , kRWI_X , 0 , 5 ), // #596
+ INST(Sha256h2_v , ISimdVVVx , (0b0101111000000000010100, kOp_Q, kOp_Q, kOp_V4S) , kRWI_X , 0 , 6 ), // #597
+ INST(Sha256su0_v , ISimdVVx , (0b0101111000101000001010, kOp_V4S, kOp_V4S) , kRWI_X , 0 , 10 ), // #598
+ INST(Sha256su1_v , ISimdVVVx , (0b0101111000000000011000, kOp_V4S, kOp_V4S, kOp_V4S) , kRWI_X , 0 , 7 ), // #599
+ INST(Sha512h_v , ISimdVVVx , (0b1100111001100000100000, kOp_Q, kOp_Q, kOp_V2D) , kRWI_X , 0 , 8 ), // #600
+ INST(Sha512h2_v , ISimdVVVx , (0b1100111001100000100001, kOp_Q, kOp_Q, kOp_V2D) , kRWI_X , 0 , 9 ), // #601
+ INST(Sha512su0_v , ISimdVVx , (0b1100111011000000100000, kOp_V2D, kOp_V2D) , kRWI_X , 0 , 11 ), // #602
+ INST(Sha512su1_v , ISimdVVVx , (0b1100111001100000100010, kOp_V2D, kOp_V2D, kOp_V2D) , kRWI_X , 0 , 10 ), // #603
+ INST(Shadd_v , ISimdVVV , (0b0000111000100000000001, kVO_V_BHS) , kRWI_W , 0 , 26 ), // #604
+ INST(Shl_v , SimdShift , (0b0000000000000000000000, 0b0000111100000000010101, 0, kVO_V_Any) , kRWI_W , 0 , 2 ), // #605
+ INST(Shll_v , SimdShiftES , (0b0010111000100001001110, kVO_V_B8H4S2) , kRWI_W , F(Long) , 0 ), // #606
+ INST(Shll2_v , SimdShiftES , (0b0110111000100001001110, kVO_V_B16H8S4) , kRWI_W , F(Long) , 1 ), // #607
+ INST(Shrn_v , SimdShift , (0b0000000000000000000000, 0b0000111100000000100001, 1, kVO_V_B8H4S2) , kRWI_W , F(Narrow) , 3 ), // #608
+ INST(Shrn2_v , SimdShift , (0b0000000000000000000000, 0b0100111100000000100001, 1, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 4 ), // #609
+ INST(Shsub_v , ISimdVVV , (0b0000111000100000001001, kVO_V_BHS) , kRWI_W , 0 , 27 ), // #610
+ INST(Sli_v , SimdShift , (0b0000000000000000000000, 0b0010111100000000010101, 0, kVO_V_Any) , kRWI_X , 0 , 5 ), // #611
+ INST(Sm3partw1_v , ISimdVVVx , (0b1100111001100000110000, kOp_V4S, kOp_V4S, kOp_V4S) , kRWI_X , 0 , 11 ), // #612
+ INST(Sm3partw2_v , ISimdVVVx , (0b1100111001100000110001, kOp_V4S, kOp_V4S, kOp_V4S) , kRWI_X , 0 , 12 ), // #613
+ INST(Sm3ss1_v , ISimdVVVVx , (0b1100111001000000000000, kOp_V4S, kOp_V4S, kOp_V4S, kOp_V4S) , kRWI_W , 0 , 0 ), // #614
+ INST(Sm3tt1a_v , SimdSm3tt , (0b1100111001000000100000) , kRWI_X , 0 , 0 ), // #615
+ INST(Sm3tt1b_v , SimdSm3tt , (0b1100111001000000100001) , kRWI_X , 0 , 1 ), // #616
+ INST(Sm3tt2a_v , SimdSm3tt , (0b1100111001000000100010) , kRWI_X , 0 , 2 ), // #617
+ INST(Sm3tt2b_v , SimdSm3tt , (0b1100111001000000100011) , kRWI_X , 0 , 3 ), // #618
+ INST(Sm4e_v , ISimdVVx , (0b1100111011000000100001, kOp_V4S, kOp_V4S) , kRWI_X , 0 , 12 ), // #619
+ INST(Sm4ekey_v , ISimdVVVx , (0b1100111001100000110010, kOp_V4S, kOp_V4S, kOp_V4S) , kRWI_X , 0 , 13 ), // #620
+ INST(Smax_v , ISimdVVV , (0b0000111000100000011001, kVO_V_BHS) , kRWI_W , 0 , 28 ), // #621
+ INST(Smaxp_v , ISimdVVV , (0b0000111000100000101001, kVO_V_BHS) , kRWI_W , 0 , 29 ), // #622
+ INST(Smaxv_v , ISimdSV , (0b0000111000110000101010, kVO_V_BH_4S) , kRWI_W , 0 , 2 ), // #623
+ INST(Smin_v , ISimdVVV , (0b0000111000100000011011, kVO_V_BHS) , kRWI_W , 0 , 30 ), // #624
+ INST(Sminp_v , ISimdVVV , (0b0000111000100000101011, kVO_V_BHS) , kRWI_W , 0 , 31 ), // #625
+ INST(Sminv_v , ISimdSV , (0b0000111000110001101010, kVO_V_BH_4S) , kRWI_W , 0 , 3 ), // #626
+ INST(Smlal_v , ISimdVVVe , (0b0000111000100000100000, kVO_V_B8H4S2, 0b0000111100000000001000, kVO_V_H4S2) , kRWI_X , F(Long) | F(VH0_15) , 3 ), // #627
+ INST(Smlal2_v , ISimdVVVe , (0b0100111000100000100000, kVO_V_B16H8S4, 0b0100111100000000001000, kVO_V_H8S4) , kRWI_X , F(Long) | F(VH0_15) , 4 ), // #628
+ INST(Smlsl_v , ISimdVVVe , (0b0000111000100000101000, kVO_V_B8H4S2, 0b0000111100000000011000, kVO_V_H4S2) , kRWI_X , F(Long) | F(VH0_15) , 5 ), // #629
+ INST(Smlsl2_v , ISimdVVVe , (0b0100111000100000101000, kVO_V_B16H8S4, 0b0100111100000000011000, kVO_V_H8S4) , kRWI_X , F(Long) | F(VH0_15) , 6 ), // #630
+ INST(Smmla_v , ISimdVVVx , (0b0100111010000000101001, kOp_V4S, kOp_V16B, kOp_V16B) , kRWI_X , 0 , 14 ), // #631
+ INST(Smov_v , SimdSmovUmov , (0b0000111000000000001011, kVO_V_BHS, 1) , kRWI_W , 0 , 0 ), // #632
+ INST(Smull_v , ISimdVVVe , (0b0000111000100000110000, kVO_V_B8H4S2, 0b0000111100000000101000, kVO_V_H4S2) , kRWI_W , F(Long) | F(VH0_15) , 7 ), // #633
+ INST(Smull2_v , ISimdVVVe , (0b0100111000100000110000, kVO_V_B16H8S4, 0b0100111100000000101000, kVO_V_H8S4) , kRWI_W , F(Long) | F(VH0_15) , 8 ), // #634
+ INST(Sqabs_v , ISimdVV , (0b0000111000100000011110, kVO_SV_Any) , kRWI_W , 0 , 13 ), // #635
+ INST(Sqadd_v , ISimdVVV , (0b0000111000100000000011, kVO_SV_Any) , kRWI_W , 0 , 32 ), // #636
+ INST(Sqdmlal_v , ISimdVVVe , (0b0000111000100000100100, kVO_SV_BHS, 0b0000111100000000001100, kVO_V_H4S2) , kRWI_X , F(Long) | F(VH0_15) , 9 ), // #637
+ INST(Sqdmlal2_v , ISimdVVVe , (0b0100111000100000100100, kVO_V_B16H8S4, 0b0100111100000000001100, kVO_V_H8S4) , kRWI_X , F(Long) | F(VH0_15) , 10 ), // #638
+ INST(Sqdmlsl_v , ISimdVVVe , (0b0000111000100000101100, kVO_SV_BHS, 0b0000111100000000011100, kVO_V_H4S2) , kRWI_X , F(Long) | F(VH0_15) , 11 ), // #639
+ INST(Sqdmlsl2_v , ISimdVVVe , (0b0100111000100000101100, kVO_V_B16H8S4, 0b0100111100000000011100, kVO_V_H8S4) , kRWI_X , F(Long) | F(VH0_15) , 12 ), // #640
+ INST(Sqdmulh_v , ISimdVVVe , (0b0000111000100000101101, kVO_SV_HS, 0b0000111100000000110000, kVO_SV_HS) , kRWI_W , F(VH0_15) , 13 ), // #641
+ INST(Sqdmull_v , ISimdVVVe , (0b0000111000100000110100, kVO_SV_BHS, 0b0000111100000000101100, kVO_V_H4S2) , kRWI_W , F(Long) | F(VH0_15) , 14 ), // #642
+ INST(Sqdmull2_v , ISimdVVVe , (0b0100111000100000110100, kVO_V_B16H8S4, 0b0100111100000000101100, kVO_V_H8S4) , kRWI_W , F(Long) | F(VH0_15) , 15 ), // #643
+ INST(Sqneg_v , ISimdVV , (0b0010111000100000011110, kVO_SV_Any) , kRWI_W , 0 , 14 ), // #644
+ INST(Sqrdmlah_v , ISimdVVVe , (0b0010111000000000100001, kVO_SV_HS, 0b0010111100000000110100, kVO_SV_HS) , kRWI_X , F(VH0_15) , 16 ), // #645
+ INST(Sqrdmlsh_v , ISimdVVVe , (0b0010111000000000100011, kVO_SV_HS, 0b0010111100000000111100, kVO_SV_HS) , kRWI_X , F(VH0_15) , 17 ), // #646
+ INST(Sqrdmulh_v , ISimdVVVe , (0b0010111000100000101101, kVO_SV_HS, 0b0000111100000000110100, kVO_SV_HS) , kRWI_W , F(VH0_15) , 18 ), // #647
+ INST(Sqrshl_v , SimdShift , (0b0000111000100000010111, 0b0000000000000000000000, 1, kVO_SV_Any) , kRWI_W , 0 , 6 ), // #648
+ INST(Sqrshrn_v , SimdShift , (0b0000000000000000000000, 0b0000111100000000100111, 1, kVO_SV_B8H4S2) , kRWI_W , F(Narrow) , 7 ), // #649
+ INST(Sqrshrn2_v , SimdShift , (0b0000000000000000000000, 0b0100111100000000100111, 1, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 8 ), // #650
+ INST(Sqrshrun_v , SimdShift , (0b0000000000000000000000, 0b0010111100000000100011, 1, kVO_SV_B8H4S2) , kRWI_W , F(Narrow) , 9 ), // #651
+ INST(Sqrshrun2_v , SimdShift , (0b0000000000000000000000, 0b0110111100000000100011, 1, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 10 ), // #652
+ INST(Sqshl_v , SimdShift , (0b0000111000100000010011, 0b0000111100000000011101, 0, kVO_SV_Any) , kRWI_W , 0 , 11 ), // #653
+ INST(Sqshlu_v , SimdShift , (0b0000000000000000000000, 0b0010111100000000011001, 0, kVO_SV_Any) , kRWI_W , 0 , 12 ), // #654
+ INST(Sqshrn_v , SimdShift , (0b0000000000000000000000, 0b0000111100000000100101, 1, kVO_SV_B8H4S2) , kRWI_W , F(Narrow) , 13 ), // #655
+ INST(Sqshrn2_v , SimdShift , (0b0000000000000000000000, 0b0100111100000000100101, 1, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 14 ), // #656
+ INST(Sqshrun_v , SimdShift , (0b0000000000000000000000, 0b0010111100000000100001, 1, kVO_SV_B8H4S2) , kRWI_W , F(Narrow) , 15 ), // #657
+ INST(Sqshrun2_v , SimdShift , (0b0000000000000000000000, 0b0110111100000000100001, 1, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 16 ), // #658
+ INST(Sqsub_v , ISimdVVV , (0b0000111000100000001011, kVO_SV_Any) , kRWI_W , 0 , 33 ), // #659
+ INST(Sqxtn_v , ISimdVV , (0b0000111000100001010010, kVO_SV_B8H4S2) , kRWI_W , F(Narrow) , 15 ), // #660
+ INST(Sqxtn2_v , ISimdVV , (0b0100111000100001010010, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 16 ), // #661
+ INST(Sqxtun_v , ISimdVV , (0b0010111000100001001010, kVO_SV_B8H4S2) , kRWI_W , F(Narrow) , 17 ), // #662
+ INST(Sqxtun2_v , ISimdVV , (0b0110111000100001001010, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 18 ), // #663
+ INST(Srhadd_v , ISimdVVV , (0b0000111000100000000101, kVO_V_BHS) , kRWI_W , 0 , 34 ), // #664
+ INST(Sri_v , SimdShift , (0b0000000000000000000000, 0b0010111100000000010001, 1, kVO_V_Any) , kRWI_W , 0 , 17 ), // #665
+ INST(Srshl_v , SimdShift , (0b0000111000100000010101, 0b0000000000000000000000, 0, kVO_V_Any) , kRWI_W , 0 , 18 ), // #666
+ INST(Srshr_v , SimdShift , (0b0000000000000000000000, 0b0000111100000000001001, 1, kVO_V_Any) , kRWI_W , 0 , 19 ), // #667
+ INST(Srsra_v , SimdShift , (0b0000000000000000000000, 0b0000111100000000001101, 1, kVO_V_Any) , kRWI_X , 0 , 20 ), // #668
+ INST(Sshl_v , SimdShift , (0b0000111000100000010001, 0b0000000000000000000000, 0, kVO_V_Any) , kRWI_W , 0 , 21 ), // #669
+ INST(Sshll_v , SimdShift , (0b0000000000000000000000, 0b0000111100000000101001, 0, kVO_V_B8H4S2) , kRWI_W , F(Long) , 22 ), // #670
+ INST(Sshll2_v , SimdShift , (0b0000000000000000000000, 0b0100111100000000101001, 0, kVO_V_B16H8S4) , kRWI_W , F(Long) , 23 ), // #671
+ INST(Sshr_v , SimdShift , (0b0000000000000000000000, 0b0000111100000000000001, 1, kVO_V_Any) , kRWI_W , 0 , 24 ), // #672
+ INST(Ssra_v , SimdShift , (0b0000000000000000000000, 0b0000111100000000000101, 1, kVO_V_Any) , kRWI_X , 0 , 25 ), // #673
+ INST(Ssubl_v , ISimdVVV , (0b0000111000100000001000, kVO_V_B8H4S2) , kRWI_W , F(Long) , 35 ), // #674
+ INST(Ssubl2_v , ISimdVVV , (0b0100111000100000001000, kVO_V_B16H8S4) , kRWI_W , F(Long) , 36 ), // #675
+ INST(Ssubw_v , ISimdWWV , (0b0000111000100000001100, kVO_V_B8H4S2) , kRWI_W , 0 , 2 ), // #676
+ INST(Ssubw2_v , ISimdWWV , (0b0000111000100000001100, kVO_V_B16H8S4) , kRWI_X , 0 , 3 ), // #677
+ INST(St1_v , SimdLdNStN , (0b0000110100000000000000, 0b0000110000000000001000, 1, 0) , kRWI_STn , F(Consecutive) , 8 ), // #678
+ INST(St2_v , SimdLdNStN , (0b0000110100100000000000, 0b0000110000000000100000, 2, 0) , kRWI_STn , F(Consecutive) , 9 ), // #679
+ INST(St3_v , SimdLdNStN , (0b0000110100000000001000, 0b0000110000000000010000, 3, 0) , kRWI_STn , F(Consecutive) , 10 ), // #680
+ INST(St4_v , SimdLdNStN , (0b0000110100100000001000, 0b0000110000000000000000, 4, 0) , kRWI_STn , F(Consecutive) , 11 ), // #681
+ INST(Stnp_v , SimdLdpStp , (0b0010110000, 0b0000000000) , kRWI_RRW , 0 , 2 ), // #682
+ INST(Stp_v , SimdLdpStp , (0b0010110100, 0b0010110010) , kRWI_RRW , 0 , 3 ), // #683
+ INST(Str_v , SimdLdSt , (0b0011110100, 0b00111100000, 0b00111100001, 0b00000000, Inst::kIdStur_v) , kRWI_RW , 0 , 1 ), // #684
+ INST(Stur_v , SimdLdurStur , (0b0011110000000000000000) , kRWI_RW , 0 , 1 ), // #685
+ INST(Sub_v , ISimdVVV , (0b0010111000100000100001, kVO_V_Any) , kRWI_W , 0 , 37 ), // #686
+ INST(Subhn_v , ISimdVVV , (0b0000111000100000011000, kVO_V_B8H4S2) , kRWI_W , F(Narrow) , 38 ), // #687
+ INST(Subhn2_v , ISimdVVV , (0b0000111000100000011000, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 39 ), // #688
+ INST(Sudot_v , SimdDot , (0b0000000000000000000000, 0b0000111100000000111100, kET_S, kET_B, kET_4B) , kRWI_X , 0 , 2 ), // #689
+ INST(Suqadd_v , ISimdVV , (0b0000111000100000001110, kVO_SV_Any) , kRWI_X , 0 , 19 ), // #690
+ INST(Sxtl_v , SimdSxtlUxtl , (0b0000111100000000101001, kVO_V_B8H4S2) , kRWI_W , F(Long) , 0 ), // #691
+ INST(Sxtl2_v , SimdSxtlUxtl , (0b0100111100000000101001, kVO_V_B16H8S4) , kRWI_W , F(Long) , 1 ), // #692
+ INST(Tbl_v , SimdTblTbx , (0b0000111000000000000000) , kRWI_W , 0 , 0 ), // #693
+ INST(Tbx_v , SimdTblTbx , (0b0000111000000000000100) , kRWI_W , 0 , 1 ), // #694
+ INST(Trn1_v , ISimdVVV , (0b0000111000000000001010, kVO_V_BHS_D2) , kRWI_W , 0 , 40 ), // #695
+ INST(Trn2_v , ISimdVVV , (0b0000111000000000011010, kVO_V_BHS_D2) , kRWI_W , 0 , 41 ), // #696
+ INST(Uaba_v , ISimdVVV , (0b0010111000100000011111, kVO_V_BHS) , kRWI_X , 0 , 42 ), // #697
+ INST(Uabal_v , ISimdVVV , (0b0010111000100000010100, kVO_V_B8H4S2) , kRWI_X , F(Long) , 43 ), // #698
+ INST(Uabal2_v , ISimdVVV , (0b0110111000100000010100, kVO_V_B16H8S4) , kRWI_X , F(Long) , 44 ), // #699
+ INST(Uabd_v , ISimdVVV , (0b0010111000100000011101, kVO_V_BHS) , kRWI_W , 0 , 45 ), // #700
+ INST(Uabdl_v , ISimdVVV , (0b0010111000100000011100, kVO_V_B8H4S2) , kRWI_W , F(Long) , 46 ), // #701
+ INST(Uabdl2_v , ISimdVVV , (0b0110111000100000011100, kVO_V_B16H8S4) , kRWI_W , F(Long) , 47 ), // #702
+ INST(Uadalp_v , ISimdVV , (0b0010111000100000011010, kVO_V_BHS) , kRWI_X , F(Long) | F(Pair) , 20 ), // #703
+ INST(Uaddl_v , ISimdVVV , (0b0010111000100000000000, kVO_V_B8H4S2) , kRWI_W , F(Long) , 48 ), // #704
+ INST(Uaddl2_v , ISimdVVV , (0b0110111000100000000000, kVO_V_B16H8S4) , kRWI_W , F(Long) , 49 ), // #705
+ INST(Uaddlp_v , ISimdVV , (0b0010111000100000001010, kVO_V_BHS) , kRWI_W , F(Long) | F(Pair) , 21 ), // #706
+ INST(Uaddlv_v , ISimdSV , (0b0010111000110000001110, kVO_V_BH_4S) , kRWI_W , F(Long) , 4 ), // #707
+ INST(Uaddw_v , ISimdWWV , (0b0010111000100000000100, kVO_V_B8H4S2) , kRWI_W , 0 , 4 ), // #708
+ INST(Uaddw2_v , ISimdWWV , (0b0010111000100000000100, kVO_V_B16H8S4) , kRWI_W , 0 , 5 ), // #709
+ INST(Ucvtf_v , SimdFcvtSV , (0b0010111000100001110110, 0b0010111100000000111001, 0b0001111000100011000000, 0) , kRWI_W , 0 , 11 ), // #710
+ INST(Udot_v , SimdDot , (0b0010111010000000100101, 0b0010111110000000111000, kET_S, kET_B, kET_4B) , kRWI_X , 0 , 3 ), // #711
+ INST(Uhadd_v , ISimdVVV , (0b0010111000100000000001, kVO_V_BHS) , kRWI_W , 0 , 50 ), // #712
+ INST(Uhsub_v , ISimdVVV , (0b0010111000100000001001, kVO_V_BHS) , kRWI_W , 0 , 51 ), // #713
+ INST(Umax_v , ISimdVVV , (0b0010111000100000011001, kVO_V_BHS) , kRWI_W , 0 , 52 ), // #714
+ INST(Umaxp_v , ISimdVVV , (0b0010111000100000101001, kVO_V_BHS) , kRWI_W , 0 , 53 ), // #715
+ INST(Umaxv_v , ISimdSV , (0b0010111000110000101010, kVO_V_BH_4S) , kRWI_W , 0 , 5 ), // #716
+ INST(Umin_v , ISimdVVV , (0b0010111000100000011011, kVO_V_BHS) , kRWI_W , 0 , 54 ), // #717
+ INST(Uminp_v , ISimdVVV , (0b0010111000100000101011, kVO_V_BHS) , kRWI_W , 0 , 55 ), // #718
+ INST(Uminv_v , ISimdSV , (0b0010111000110001101010, kVO_V_BH_4S) , kRWI_W , 0 , 6 ), // #719
+ INST(Umlal_v , ISimdVVVe , (0b0010111000100000100000, kVO_V_B8H4S2, 0b0010111100000000001000, kVO_V_H4S2) , kRWI_X , F(Long) | F(VH0_15) , 19 ), // #720
+ INST(Umlal2_v , ISimdVVVe , (0b0110111000100000100000, kVO_V_B16H8S4, 0b0010111100000000001000, kVO_V_H8S4) , kRWI_X , F(Long) | F(VH0_15) , 20 ), // #721
+ INST(Umlsl_v , ISimdVVVe , (0b0010111000100000101000, kVO_V_B8H4S2, 0b0010111100000000011000, kVO_V_H4S2) , kRWI_X , F(Long) | F(VH0_15) , 21 ), // #722
+ INST(Umlsl2_v , ISimdVVVe , (0b0110111000100000101000, kVO_V_B16H8S4, 0b0110111100000000011000, kVO_V_H8S4) , kRWI_X , F(Long) | F(VH0_15) , 22 ), // #723
+ INST(Ummla_v , ISimdVVVx , (0b0110111010000000101001, kOp_V4S, kOp_V16B, kOp_V16B) , kRWI_X , 0 , 15 ), // #724
+ INST(Umov_v , SimdSmovUmov , (0b0000111000000000001111, kVO_V_Any, 0) , kRWI_W , 0 , 1 ), // #725
+ INST(Umull_v , ISimdVVVe , (0b0010111000100000110000, kVO_V_B8H4S2, 0b0010111100000000101000, kVO_V_H4S2) , kRWI_W , F(Long) | F(VH0_15) , 23 ), // #726
+ INST(Umull2_v , ISimdVVVe , (0b0110111000100000110000, kVO_V_B16H8S4, 0b0110111100000000101000, kVO_V_H8S4) , kRWI_W , F(Long) | F(VH0_15) , 24 ), // #727
+ INST(Uqadd_v , ISimdVVV , (0b0010111000100000000011, kVO_SV_Any) , kRWI_W , 0 , 56 ), // #728
+ INST(Uqrshl_v , SimdShift , (0b0010111000100000010111, 0b0000000000000000000000, 0, kVO_SV_Any) , kRWI_W , 0 , 26 ), // #729
+ INST(Uqrshrn_v , SimdShift , (0b0000000000000000000000, 0b0010111100000000100111, 1, kVO_SV_B8H4S2) , kRWI_W , F(Narrow) , 27 ), // #730
+ INST(Uqrshrn2_v , SimdShift , (0b0000000000000000000000, 0b0110111100000000100111, 1, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 28 ), // #731
+ INST(Uqshl_v , SimdShift , (0b0010111000100000010011, 0b0010111100000000011101, 0, kVO_SV_Any) , kRWI_W , 0 , 29 ), // #732
+ INST(Uqshrn_v , SimdShift , (0b0000000000000000000000, 0b0010111100000000100101, 1, kVO_SV_B8H4S2) , kRWI_W , F(Narrow) , 30 ), // #733
+ INST(Uqshrn2_v , SimdShift , (0b0000000000000000000000, 0b0110111100000000100101, 1, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 31 ), // #734
+ INST(Uqsub_v , ISimdVVV , (0b0010111000100000001011, kVO_SV_Any) , kRWI_W , 0 , 57 ), // #735
+ INST(Uqxtn_v , ISimdVV , (0b0010111000100001010010, kVO_SV_B8H4S2) , kRWI_W , F(Narrow) , 22 ), // #736
+ INST(Uqxtn2_v , ISimdVV , (0b0110111000100001010010, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 23 ), // #737
+ INST(Urecpe_v , ISimdVV , (0b0000111010100001110010, kVO_V_S) , kRWI_W , 0 , 24 ), // #738
+ INST(Urhadd_v , ISimdVVV , (0b0010111000100000000101, kVO_V_BHS) , kRWI_W , 0 , 58 ), // #739
+ INST(Urshl_v , SimdShift , (0b0010111000100000010101, 0b0000000000000000000000, 0, kVO_V_Any) , kRWI_W , 0 , 32 ), // #740
+ INST(Urshr_v , SimdShift , (0b0000000000000000000000, 0b0010111100000000001001, 1, kVO_V_Any) , kRWI_W , 0 , 33 ), // #741
+ INST(Ursqrte_v , ISimdVV , (0b0010111010100001110010, kVO_V_S) , kRWI_W , 0 , 25 ), // #742
+ INST(Ursra_v , SimdShift , (0b0000000000000000000000, 0b0010111100000000001101, 1, kVO_V_Any) , kRWI_X , 0 , 34 ), // #743
+ INST(Usdot_v , SimdDot , (0b0000111010000000100111, 0b0000111110000000111100, kET_S, kET_B, kET_4B) , kRWI_X , 0 , 4 ), // #744
+ INST(Ushl_v , SimdShift , (0b0010111000100000010001, 0b0000000000000000000000, 0, kVO_V_Any) , kRWI_W , 0 , 35 ), // #745
+ INST(Ushll_v , SimdShift , (0b0000000000000000000000, 0b0010111100000000101001, 0, kVO_V_B8H4S2) , kRWI_W , F(Long) , 36 ), // #746
+ INST(Ushll2_v , SimdShift , (0b0000000000000000000000, 0b0110111100000000101001, 0, kVO_V_B16H8S4) , kRWI_W , F(Long) , 37 ), // #747
+ INST(Ushr_v , SimdShift , (0b0000000000000000000000, 0b0010111100000000000001, 1, kVO_V_Any) , kRWI_W , 0 , 38 ), // #748
+ INST(Usmmla_v , ISimdVVVx , (0b0100111010000000101011, kOp_V4S, kOp_V16B, kOp_V16B) , kRWI_X , 0 , 16 ), // #749
+ INST(Usqadd_v , ISimdVV , (0b0010111000100000001110, kVO_SV_Any) , kRWI_X , 0 , 26 ), // #750
+ INST(Usra_v , SimdShift , (0b0000000000000000000000, 0b0010111100000000000101, 1, kVO_V_Any) , kRWI_X , 0 , 39 ), // #751
+ INST(Usubl_v , ISimdVVV , (0b0010111000100000001000, kVO_V_B8H4S2) , kRWI_W , F(Long) , 59 ), // #752
+ INST(Usubl2_v , ISimdVVV , (0b0110111000100000001000, kVO_V_B16H8S4) , kRWI_W , F(Long) , 60 ), // #753
+ INST(Usubw_v , ISimdWWV , (0b0010111000100000001100, kVO_V_B8H4S2) , kRWI_W , 0 , 6 ), // #754
+ INST(Usubw2_v , ISimdWWV , (0b0010111000100000001100, kVO_V_B16H8S4) , kRWI_W , 0 , 7 ), // #755
+ INST(Uxtl_v , SimdSxtlUxtl , (0b0010111100000000101001, kVO_V_B8H4S2) , kRWI_W , F(Long) , 2 ), // #756
+ INST(Uxtl2_v , SimdSxtlUxtl , (0b0110111100000000101001, kVO_V_B16H8S4) , kRWI_W , F(Long) , 3 ), // #757
+ INST(Uzp1_v , ISimdVVV , (0b0000111000000000000110, kVO_V_BHS_D2) , kRWI_W , 0 , 61 ), // #758
+ INST(Uzp2_v , ISimdVVV , (0b0000111000000000010110, kVO_V_BHS_D2) , kRWI_W , 0 , 62 ), // #759
+ INST(Xar_v , ISimdVVVI , (0b1100111001100000100011, kVO_V_D2, 6, 10, 0) , kRWI_W , 0 , 1 ), // #760
+ INST(Xtn_v , ISimdVV , (0b0000111000100001001010, kVO_V_B8H4S2) , kRWI_W , F(Narrow) , 27 ), // #761
+ INST(Xtn2_v , ISimdVV , (0b0100111000100001001010, kVO_V_B16H8S4) , kRWI_X , F(Narrow) , 28 ), // #762
+ INST(Zip1_v , ISimdVVV , (0b0000111000000000001110, kVO_V_BHS_D2) , kRWI_W , 0 , 63 ), // #763
+ INST(Zip2_v , ISimdVVV , (0b0000111000000000011110, kVO_V_BHS_D2) , kRWI_W , 0 , 64 ) // #764
// ${InstInfo:End}
};
@@ -1132,8 +1124,8 @@ const BaseLdSt baseLdSt[9] = {
{ 0b1011100101, 0b10111000010, 0b10111000011, 0b00011000, kWX, 30, 2, Inst::kIdLdur }, // ldr
{ 0b0011100101, 0b00111000010, 0b00111000011, 0 , kW , 0 , 0, Inst::kIdLdurb }, // ldrb
{ 0b0111100101, 0b01111000010, 0b01111000011, 0 , kW , 0 , 1, Inst::kIdLdurh }, // ldrh
- { 0b0011100111, 0b00111000100, 0b00111000101, 0 , kWX, 22, 0, Inst::kIdLdursb }, // ldrsb
- { 0b0111100110, 0b01111000100, 0b01111000101, 0 , kWX, 22, 1, Inst::kIdLdursh }, // ldrsh
+ { 0b0011100111, 0b00111000100, 0b00111000111, 0 , kWX, 22, 0, Inst::kIdLdursb }, // ldrsb
+ { 0b0111100111, 0b01111000100, 0b01111000111, 0 , kWX, 22, 1, Inst::kIdLdursh }, // ldrsh
{ 0b1011100110, 0b10111000100, 0b10111000101, 0b10011000, kX , 0 , 2, Inst::kIdLdursw }, // ldrsw
{ 0b1011100100, 0b10111000000, 0b10111000001, 0 , kWX, 30, 2, Inst::kIdStur }, // str
{ 0b0011100100, 0b00111000000, 0b00111000001, 0 , kW , 30, 0, Inst::kIdSturb }, // strb
@@ -1220,6 +1212,10 @@ const BaseOpImm baseOpImm[14] = {
{ 0b00000000000000000000000000000000, 16, 0 } // udf
};
+const BasePrfm basePrfm[1] = {
+ { 0b11111000101, 0b1111100110, 0b11111000100, 0b11011000 } // prfm
+};
+
const BaseR baseR[10] = {
{ 0b11011010110000010011101111100000, kX, kZR, 0 }, // autdza
{ 0b11011010110000010011111111100000, kX, kZR, 0 }, // autdzb
@@ -1275,7 +1271,7 @@ const BaseRM_SImm9 baseRM_SImm9[23] = {
{ 0b0111100001000000000000, 0b0000000000000000000000, kW , kZR, 0 , 0 }, // ldurh
{ 0b0011100011000000000000, 0b0000000000000000000000, kWX, kZR, 22, 0 }, // ldursb
{ 0b0111100011000000000000, 0b0000000000000000000000, kWX, kZR, 22, 0 }, // ldursh
- { 0b1011100010000000000000, 0b0000000000000000000000, kWX, kZR, 0 , 0 }, // ldursw
+ { 0b1011100010000000000000, 0b0000000000000000000000, kX , kZR, 0 , 0 }, // ldursw
{ 0b1101100110100000000010, 0b1101100110100000000001, kX, kSP, 0, 4 }, // st2g
{ 0b1101100100100000000010, 0b1101100100100000000001, kX, kSP, 0, 4 }, // stg
{ 0b1011100000000000000010, 0b0000000000000000000000, kWX, kZR, 30, 0 }, // sttr
@@ -1852,75 +1848,10 @@ const InstDB::CommonInfo InstDB::commonData[] = {
// ArmUtil - Id <-> Name
// =====================
-#ifndef ASMJIT_DISABLE_TEXT
+#ifndef ASMJIT_NO_TEXT
// ${NameData:Begin}
// ------------------- Automatically generated, do not edit -------------------
-const char InstDB::_nameData[] =
- "\0" "adc\0" "adcs\0" "addg\0" "adds\0" "addv\0" "adr\0" "adrp\0" "aesd\0" "aese\0" "aesimc\0" "aesmc\0" "and\0"
- "ands\0" "asr\0" "asrv\0" "at\0" "autda\0" "autdb\0" "autdza\0" "autdzb\0" "autia\0" "autia1716\0" "autiasp\0"
- "autiaz\0" "autib\0" "autib1716\0" "autibsp\0" "autibz\0" "autiza\0" "autizb\0" "axflag\0" "bcax\0" "bfc\0" "bfcvt\0"
- "bfcvtn\0" "bfcvtn2\0" "bfdot\0" "bfi\0" "bfmlalb\0" "bfmlalt\0" "bfmmla\0" "bfxil\0" "bic\0" "bics\0" "bif\0"
- "blr\0" "br\0" "brk\0" "bsl\0" "cas\0" "casa\0" "casab\0" "casah\0" "casal\0" "casalb\0" "casalh\0" "casb\0" "cash\0"
- "casl\0" "caslb\0" "caslh\0" "casp\0" "caspa\0" "caspal\0" "caspl\0" "cbnz\0" "cbz\0" "ccmn\0" "cfinv\0" "cinc\0"
- "cinv\0" "clrex\0" "cls\0" "clz\0" "cmhi\0" "cmhs\0" "cmpp\0" "cmtst\0" "cneg\0" "cnt\0" "crc32b\0" "crc32cb\0"
- "crc32ch\0" "crc32cw\0" "crc32cx\0" "crc32h\0" "crc32w\0" "crc32x\0" "csdb\0" "cset\0" "csetm\0" "csinc\0" "csinv\0"
- "csneg\0" "dcps1\0" "dcps2\0" "dcps3\0" "dgh\0" "dmb\0" "drps\0" "dsb\0" "dup\0" "eon\0" "eor3\0" "eret\0" "esb\0"
- "ext\0" "extr\0" "fabd\0" "fabs\0" "facge\0" "facgt\0" "fadd\0" "faddp\0" "fcadd\0" "fccmp\0" "fccmpe\0" "fcmeq\0"
- "fcmge\0" "fcmgt\0" "fcmla\0" "fcmle\0" "fcmlt\0" "fcmp\0" "fcmpe\0" "fcsel\0" "fcvtas\0" "fcvtau\0" "fcvtl\0"
- "fcvtl2\0" "fcvtms\0" "fcvtmu\0" "fcvtns\0" "fcvtnu\0" "fcvtps\0" "fcvtpu\0" "fcvtxn\0" "fcvtxn2\0" "fcvtzs\0"
- "fcvtzu\0" "fdiv\0" "fjcvtzs\0" "fmadd\0" "fmax\0" "fmaxnm\0" "fmaxnmp\0" "fmaxnmv\0" "fmaxp\0" "fmaxv\0" "fmin\0"
- "fminnm\0" "fminnmp\0" "fminnmv\0" "fminp\0" "fminv\0" "fmla\0" "fmlal\0" "fmlal2\0" "fmls\0" "fmlsl\0" "fmlsl2\0"
- "fmov\0" "fmsub\0" "fmul\0" "fmulx\0" "fneg\0" "fnmadd\0" "fnmsub\0" "fnmul\0" "frecpe\0" "frecps\0" "frecpx\0"
- "frint32x\0" "frint32z\0" "frint64x\0" "frint64z\0" "frinta\0" "frinti\0" "frintm\0" "frintn\0" "frintp\0" "frintx\0"
- "frintz\0" "frsqrte\0" "frsqrts\0" "fsqrt\0" "fsub\0" "gmi\0" "hint\0" "hlt\0" "hvc\0" "ins\0" "isb\0" "ld1\0"
- "ld1r\0" "ld2\0" "ld2r\0" "ld3\0" "ld3r\0" "ld4\0" "ld4r\0" "ldadd\0" "ldadda\0" "ldaddab\0" "ldaddah\0" "ldaddal\0"
- "ldaddalb\0" "ldaddalh\0" "ldaddb\0" "ldaddh\0" "ldaddl\0" "ldaddlb\0" "ldaddlh\0" "ldar\0" "ldarb\0" "ldarh\0"
- "ldaxp\0" "ldaxr\0" "ldaxrb\0" "ldaxrh\0" "ldclr\0" "ldclra\0" "ldclrab\0" "ldclrah\0" "ldclral\0" "ldclralb\0"
- "ldclralh\0" "ldclrb\0" "ldclrh\0" "ldclrl\0" "ldclrlb\0" "ldclrlh\0" "ldeor\0" "ldeora\0" "ldeorab\0" "ldeorah\0"
- "ldeoral\0" "ldeoralb\0" "ldeoralh\0" "ldeorb\0" "ldeorh\0" "ldeorl\0" "ldeorlb\0" "ldeorlh\0" "ldg\0" "ldgm\0"
- "ldlar\0" "ldlarb\0" "ldlarh\0" "ldnp\0" "ldp\0" "ldpsw\0" "ldr\0" "ldraa\0" "ldrab\0" "ldrb\0" "ldrh\0" "ldrsb\0"
- "ldrsh\0" "ldrsw\0" "ldset\0" "ldseta\0" "ldsetab\0" "ldsetah\0" "ldsetal\0" "ldsetalb\0" "ldsetalh\0" "ldsetb\0"
- "ldseth\0" "ldsetl\0" "ldsetlb\0" "ldsetlh\0" "ldsmax\0" "ldsmaxa\0" "ldsmaxab\0" "ldsmaxah\0" "ldsmaxal\0"
- "ldsmaxalb\0" "ldsmaxalh\0" "ldsmaxb\0" "ldsmaxh\0" "ldsmaxl\0" "ldsmaxlb\0" "ldsmaxlh\0" "ldsmin\0" "ldsmina\0"
- "ldsminab\0" "ldsminah\0" "ldsminal\0" "ldsminalb\0" "ldsminalh\0" "ldsminb\0" "ldsminh\0" "ldsminl\0" "ldsminlb\0"
- "ldsminlh\0" "ldtr\0" "ldtrb\0" "ldtrh\0" "ldtrsb\0" "ldtrsh\0" "ldtrsw\0" "ldumax\0" "ldumaxa\0" "ldumaxab\0"
- "ldumaxah\0" "ldumaxal\0" "ldumaxalb\0" "ldumaxalh\0" "ldumaxb\0" "ldumaxh\0" "ldumaxl\0" "ldumaxlb\0" "ldumaxlh\0"
- "ldumin\0" "ldumina\0" "lduminab\0" "lduminah\0" "lduminal\0" "lduminalb\0" "lduminalh\0" "lduminb\0" "lduminh\0"
- "lduminl\0" "lduminlb\0" "lduminlh\0" "ldur\0" "ldurb\0" "ldurh\0" "ldursb\0" "ldursh\0" "ldursw\0" "ldxp\0" "ldxr\0"
- "ldxrb\0" "ldxrh\0" "lslv\0" "lsr\0" "lsrv\0" "mneg\0" "movi\0" "movk\0" "movn\0" "movz\0" "mrs\0" "msr\0" "mvn\0"
- "mvni\0" "negs\0" "ngc\0" "ngcs\0" "nop\0" "not\0" "orn\0" "orr\0" "pacda\0" "pacdb\0" "pacdza\0" "pacdzb\0"
- "pacga\0" "pmul\0" "pmull\0" "pmull2\0" "pssbb\0" "raddhn\0" "raddhn2\0" "rax1\0" "rbit\0" "rev\0" "rev16\0"
- "rev32\0" "rev64\0" "ror\0" "rorv\0" "rsubhn\0" "rsubhn2\0" "saba\0" "sabal\0" "sabal2\0" "sabd\0" "sabdl\0"
- "sabdl2\0" "sadalp\0" "saddl\0" "saddl2\0" "saddlp\0" "saddlv\0" "saddw\0" "saddw2\0" "sbc\0" "sbcs\0" "sbfiz\0"
- "sbfm\0" "sbfx\0" "scvtf\0" "sdiv\0" "setf16\0" "setf8\0" "sev\0" "sevl\0" "sha1c\0" "sha1h\0" "sha1m\0" "sha1p\0"
- "sha1su0\0" "sha1su1\0" "sha256h\0" "sha256h2\0" "sha256su0\0" "sha256su1\0" "sha512h\0" "sha512h2\0" "sha512su0\0"
- "sha512su1\0" "shadd\0" "shsub\0" "sli\0" "sm3partw1\0" "sm3partw2\0" "sm3ss1\0" "sm3tt1a\0" "sm3tt1b\0" "sm3tt2a\0"
- "sm3tt2b\0" "sm4e\0" "sm4ekey\0" "smaddl\0" "smaxp\0" "smaxv\0" "sminp\0" "sminv\0" "smlal\0" "smlal2\0" "smlsl\0"
- "smlsl2\0" "smnegl\0" "smov\0" "smsubl\0" "smulh\0" "smull\0" "smull2\0" "sqabs\0" "sqdmlal\0" "sqdmlal2\0"
- "sqdmlsl\0" "sqdmlsl2\0" "sqdmulh\0" "sqdmull\0" "sqdmull2\0" "sqneg\0" "sqrdmlah\0" "sqrdmlsh\0" "sqrdmulh\0"
- "sqrshl\0" "sqrshrn\0" "sqrshrn2\0" "sqrshrun\0" "sqrshrun2\0" "sqshl\0" "sqshlu\0" "sqshrn\0" "sqshrn2\0"
- "sqshrun\0" "sqshrun2\0" "sqsub\0" "sqxtn\0" "sqxtn2\0" "sqxtun\0" "sqxtun2\0" "srhadd\0" "sri\0" "srshl\0" "srshr\0"
- "srsra\0" "sshl\0" "sshll\0" "sshll2\0" "sshr\0" "ssra\0" "ssubl\0" "ssubl2\0" "ssubw\0" "ssubw2\0" "st1\0" "st2\0"
- "st2g\0" "st3\0" "st4\0" "stadd\0" "staddb\0" "staddh\0" "staddl\0" "staddlb\0" "staddlh\0" "stclr\0" "stclrb\0"
- "stclrh\0" "stclrl\0" "stclrlb\0" "stclrlh\0" "steor\0" "steorb\0" "steorh\0" "steorl\0" "steorlb\0" "steorlh\0"
- "stg\0" "stgm\0" "stgp\0" "stllr\0" "stllrb\0" "stllrh\0" "stlr\0" "stlrb\0" "stlrh\0" "stlxp\0" "stlxr\0" "stlxrb\0"
- "stlxrh\0" "stnp\0" "stp\0" "str\0" "strb\0" "strh\0" "stset\0" "stsetb\0" "stseth\0" "stsetl\0" "stsetlb\0"
- "stsetlh\0" "stsmax\0" "stsmaxb\0" "stsmaxh\0" "stsmaxl\0" "stsmaxlb\0" "stsmaxlh\0" "stsmin\0" "stsminb\0"
- "stsminh\0" "stsminl\0" "stsminlb\0" "stsminlh\0" "sttr\0" "sttrb\0" "sttrh\0" "stumax\0" "stumaxb\0" "stumaxh\0"
- "stumaxl\0" "stumaxlb\0" "stumaxlh\0" "stumin\0" "stuminb\0" "stuminh\0" "stuminl\0" "stuminlb\0" "stuminlh\0"
- "stur\0" "sturb\0" "sturh\0" "stxp\0" "stxr\0" "stxrb\0" "stxrh\0" "stz2g\0" "stzg\0" "stzgm\0" "subg\0" "subp\0"
- "subps\0" "subs\0" "sudot\0" "suqadd\0" "svc\0" "swp\0" "swpa\0" "swpab\0" "swpah\0" "swpal\0" "swpalb\0" "swpalh\0"
- "swpb\0" "swph\0" "swpl\0" "swplb\0" "swplh\0" "sxtb\0" "sxth\0" "sxtl\0" "sxtl2\0" "sxtw\0" "sys\0" "tbl\0" "tbnz\0"
- "tbx\0" "tbz\0" "tlbi\0" "trn1\0" "trn2\0" "uaba\0" "uabal\0" "uabal2\0" "uabd\0" "uabdl\0" "uabdl2\0" "uadalp\0"
- "uaddl\0" "uaddl2\0" "uaddlp\0" "uaddlv\0" "uaddw\0" "uaddw2\0" "ubfiz\0" "ubfm\0" "ubfx\0" "ucvtf\0" "udf\0"
- "udiv\0" "uhadd\0" "uhsub\0" "umaddl\0" "umaxp\0" "umaxv\0" "uminp\0" "uminv\0" "umlal\0" "umlal2\0" "umlsl\0"
- "umlsl2\0" "ummla\0" "umnegl\0" "umov\0" "umsubl\0" "umulh\0" "umull\0" "umull2\0" "uqrshl\0" "uqrshrn\0"
- "uqrshrn2\0" "uqshl\0" "uqshrn\0" "uqshrn2\0" "uqsub\0" "uqxtn\0" "uqxtn2\0" "urecpe\0" "urhadd\0" "urshl\0"
- "urshr\0" "ursqrte\0" "ursra\0" "usdot\0" "ushl\0" "ushll\0" "ushll2\0" "ushr\0" "usmmla\0" "usqadd\0" "usra\0"
- "usubl\0" "usubl2\0" "usubw\0" "usubw2\0" "uxtb\0" "uxth\0" "uxtl\0" "uxtl2\0" "uzp1\0" "uzp2\0" "wfe\0" "wfi\0"
- "xaflag\0" "xar\0" "xpacd\0" "xpaci\0" "xpaclri\0" "yield\0" "zip1\0" "zip2";
-
-const InstDB::InstNameIndex InstDB::instNameIndex[26] = {
+const InstNameIndex InstDB::instNameIndex = {{
{ Inst::kIdAdc , Inst::kIdAnd_v + 1 },
{ Inst::kIdB , Inst::kIdBsl_v + 1 },
{ Inst::kIdCas , Inst::kIdCnt_v + 1 },
@@ -1947,10 +1878,785 @@ const InstDB::InstNameIndex InstDB::instNameIndex[26] = {
{ Inst::kIdXaflag , Inst::kIdXtn2_v + 1 },
{ Inst::kIdYield , Inst::kIdYield + 1 },
{ Inst::kIdZip1_v , Inst::kIdZip2_v + 1 }
+}, uint16_t(9)};
+
+const char InstDB::_instNameStringTable[] =
+ "autia1716autibldsmaxalhldsminalldumaxallduminalsha256su0sha512su1sm3partwsqrshru"
+ "nldaddalldclralldeoralldsetallbstsmaxstsminstumaxstuminfrint32z64x64zh2sqdmlalsl"
+ "2sqdmulsqrdmlaulhn2sqshruuqrshrspcrc32cstaddstclrsteorstsetxpaclbfcvtbfmlaltfcvt"
+ "xfjcvtzfmaxnmfminnmfrsqrraddrsubsha1sm3tt12a2bsm4ekeysqxtuuqshrursqrsetfrev8";
+
+
+const uint32_t InstDB::_instNameIndexTable[] = {
+ 0x80000000, // Small ''.
+ 0x80000C81, // Small 'adc'.
+ 0x80098C81, // Small 'adcs'.
+ 0x80001081, // Small 'add'.
+ 0x80039081, // Small 'addg'.
+ 0x80099081, // Small 'adds'.
+ 0x80004881, // Small 'adr'.
+ 0x80084881, // Small 'adrp'.
+ 0x800011C1, // Small 'and'.
+ 0x800991C1, // Small 'ands'.
+ 0x80004A61, // Small 'asr'.
+ 0x800B4A61, // Small 'asrv'.
+ 0x80000281, // Small 'at'.
+ 0x801252A1, // Small 'autda'.
+ 0x83A252A1, // Small 'autdza'.
+ 0x802252A1, // Small 'autdb'.
+ 0x85A252A1, // Small 'autdzb'.
+ 0x8014D2A1, // Small 'autia'.
+ 0x00009000, // Large 'autia1716'.
+ 0x20BF5000, // Large 'autia|sp'.
+ 0xB414D2A1, // Small 'autiaz'.
+ 0x8024D2A1, // Small 'autib'.
+ 0x40055009, // Large 'autib|1716'.
+ 0x20BF5009, // Large 'autib|sp'.
+ 0xB424D2A1, // Small 'autibz'.
+ 0x83A4D2A1, // Small 'autiza'.
+ 0x85A4D2A1, // Small 'autizb'.
+ 0x8E161B01, // Small 'axflag'.
+ 0x80000002, // Small 'b'.
+ 0x80000CC2, // Small 'bfc'.
+ 0x800024C2, // Small 'bfi'.
+ 0x800034C2, // Small 'bfm'.
+ 0x80C4E0C2, // Small 'bfxil'.
+ 0x80000D22, // Small 'bic'.
+ 0x80098D22, // Small 'bics'.
+ 0x80000182, // Small 'bl'.
+ 0x80004982, // Small 'blr'.
+ 0x80000242, // Small 'br'.
+ 0x80002E42, // Small 'brk'.
+ 0x80004C23, // Small 'cas'.
+ 0x8000CC23, // Small 'casa'.
+ 0x8020CC23, // Small 'casab'.
+ 0x8080CC23, // Small 'casah'.
+ 0x80C0CC23, // Small 'casal'.
+ 0x84C0CC23, // Small 'casalb'.
+ 0x90C0CC23, // Small 'casalh'.
+ 0x80014C23, // Small 'casb'.
+ 0x80044C23, // Small 'cash'.
+ 0x80064C23, // Small 'casl'.
+ 0x80264C23, // Small 'caslb'.
+ 0x80864C23, // Small 'caslh'.
+ 0x80084C23, // Small 'casp'.
+ 0x80184C23, // Small 'caspa'.
+ 0x98184C23, // Small 'caspal'.
+ 0x80C84C23, // Small 'caspl'.
+ 0x800D3843, // Small 'cbnz'.
+ 0x80006843, // Small 'cbz'.
+ 0x80073463, // Small 'ccmn'.
+ 0x80083463, // Small 'ccmp'.
+ 0x816724C3, // Small 'cfinv'.
+ 0x8001B923, // Small 'cinc'.
+ 0x800B3923, // Small 'cinv'.
+ 0x8182C983, // Small 'clrex'.
+ 0x80004D83, // Small 'cls'.
+ 0x80006983, // Small 'clz'.
+ 0x800039A3, // Small 'cmn'.
+ 0x800041A3, // Small 'cmp'.
+ 0x800841A3, // Small 'cmpp'.
+ 0x800395C3, // Small 'cneg'.
+ 0x85DF0E43, // Small 'crc32b'.
+ 0x100D60C1, // Large 'crc32c|b'.
+ 0x101660C1, // Large 'crc32c|h'.
+ 0x104860C1, // Large 'crc32c|w'.
+ 0x101360C1, // Large 'crc32c|x'.
+ 0x91DF0E43, // Small 'crc32h'.
+ 0xAFDF0E43, // Small 'crc32w'.
+ 0xB1DF0E43, // Small 'crc32x'.
+ 0x80011263, // Small 'csdb'.
+ 0x80061663, // Small 'csel'.
+ 0x800A1663, // Small 'cset'.
+ 0x80DA1663, // Small 'csetm'.
+ 0x80372663, // Small 'csinc'.
+ 0x81672663, // Small 'csinv'.
+ 0x8072BA63, // Small 'csneg'.
+ 0x80000064, // Small 'dc'.
+ 0x81C9C064, // Small 'dcps1'.
+ 0x81D9C064, // Small 'dcps2'.
+ 0x81E9C064, // Small 'dcps3'.
+ 0x800020E4, // Small 'dgh'.
+ 0x800009A4, // Small 'dmb'.
+ 0x8009C244, // Small 'drps'.
+ 0x80000A64, // Small 'dsb'.
+ 0x800039E5, // Small 'eon'.
+ 0x800049E5, // Small 'eor'.
+ 0x80000A65, // Small 'esb'.
+ 0x80095305, // Small 'extr'.
+ 0x800A1645, // Small 'eret'.
+ 0x800025A7, // Small 'gmi'.
+ 0x800A3928, // Small 'hint'.
+ 0x80005188, // Small 'hlt'.
+ 0x80000EC8, // Small 'hvc'.
+ 0x80000069, // Small 'ic'.
+ 0x80000A69, // Small 'isb'.
+ 0x8042048C, // Small 'ldadd'.
+ 0x8242048C, // Small 'ldadda'.
+ 0x100D6051, // Large 'ldadda|b'.
+ 0x10166051, // Large 'ldadda|h'.
+ 0x00007051, // Large 'ldaddal'.
+ 0x100D7051, // Large 'ldaddal|b'.
+ 0x10167051, // Large 'ldaddal|h'.
+ 0x8442048C, // Small 'ldaddb'.
+ 0x9042048C, // Small 'ldaddh'.
+ 0x9842048C, // Small 'ldaddl'.
+ 0x206D5051, // Large 'ldadd|lb'.
+ 0x20155051, // Large 'ldadd|lh'.
+ 0x8009048C, // Small 'ldar'.
+ 0x8029048C, // Small 'ldarb'.
+ 0x8089048C, // Small 'ldarh'.
+ 0x810C048C, // Small 'ldaxp'.
+ 0x812C048C, // Small 'ldaxr'.
+ 0x852C048C, // Small 'ldaxrb'.
+ 0x912C048C, // Small 'ldaxrh'.
+ 0x81260C8C, // Small 'ldclr'.
+ 0x83260C8C, // Small 'ldclra'.
+ 0x100D6058, // Large 'ldclra|b'.
+ 0x10166058, // Large 'ldclra|h'.
+ 0x00007058, // Large 'ldclral'.
+ 0x100D7058, // Large 'ldclral|b'.
+ 0x10167058, // Large 'ldclral|h'.
+ 0x85260C8C, // Small 'ldclrb'.
+ 0x91260C8C, // Small 'ldclrh'.
+ 0x99260C8C, // Small 'ldclrl'.
+ 0x206D5058, // Large 'ldclr|lb'.
+ 0x20155058, // Large 'ldclr|lh'.
+ 0x8127948C, // Small 'ldeor'.
+ 0x8327948C, // Small 'ldeora'.
+ 0x100D605F, // Large 'ldeora|b'.
+ 0x1016605F, // Large 'ldeora|h'.
+ 0x0000705F, // Large 'ldeoral'.
+ 0x100D705F, // Large 'ldeoral|b'.
+ 0x1016705F, // Large 'ldeoral|h'.
+ 0x8527948C, // Small 'ldeorb'.
+ 0x9127948C, // Small 'ldeorh'.
+ 0x9927948C, // Small 'ldeorl'.
+ 0x206D505F, // Large 'ldeor|lb'.
+ 0x2015505F, // Large 'ldeor|lh'.
+ 0x80001C8C, // Small 'ldg'.
+ 0x80069C8C, // Small 'ldgm'.
+ 0x8120B08C, // Small 'ldlar'.
+ 0x8520B08C, // Small 'ldlarb'.
+ 0x9120B08C, // Small 'ldlarh'.
+ 0x8008388C, // Small 'ldnp'.
+ 0x8000408C, // Small 'ldp'.
+ 0x8179C08C, // Small 'ldpsw'.
+ 0x8000488C, // Small 'ldr'.
+ 0x8010C88C, // Small 'ldraa'.
+ 0x8020C88C, // Small 'ldrab'.
+ 0x8001488C, // Small 'ldrb'.
+ 0x8004488C, // Small 'ldrh'.
+ 0x8029C88C, // Small 'ldrsb'.
+ 0x8089C88C, // Small 'ldrsh'.
+ 0x8179C88C, // Small 'ldrsw'.
+ 0x8142CC8C, // Small 'ldset'.
+ 0x8342CC8C, // Small 'ldseta'.
+ 0x100D6066, // Large 'ldseta|b'.
+ 0x10166066, // Large 'ldseta|h'.
+ 0x00007066, // Large 'ldsetal'.
+ 0x100D7066, // Large 'ldsetal|b'.
+ 0x10167066, // Large 'ldsetal|h'.
+ 0x8542CC8C, // Small 'ldsetb'.
+ 0x9142CC8C, // Small 'ldseth'.
+ 0x9942CC8C, // Small 'ldsetl'.
+ 0x206D5066, // Large 'ldset|lb'.
+ 0x20155066, // Large 'ldset|lh'.
+ 0xB016CC8C, // Small 'ldsmax'.
+ 0x0000700E, // Large 'ldsmaxa'.
+ 0x100D700E, // Large 'ldsmaxa|b'.
+ 0x1016700E, // Large 'ldsmaxa|h'.
+ 0x0000800E, // Large 'ldsmaxal'.
+ 0x100D800E, // Large 'ldsmaxal|b'.
+ 0x1016800E, // Large 'ldsmaxal|h'.
+ 0x100D600E, // Large 'ldsmax|b'.
+ 0x1016600E, // Large 'ldsmax|h'.
+ 0x100E600E, // Large 'ldsmax|l'.
+ 0x206D600E, // Large 'ldsmax|lb'.
+ 0x2015600E, // Large 'ldsmax|lh'.
+ 0x9C96CC8C, // Small 'ldsmin'.
+ 0x00007017, // Large 'ldsmina'.
+ 0x100D7017, // Large 'ldsmina|b'.
+ 0x10167017, // Large 'ldsmina|h'.
+ 0x00008017, // Large 'ldsminal'.
+ 0x100D8017, // Large 'ldsminal|b'.
+ 0x10168017, // Large 'ldsminal|h'.
+ 0x100D6017, // Large 'ldsmin|b'.
+ 0x10166017, // Large 'ldsmin|h'.
+ 0x100E6017, // Large 'ldsmin|l'.
+ 0x206D6017, // Large 'ldsmin|lb'.
+ 0x20156017, // Large 'ldsmin|lh'.
+ 0x8009508C, // Small 'ldtr'.
+ 0x8029508C, // Small 'ldtrb'.
+ 0x8089508C, // Small 'ldtrh'.
+ 0x8539508C, // Small 'ldtrsb'.
+ 0x9139508C, // Small 'ldtrsh'.
+ 0xAF39508C, // Small 'ldtrsw'.
+ 0xB016D48C, // Small 'ldumax'.
+ 0x0000701F, // Large 'ldumaxa'.
+ 0x100D701F, // Large 'ldumaxa|b'.
+ 0x1016701F, // Large 'ldumaxa|h'.
+ 0x0000801F, // Large 'ldumaxal'.
+ 0x100D801F, // Large 'ldumaxal|b'.
+ 0x1016801F, // Large 'ldumaxal|h'.
+ 0x100D601F, // Large 'ldumax|b'.
+ 0x1016601F, // Large 'ldumax|h'.
+ 0x100E601F, // Large 'ldumax|l'.
+ 0x206D601F, // Large 'ldumax|lb'.
+ 0x2015601F, // Large 'ldumax|lh'.
+ 0x9C96D48C, // Small 'ldumin'.
+ 0x00007027, // Large 'ldumina'.
+ 0x100D7027, // Large 'ldumina|b'.
+ 0x10167027, // Large 'ldumina|h'.
+ 0x00008027, // Large 'lduminal'.
+ 0x100D8027, // Large 'lduminal|b'.
+ 0x10168027, // Large 'lduminal|h'.
+ 0x100D6027, // Large 'ldumin|b'.
+ 0x10166027, // Large 'ldumin|h'.
+ 0x100E6027, // Large 'ldumin|l'.
+ 0x206D6027, // Large 'ldumin|lb'.
+ 0x20156027, // Large 'ldumin|lh'.
+ 0x8009548C, // Small 'ldur'.
+ 0x8029548C, // Small 'ldurb'.
+ 0x8089548C, // Small 'ldurh'.
+ 0x8539548C, // Small 'ldursb'.
+ 0x9139548C, // Small 'ldursh'.
+ 0xAF39548C, // Small 'ldursw'.
+ 0x8008608C, // Small 'ldxp'.
+ 0x8009608C, // Small 'ldxr'.
+ 0x8029608C, // Small 'ldxrb'.
+ 0x8089608C, // Small 'ldxrh'.
+ 0x8000326C, // Small 'lsl'.
+ 0x800B326C, // Small 'lslv'.
+ 0x80004A6C, // Small 'lsr'.
+ 0x800B4A6C, // Small 'lsrv'.
+ 0x8002102D, // Small 'madd'.
+ 0x800395CD, // Small 'mneg'.
+ 0x800059ED, // Small 'mov'.
+ 0x8005D9ED, // Small 'movk'.
+ 0x800759ED, // Small 'movn'.
+ 0x800D59ED, // Small 'movz'.
+ 0x80004E4D, // Small 'mrs'.
+ 0x80004A6D, // Small 'msr'.
+ 0x8001566D, // Small 'msub'.
+ 0x800032AD, // Small 'mul'.
+ 0x80003ACD, // Small 'mvn'.
+ 0x80001CAE, // Small 'neg'.
+ 0x80099CAE, // Small 'negs'.
+ 0x80000CEE, // Small 'ngc'.
+ 0x80098CEE, // Small 'ngcs'.
+ 0x800041EE, // Small 'nop'.
+ 0x80003A4F, // Small 'orn'.
+ 0x80004A4F, // Small 'orr'.
+ 0x80120C30, // Small 'pacda'.
+ 0x80220C30, // Small 'pacdb'.
+ 0x83A20C30, // Small 'pacdza'.
+ 0x85A20C30, // Small 'pacdzb'.
+ 0x80138C30, // Small 'pacga'.
+ 0x80069A50, // Small 'prfm'.
+ 0x80214E70, // Small 'pssbb'.
+ 0x800A2452, // Small 'rbit'.
+ 0x800050B2, // Small 'ret'.
+ 0x800058B2, // Small 'rev'.
+ 0x20073138, // Large 'rev|16'.
+ 0x81DF58B2, // Small 'rev32'.
+ 0x208F3138, // Large 'rev|64'.
+ 0x800049F2, // Small 'ror'.
+ 0x800B49F2, // Small 'rorv'.
+ 0x80000C53, // Small 'sbc'.
+ 0x80098C53, // Small 'sbcs'.
+ 0x81A49853, // Small 'sbfiz'.
+ 0x80069853, // Small 'sbfm'.
+ 0x800C1853, // Small 'sbfx'.
+ 0x800B2493, // Small 'sdiv'.
+ 0x113B4134, // Large 'setf|8'.
+ 0x20074134, // Large 'setf|16'.
+ 0x800058B3, // Small 'sev'.
+ 0x800658B3, // Small 'sevl'.
+ 0x984205B3, // Small 'smaddl'.
+ 0x80000DB3, // Small 'smc'.
+ 0x9872B9B3, // Small 'smnegl'.
+ 0x982ACDB3, // Small 'smsubl'.
+ 0x808655B3, // Small 'smulh'.
+ 0x80C655B3, // Small 'smull'.
+ 0x80010A73, // Small 'ssbb'.
+ 0x8003F693, // Small 'st2g'.
+ 0x80420693, // Small 'stadd'.
+ 0x98420693, // Small 'staddl'.
+ 0x84420693, // Small 'staddb'.
+ 0x206D50C7, // Large 'stadd|lb'.
+ 0x90420693, // Small 'staddh'.
+ 0x201550C7, // Large 'stadd|lh'.
+ 0x81260E93, // Small 'stclr'.
+ 0x99260E93, // Small 'stclrl'.
+ 0x85260E93, // Small 'stclrb'.
+ 0x206D50CC, // Large 'stclr|lb'.
+ 0x91260E93, // Small 'stclrh'.
+ 0x201550CC, // Large 'stclr|lh'.
+ 0x81279693, // Small 'steor'.
+ 0x99279693, // Small 'steorl'.
+ 0x85279693, // Small 'steorb'.
+ 0x206D50D1, // Large 'steor|lb'.
+ 0x91279693, // Small 'steorh'.
+ 0x201550D1, // Large 'steor|lh'.
+ 0x80001E93, // Small 'stg'.
+ 0x80069E93, // Small 'stgm'.
+ 0x80081E93, // Small 'stgp'.
+ 0x81263293, // Small 'stllr'.
+ 0x85263293, // Small 'stllrb'.
+ 0x91263293, // Small 'stllrh'.
+ 0x80093293, // Small 'stlr'.
+ 0x80293293, // Small 'stlrb'.
+ 0x80893293, // Small 'stlrh'.
+ 0x810C3293, // Small 'stlxp'.
+ 0x812C3293, // Small 'stlxr'.
+ 0x852C3293, // Small 'stlxrb'.
+ 0x912C3293, // Small 'stlxrh'.
+ 0x80083A93, // Small 'stnp'.
+ 0x80004293, // Small 'stp'.
+ 0x80004A93, // Small 'str'.
+ 0x80014A93, // Small 'strb'.
+ 0x80044A93, // Small 'strh'.
+ 0x8142CE93, // Small 'stset'.
+ 0x9942CE93, // Small 'stsetl'.
+ 0x8542CE93, // Small 'stsetb'.
+ 0x206D50D6, // Large 'stset|lb'.
+ 0x9142CE93, // Small 'stseth'.
+ 0x201550D6, // Large 'stset|lh'.
+ 0xB016CE93, // Small 'stsmax'.
+ 0x100E606F, // Large 'stsmax|l'.
+ 0x100D606F, // Large 'stsmax|b'.
+ 0x206D606F, // Large 'stsmax|lb'.
+ 0x1016606F, // Large 'stsmax|h'.
+ 0x2015606F, // Large 'stsmax|lh'.
+ 0x9C96CE93, // Small 'stsmin'.
+ 0x100E6075, // Large 'stsmin|l'.
+ 0x100D6075, // Large 'stsmin|b'.
+ 0x206D6075, // Large 'stsmin|lb'.
+ 0x10166075, // Large 'stsmin|h'.
+ 0x20156075, // Large 'stsmin|lh'.
+ 0x80095293, // Small 'sttr'.
+ 0x80295293, // Small 'sttrb'.
+ 0x80895293, // Small 'sttrh'.
+ 0xB016D693, // Small 'stumax'.
+ 0x100E607B, // Large 'stumax|l'.
+ 0x100D607B, // Large 'stumax|b'.
+ 0x206D607B, // Large 'stumax|lb'.
+ 0x1016607B, // Large 'stumax|h'.
+ 0x2015607B, // Large 'stumax|lh'.
+ 0x9C96D693, // Small 'stumin'.
+ 0x100E6081, // Large 'stumin|l'.
+ 0x100D6081, // Large 'stumin|b'.
+ 0x206D6081, // Large 'stumin|lb'.
+ 0x10166081, // Large 'stumin|h'.
+ 0x20156081, // Large 'stumin|lh'.
+ 0x80095693, // Small 'stur'.
+ 0x80295693, // Small 'sturb'.
+ 0x80895693, // Small 'sturh'.
+ 0x80086293, // Small 'stxp'.
+ 0x80096293, // Small 'stxr'.
+ 0x80296293, // Small 'stxrb'.
+ 0x80896293, // Small 'stxrh'.
+ 0x807EEA93, // Small 'stz2g'.
+ 0x8003EA93, // Small 'stzg'.
+ 0x80D3EA93, // Small 'stzgm'.
+ 0x80000AB3, // Small 'sub'.
+ 0x80038AB3, // Small 'subg'.
+ 0x80080AB3, // Small 'subp'.
+ 0x81380AB3, // Small 'subps'.
+ 0x80098AB3, // Small 'subs'.
+ 0x80000ED3, // Small 'svc'.
+ 0x800042F3, // Small 'swp'.
+ 0x8000C2F3, // Small 'swpa'.
+ 0x8020C2F3, // Small 'swpab'.
+ 0x8080C2F3, // Small 'swpah'.
+ 0x80C0C2F3, // Small 'swpal'.
+ 0x84C0C2F3, // Small 'swpalb'.
+ 0x90C0C2F3, // Small 'swpalh'.
+ 0x800142F3, // Small 'swpb'.
+ 0x800442F3, // Small 'swph'.
+ 0x800642F3, // Small 'swpl'.
+ 0x802642F3, // Small 'swplb'.
+ 0x808642F3, // Small 'swplh'.
+ 0x80015313, // Small 'sxtb'.
+ 0x80045313, // Small 'sxth'.
+ 0x800BD313, // Small 'sxtw'.
+ 0x80004F33, // Small 'sys'.
+ 0x80048994, // Small 'tlbi'.
+ 0x80005274, // Small 'tst'.
+ 0x800D3854, // Small 'tbnz'.
+ 0x80006854, // Small 'tbz'.
+ 0x81A49855, // Small 'ubfiz'.
+ 0x80069855, // Small 'ubfm'.
+ 0x800C1855, // Small 'ubfx'.
+ 0x80001895, // Small 'udf'.
+ 0x800B2495, // Small 'udiv'.
+ 0x984205B5, // Small 'umaddl'.
+ 0x9872B9B5, // Small 'umnegl'.
+ 0x80C655B5, // Small 'umull'.
+ 0x808655B5, // Small 'umulh'.
+ 0x982ACDB5, // Small 'umsubl'.
+ 0x80015315, // Small 'uxtb'.
+ 0x80045315, // Small 'uxth'.
+ 0x800014D7, // Small 'wfe'.
+ 0x800024D7, // Small 'wfi'.
+ 0x8E161838, // Small 'xaflag'.
+ 0x80418618, // Small 'xpacd'.
+ 0x80918618, // Small 'xpaci'.
+ 0x208850DB, // Large 'xpacl|ri'.
+ 0x80461539, // Small 'yield'.
+ 0x80004C41, // Small 'abs'.
+ 0x80001081, // Small 'add'.
+ 0x80E41081, // Small 'addhn'.
+ 0xBAE41081, // Small 'addhn2'.
+ 0x80081081, // Small 'addp'.
+ 0x800B1081, // Small 'addv'.
+ 0x80024CA1, // Small 'aesd'.
+ 0x8002CCA1, // Small 'aese'.
+ 0x86D4CCA1, // Small 'aesimc'.
+ 0x8036CCA1, // Small 'aesmc'.
+ 0x800011C1, // Small 'and'.
+ 0x800C0462, // Small 'bcax'.
+ 0x814B0CC2, // Small 'bfcvt'.
+ 0x9D4B0CC2, // Small 'bfcvtn'.
+ 0x20B150E0, // Large 'bfcvt|n2'.
+ 0x814790C2, // Small 'bfdot'.
+ 0x206D50E5, // Large 'bfmla|lb'.
+ 0x20EA50E5, // Large 'bfmla|lt'.
+ 0x82C6B4C2, // Small 'bfmmla'.
+ 0x80000D22, // Small 'bic'.
+ 0x80001922, // Small 'bif'.
+ 0x80005122, // Small 'bit'.
+ 0x80003262, // Small 'bsl'.
+ 0x80004D83, // Small 'cls'.
+ 0x80006983, // Small 'clz'.
+ 0x800895A3, // Small 'cmeq'.
+ 0x80029DA3, // Small 'cmge'.
+ 0x800A1DA3, // Small 'cmgt'.
+ 0x8004A1A3, // Small 'cmhi'.
+ 0x8009A1A3, // Small 'cmhs'.
+ 0x8002B1A3, // Small 'cmle'.
+ 0x800A31A3, // Small 'cmlt'.
+ 0x8149D1A3, // Small 'cmtst'.
+ 0x800051C3, // Small 'cnt'.
+ 0x800042A4, // Small 'dup'.
+ 0x800049E5, // Small 'eor'.
+ 0x800F49E5, // Small 'eor3'.
+ 0x80005305, // Small 'ext'.
+ 0x80020826, // Small 'fabd'.
+ 0x80098826, // Small 'fabs'.
+ 0x80538C26, // Small 'facge'.
+ 0x81438C26, // Small 'facgt'.
+ 0x80021026, // Small 'fadd'.
+ 0x81021026, // Small 'faddp'.
+ 0x80420466, // Small 'fcadd'.
+ 0x81068C66, // Small 'fccmp'.
+ 0x8B068C66, // Small 'fccmpe'.
+ 0x8112B466, // Small 'fcmeq'.
+ 0x8053B466, // Small 'fcmge'.
+ 0x8143B466, // Small 'fcmgt'.
+ 0x80163466, // Small 'fcmla'.
+ 0x80563466, // Small 'fcmle'.
+ 0x81463466, // Small 'fcmlt'.
+ 0x80083466, // Small 'fcmp'.
+ 0x80583466, // Small 'fcmpe'.
+ 0x80C2CC66, // Small 'fcsel'.
+ 0x800A5866, // Small 'fcvt'.
+ 0xA61A5866, // Small 'fcvtas'.
+ 0xAA1A5866, // Small 'fcvtau'.
+ 0x80CA5866, // Small 'fcvtl'.
+ 0xBACA5866, // Small 'fcvtl2'.
+ 0xA6DA5866, // Small 'fcvtms'.
+ 0xAADA5866, // Small 'fcvtmu'.
+ 0x80EA5866, // Small 'fcvtn'.
+ 0xBAEA5866, // Small 'fcvtn2'.
+ 0xA6EA5866, // Small 'fcvtns'.
+ 0xAAEA5866, // Small 'fcvtnu'.
+ 0xA70A5866, // Small 'fcvtps'.
+ 0xAB0A5866, // Small 'fcvtpu'.
+ 0x9D8A5866, // Small 'fcvtxn'.
+ 0x20B150EC, // Large 'fcvtx|n2'.
+ 0xA7AA5866, // Small 'fcvtzs'.
+ 0xABAA5866, // Small 'fcvtzu'.
+ 0x800B2486, // Small 'fdiv'.
+ 0x101060F1, // Large 'fjcvtz|s'.
+ 0x804205A6, // Small 'fmadd'.
+ 0x800C05A6, // Small 'fmax'.
+ 0x9AEC05A6, // Small 'fmaxnm'.
+ 0x104460F7, // Large 'fmaxnm|p'.
+ 0x10E360F7, // Large 'fmaxnm|v'.
+ 0x810C05A6, // Small 'fmaxp'.
+ 0x816C05A6, // Small 'fmaxv'.
+ 0x800725A6, // Small 'fmin'.
+ 0x9AE725A6, // Small 'fminnm'.
+ 0x104460FD, // Large 'fminnm|p'.
+ 0x10E360FD, // Large 'fminnm|v'.
+ 0x810725A6, // Small 'fminp'.
+ 0x816725A6, // Small 'fminv'.
+ 0x8000B1A6, // Small 'fmla'.
+ 0x80C0B1A6, // Small 'fmlal'.
+ 0xBAC0B1A6, // Small 'fmlal2'.
+ 0x8009B1A6, // Small 'fmls'.
+ 0x80C9B1A6, // Small 'fmlsl'.
+ 0xBAC9B1A6, // Small 'fmlsl2'.
+ 0x800B3DA6, // Small 'fmov'.
+ 0x802ACDA6, // Small 'fmsub'.
+ 0x800655A6, // Small 'fmul'.
+ 0x818655A6, // Small 'fmulx'.
+ 0x800395C6, // Small 'fneg'.
+ 0x8840B5C6, // Small 'fnmadd'.
+ 0x8559B5C6, // Small 'fnmsub'.
+ 0x80CAB5C6, // Small 'fnmul'.
+ 0x8B019646, // Small 'frecpe'.
+ 0xA7019646, // Small 'frecps'.
+ 0xB1019646, // Small 'frecpx'.
+ 0x10137087, // Large 'frint32|x'.
+ 0x108E7087, // Large 'frint32|z'.
+ 0x308F5087, // Large 'frint|64x'.
+ 0x30925087, // Large 'frint|64z'.
+ 0x83472646, // Small 'frinta'.
+ 0x93472646, // Small 'frinti'.
+ 0x9B472646, // Small 'frintm'.
+ 0x9D472646, // Small 'frintn'.
+ 0xA1472646, // Small 'frintp'.
+ 0xB1472646, // Small 'frintx'.
+ 0xB5472646, // Small 'frintz'.
+ 0x20D25103, // Large 'frsqr|te'.
+ 0x20705103, // Large 'frsqr|ts'.
+ 0x81494666, // Small 'fsqrt'.
+ 0x80015666, // Small 'fsub'.
+ 0x80004DC9, // Small 'ins'.
+ 0x8000708C, // Small 'ld1'.
+ 0x8009708C, // Small 'ld1r'.
+ 0x8000748C, // Small 'ld2'.
+ 0x8009748C, // Small 'ld2r'.
+ 0x8000788C, // Small 'ld3'.
+ 0x8009788C, // Small 'ld3r'.
+ 0x80007C8C, // Small 'ld4'.
+ 0x80097C8C, // Small 'ld4r'.
+ 0x8008388C, // Small 'ldnp'.
+ 0x8000408C, // Small 'ldp'.
+ 0x8000488C, // Small 'ldr'.
+ 0x8009548C, // Small 'ldur'.
+ 0x8000058D, // Small 'mla'.
+ 0x80004D8D, // Small 'mls'.
+ 0x800059ED, // Small 'mov'.
+ 0x8004D9ED, // Small 'movi'.
+ 0x800032AD, // Small 'mul'.
+ 0x80003ACD, // Small 'mvn'.
+ 0x8004BACD, // Small 'mvni'.
+ 0x80001CAE, // Small 'neg'.
+ 0x800051EE, // Small 'not'.
+ 0x80003A4F, // Small 'orn'.
+ 0x80004A4F, // Small 'orr'.
+ 0x800655B0, // Small 'pmul'.
+ 0x80C655B0, // Small 'pmull'.
+ 0xBAC655B0, // Small 'pmull2'.
+ 0x9C821032, // Small 'raddhn'.
+ 0x30B04108, // Large 'radd|hn2'.
+ 0x800E6032, // Small 'rax1'.
+ 0x800A2452, // Small 'rbit'.
+ 0x20073138, // Large 'rev|16'.
+ 0x81DF58B2, // Small 'rev32'.
+ 0x208F3138, // Large 'rev|64'.
+ 0x80E92272, // Small 'rshrn'.
+ 0xBAE92272, // Small 'rshrn2'.
+ 0x9C815672, // Small 'rsubhn'.
+ 0x30B0410C, // Large 'rsub|hn2'.
+ 0x80008833, // Small 'saba'.
+ 0x80C08833, // Small 'sabal'.
+ 0xBAC08833, // Small 'sabal2'.
+ 0x80020833, // Small 'sabd'.
+ 0x80C20833, // Small 'sabdl'.
+ 0xBAC20833, // Small 'sabdl2'.
+ 0xA0C09033, // Small 'sadalp'.
+ 0x80C21033, // Small 'saddl'.
+ 0xBAC21033, // Small 'saddl2'.
+ 0xA0C21033, // Small 'saddlp'.
+ 0xACC21033, // Small 'saddlv'.
+ 0x81721033, // Small 'saddw'.
+ 0xBB721033, // Small 'saddw2'.
+ 0x806A5873, // Small 'scvtf'.
+ 0x800A3C93, // Small 'sdot'.
+ 0x803E0513, // Small 'sha1c'.
+ 0x808E0513, // Small 'sha1h'.
+ 0x80DE0513, // Small 'sha1m'.
+ 0x810E0513, // Small 'sha1p'.
+ 0x30354110, // Large 'sha1|su0'.
+ 0x303E4110, // Large 'sha1|su1'.
+ 0x1016602F, // Large 'sha256|h'.
+ 0x2095602F, // Large 'sha256|h2'.
+ 0x0000902F, // Large 'sha256su0'.
+ 0x1005802F, // Large 'sha256su|1'.
+ 0x10166038, // Large 'sha512|h'.
+ 0x20956038, // Large 'sha512|h2'.
+ 0x30356038, // Large 'sha512|su0'.
+ 0x303E6038, // Large 'sha512|su1'.
+ 0x80420513, // Small 'shadd'.
+ 0x80003113, // Small 'shl'.
+ 0x80063113, // Small 'shll'.
+ 0x81D63113, // Small 'shll2'.
+ 0x80074913, // Small 'shrn'.
+ 0x81D74913, // Small 'shrn2'.
+ 0x802ACD13, // Small 'shsub'.
+ 0x80002593, // Small 'sli'.
+ 0x10058041, // Large 'sm3partw|1'.
+ 0x10328041, // Large 'sm3partw|2'.
+ 0xB939F9B3, // Small 'sm3ss1'.
+ 0x10006114, // Large 'sm3tt1|a'.
+ 0x100D6114, // Large 'sm3tt1|b'.
+ 0x211A5114, // Large 'sm3tt|2a'.
+ 0x211C5114, // Large 'sm3tt|2b'.
+ 0x8002FDB3, // Small 'sm4e'.
+ 0x0000711E, // Large 'sm4ekey'.
+ 0x800C05B3, // Small 'smax'.
+ 0x810C05B3, // Small 'smaxp'.
+ 0x816C05B3, // Small 'smaxv'.
+ 0x800725B3, // Small 'smin'.
+ 0x810725B3, // Small 'sminp'.
+ 0x816725B3, // Small 'sminv'.
+ 0x80C0B1B3, // Small 'smlal'.
+ 0xBAC0B1B3, // Small 'smlal2'.
+ 0x80C9B1B3, // Small 'smlsl'.
+ 0xBAC9B1B3, // Small 'smlsl2'.
+ 0x801635B3, // Small 'smmla'.
+ 0x800B3DB3, // Small 'smov'.
+ 0x80C655B3, // Small 'smull'.
+ 0xBAC655B3, // Small 'smull2'.
+ 0x81310633, // Small 'sqabs'.
+ 0x80420633, // Small 'sqadd'.
+ 0x00007097, // Large 'sqdmlal'.
+ 0x10327097, // Large 'sqdmlal|2'.
+ 0x209E5097, // Large 'sqdml|sl'.
+ 0x309E5097, // Large 'sqdml|sl2'.
+ 0x101660A1, // Large 'sqdmul|h'.
+ 0x100E60A1, // Large 'sqdmul|l'.
+ 0x209F60A1, // Large 'sqdmul|l2'.
+ 0x8072BA33, // Small 'sqneg'.
+ 0x101670A7, // Large 'sqrdmla|h'.
+ 0x202F60A7, // Large 'sqrdml|sh'.
+ 0x30AE50A7, // Large 'sqrdm|ulh'.
+ 0x9889CA33, // Small 'sqrshl'.
+ 0x101C6049, // Large 'sqrshr|n'.
+ 0x20B16049, // Large 'sqrshr|n2'.
+ 0x00008049, // Large 'sqrshrun'.
+ 0x10328049, // Large 'sqrshrun|2'.
+ 0x80C44E33, // Small 'sqshl'.
+ 0xAAC44E33, // Small 'sqshlu'.
+ 0x9D244E33, // Small 'sqshrn'.
+ 0x20B150B3, // Large 'sqshr|n2'.
+ 0x101C60B3, // Large 'sqshru|n'.
+ 0x20B160B3, // Large 'sqshru|n2'.
+ 0x802ACE33, // Small 'sqsub'.
+ 0x80EA6233, // Small 'sqxtn'.
+ 0xBAEA6233, // Small 'sqxtn2'.
+ 0x9D5A6233, // Small 'sqxtun'.
+ 0x20B15125, // Large 'sqxtu|n2'.
+ 0x8840A253, // Small 'srhadd'.
+ 0x80002653, // Small 'sri'.
+ 0x80C44E53, // Small 'srshl'.
+ 0x81244E53, // Small 'srshr'.
+ 0x80194E53, // Small 'srsra'.
+ 0x80062273, // Small 'sshl'.
+ 0x80C62273, // Small 'sshll'.
+ 0xBAC62273, // Small 'sshll2'.
+ 0x80092273, // Small 'sshr'.
+ 0x8000CA73, // Small 'ssra'.
+ 0x80C15673, // Small 'ssubl'.
+ 0xBAC15673, // Small 'ssubl2'.
+ 0x81715673, // Small 'ssubw'.
+ 0xBB715673, // Small 'ssubw2'.
+ 0x80007293, // Small 'st1'.
+ 0x80007693, // Small 'st2'.
+ 0x80007A93, // Small 'st3'.
+ 0x80007E93, // Small 'st4'.
+ 0x80083A93, // Small 'stnp'.
+ 0x80004293, // Small 'stp'.
+ 0x80004A93, // Small 'str'.
+ 0x80095693, // Small 'stur'.
+ 0x80000AB3, // Small 'sub'.
+ 0x80E40AB3, // Small 'subhn'.
+ 0xBAE40AB3, // Small 'subhn2'.
+ 0x814792B3, // Small 'sudot'.
+ 0x8840C6B3, // Small 'suqadd'.
+ 0x80065313, // Small 'sxtl'.
+ 0x81D65313, // Small 'sxtl2'.
+ 0x80003054, // Small 'tbl'.
+ 0x80006054, // Small 'tbx'.
+ 0x800E3A54, // Small 'trn1'.
+ 0x800EBA54, // Small 'trn2'.
+ 0x80008835, // Small 'uaba'.
+ 0x80C08835, // Small 'uabal'.
+ 0xBAC08835, // Small 'uabal2'.
+ 0x80020835, // Small 'uabd'.
+ 0x80C20835, // Small 'uabdl'.
+ 0xBAC20835, // Small 'uabdl2'.
+ 0xA0C09035, // Small 'uadalp'.
+ 0x80C21035, // Small 'uaddl'.
+ 0xBAC21035, // Small 'uaddl2'.
+ 0xA0C21035, // Small 'uaddlp'.
+ 0xACC21035, // Small 'uaddlv'.
+ 0x81721035, // Small 'uaddw'.
+ 0xBB721035, // Small 'uaddw2'.
+ 0x806A5875, // Small 'ucvtf'.
+ 0x800A3C95, // Small 'udot'.
+ 0x80420515, // Small 'uhadd'.
+ 0x802ACD15, // Small 'uhsub'.
+ 0x800C05B5, // Small 'umax'.
+ 0x810C05B5, // Small 'umaxp'.
+ 0x816C05B5, // Small 'umaxv'.
+ 0x800725B5, // Small 'umin'.
+ 0x810725B5, // Small 'uminp'.
+ 0x816725B5, // Small 'uminv'.
+ 0x80C0B1B5, // Small 'umlal'.
+ 0xBAC0B1B5, // Small 'umlal2'.
+ 0x80C9B1B5, // Small 'umlsl'.
+ 0xBAC9B1B5, // Small 'umlsl2'.
+ 0x801635B5, // Small 'ummla'.
+ 0x800B3DB5, // Small 'umov'.
+ 0x80C655B5, // Small 'umull'.
+ 0xBAC655B5, // Small 'umull2'.
+ 0x80420635, // Small 'uqadd'.
+ 0x9889CA35, // Small 'uqrshl'.
+ 0x101C60B9, // Large 'uqrshr|n'.
+ 0x20B160B9, // Large 'uqrshr|n2'.
+ 0x80C44E35, // Small 'uqshl'.
+ 0x9D244E35, // Small 'uqshrn'.
+ 0x20B1512A, // Large 'uqshr|n2'.
+ 0x802ACE35, // Small 'uqsub'.
+ 0x80EA6235, // Small 'uqxtn'.
+ 0xBAEA6235, // Small 'uqxtn2'.
+ 0x8B019655, // Small 'urecpe'.
+ 0x8840A255, // Small 'urhadd'.
+ 0x80C44E55, // Small 'urshl'.
+ 0x81244E55, // Small 'urshr'.
+ 0x20D2512F, // Large 'ursqr|te'.
+ 0x80194E55, // Small 'ursra'.
+ 0x81479275, // Small 'usdot'.
+ 0x80062275, // Small 'ushl'.
+ 0x80C62275, // Small 'ushll'.
+ 0xBAC62275, // Small 'ushll2'.
+ 0x80092275, // Small 'ushr'.
+ 0x82C6B675, // Small 'usmmla'.
+ 0x8840C675, // Small 'usqadd'.
+ 0x8000CA75, // Small 'usra'.
+ 0x80C15675, // Small 'usubl'.
+ 0xBAC15675, // Small 'usubl2'.
+ 0x81715675, // Small 'usubw'.
+ 0xBB715675, // Small 'usubw2'.
+ 0x80065315, // Small 'uxtl'.
+ 0x81D65315, // Small 'uxtl2'.
+ 0x800E4355, // Small 'uzp1'.
+ 0x800EC355, // Small 'uzp2'.
+ 0x80004838, // Small 'xar'.
+ 0x80003A98, // Small 'xtn'.
+ 0x800EBA98, // Small 'xtn2'.
+ 0x800E413A, // Small 'zip1'.
+ 0x800EC13A // Small 'zip2'.
};
// ----------------------------------------------------------------------------
// ${NameData:End}
-#endif
+#endif // !ASMJIT_NO_TEXT
ASMJIT_END_SUB_NAMESPACE
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64instdb.h b/3rdparty/asmjit/src/asmjit/arm/a64instdb.h
index 0575d1a2fa6..a03125401ad 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64instdb.h
+++ b/3rdparty/asmjit/src/asmjit/arm/a64instdb.h
@@ -29,7 +29,7 @@ enum InstFlags : uint32_t {
//! SIMD element access of half-words can only be used with v0..15.
kInstFlagVH0_15 = 0x00000010u,
- //! Instruction may consecutive registers if the number of operands is greater than 2.
+ //! Instruction uses consecutive registers if the number of operands is greater than 2.
kInstFlagConsecutive = 0x00000080u
};
@@ -39,9 +39,7 @@ struct InstInfo {
uint32_t _encoding : 8;
//! Index to data specific to each encoding type.
uint32_t _encodingDataIndex : 8;
- uint32_t _reserved : 2;
- //! Index to \ref _nameData.
- uint32_t _nameDataIndex : 14;
+ uint32_t _reserved : 16;
uint16_t _rwInfoIndex;
uint16_t _flags;
@@ -49,10 +47,10 @@ struct InstInfo {
//! \name Accessors
//! \{
- inline uint32_t rwInfoIndex() const noexcept { return _rwInfoIndex; }
- inline uint32_t flags() const noexcept { return _flags; }
+ ASMJIT_INLINE_NODEBUG uint32_t rwInfoIndex() const noexcept { return _rwInfoIndex; }
+ ASMJIT_INLINE_NODEBUG uint32_t flags() const noexcept { return _flags; }
- inline bool hasFlag(uint32_t flag) const { return (_flags & flag) != 0; }
+ ASMJIT_INLINE_NODEBUG bool hasFlag(uint32_t flag) const { return (_flags & flag) != 0; }
//! \}
};
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64instdb_p.h b/3rdparty/asmjit/src/asmjit/arm/a64instdb_p.h
index eb4f3f83766..5c3da7e1f9f 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64instdb_p.h
+++ b/3rdparty/asmjit/src/asmjit/arm/a64instdb_p.h
@@ -7,6 +7,7 @@
#define ASMJIT_ARM_A64INSTDB_H_P_INCLUDED
#include "../core/codeholder.h"
+#include "../core/instdb_p.h"
#include "../arm/a64instdb.h"
#include "../arm/a64operand.h"
@@ -58,14 +59,14 @@ enum RWInfoType : uint32_t {
// a64::InstDB - ElementType
// =========================
-enum ElementType : uint8_t {
- kET_None = Vec::kElementTypeNone,
- kET_B = Vec::kElementTypeB,
- kET_H = Vec::kElementTypeH,
- kET_S = Vec::kElementTypeS,
- kET_D = Vec::kElementTypeD,
- kET_2H = Vec::kElementTypeH2,
- kET_4B = Vec::kElementTypeB4
+enum InstElementType : uint8_t {
+ kET_None = uint8_t(VecElementType::kNone),
+ kET_B = uint8_t(VecElementType::kB),
+ kET_H = uint8_t(VecElementType::kH),
+ kET_S = uint8_t(VecElementType::kS),
+ kET_D = uint8_t(VecElementType::kD),
+ kET_2H = uint8_t(VecElementType::kH2),
+ kET_4B = uint8_t(VecElementType::kB4)
};
// a64::InstDB - GpType
@@ -192,6 +193,7 @@ enum EncodingId : uint32_t {
kEncodingBaseMvnNeg,
kEncodingBaseOp,
kEncodingBaseOpImm,
+ kEncodingBasePrfm,
kEncodingBaseR,
kEncodingBaseRM_NoImm,
kEncodingBaseRM_SImm10,
@@ -262,7 +264,7 @@ namespace EncodingData {
#define M_OPCODE(field, bits) \
uint32_t _##field : bits; \
- inline constexpr uint32_t field() const noexcept { return uint32_t(_##field) << (32 - bits); }
+ ASMJIT_INLINE_NODEBUG constexpr uint32_t field() const noexcept { return uint32_t(_##field) << (32 - bits); }
struct BaseOp {
uint32_t opcode;
@@ -412,6 +414,13 @@ struct BaseRM_SImm10 {
uint32_t immShift : 4;
};
+struct BasePrfm {
+ uint32_t registerOp : 11;
+ uint32_t sOffsetOp : 10;
+ uint32_t uOffsetOp : 11;
+ uint32_t literalOp;
+};
+
struct BaseLdSt {
uint32_t uOffsetOp : 10;
uint32_t prePostOp : 11;
@@ -787,6 +796,7 @@ extern const BaseMovKNZ baseMovKNZ[3];
extern const BaseMvnNeg baseMvnNeg[3];
extern const BaseOp baseOp[23];
extern const BaseOpImm baseOpImm[14];
+extern const BasePrfm basePrfm[1];
extern const BaseR baseR[10];
extern const BaseRM_NoImm baseRM_NoImm[21];
extern const BaseRM_SImm10 baseRM_SImm10[2];
@@ -843,26 +853,13 @@ extern const SimdTblTbx simdTblTbx[2];
} // {EncodingData}
-// a64::InstDB - InstNameIndex
-// ===========================
-
-// ${NameLimits:Begin}
-// ------------------- Automatically generated, do not edit -------------------
-enum : uint32_t { kMaxNameSize = 9 };
-// ----------------------------------------------------------------------------
-// ${NameLimits:End}
-
-struct InstNameIndex {
- uint16_t start;
- uint16_t end;
-};
-
// a64::InstDB - Tables
// ====================
#ifndef ASMJIT_NO_TEXT
-extern const char _nameData[];
-extern const InstNameIndex instNameIndex[26];
+extern const InstNameIndex instNameIndex;
+extern const char _instNameStringTable[];
+extern const uint32_t _instNameIndexTable[];
#endif // !ASMJIT_NO_TEXT
} // {InstDB}
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64operand.cpp b/3rdparty/asmjit/src/asmjit/arm/a64operand.cpp
index 40a4a7952bc..e8c6100fa68 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64operand.cpp
+++ b/3rdparty/asmjit/src/asmjit/arm/a64operand.cpp
@@ -17,66 +17,66 @@ ASMJIT_BEGIN_SUB_NAMESPACE(a64)
#if defined(ASMJIT_TEST)
UNIT(a64_operand) {
INFO("Checking if a64::reg(...) matches built-in IDs");
- EXPECT(w(5) == w5);
- EXPECT(x(5) == x5);
+ EXPECT_EQ(w(5), w5);
+ EXPECT_EQ(x(5), x5);
INFO("Checking Gp register properties");
- EXPECT(Gp().isReg() == true);
- EXPECT(w0.isReg() == true);
- EXPECT(x0.isReg() == true);
- EXPECT(w0.id() == 0);
- EXPECT(x0.id() == 0);
- EXPECT(wzr.id() == Gp::kIdZr);
- EXPECT(xzr.id() == Gp::kIdZr);
- EXPECT(wsp.id() == Gp::kIdSp);
- EXPECT(sp.id() == Gp::kIdSp);
- EXPECT(w0.size() == 4);
- EXPECT(x0.size() == 8);
- EXPECT(w0.type() == RegType::kARM_GpW);
- EXPECT(x0.type() == RegType::kARM_GpX);
- EXPECT(w0.group() == RegGroup::kGp);
- EXPECT(x0.group() == RegGroup::kGp);
+ EXPECT_TRUE(Gp().isReg());
+ EXPECT_TRUE(w0.isReg());
+ EXPECT_TRUE(x0.isReg());
+ EXPECT_EQ(w0.id(), 0u);
+ EXPECT_EQ(x0.id(), 0u);
+ EXPECT_EQ(wzr.id(), Gp::kIdZr);
+ EXPECT_EQ(xzr.id(), Gp::kIdZr);
+ EXPECT_EQ(wsp.id(), Gp::kIdSp);
+ EXPECT_EQ(sp.id(), Gp::kIdSp);
+ EXPECT_EQ(w0.size(), 4u);
+ EXPECT_EQ(x0.size(), 8u);
+ EXPECT_EQ(w0.type(), RegType::kARM_GpW);
+ EXPECT_EQ(x0.type(), RegType::kARM_GpX);
+ EXPECT_EQ(w0.group(), RegGroup::kGp);
+ EXPECT_EQ(x0.group(), RegGroup::kGp);
INFO("Checking Vec register properties");
- EXPECT(v0.type() == RegType::kARM_VecV);
- EXPECT(d0.type() == RegType::kARM_VecD);
- EXPECT(s0.type() == RegType::kARM_VecS);
- EXPECT(h0.type() == RegType::kARM_VecH);
- EXPECT(b0.type() == RegType::kARM_VecB);
+ EXPECT_EQ(v0.type(), RegType::kARM_VecV);
+ EXPECT_EQ(d0.type(), RegType::kARM_VecD);
+ EXPECT_EQ(s0.type(), RegType::kARM_VecS);
+ EXPECT_EQ(h0.type(), RegType::kARM_VecH);
+ EXPECT_EQ(b0.type(), RegType::kARM_VecB);
- EXPECT(v0.group() == RegGroup::kVec);
- EXPECT(d0.group() == RegGroup::kVec);
- EXPECT(s0.group() == RegGroup::kVec);
- EXPECT(h0.group() == RegGroup::kVec);
- EXPECT(b0.group() == RegGroup::kVec);
+ EXPECT_EQ(v0.group(), RegGroup::kVec);
+ EXPECT_EQ(d0.group(), RegGroup::kVec);
+ EXPECT_EQ(s0.group(), RegGroup::kVec);
+ EXPECT_EQ(h0.group(), RegGroup::kVec);
+ EXPECT_EQ(b0.group(), RegGroup::kVec);
INFO("Checking Vec register element[] access");
Vec vd_1 = v15.d(1);
- EXPECT(vd_1.type() == RegType::kARM_VecV);
- EXPECT(vd_1.group() == RegGroup::kVec);
- EXPECT(vd_1.id() == 15);
- EXPECT(vd_1.isVecD2());
- EXPECT(vd_1.elementType() == Vec::kElementTypeD);
- EXPECT(vd_1.hasElementIndex());
- EXPECT(vd_1.elementIndex() == 1);
+ EXPECT_EQ(vd_1.type(), RegType::kARM_VecV);
+ EXPECT_EQ(vd_1.group(), RegGroup::kVec);
+ EXPECT_EQ(vd_1.id(), 15u);
+ EXPECT_TRUE(vd_1.isVecD2());
+ EXPECT_EQ(vd_1.elementType(), VecElementType::kD);
+ EXPECT_TRUE(vd_1.hasElementIndex());
+ EXPECT_EQ(vd_1.elementIndex(), 1u);
Vec vs_3 = v15.s(3);
- EXPECT(vs_3.type() == RegType::kARM_VecV);
- EXPECT(vs_3.group() == RegGroup::kVec);
- EXPECT(vs_3.id() == 15);
- EXPECT(vs_3.isVecS4());
- EXPECT(vs_3.elementType() == Vec::kElementTypeS);
- EXPECT(vs_3.hasElementIndex());
- EXPECT(vs_3.elementIndex() == 3);
+ EXPECT_EQ(vs_3.type(), RegType::kARM_VecV);
+ EXPECT_EQ(vs_3.group(), RegGroup::kVec);
+ EXPECT_EQ(vs_3.id(), 15u);
+ EXPECT_TRUE(vs_3.isVecS4());
+ EXPECT_EQ(vs_3.elementType(), VecElementType::kS);
+ EXPECT_TRUE(vs_3.hasElementIndex());
+ EXPECT_EQ(vs_3.elementIndex(), 3u);
Vec vb_4 = v15.b4(3);
- EXPECT(vb_4.type() == RegType::kARM_VecV);
- EXPECT(vb_4.group() == RegGroup::kVec);
- EXPECT(vb_4.id() == 15);
- EXPECT(vb_4.isVecB4x4());
- EXPECT(vb_4.elementType() == Vec::kElementTypeB4);
- EXPECT(vb_4.hasElementIndex());
- EXPECT(vb_4.elementIndex() == 3);
+ EXPECT_EQ(vb_4.type(), RegType::kARM_VecV);
+ EXPECT_EQ(vb_4.group(), RegGroup::kVec);
+ EXPECT_EQ(vb_4.id(), 15u);
+ EXPECT_TRUE(vb_4.isVecB4x4());
+ EXPECT_EQ(vb_4.elementType(), VecElementType::kB4);
+ EXPECT_TRUE(vb_4.hasElementIndex());
+ EXPECT_EQ(vb_4.elementIndex(), 3u);
}
#endif
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64operand.h b/3rdparty/asmjit/src/asmjit/arm/a64operand.h
index c2d3c179a86..9e233062b69 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64operand.h
+++ b/3rdparty/asmjit/src/asmjit/arm/a64operand.h
@@ -13,24 +13,304 @@ ASMJIT_BEGIN_SUB_NAMESPACE(a64)
//! \addtogroup asmjit_a64
//! \{
-using arm::Reg;
-using arm::Mem;
-using arm::Gp;
-using arm::GpW;
-using arm::GpX;
-
-using arm::Vec;
-using arm::VecB;
-using arm::VecH;
-using arm::VecS;
-using arm::VecD;
-using arm::VecV;
+class GpW;
+class GpX;
+
+class VecB;
+class VecH;
+class VecS;
+class VecD;
+class VecV;
+
+//! General purpose register (AArch64).
+class Gp : public Reg {
+public:
+ ASMJIT_DEFINE_ABSTRACT_REG(Gp, Reg)
+
+ //! Special register id.
+ enum Id : uint32_t {
+ //! Register that depends on OS, could be used as TLS offset.
+ kIdOs = 18,
+ //! Frame pointer register id.
+ kIdFp = 29,
+ //! Link register id.
+ kIdLr = 30,
+ //! Stack register id.
+ kIdSp = 31,
+ //! Zero register id.
+ //!
+ //! Although zero register has the same id as stack register it has a special treatment, because we need to be
+ //! able to distinguish between these two at API level. Some instructions were designed to be used with SP and
+ //! some other with ZR - so we need a way to distinguish these two to make sure we emit the right thing.
+ //!
+ //! The number 63 is not random, when you perform `id & 31` you would always get 31 for both SP and ZR inputs,
+ //! which is the identifier used by AArch64 ISA to encode either SP or ZR depending on the instruction.
+ kIdZr = 63
+ };
+
+ //! Test whether this register is ZR register.
+ ASMJIT_INLINE_NODEBUG constexpr bool isZR() const noexcept { return id() == kIdZr; }
+ //! Test whether this register is SP register.
+ ASMJIT_INLINE_NODEBUG constexpr bool isSP() const noexcept { return id() == kIdSp; }
+
+ //! Cast this register to a 32-bit W register (returns a new operand).
+ ASMJIT_INLINE_NODEBUG GpW w() const noexcept;
+ //! \overload
+ ASMJIT_INLINE_NODEBUG GpW r32() const noexcept;
+ //! Cast this register to a 64-bit X register (returns a new operand).
+ ASMJIT_INLINE_NODEBUG GpX x() const noexcept;
+ //! \overload
+ ASMJIT_INLINE_NODEBUG GpX r64() const noexcept;
+};
+
+//! 32-bit general purpose W register (AArch64).
+class GpW : public Gp { ASMJIT_DEFINE_FINAL_REG(GpW, Gp, RegTraits<RegType::kARM_GpW>); };
+//! 64-bit general purpose X register (AArch64).
+class GpX : public Gp { ASMJIT_DEFINE_FINAL_REG(GpX, Gp, RegTraits<RegType::kARM_GpX>); };
+
+#ifndef _DOXYGEN
+ASMJIT_INLINE_NODEBUG GpW Gp::w() const noexcept { return GpW(id()); }
+ASMJIT_INLINE_NODEBUG GpX Gp::x() const noexcept { return GpX(id()); }
+ASMJIT_INLINE_NODEBUG GpW Gp::r32() const noexcept { return GpW(id()); }
+ASMJIT_INLINE_NODEBUG GpX Gp::r64() const noexcept { return GpX(id()); }
+#endif
+
+//! Vector element type (AArch64).
+enum class VecElementType : uint32_t {
+ //! No element type specified.
+ kNone = 0,
+ //! Byte elements (B8 or B16).
+ kB,
+ //! Halfword elements (H4 or H8).
+ kH,
+ //! Singleword elements (S2 or S4).
+ kS,
+ //! Doubleword elements (D2).
+ kD,
+ //! Byte elements grouped by 4 bytes (B4).
+ //!
+ //! \note This element-type is only used by few instructions.
+ kB4,
+ //! Halfword elements grouped by 2 halfwords (H2).
+ //!
+ //! \note This element-type is only used by few instructions.
+ kH2,
+
+ //! Maximum value of \ref VecElementType
+ kMaxValue = kH2
+};
+
+//! Vector register (AArch64).
+class Vec : public BaseVec {
+public:
+ ASMJIT_DEFINE_ABSTRACT_REG(Vec, BaseVec)
+
+ //! \cond
+ //! Shortcuts.
+ enum SignatureReg : uint32_t {
+ kSignatureElementB = uint32_t(VecElementType::kB) << kSignatureRegElementTypeShift,
+ kSignatureElementH = uint32_t(VecElementType::kH) << kSignatureRegElementTypeShift,
+ kSignatureElementS = uint32_t(VecElementType::kS) << kSignatureRegElementTypeShift,
+ kSignatureElementD = uint32_t(VecElementType::kD) << kSignatureRegElementTypeShift,
+ kSignatureElementB4 = uint32_t(VecElementType::kB4) << kSignatureRegElementTypeShift,
+ kSignatureElementH2 = uint32_t(VecElementType::kH2) << kSignatureRegElementTypeShift
+ };
+ //! \endcond
+
+ //! Returns whether the register has element type or element index (or both).
+ ASMJIT_INLINE_NODEBUG constexpr bool hasElementTypeOrIndex() const noexcept { return _signature.hasField<kSignatureRegElementTypeMask | kSignatureRegElementFlagMask>(); }
+
+ //! Returns whether the vector register has associated a vector element type.
+ ASMJIT_INLINE_NODEBUG constexpr bool hasElementType() const noexcept { return _signature.hasField<kSignatureRegElementTypeMask>(); }
+ //! Returns vector element type of the register.
+ ASMJIT_INLINE_NODEBUG constexpr VecElementType elementType() const noexcept { return VecElementType(_signature.getField<kSignatureRegElementTypeMask>()); }
+ //! Sets vector element type of the register to `elementType`.
+ ASMJIT_INLINE_NODEBUG void setElementType(VecElementType elementType) noexcept { _signature.setField<kSignatureRegElementTypeMask>(uint32_t(elementType)); }
+ //! Resets vector element type to none.
+ ASMJIT_INLINE_NODEBUG void resetElementType() noexcept { _signature.setField<kSignatureRegElementTypeMask>(0); }
+
+ ASMJIT_INLINE_NODEBUG constexpr bool isVecB8() const noexcept {
+ return _signature.subset(uint32_t(kBaseSignatureMask) | uint32_t(kSignatureRegElementTypeMask)) == (RegTraits<RegType::kARM_VecD>::kSignature | kSignatureElementB);
+ }
+
+ ASMJIT_INLINE_NODEBUG constexpr bool isVecH4() const noexcept {
+ return _signature.subset(uint32_t(kBaseSignatureMask) | uint32_t(kSignatureRegElementTypeMask)) == (RegTraits<RegType::kARM_VecD>::kSignature | kSignatureElementH);
+ }
+
+ ASMJIT_INLINE_NODEBUG constexpr bool isVecS2() const noexcept {
+ return _signature.subset(uint32_t(kBaseSignatureMask) | uint32_t(kSignatureRegElementTypeMask)) == (RegTraits<RegType::kARM_VecD>::kSignature | kSignatureElementS);
+ }
+
+ ASMJIT_INLINE_NODEBUG constexpr bool isVecD1() const noexcept {
+ return _signature.subset(uint32_t(kBaseSignatureMask) | uint32_t(kSignatureRegElementTypeMask)) == (RegTraits<RegType::kARM_VecD>::kSignature);
+ }
+
+ ASMJIT_INLINE_NODEBUG constexpr bool isVecB16() const noexcept {
+ return _signature.subset(uint32_t(kBaseSignatureMask) | uint32_t(kSignatureRegElementTypeMask)) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementB);
+ }
+
+ ASMJIT_INLINE_NODEBUG constexpr bool isVecH8() const noexcept {
+ return _signature.subset(uint32_t(kBaseSignatureMask) | uint32_t(kSignatureRegElementTypeMask)) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementH);
+ }
+
+ ASMJIT_INLINE_NODEBUG constexpr bool isVecS4() const noexcept {
+ return _signature.subset(uint32_t(kBaseSignatureMask) | uint32_t(kSignatureRegElementTypeMask)) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementS);
+ }
+
+ ASMJIT_INLINE_NODEBUG constexpr bool isVecD2() const noexcept {
+ return _signature.subset(uint32_t(kBaseSignatureMask) | uint32_t(kSignatureRegElementTypeMask)) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementD);
+ }
+
+ ASMJIT_INLINE_NODEBUG constexpr bool isVecB4x4() const noexcept {
+ return _signature.subset(uint32_t(kBaseSignatureMask) | uint32_t(kSignatureRegElementTypeMask)) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementB4);
+ }
+
+ ASMJIT_INLINE_NODEBUG constexpr bool isVecH2x4() const noexcept {
+ return _signature.subset(uint32_t(kBaseSignatureMask) | uint32_t(kSignatureRegElementTypeMask)) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementH2);
+ }
+
+ //! Creates a cloned register with element access.
+ ASMJIT_INLINE_NODEBUG Vec at(uint32_t elementIndex) const noexcept {
+ return Vec((signature() & ~kSignatureRegElementIndexMask) | (elementIndex << kSignatureRegElementIndexShift) | kSignatureRegElementFlagMask, id());
+ }
+
+ //! Cast this register to an 8-bit B register (AArch64 only).
+ ASMJIT_INLINE_NODEBUG VecB b() const noexcept;
+ //! Cast this register to a 16-bit H register (AArch64 only).
+ ASMJIT_INLINE_NODEBUG VecH h() const noexcept;
+ //! Cast this register to a 32-bit S register.
+ ASMJIT_INLINE_NODEBUG VecS s() const noexcept;
+ //! Cast this register to a 64-bit D register.
+ ASMJIT_INLINE_NODEBUG VecD d() const noexcept;
+ //! Cast this register to a 128-bit Q register.
+ ASMJIT_INLINE_NODEBUG VecV q() const noexcept;
+ //! Cast this register to a 128-bit V register.
+ ASMJIT_INLINE_NODEBUG VecV v() const noexcept;
+
+ //! Casts this register to b (clone).
+ ASMJIT_INLINE_NODEBUG Vec v8() const noexcept;
+ //! Casts this register to h (clone).
+ ASMJIT_INLINE_NODEBUG Vec v16() const noexcept;
+ //! Casts this register to s (clone).
+ ASMJIT_INLINE_NODEBUG Vec v32() const noexcept;
+ //! Casts this register to d (clone).
+ ASMJIT_INLINE_NODEBUG Vec v64() const noexcept;
+ //! Casts this register to q (clone).
+ ASMJIT_INLINE_NODEBUG Vec v128() const noexcept;
+
+ //! Cast this register to a 128-bit V.B[elementIndex] register.
+ ASMJIT_INLINE_NODEBUG VecV b(uint32_t elementIndex) const noexcept;
+ //! Cast this register to a 128-bit V.H[elementIndex] register.
+ ASMJIT_INLINE_NODEBUG VecV h(uint32_t elementIndex) const noexcept;
+ //! Cast this register to a 128-bit V.S[elementIndex] register.
+ ASMJIT_INLINE_NODEBUG VecV s(uint32_t elementIndex) const noexcept;
+ //! Cast this register to a 128-bit V.D[elementIndex] register.
+ ASMJIT_INLINE_NODEBUG VecV d(uint32_t elementIndex) const noexcept;
+ //! Cast this register to a 128-bit V.H2[elementIndex] register.
+ ASMJIT_INLINE_NODEBUG VecV h2(uint32_t elementIndex) const noexcept;
+ //! Cast this register to a 128-bit V.B4[elementIndex] register.
+ ASMJIT_INLINE_NODEBUG VecV b4(uint32_t elementIndex) const noexcept;
+
+ //! Cast this register to V.8B.
+ ASMJIT_INLINE_NODEBUG VecD b8() const noexcept;
+ //! Cast this register to V.16B.
+ ASMJIT_INLINE_NODEBUG VecV b16() const noexcept;
+ //! Cast this register to V.2H.
+ ASMJIT_INLINE_NODEBUG VecS h2() const noexcept;
+ //! Cast this register to V.4H.
+ ASMJIT_INLINE_NODEBUG VecD h4() const noexcept;
+ //! Cast this register to V.8H.
+ ASMJIT_INLINE_NODEBUG VecV h8() const noexcept;
+ //! Cast this register to V.2S.
+ ASMJIT_INLINE_NODEBUG VecD s2() const noexcept;
+ //! Cast this register to V.4S.
+ ASMJIT_INLINE_NODEBUG VecV s4() const noexcept;
+ //! Cast this register to V.2D.
+ ASMJIT_INLINE_NODEBUG VecV d2() const noexcept;
+
+ static ASMJIT_INLINE_NODEBUG constexpr OperandSignature _makeElementAccessSignature(VecElementType elementType, uint32_t elementIndex) noexcept {
+ return OperandSignature{
+ uint32_t(RegTraits<RegType::kARM_VecV>::kSignature) |
+ uint32_t(kSignatureRegElementFlagMask) |
+ (uint32_t(elementType) << kSignatureRegElementTypeShift) |
+ (uint32_t(elementIndex << kSignatureRegElementIndexShift))};
+ }
+};
+
+//! 8-bit view (S) of VFP/SIMD register.
+class VecB : public Vec {
+public:
+ ASMJIT_DEFINE_FINAL_REG(VecB, Vec, RegTraits<RegType::kARM_VecB>)
+};
+
+//! 16-bit view (S) of VFP/SIMD register.
+class VecH : public Vec {
+public:
+ ASMJIT_DEFINE_FINAL_REG(VecH, Vec, RegTraits<RegType::kARM_VecH>)
+};
+
+//! 32-bit view (S) of VFP/SIMD register.
+class VecS : public Vec {
+public:
+ ASMJIT_DEFINE_FINAL_REG(VecS, Vec, RegTraits<RegType::kARM_VecS>)
+};
+
+//! 64-bit view (D) of VFP/SIMD register.
+class VecD : public Vec {
+public:
+ ASMJIT_DEFINE_FINAL_REG(VecD, Vec, RegTraits<RegType::kARM_VecD>)
+};
+
+//! 128-bit vector register (Q or V).
+class VecV : public Vec {
+public:
+ ASMJIT_DEFINE_FINAL_REG(VecV, Vec, RegTraits<RegType::kARM_VecV>)
+};
+
+ASMJIT_INLINE_NODEBUG VecB Vec::b() const noexcept { return VecB(id()); }
+ASMJIT_INLINE_NODEBUG VecH Vec::h() const noexcept { return VecH(id()); }
+ASMJIT_INLINE_NODEBUG VecS Vec::s() const noexcept { return VecS(id()); }
+ASMJIT_INLINE_NODEBUG VecD Vec::d() const noexcept { return VecD(id()); }
+ASMJIT_INLINE_NODEBUG VecV Vec::q() const noexcept { return VecV(id()); }
+ASMJIT_INLINE_NODEBUG VecV Vec::v() const noexcept { return VecV(id()); }
+
+ASMJIT_INLINE_NODEBUG Vec Vec::v8() const noexcept { return VecB(id()); }
+ASMJIT_INLINE_NODEBUG Vec Vec::v16() const noexcept { return VecH(id()); }
+ASMJIT_INLINE_NODEBUG Vec Vec::v32() const noexcept { return VecS(id()); }
+ASMJIT_INLINE_NODEBUG Vec Vec::v64() const noexcept { return VecD(id()); }
+ASMJIT_INLINE_NODEBUG Vec Vec::v128() const noexcept { return VecV(id()); }
+
+ASMJIT_INLINE_NODEBUG VecV Vec::b(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(VecElementType::kB, elementIndex), id()); }
+ASMJIT_INLINE_NODEBUG VecV Vec::h(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(VecElementType::kH, elementIndex), id()); }
+ASMJIT_INLINE_NODEBUG VecV Vec::s(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(VecElementType::kS, elementIndex), id()); }
+ASMJIT_INLINE_NODEBUG VecV Vec::d(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(VecElementType::kD, elementIndex), id()); }
+ASMJIT_INLINE_NODEBUG VecV Vec::h2(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(VecElementType::kH2, elementIndex), id()); }
+ASMJIT_INLINE_NODEBUG VecV Vec::b4(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(VecElementType::kB4, elementIndex), id()); }
+
+ASMJIT_INLINE_NODEBUG VecD Vec::b8() const noexcept { return VecD(OperandSignature{VecD::kSignature | kSignatureElementB}, id()); }
+ASMJIT_INLINE_NODEBUG VecS Vec::h2() const noexcept { return VecS(OperandSignature{VecS::kSignature | kSignatureElementH}, id()); }
+ASMJIT_INLINE_NODEBUG VecD Vec::h4() const noexcept { return VecD(OperandSignature{VecD::kSignature | kSignatureElementH}, id()); }
+ASMJIT_INLINE_NODEBUG VecD Vec::s2() const noexcept { return VecD(OperandSignature{VecD::kSignature | kSignatureElementS}, id()); }
+ASMJIT_INLINE_NODEBUG VecV Vec::b16() const noexcept { return VecV(OperandSignature{VecV::kSignature | kSignatureElementB}, id()); }
+ASMJIT_INLINE_NODEBUG VecV Vec::h8() const noexcept { return VecV(OperandSignature{VecV::kSignature | kSignatureElementH}, id()); }
+ASMJIT_INLINE_NODEBUG VecV Vec::s4() const noexcept { return VecV(OperandSignature{VecV::kSignature | kSignatureElementS}, id()); }
+ASMJIT_INLINE_NODEBUG VecV Vec::d2() const noexcept { return VecV(OperandSignature{VecV::kSignature | kSignatureElementD}, id()); }
#ifndef _DOXYGEN
namespace regs {
#endif
-using namespace ::asmjit::arm::regs;
+//! Creates a 32-bit W register operand.
+static ASMJIT_INLINE_NODEBUG constexpr GpW w(uint32_t id) noexcept { return GpW(id); }
+//! Creates a 64-bit X register operand.
+static ASMJIT_INLINE_NODEBUG constexpr GpX x(uint32_t id) noexcept { return GpX(id); }
+
+//! Creates a 32-bit S register operand.
+static ASMJIT_INLINE_NODEBUG constexpr VecS s(uint32_t id) noexcept { return VecS(id); }
+//! Creates a 64-bit D register operand.
+static ASMJIT_INLINE_NODEBUG constexpr VecD d(uint32_t id) noexcept { return VecD(id); }
+//! Creates a 1282-bit V register operand.
+static ASMJIT_INLINE_NODEBUG constexpr VecV v(uint32_t id) noexcept { return VecV(id); }
static constexpr GpW w0 = GpW(0);
static constexpr GpW w1 = GpW(1);
@@ -305,8 +585,94 @@ static constexpr VecV v31 = VecV(31);
using namespace regs;
#endif
+//! \name Shift Operation Construction
+//! \{
+
+//! Constructs a `UXTB #value` extend and shift (unsigned byte extend) (AArch64).
+static ASMJIT_INLINE_NODEBUG constexpr Shift uxtb(uint32_t value) noexcept { return Shift(ShiftOp::kUXTB, value); }
+//! Constructs a `UXTH #value` extend and shift (unsigned hword extend) (AArch64).
+static ASMJIT_INLINE_NODEBUG constexpr Shift uxth(uint32_t value) noexcept { return Shift(ShiftOp::kUXTH, value); }
+//! Constructs a `UXTW #value` extend and shift (unsigned word extend) (AArch64).
+static ASMJIT_INLINE_NODEBUG constexpr Shift uxtw(uint32_t value) noexcept { return Shift(ShiftOp::kUXTW, value); }
+//! Constructs a `UXTX #value` extend and shift (unsigned dword extend) (AArch64).
+static ASMJIT_INLINE_NODEBUG constexpr Shift uxtx(uint32_t value) noexcept { return Shift(ShiftOp::kUXTX, value); }
+
+//! Constructs a `SXTB #value` extend and shift (signed byte extend) (AArch64).
+static ASMJIT_INLINE_NODEBUG constexpr Shift sxtb(uint32_t value) noexcept { return Shift(ShiftOp::kSXTB, value); }
+//! Constructs a `SXTH #value` extend and shift (signed hword extend) (AArch64).
+static ASMJIT_INLINE_NODEBUG constexpr Shift sxth(uint32_t value) noexcept { return Shift(ShiftOp::kSXTH, value); }
+//! Constructs a `SXTW #value` extend and shift (signed word extend) (AArch64).
+static ASMJIT_INLINE_NODEBUG constexpr Shift sxtw(uint32_t value) noexcept { return Shift(ShiftOp::kSXTW, value); }
+//! Constructs a `SXTX #value` extend and shift (signed dword extend) (AArch64).
+static ASMJIT_INLINE_NODEBUG constexpr Shift sxtx(uint32_t value) noexcept { return Shift(ShiftOp::kSXTX, value); }
+
+//! \}
+
+//! \name Memory Operand Construction
+//! \{
+
+//! Creates `[base, offset]` memory operand (offset mode) (AArch64).
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr(const Gp& base, int32_t offset = 0) noexcept {
+ return Mem(base, offset);
+}
+
+//! Creates `[base, offset]!` memory operand (pre-index mode) (AArch64).
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr_pre(const Gp& base, int32_t offset = 0) noexcept {
+ return Mem(base, offset, OperandSignature::fromValue<Mem::kSignatureMemOffsetModeMask>(OffsetMode::kPreIndex));
+}
+
+//! Creates `[base], offset` memory operand (post-index mode) (AArch64).
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr_post(const Gp& base, int32_t offset = 0) noexcept {
+ return Mem(base, offset, OperandSignature::fromValue<Mem::kSignatureMemOffsetModeMask>(OffsetMode::kPostIndex));
+}
+
+//! Creates `[base, index]` memory operand (AArch64).
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr(const Gp& base, const Gp& index) noexcept {
+ return Mem(base, index);
+}
+
+//! Creates `[base, index]!` memory operand (pre-index mode) (AArch64).
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr_pre(const Gp& base, const Gp& index) noexcept {
+ return Mem(base, index, OperandSignature::fromValue<Mem::kSignatureMemOffsetModeMask>(OffsetMode::kPreIndex));
+}
+
+//! Creates `[base], index` memory operand (post-index mode) (AArch64).
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr_post(const Gp& base, const Gp& index) noexcept {
+ return Mem(base, index, OperandSignature::fromValue<Mem::kSignatureMemOffsetModeMask>(OffsetMode::kPostIndex));
+}
+
+//! Creates `[base, index, SHIFT_OP #shift]` memory operand (AArch64).
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr(const Gp& base, const Gp& index, const Shift& shift) noexcept {
+ return Mem(base, index, shift);
+}
+
+//! Creates `[base, offset]` memory operand (AArch64).
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr(const Label& base, int32_t offset = 0) noexcept {
+ return Mem(base, offset);
+}
+
+// TODO: [ARM] PC + offset address.
+#if 0
+//! Creates `[PC + offset]` (relative) memory operand.
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr(const PC& pc, int32_t offset = 0) noexcept {
+ return Mem(pc, offset);
+}
+#endif
+
+//! \}
+
//! \}
ASMJIT_END_SUB_NAMESPACE
+//! \cond INTERNAL
+ASMJIT_BEGIN_NAMESPACE
+ASMJIT_DEFINE_TYPE_ID(a64::GpW, TypeId::kInt32);
+ASMJIT_DEFINE_TYPE_ID(a64::GpX, TypeId::kInt64);
+ASMJIT_DEFINE_TYPE_ID(a64::VecS, TypeId::kFloat32x1);
+ASMJIT_DEFINE_TYPE_ID(a64::VecD, TypeId::kFloat64x1);
+ASMJIT_DEFINE_TYPE_ID(a64::VecV, TypeId::kInt32x4);
+ASMJIT_END_NAMESPACE
+//! \endcond
+
#endif // ASMJIT_ARM_A64OPERAND_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64rapass.cpp b/3rdparty/asmjit/src/asmjit/arm/a64rapass.cpp
index aaec1c90f99..b97f259efa0 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64rapass.cpp
+++ b/3rdparty/asmjit/src/asmjit/arm/a64rapass.cpp
@@ -131,7 +131,7 @@ Error RACFGBuilder::onInst(InstNode* inst, InstControlFlow& controlType, RAInstB
InstId instId = inst->id();
uint32_t opCount = inst->opCount();
const Operand* opArray = inst->operands();
- ASMJIT_PROPAGATE(InstInternal::queryRWInfo(_arch, inst->baseInst(), opArray, opCount, &rwInfo));
+ ASMJIT_PROPAGATE(InstInternal::queryRWInfo(inst->baseInst(), opArray, opCount, &rwInfo));
const InstDB::InstInfo& instInfo = InstDB::infoById(instId);
uint32_t singleRegOps = 0;
@@ -230,7 +230,7 @@ Error RACFGBuilder::onInst(InstNode* inst, InstControlFlow& controlType, RAInstB
if (reg.as<Vec>().hasElementIndex()) {
// Only the first 0..15 registers can be used if the register uses
// element accessor that accesses half-words (h[0..7] elements).
- if (instInfo.hasFlag(InstDB::kInstFlagVH0_15) && reg.as<Vec>().elementType() == Vec::kElementTypeH) {
+ if (instInfo.hasFlag(InstDB::kInstFlagVH0_15) && reg.as<Vec>().elementType() == VecElementType::kH) {
if (Support::test(flags, RATiedFlags::kUse))
useId &= 0x0000FFFFu;
else
@@ -595,14 +595,14 @@ void ARMRAPass::onInit() noexcept {
_archTraits = &ArchTraits::byArch(arch);
_physRegCount.set(RegGroup::kGp, 32);
_physRegCount.set(RegGroup::kVec, 32);
- _physRegCount.set(RegGroup::kExtraVirt2, 0);
+ _physRegCount.set(RegGroup::kMask, 0);
_physRegCount.set(RegGroup::kExtraVirt3, 0);
_buildPhysIndex();
_availableRegCount = _physRegCount;
_availableRegs[RegGroup::kGp] = Support::lsbMask<uint32_t>(_physRegCount.get(RegGroup::kGp));
_availableRegs[RegGroup::kVec] = Support::lsbMask<uint32_t>(_physRegCount.get(RegGroup::kVec));
- _availableRegs[RegGroup::kExtraVirt3] = Support::lsbMask<uint32_t>(_physRegCount.get(RegGroup::kExtraVirt2));
+ _availableRegs[RegGroup::kMask] = Support::lsbMask<uint32_t>(_physRegCount.get(RegGroup::kMask));
_availableRegs[RegGroup::kExtraVirt3] = Support::lsbMask<uint32_t>(_physRegCount.get(RegGroup::kExtraVirt3));
_scratchRegIndexes[0] = uint8_t(27);
@@ -612,7 +612,9 @@ void ARMRAPass::onInit() noexcept {
// make unavailable all registers that are special and cannot be used in general.
bool hasFP = _func->frame().hasPreservedFP();
- if (hasFP)
+ // Apple ABI requires that the frame-pointer register is not changed by leaf functions and properly updated
+ // by non-leaf functions. So, let's make this register unavailable as it's just not safe to update it.
+ if (hasFP || cc()->environment().isDarwin())
makeUnavailable(RegGroup::kGp, Gp::kIdFp);
makeUnavailable(RegGroup::kGp, Gp::kIdSp);
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64rapass_p.h b/3rdparty/asmjit/src/asmjit/arm/a64rapass_p.h
index e1a90ab8df7..73130873f44 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64rapass_p.h
+++ b/3rdparty/asmjit/src/asmjit/arm/a64rapass_p.h
@@ -37,7 +37,7 @@ public:
//! \{
ARMRAPass() noexcept;
- virtual ~ARMRAPass() noexcept;
+ ~ARMRAPass() noexcept override;
//! \}
@@ -45,10 +45,10 @@ public:
//! \{
//! Returns the compiler casted to `arm::Compiler`.
- inline Compiler* cc() const noexcept { return static_cast<Compiler*>(_cb); }
+ ASMJIT_INLINE_NODEBUG Compiler* cc() const noexcept { return static_cast<Compiler*>(_cb); }
//! Returns emit helper.
- inline EmitHelper* emitHelper() noexcept { return &_emitHelper; }
+ ASMJIT_INLINE_NODEBUG EmitHelper* emitHelper() noexcept { return &_emitHelper; }
//! \}
diff --git a/3rdparty/asmjit/src/asmjit/arm/armformatter.cpp b/3rdparty/asmjit/src/asmjit/arm/armformatter.cpp
index 0432043106a..3fe2c6b911c 100644
--- a/3rdparty/asmjit/src/asmjit/arm/armformatter.cpp
+++ b/3rdparty/asmjit/src/asmjit/arm/armformatter.cpp
@@ -9,7 +9,7 @@
#include "../core/misc_p.h"
#include "../core/support.h"
#include "../arm/armformatter_p.h"
-#include "../arm/armoperand.h"
+#include "../arm/a64operand.h"
#include "../arm/a64instapi_p.h"
#include "../arm/a64instdb_p.h"
@@ -26,78 +26,225 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
// @EnumStringBegin{"enum": "CpuFeatures::ARM", "output": "sFeature", "strip": "k"}@
static const char sFeatureString[] =
"None\0"
- "THUMB\0"
- "THUMBv2\0"
"ARMv6\0"
"ARMv7\0"
"ARMv8a\0"
- "ARMv8_1a\0"
- "ARMv8_2a\0"
- "ARMv8_3a\0"
- "ARMv8_4a\0"
- "ARMv8_5a\0"
- "ARMv8_6a\0"
- "ARMv8_7a\0"
- "VFPv2\0"
- "VFPv3\0"
- "VFPv4\0"
- "VFP_D32\0"
+ "THUMB\0"
+ "THUMBv2\0"
+ "ABLE\0"
+ "ADERR\0"
"AES\0"
- "ALTNZCV\0"
+ "AFP\0"
+ "AIE\0"
+ "AMU1\0"
+ "AMU1_1\0"
+ "ANERR\0"
"ASIMD\0"
"BF16\0"
+ "BRBE\0"
"BTI\0"
+ "BWE\0"
+ "CCIDX\0"
+ "CHK\0"
+ "CLRBHB\0"
+ "CMOW\0"
+ "CONSTPACFIELD\0"
+ "CPA\0"
+ "CPA2\0"
"CPUID\0"
"CRC32\0"
+ "CSSC\0"
+ "CSV2\0"
+ "CSV2_3\0"
+ "CSV3\0"
+ "D128\0"
"DGH\0"
"DIT\0"
"DOTPROD\0"
+ "DPB\0"
+ "DPB2\0"
+ "EBEP\0"
+ "EBF16\0"
+ "ECBHB\0"
+ "ECV\0"
+ "EDHSR\0"
"EDSP\0"
+ "FAMINMAX\0"
"FCMA\0"
- "FJCVTZS\0"
+ "FGT\0"
+ "FGT2\0"
+ "FHM\0"
"FLAGM\0"
+ "FLAGM2\0"
+ "FMAC\0"
+ "FP\0"
+ "FP16\0"
"FP16CONV\0"
- "FP16FML\0"
- "FP16FULL\0"
- "FRINT\0"
+ "FP8\0"
+ "FP8DOT2\0"
+ "FP8DOT4\0"
+ "FP8FMA\0"
+ "FPMR\0"
+ "FRINTTS\0"
+ "GCS\0"
+ "HACDBS\0"
+ "HAFDBS\0"
+ "HAFT\0"
+ "HDBSS\0"
+ "HBC\0"
+ "HCX\0"
+ "HPDS\0"
+ "HPDS2\0"
"I8MM\0"
"IDIVA\0"
"IDIVT\0"
+ "ITE\0"
+ "JSCVT\0"
+ "LOR\0"
+ "LRCPC\0"
+ "LRCPC2\0"
+ "LRCPC3\0"
+ "LS64\0"
+ "LS64_ACCDATA\0"
+ "LS64_V\0"
"LSE\0"
+ "LSE128\0"
+ "LSE2\0"
+ "LUT\0"
+ "LVA\0"
+ "LVA3\0"
+ "MEC\0"
+ "MOPS\0"
+ "MPAM\0"
"MTE\0"
- "RCPC_IMMO\0"
- "RDM\0"
+ "MTE2\0"
+ "MTE3\0"
+ "MTE4\0"
+ "MTE_ASYM_FAULT\0"
+ "MTE_ASYNC\0"
+ "MTE_CANONICAL_TAGS\0"
+ "MTE_NO_ADDRESS_TAGS\0"
+ "MTE_PERM_S1\0"
+ "MTE_STORE_ONLY\0"
+ "MTE_TAGGED_FAR\0"
+ "MTPMU\0"
+ "NMI\0"
+ "NV\0"
+ "NV2\0"
+ "PAN\0"
+ "PAN2\0"
+ "PAN3\0"
+ "PAUTH\0"
+ "PFAR\0"
"PMU\0"
"PMULL\0"
+ "PRFMSLC\0"
+ "RAS\0"
+ "RAS1_1\0"
+ "RAS2\0"
+ "RASSA2\0"
+ "RDM\0"
+ "RME\0"
"RNG\0"
+ "RNG_TRAP\0"
+ "RPRES\0"
+ "RPRFM\0"
+ "S1PIE\0"
+ "S1POE\0"
+ "S2PIE\0"
+ "S2POE\0"
"SB\0"
+ "SCTLR2\0"
+ "SEBEP\0"
+ "SEL2\0"
"SHA1\0"
- "SHA2\0"
+ "SHA256\0"
"SHA3\0"
"SHA512\0"
"SM3\0"
"SM4\0"
+ "SME\0"
+ "SME2\0"
+ "SME2_1\0"
+ "SME_B16B16\0"
+ "SME_B16F32\0"
+ "SME_BI32I32\0"
+ "SME_F16F16\0"
+ "SME_F16F32\0"
+ "SME_F32F32\0"
+ "SME_F64F64\0"
+ "SME_F8F16\0"
+ "SME_F8F32\0"
+ "SME_FA64\0"
+ "SME_I16I32\0"
+ "SME_I16I64\0"
+ "SME_I8I32\0"
+ "SME_LUTv2\0"
+ "SPE\0"
+ "SPE1_1\0"
+ "SPE1_2\0"
+ "SPE1_3\0"
+ "SPE1_4\0"
+ "SPE_ALTCLK\0"
+ "SPE_CRR\0"
+ "SPE_EFT\0"
+ "SPE_FDS\0"
+ "SPE_FPF\0"
+ "SPE_SME\0"
+ "SPECRES\0"
+ "SPECRES2\0"
+ "SPMU\0"
"SSBS\0"
+ "SSBS2\0"
+ "SSVE_FP8DOT2\0"
+ "SSVE_FP8DOT4\0"
+ "SSVE_FP8FMA\0"
"SVE\0"
+ "SVE2\0"
+ "SVE2_1\0"
+ "SVE_AES\0"
+ "SVE_B16B16\0"
"SVE_BF16\0"
+ "SVE_BITPERM\0"
+ "SVE_EBF16\0"
"SVE_F32MM\0"
"SVE_F64MM\0"
"SVE_I8MM\0"
- "SVE_PMULL\0"
- "SVE2\0"
- "SVE2_AES\0"
- "SVE2_BITPERM\0"
- "SVE2_SHA3\0"
- "SVE2_SM4\0"
+ "SVE_PMULL128\0"
+ "SVE_SHA3\0"
+ "SVE_SM4\0"
+ "SYSINSTR128\0"
+ "SYSREG128\0"
+ "THE\0"
+ "TLBIOS\0"
+ "TLBIRANGE\0"
+ "TLBIW\0"
"TME\0"
+ "TRF\0"
+ "UAO\0"
+ "VFP_D32\0"
+ "VHE\0"
+ "VMID16\0"
+ "WFXT\0"
+ "XNX\0"
+ "XS\0"
"<Unknown>\0";
static const uint16_t sFeatureIndex[] = {
- 0, 5, 11, 19, 25, 31, 38, 47, 56, 65, 74, 83, 92, 101, 107, 113, 119, 127,
- 131, 139, 145, 150, 154, 160, 166, 170, 174, 182, 187, 192, 200, 206, 215,
- 223, 232, 238, 243, 249, 255, 259, 263, 273, 277, 281, 287, 291, 294, 299,
- 304, 309, 316, 320, 324, 329, 333, 342, 352, 362, 371, 381, 386, 395, 408,
- 418, 427, 431
+ 0, 5, 11, 17, 24, 30, 38, 43, 49, 53, 57, 61, 66, 73, 79, 85, 90, 95, 99,
+ 103, 109, 113, 120, 125, 139, 143, 148, 154, 160, 165, 170, 177, 182, 187,
+ 191, 195, 203, 207, 212, 217, 223, 229, 233, 239, 244, 253, 258, 262, 267,
+ 271, 277, 284, 289, 292, 297, 306, 310, 318, 326, 333, 338, 346, 350, 357,
+ 364, 369, 375, 379, 383, 388, 394, 399, 405, 411, 415, 421, 425, 431, 438,
+ 445, 450, 463, 470, 474, 481, 486, 490, 494, 499, 503, 508, 513, 517, 522,
+ 527, 532, 547, 557, 576, 596, 608, 623, 638, 644, 648, 651, 655, 659, 664,
+ 669, 675, 680, 684, 690, 698, 702, 709, 714, 721, 725, 729, 733, 742, 748,
+ 754, 760, 766, 772, 778, 781, 788, 794, 799, 804, 811, 816, 823, 827, 831,
+ 835, 840, 847, 858, 869, 881, 892, 903, 914, 925, 935, 945, 954, 965, 976,
+ 986, 996, 1000, 1007, 1014, 1021, 1028, 1039, 1047, 1055, 1063, 1071, 1079,
+ 1087, 1096, 1101, 1106, 1112, 1125, 1138, 1150, 1154, 1159, 1166, 1174, 1185,
+ 1194, 1206, 1216, 1226, 1236, 1245, 1258, 1267, 1275, 1287, 1297, 1301, 1308,
+ 1318, 1324, 1328, 1332, 1336, 1344, 1348, 1355, 1360, 1364, 1367
};
// @EnumStringEnd@
@@ -111,14 +258,14 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatCondCode(String& sb, CondCode c
static const char condCodeData[] =
"al\0" "na\0"
"eq\0" "ne\0"
- "cs\0" "cc\0" "mi\0" "pl\0" "vs\0" "vc\0"
+ "hs\0" "lo\0" "mi\0" "pl\0" "vs\0" "vc\0"
"hi\0" "ls\0" "ge\0" "lt\0" "gt\0" "le\0"
"<Unknown>";
return sb.append(condCodeData + Support::min<uint32_t>(uint32_t(cc), 16u) * 3);
}
ASMJIT_FAVOR_SIZE Error FormatterInternal::formatShiftOp(String& sb, ShiftOp shiftOp) noexcept {
- const char* str = "<Unknown>";
+ const char* str = nullptr;
switch (shiftOp) {
case ShiftOp::kLSL: str = "lsl"; break;
case ShiftOp::kLSR: str = "lsr"; break;
@@ -134,10 +281,308 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatShiftOp(String& sb, ShiftOp shi
case ShiftOp::kSXTH: str = "sxth"; break;
case ShiftOp::kSXTW: str = "sxtw"; break;
case ShiftOp::kSXTX: str = "sxtx"; break;
+ default: str = "<Unknown>"; break;
}
return sb.append(str);
}
+// arm::FormatterInternal - Format Register
+// ========================================
+
+struct FormatElementData {
+ char letter;
+ uint8_t elementCount;
+ uint8_t onlyIndex;
+ uint8_t reserved;
+};
+
+static constexpr FormatElementData formatElementDataTable[9] = {
+ { '?' , 0 , 0, 0 }, // None
+ { 'b' , 16, 0, 0 }, // bX or b[index]
+ { 'h' , 8 , 0, 0 }, // hX or h[index]
+ { 's' , 4 , 0, 0 }, // sX or s[index]
+ { 'd' , 2 , 0, 0 }, // dX or d[index]
+ { 'b' , 4 , 1, 0 }, // ?? or b4[index]
+ { 'h' , 2 , 1, 0 }, // ?? or h2[index]
+ { '?' , 0 , 0, 0 }, // invalid (possibly stored in Operand)
+ { '?' , 0 , 0, 0 } // invalid (never stored in Operand, bug...)
+};
+
+ASMJIT_FAVOR_SIZE Error FormatterInternal::formatRegister(
+ String& sb,
+ FormatFlags flags,
+ const BaseEmitter* emitter,
+ Arch arch,
+ RegType regType,
+ uint32_t rId,
+ uint32_t elementType,
+ uint32_t elementIndex) noexcept {
+
+ DebugUtils::unused(flags);
+ DebugUtils::unused(arch);
+
+ static const char bhsdq[] = "bhsdq";
+
+ bool virtRegFormatted = false;
+
+#ifndef ASMJIT_NO_COMPILER
+ if (Operand::isVirtId(rId)) {
+ if (emitter && emitter->isCompiler()) {
+ const BaseCompiler* cc = static_cast<const BaseCompiler*>(emitter);
+ if (cc->isVirtIdValid(rId)) {
+ VirtReg* vReg = cc->virtRegById(rId);
+ 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))));
+
+ virtRegFormatted = true;
+ }
+ }
+ }
+#else
+ DebugUtils::unused(emitter, flags);
+#endif
+
+ if (!virtRegFormatted) {
+ char letter = '\0';
+ switch (regType) {
+ case RegType::kARM_VecB:
+ case RegType::kARM_VecH:
+ case RegType::kARM_VecS:
+ case RegType::kARM_VecD:
+ case RegType::kARM_VecV:
+ letter = bhsdq[uint32_t(regType) - uint32_t(RegType::kARM_VecB)];
+ if (elementType)
+ letter = 'v';
+ break;
+
+ case RegType::kARM_GpW:
+ if (Environment::is64Bit(arch)) {
+ letter = 'w';
+
+ if (rId == a64::Gp::kIdZr)
+ return sb.append("wzr", 3);
+
+ if (rId == a64::Gp::kIdSp)
+ return sb.append("wsp", 3);
+ }
+ else {
+ letter = 'r';
+ }
+ break;
+
+ case RegType::kARM_GpX:
+ if (Environment::is64Bit(arch)) {
+ if (rId == a64::Gp::kIdZr)
+ return sb.append("xzr", 3);
+ if (rId == a64::Gp::kIdSp)
+ return sb.append("sp", 2);
+
+ letter = 'x';
+ break;
+ }
+
+ // X registers are undefined in 32-bit mode.
+ ASMJIT_FALLTHROUGH;
+
+ default:
+ ASMJIT_PROPAGATE(sb.appendFormat("<Reg-%u>?%u", uint32_t(regType), rId));
+ break;
+ }
+
+ if (letter)
+ ASMJIT_PROPAGATE(sb.appendFormat("%c%u", letter, rId));
+ }
+
+ constexpr uint32_t kElementTypeCount = uint32_t(a64::VecElementType::kMaxValue) + 1;
+ if (elementType) {
+ elementType = Support::min(elementType, kElementTypeCount);
+
+ FormatElementData elementData = formatElementDataTable[elementType];
+ uint32_t elementCount = elementData.elementCount;
+
+ if (regType == RegType::kARM_VecD) {
+ elementCount /= 2u;
+ }
+
+ ASMJIT_PROPAGATE(sb.append('.'));
+ if (elementCount) {
+ ASMJIT_PROPAGATE(sb.appendUInt(elementCount));
+ }
+ ASMJIT_PROPAGATE(sb.append(elementData.letter));
+ }
+
+ if (elementIndex != 0xFFFFFFFFu) {
+ ASMJIT_PROPAGATE(sb.appendFormat("[%u]", elementIndex));
+ }
+
+ return kErrorOk;
+}
+
+ASMJIT_FAVOR_SIZE Error FormatterInternal::formatRegisterList(
+ String& sb,
+ FormatFlags flags,
+ const BaseEmitter* emitter,
+ Arch arch,
+ RegType regType,
+ uint32_t rMask) noexcept {
+
+ bool first = true;
+
+ ASMJIT_PROPAGATE(sb.append('{'));
+ while (rMask != 0u) {
+ uint32_t start = Support::ctz(rMask);
+ uint32_t count = 0u;
+
+ uint32_t mask = 1u << start;
+ do {
+ rMask &= ~mask;
+ mask <<= 1u;
+ count++;
+ } while (rMask & mask);
+
+ if (!first)
+ ASMJIT_PROPAGATE(sb.append(", "));
+
+ ASMJIT_PROPAGATE(formatRegister(sb, flags, emitter, arch, regType, start, 0, 0xFFFFFFFFu));
+ if (count >= 2u) {
+ ASMJIT_PROPAGATE(sb.append('-'));
+ ASMJIT_PROPAGATE(formatRegister(sb, flags, emitter, arch, regType, start + count - 1, 0, 0xFFFFFFFFu));
+ }
+
+ first = false;
+ }
+ ASMJIT_PROPAGATE(sb.append('}'));
+
+ return kErrorOk;
+}
+
+// a64::FormatterInternal - Format Operand
+// =======================================
+
+ASMJIT_FAVOR_SIZE Error FormatterInternal::formatOperand(
+ String& sb,
+ FormatFlags flags,
+ const BaseEmitter* emitter,
+ Arch arch,
+ const Operand_& op) noexcept {
+
+ if (op.isReg()) {
+ const BaseReg& reg = op.as<BaseReg>();
+
+ uint32_t elementType = op._signature.getField<BaseVec::kSignatureRegElementTypeMask>();
+ uint32_t elementIndex = op.as<BaseVec>().elementIndex();
+
+ if (!op.as<BaseVec>().hasElementIndex())
+ elementIndex = 0xFFFFFFFFu;
+
+ return formatRegister(sb, flags, emitter, arch, reg.type(), reg.id(), elementType, elementIndex);
+ }
+
+ if (op.isMem()) {
+ const Mem& m = op.as<Mem>();
+ ASMJIT_PROPAGATE(sb.append('['));
+
+ if (m.hasBase()) {
+ if (m.hasBaseLabel()) {
+ ASMJIT_PROPAGATE(Formatter::formatLabel(sb, flags, emitter, m.baseId()));
+ }
+ else {
+ FormatFlags modifiedFlags = flags;
+ if (m.isRegHome()) {
+ ASMJIT_PROPAGATE(sb.append('&'));
+ modifiedFlags &= ~FormatFlags::kRegCasts;
+ }
+ ASMJIT_PROPAGATE(formatRegister(sb, modifiedFlags, emitter, arch, m.baseType(), m.baseId()));
+ }
+ }
+ else {
+ // ARM really requires base.
+ if (m.hasIndex() || m.hasOffset()) {
+ ASMJIT_PROPAGATE(sb.append("<None>"));
+ }
+ }
+
+ // The post index makes it look like there was another operand, but it's
+ // still the part of AsmJit's `arm::Mem` operand so it's consistent with
+ // other architectures.
+ if (m.isPostIndex())
+ ASMJIT_PROPAGATE(sb.append(']'));
+
+ if (m.hasIndex()) {
+ ASMJIT_PROPAGATE(sb.append(", "));
+ ASMJIT_PROPAGATE(formatRegister(sb, flags, emitter, arch, m.indexType(), m.indexId()));
+ }
+
+ if (m.hasOffset()) {
+ ASMJIT_PROPAGATE(sb.append(", "));
+
+ int64_t off = int64_t(m.offset());
+ uint32_t base = 10;
+
+ if (Support::test(flags, FormatFlags::kHexOffsets) && uint64_t(off) > 9)
+ base = 16;
+
+ if (base == 10) {
+ ASMJIT_PROPAGATE(sb.appendInt(off, base));
+ }
+ else {
+ ASMJIT_PROPAGATE(sb.append("0x"));
+ ASMJIT_PROPAGATE(sb.appendUInt(uint64_t(off), base));
+ }
+ }
+
+ if (m.hasShift()) {
+ ASMJIT_PROPAGATE(sb.append(' '));
+ if (!m.isPreOrPost())
+ ASMJIT_PROPAGATE(formatShiftOp(sb, m.shiftOp()));
+ ASMJIT_PROPAGATE(sb.appendFormat(" %u", m.shift()));
+ }
+
+ if (!m.isPostIndex())
+ ASMJIT_PROPAGATE(sb.append(']'));
+
+ if (m.isPreIndex())
+ ASMJIT_PROPAGATE(sb.append('!'));
+
+ return kErrorOk;
+ }
+
+ if (op.isImm()) {
+ const Imm& i = op.as<Imm>();
+ int64_t val = i.value();
+ uint32_t predicate = i.predicate();
+
+ if (predicate) {
+ ASMJIT_PROPAGATE(formatShiftOp(sb, ShiftOp(predicate)));
+ ASMJIT_PROPAGATE(sb.append(' '));
+ }
+
+ if (Support::test(flags, FormatFlags::kHexImms) && uint64_t(val) > 9) {
+ ASMJIT_PROPAGATE(sb.append("0x"));
+ return sb.appendUInt(uint64_t(val), 16);
+ }
+ else {
+ return sb.appendInt(val, 10);
+ }
+ }
+
+ if (op.isLabel()) {
+ return Formatter::formatLabel(sb, flags, emitter, op.id());
+ }
+
+ if (op.isRegList()) {
+ const BaseRegList& regList = op.as<BaseRegList>();
+ return formatRegisterList(sb, flags, emitter, arch, regList.type(), regList.list());
+ }
+
+ return sb.append("<None>");
+}
+
ASMJIT_END_SUB_NAMESPACE
#endif // !ASMJIT_NO_LOGGING
diff --git a/3rdparty/asmjit/src/asmjit/arm/armformatter_p.h b/3rdparty/asmjit/src/asmjit/arm/armformatter_p.h
index 582173054a8..20b4812e913 100644
--- a/3rdparty/asmjit/src/asmjit/arm/armformatter_p.h
+++ b/3rdparty/asmjit/src/asmjit/arm/armformatter_p.h
@@ -33,6 +33,31 @@ Error ASMJIT_CDECL formatShiftOp(
String& sb,
ShiftOp shiftOp) noexcept;
+Error ASMJIT_CDECL formatRegister(
+ String& sb,
+ FormatFlags flags,
+ const BaseEmitter* emitter,
+ Arch arch,
+ RegType regType,
+ uint32_t rId,
+ uint32_t elementType = 0,
+ uint32_t elementIndex = 0xFFFFFFFF) noexcept;
+
+Error ASMJIT_CDECL formatRegisterList(
+ String& sb,
+ FormatFlags flags,
+ const BaseEmitter* emitter,
+ Arch arch,
+ RegType regType,
+ uint32_t rMask) noexcept;
+
+Error ASMJIT_CDECL formatOperand(
+ String& sb,
+ FormatFlags flags,
+ const BaseEmitter* emitter,
+ Arch arch,
+ const Operand_& op) noexcept;
+
} // {FormatterInternal}
//! \}
diff --git a/3rdparty/asmjit/src/asmjit/arm/armglobals.h b/3rdparty/asmjit/src/asmjit/arm/armglobals.h
index 506646f8068..851f6708601 100644
--- a/3rdparty/asmjit/src/asmjit/arm/armglobals.h
+++ b/3rdparty/asmjit/src/asmjit/arm/armglobals.h
@@ -14,8 +14,4 @@
//!
//! API shared between AArch32 & AArch64 backends.
-ASMJIT_BEGIN_SUB_NAMESPACE(arm)
-
-ASMJIT_END_SUB_NAMESPACE
-
#endif // ASMJIT_ARM_ARMGLOBALS_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/arm/armoperand.h b/3rdparty/asmjit/src/asmjit/arm/armoperand.h
index ede829d9c18..583a3d8c326 100644
--- a/3rdparty/asmjit/src/asmjit/arm/armoperand.h
+++ b/3rdparty/asmjit/src/asmjit/arm/armoperand.h
@@ -19,18 +19,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(arm)
class Reg;
class Mem;
-class Gp;
-class GpW;
-class GpX;
-
-class Vec;
-class VecB;
-class VecH;
-class VecS;
-class VecD;
-class VecV;
-
-//! Register traits (ARM/AArch64).
+//! Register traits (AArch32/AArch64).
//!
//! 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
@@ -39,128 +28,106 @@ template<RegType kRegType>
struct RegTraits : public BaseRegTraits {};
//! \cond
-// <--------------------+-----+-------------------------+------------------------+---+---+------------------+
-// | Reg | Reg-Type | Reg-Group |Sz |Cnt| TypeId |
-// <--------------------+-----+-------------------------+------------------------+---+---+------------------+
-ASMJIT_DEFINE_REG_TRAITS(GpW , RegType::kARM_GpW , RegGroup::kGp , 4 , 32, TypeId::kInt32 );
-ASMJIT_DEFINE_REG_TRAITS(GpX , RegType::kARM_GpX , RegGroup::kGp , 8 , 32, TypeId::kInt64 );
-ASMJIT_DEFINE_REG_TRAITS(VecB , RegType::kARM_VecB , RegGroup::kVec , 1 , 32, TypeId::kVoid );
-ASMJIT_DEFINE_REG_TRAITS(VecH , RegType::kARM_VecH , RegGroup::kVec , 2 , 32, TypeId::kVoid );
-ASMJIT_DEFINE_REG_TRAITS(VecS , RegType::kARM_VecS , RegGroup::kVec , 4 , 32, TypeId::kInt32x1 );
-ASMJIT_DEFINE_REG_TRAITS(VecD , RegType::kARM_VecD , RegGroup::kVec , 8 , 32, TypeId::kInt32x2 );
-ASMJIT_DEFINE_REG_TRAITS(VecV , RegType::kARM_VecV , RegGroup::kVec , 16, 32, TypeId::kInt32x4 );
+// <--------------------+------------------------+------------------------+---+------------------+
+// | Reg-Type | Reg-Group |Sz | TypeId |
+// <--------------------+------------------------+------------------------+---+------------------+
+ASMJIT_DEFINE_REG_TRAITS(RegType::kARM_GpW , RegGroup::kGp , 4 , TypeId::kInt32 ); // AArch32 & AArch64
+ASMJIT_DEFINE_REG_TRAITS(RegType::kARM_GpX , RegGroup::kGp , 8 , TypeId::kInt64 ); // AArch64
+ASMJIT_DEFINE_REG_TRAITS(RegType::kARM_VecB , RegGroup::kVec , 1 , TypeId::kVoid ); // AArch64
+ASMJIT_DEFINE_REG_TRAITS(RegType::kARM_VecH , RegGroup::kVec , 2 , TypeId::kVoid ); // AArch64
+ASMJIT_DEFINE_REG_TRAITS(RegType::kARM_VecS , RegGroup::kVec , 4 , TypeId::kInt32x1 ); // AArch32 & AArch64
+ASMJIT_DEFINE_REG_TRAITS(RegType::kARM_VecD , RegGroup::kVec , 8 , TypeId::kInt32x2 ); // AArch32 & AArch64
+ASMJIT_DEFINE_REG_TRAITS(RegType::kARM_VecQ , RegGroup::kVec , 16, TypeId::kInt32x4 ); // AArch32 & AArch64
+ASMJIT_DEFINE_REG_TRAITS(RegType::kARM_PC , RegGroup::kPC , 8 , TypeId::kInt64 ); // AArch64
//! \endcond
-//! Register (ARM).
+//! Register operand that can represent AArch32 and AArch64 registers.
class Reg : public BaseReg {
public:
ASMJIT_DEFINE_ABSTRACT_REG(Reg, BaseReg)
- //! Gets whether the register is a `R|W` register (32-bit).
- inline constexpr bool isGpW() const noexcept { return baseSignature() == RegTraits<RegType::kARM_GpW>::kSignature; }
+ //! Gets whether the register is either `R` or `W` register (32-bit).
+ ASMJIT_INLINE_NODEBUG constexpr bool isGpR() const noexcept { return baseSignature() == RegTraits<RegType::kARM_GpW>::kSignature; }
+ //! Gets whether the register is either `R` or `W` register (32-bit).
+ ASMJIT_INLINE_NODEBUG constexpr bool isGpW() const noexcept { return baseSignature() == RegTraits<RegType::kARM_GpW>::kSignature; }
//! Gets whether the register is an `X` register (64-bit).
- inline constexpr bool isGpX() const noexcept { return baseSignature() == RegTraits<RegType::kARM_GpX>::kSignature; }
+ ASMJIT_INLINE_NODEBUG constexpr bool isGpX() const noexcept { return baseSignature() == RegTraits<RegType::kARM_GpX>::kSignature; }
+
//! Gets whether the register is a VEC-B register (8-bit).
- inline constexpr bool isVecB() const noexcept { return baseSignature() == RegTraits<RegType::kARM_VecB>::kSignature; }
+ ASMJIT_INLINE_NODEBUG constexpr bool isVecB() const noexcept { return baseSignature() == RegTraits<RegType::kARM_VecB>::kSignature; }
//! Gets whether the register is a VEC-H register (16-bit).
- inline constexpr bool isVecH() const noexcept { return baseSignature() == RegTraits<RegType::kARM_VecH>::kSignature; }
+ ASMJIT_INLINE_NODEBUG constexpr bool isVecH() const noexcept { return baseSignature() == RegTraits<RegType::kARM_VecH>::kSignature; }
//! Gets whether the register is a VEC-S register (32-bit).
- inline constexpr bool isVecS() const noexcept { return baseSignature() == RegTraits<RegType::kARM_VecS>::kSignature; }
+ ASMJIT_INLINE_NODEBUG constexpr bool isVecS() const noexcept { return baseSignature() == RegTraits<RegType::kARM_VecS>::kSignature; }
//! Gets whether the register is a VEC-D register (64-bit).
- inline constexpr bool isVecD() const noexcept { return baseSignature() == RegTraits<RegType::kARM_VecD>::kSignature; }
+ ASMJIT_INLINE_NODEBUG constexpr bool isVecD() const noexcept { return baseSignature() == RegTraits<RegType::kARM_VecD>::kSignature; }
//! Gets whether the register is a VEC-Q register (128-bit).
- inline constexpr bool isVecQ() const noexcept { return baseSignature() == RegTraits<RegType::kARM_VecV>::kSignature; }
-
+ ASMJIT_INLINE_NODEBUG constexpr bool isVecQ() const noexcept { return baseSignature() == RegTraits<RegType::kARM_VecV>::kSignature; }
//! Gets whether the register is either VEC-D (64-bit) or VEC-Q (128-bit).
- inline constexpr bool isVecDOrQ() const noexcept { return uint32_t(type()) - uint32_t(RegType::kARM_VecD) <= 1u; }
-
+ ASMJIT_INLINE_NODEBUG constexpr bool isVecDOrQ() const noexcept { return uint32_t(type()) - uint32_t(RegType::kARM_VecD) <= 1u; }
//! Gets whether the register is a VEC-V register (128-bit).
- inline constexpr bool isVecV() const noexcept { return baseSignature() == RegTraits<RegType::kARM_VecV>::kSignature; }
+ ASMJIT_INLINE_NODEBUG constexpr bool isVecV() const noexcept { return baseSignature() == RegTraits<RegType::kARM_VecV>::kSignature; }
+
+ //! Gets whether the register is an 8-bit vector register or view, alias if \ref isVecB().
+ ASMJIT_INLINE_NODEBUG constexpr bool isVec8() const noexcept { return baseSignature() == RegTraits<RegType::kARM_VecB>::kSignature; }
+ //! Gets whether the register is a 16-bit vector register or view, alias if \ref isVecH().
+ ASMJIT_INLINE_NODEBUG constexpr bool isVec16() const noexcept { return baseSignature() == RegTraits<RegType::kARM_VecH>::kSignature; }
+ //! Gets whether the register is a 32-bit vector register or view, alias if \ref isVecS().
+ ASMJIT_INLINE_NODEBUG constexpr bool isVec32() const noexcept { return baseSignature() == RegTraits<RegType::kARM_VecS>::kSignature; }
+ //! Gets whether the register is a 64-bit vector register or view, alias if \ref isVecD().
+ ASMJIT_INLINE_NODEBUG constexpr bool isVec64() const noexcept { return baseSignature() == RegTraits<RegType::kARM_VecD>::kSignature; }
+ //! Gets whether the register is a 128-bit vector register or view, alias if \ref isVecQ().
+ ASMJIT_INLINE_NODEBUG constexpr bool isVec128() const noexcept { return baseSignature() == RegTraits<RegType::kARM_VecV>::kSignature; }
template<RegType kRegType>
- inline void setRegT(uint32_t id) noexcept {
+ ASMJIT_INLINE_NODEBUG void setRegT(uint32_t id) noexcept {
setSignature(RegTraits<kRegType>::kSignature);
setId(id);
}
- inline void setTypeAndId(RegType type, uint32_t id) noexcept {
+ ASMJIT_INLINE_NODEBUG void setTypeAndId(RegType type, uint32_t id) noexcept {
setSignature(signatureOf(type));
setId(id);
}
- static inline RegGroup groupOf(RegType type) noexcept { return ArchTraits::byArch(Arch::kAArch64).regTypeToGroup(type); }
- static inline TypeId typeIdOf(RegType type) noexcept { return ArchTraits::byArch(Arch::kAArch64).regTypeToTypeId(type); }
- static inline OperandSignature signatureOf(RegType type) noexcept { return ArchTraits::byArch(Arch::kAArch64).regTypeToSignature(type); }
+ static ASMJIT_INLINE_NODEBUG RegGroup groupOf(RegType type) noexcept { return ArchTraits::byArch(Arch::kAArch64).regTypeToGroup(type); }
+ static ASMJIT_INLINE_NODEBUG TypeId typeIdOf(RegType type) noexcept { return ArchTraits::byArch(Arch::kAArch64).regTypeToTypeId(type); }
+ static ASMJIT_INLINE_NODEBUG OperandSignature signatureOf(RegType type) noexcept { return ArchTraits::byArch(Arch::kAArch64).regTypeToSignature(type); }
template<RegType kRegType>
- static inline RegGroup groupOfT() noexcept { return RegTraits<kRegType>::kGroup; }
+ static ASMJIT_INLINE_NODEBUG RegGroup groupOfT() noexcept { return RegTraits<kRegType>::kGroup; }
template<RegType kRegType>
- static inline TypeId typeIdOfT() noexcept { return RegTraits<kRegType>::kTypeId; }
+ static ASMJIT_INLINE_NODEBUG TypeId typeIdOfT() noexcept { return RegTraits<kRegType>::kTypeId; }
template<RegType kRegType>
- static inline OperandSignature signatureOfT() noexcept { return RegTraits<kRegType>::kSignature; }
-
- static inline bool isGpW(const Operand_& op) noexcept { return op.as<Reg>().isGpW(); }
- static inline bool isGpX(const Operand_& op) noexcept { return op.as<Reg>().isGpX(); }
- static inline bool isVecB(const Operand_& op) noexcept { return op.as<Reg>().isVecB(); }
- static inline bool isVecH(const Operand_& op) noexcept { return op.as<Reg>().isVecH(); }
- static inline bool isVecS(const Operand_& op) noexcept { return op.as<Reg>().isVecS(); }
- static inline bool isVecD(const Operand_& op) noexcept { return op.as<Reg>().isVecD(); }
- static inline bool isVecQ(const Operand_& op) noexcept { return op.as<Reg>().isVecQ(); }
- static inline bool isVecV(const Operand_& op) noexcept { return op.as<Reg>().isVecV(); }
-
- static inline bool isGpW(const Operand_& op, uint32_t id) noexcept { return isGpW(op) & (op.id() == id); }
- static inline bool isGpX(const Operand_& op, uint32_t id) noexcept { return isGpX(op) & (op.id() == id); }
- static inline bool isVecB(const Operand_& op, uint32_t id) noexcept { return isVecB(op) & (op.id() == id); }
- static inline bool isVecH(const Operand_& op, uint32_t id) noexcept { return isVecH(op) & (op.id() == id); }
- static inline bool isVecS(const Operand_& op, uint32_t id) noexcept { return isVecS(op) & (op.id() == id); }
- static inline bool isVecD(const Operand_& op, uint32_t id) noexcept { return isVecD(op) & (op.id() == id); }
- static inline bool isVecQ(const Operand_& op, uint32_t id) noexcept { return isVecQ(op) & (op.id() == id); }
- static inline bool isVecV(const Operand_& op, uint32_t id) noexcept { return isVecV(op) & (op.id() == id); }
-};
-
-//! General purpose register (ARM).
-class Gp : public Reg {
-public:
- ASMJIT_DEFINE_ABSTRACT_REG(Gp, Reg)
-
- //! Special register id.
- enum Id : uint32_t {
- //! Register that depends on OS, could be used as TLS offset.
- kIdOs = 18,
- //! Frame pointer.
- kIdFp = 29,
- //! Link register.
- kIdLr = 30,
- //! Stack register id.
- kIdSp = 31,
- //! Zero register id.
- //!
- //! Although zero register has the same id as stack register it has a special treatment, because we need to be
- //! able to distinguish between these two at API level. Some intructions were designed to be used with SP and
- //! some other with ZR - so we need a way to distinguish these two to make sure we emit the right thing.
- //!
- //! The number 63 is not random, when you perform `id & 31` you would always get 31 for both SP and ZR inputs,
- //! which is the identifier used by AArch64 ISA to encode either SP or ZR depending on the instruction.
- kIdZr = 63
- };
-
- inline constexpr bool isZR() const noexcept { return id() == kIdZr; }
- inline constexpr bool isSP() const noexcept { return id() == kIdSp; }
-
- //! Cast this register to a 32-bit R|W.
- inline GpW w() const noexcept;
- //! Cast this register to a 64-bit X.
- inline GpX x() const noexcept;
+ static ASMJIT_INLINE_NODEBUG OperandSignature signatureOfT() noexcept { return OperandSignature{RegTraits<kRegType>::kSignature}; }
+
+ static ASMJIT_INLINE_NODEBUG bool isGpW(const Operand_& op) noexcept { return op.as<Reg>().isGpW(); }
+ static ASMJIT_INLINE_NODEBUG bool isGpX(const Operand_& op) noexcept { return op.as<Reg>().isGpX(); }
+ static ASMJIT_INLINE_NODEBUG bool isVecB(const Operand_& op) noexcept { return op.as<Reg>().isVecB(); }
+ static ASMJIT_INLINE_NODEBUG bool isVecH(const Operand_& op) noexcept { return op.as<Reg>().isVecH(); }
+ static ASMJIT_INLINE_NODEBUG bool isVecS(const Operand_& op) noexcept { return op.as<Reg>().isVecS(); }
+ static ASMJIT_INLINE_NODEBUG bool isVecD(const Operand_& op) noexcept { return op.as<Reg>().isVecD(); }
+ static ASMJIT_INLINE_NODEBUG bool isVecQ(const Operand_& op) noexcept { return op.as<Reg>().isVecQ(); }
+ static ASMJIT_INLINE_NODEBUG bool isVecV(const Operand_& op) noexcept { return op.as<Reg>().isVecV(); }
+
+ static ASMJIT_INLINE_NODEBUG bool isGpW(const Operand_& op, uint32_t id) noexcept { return bool(unsigned(isGpW(op)) & unsigned(op.id() == id)); }
+ static ASMJIT_INLINE_NODEBUG bool isGpX(const Operand_& op, uint32_t id) noexcept { return bool(unsigned(isGpX(op)) & unsigned(op.id() == id)); }
+ static ASMJIT_INLINE_NODEBUG bool isVecB(const Operand_& op, uint32_t id) noexcept { return bool(unsigned(isVecB(op)) & unsigned(op.id() == id)); }
+ static ASMJIT_INLINE_NODEBUG bool isVecH(const Operand_& op, uint32_t id) noexcept { return bool(unsigned(isVecH(op)) & unsigned(op.id() == id)); }
+ static ASMJIT_INLINE_NODEBUG bool isVecS(const Operand_& op, uint32_t id) noexcept { return bool(unsigned(isVecS(op)) & unsigned(op.id() == id)); }
+ static ASMJIT_INLINE_NODEBUG bool isVecD(const Operand_& op, uint32_t id) noexcept { return bool(unsigned(isVecD(op)) & unsigned(op.id() == id)); }
+ static ASMJIT_INLINE_NODEBUG bool isVecQ(const Operand_& op, uint32_t id) noexcept { return bool(unsigned(isVecQ(op)) & unsigned(op.id() == id)); }
+ static ASMJIT_INLINE_NODEBUG bool isVecV(const Operand_& op, uint32_t id) noexcept { return bool(unsigned(isVecV(op)) & unsigned(op.id() == id)); }
};
-//! Vector register (ARM).
-class Vec : public Reg {
+//! Vector register base - a common base for both AArch32 & AArch64 vector register.
+class BaseVec : public Reg {
public:
- ASMJIT_DEFINE_ABSTRACT_REG(Vec, Reg)
+ ASMJIT_DEFINE_ABSTRACT_REG(BaseVec, Reg)
- //! Additional signature bits used by arm::Vec.
+ //! Additional signature bits used by a vector register.
enum AdditionalBits : uint32_t {
// Register element type (3 bits).
// |........|........|.XXX....|........|
@@ -178,202 +145,21 @@ public:
kSignatureRegElementIndexMask = 0x0F << kSignatureRegElementIndexShift
};
- //! Element type.
- enum ElementType : uint32_t {
- //! No element type specified.
- kElementTypeNone = 0,
- //! Byte elements (B8 or B16).
- kElementTypeB,
- //! Halfword elements (H4 or H8).
- kElementTypeH,
- //! Singleword elements (S2 or S4).
- kElementTypeS,
- //! Doubleword elements (D2).
- kElementTypeD,
- //! Byte elements grouped by 4 bytes (B4).
- //!
- //! \note This element-type is only used by few instructions.
- kElementTypeB4,
- //! Halfword elements grouped by 2 halfwords (H2).
- //!
- //! \note This element-type is only used by few instructions.
- kElementTypeH2,
-
- //! Count of element types.
- kElementTypeCount
- };
-
- //! \cond
- //! Shortcuts.
- enum SignatureReg : uint32_t {
- kSignatureElementB = kElementTypeB << kSignatureRegElementTypeShift,
- kSignatureElementH = kElementTypeH << kSignatureRegElementTypeShift,
- kSignatureElementS = kElementTypeS << kSignatureRegElementTypeShift,
- kSignatureElementD = kElementTypeD << kSignatureRegElementTypeShift,
- kSignatureElementB4 = kElementTypeB4 << kSignatureRegElementTypeShift,
- kSignatureElementH2 = kElementTypeH2 << kSignatureRegElementTypeShift
- };
- //! \endcond
-
- //! Returns whether the register has associated an element type.
- inline constexpr bool hasElementType() const noexcept { return _signature.hasField<kSignatureRegElementTypeMask>(); }
//! Returns whether the register has element index (it's an element index access).
- inline constexpr bool hasElementIndex() const noexcept { return _signature.hasField<kSignatureRegElementFlagMask>(); }
- //! Returns whether the reggister has element type or element index (or both).
- inline constexpr bool hasElementTypeOrIndex() const noexcept { return _signature.hasField<kSignatureRegElementTypeMask | kSignatureRegElementFlagMask>(); }
-
- //! Returns element type of the register.
- inline constexpr uint32_t elementType() const noexcept { return _signature.getField<kSignatureRegElementTypeMask>(); }
- //! Sets element type of the register to `elementType`.
- inline void setElementType(uint32_t elementType) noexcept { _signature.setField<kSignatureRegElementTypeMask>(elementType); }
- //! Resets element type to none.
- inline void resetElementType() noexcept { _signature.setField<kSignatureRegElementTypeMask>(0); }
-
+ ASMJIT_INLINE_NODEBUG constexpr bool hasElementIndex() const noexcept { return _signature.hasField<kSignatureRegElementFlagMask>(); }
//! Returns element index of the register.
- inline constexpr uint32_t elementIndex() const noexcept { return _signature.getField<kSignatureRegElementIndexMask>(); }
+ ASMJIT_INLINE_NODEBUG constexpr uint32_t elementIndex() const noexcept { return _signature.getField<kSignatureRegElementIndexMask>(); }
//! Sets element index of the register to `elementType`.
- inline void setElementIndex(uint32_t elementIndex) noexcept {
+ ASMJIT_INLINE_NODEBUG void setElementIndex(uint32_t elementIndex) noexcept {
_signature |= kSignatureRegElementFlagMask;
_signature.setField<kSignatureRegElementIndexMask>(elementIndex);
}
//! Resets element index of the register.
- inline void resetElementIndex() noexcept {
+ ASMJIT_INLINE_NODEBUG void resetElementIndex() noexcept {
_signature &= ~(kSignatureRegElementFlagMask | kSignatureRegElementIndexMask);
}
-
- inline constexpr bool isVecB8() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecD>::kSignature | kSignatureElementB); }
- inline constexpr bool isVecH4() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecD>::kSignature | kSignatureElementH); }
- inline constexpr bool isVecS2() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecD>::kSignature | kSignatureElementS); }
- inline constexpr bool isVecD1() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecD>::kSignature); }
-
- inline constexpr bool isVecB16() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementB); }
- inline constexpr bool isVecH8() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementH); }
- inline constexpr bool isVecS4() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementS); }
- inline constexpr bool isVecD2() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementD); }
- inline constexpr bool isVecB4x4() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementB4); }
- inline constexpr bool isVecH2x4() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementH2); }
-
- //! Creates a cloned register with element access.
- inline Vec at(uint32_t elementIndex) const noexcept {
- return Vec((signature() & ~kSignatureRegElementIndexMask) | (elementIndex << kSignatureRegElementIndexShift) | kSignatureRegElementFlagMask, id());
- }
-
- //! Cast this register to an 8-bit B register (scalar).
- inline VecB b() const noexcept;
- //! Cast this register to a 16-bit H register (scalar).
- inline VecH h() const noexcept;
- //! Cast this register to a 32-bit S register (scalar).
- inline VecS s() const noexcept;
- //! Cast this register to a 64-bit D register (scalar).
- inline VecD d() const noexcept;
- //! Cast this register to a 128-bit Q register (scalar).
- inline VecV q() const noexcept;
- //! Cast this register to a 128-bit V register.
- inline VecV v() const noexcept;
-
- //! Cast this register to a 128-bit V.B[elementIndex] register.
- inline VecV b(uint32_t elementIndex) const noexcept;
- //! Cast this register to a 128-bit V.H[elementIndex] register.
- inline VecV h(uint32_t elementIndex) const noexcept;
- //! Cast this register to a 128-bit V.S[elementIndex] register.
- inline VecV s(uint32_t elementIndex) const noexcept;
- //! Cast this register to a 128-bit V.D[elementIndex] register.
- inline VecV d(uint32_t elementIndex) const noexcept;
- //! Cast this register to a 128-bit V.H2[elementIndex] register.
- inline VecV h2(uint32_t elementIndex) const noexcept;
- //! Cast this register to a 128-bit V.B4[elementIndex] register.
- inline VecV b4(uint32_t elementIndex) const noexcept;
-
- //! Cast this register to V.8B.
- inline VecD b8() const noexcept;
- //! Cast this register to V.16B.
- inline VecV b16() const noexcept;
- //! Cast this register to V.2H.
- inline VecS h2() const noexcept;
- //! Cast this register to V.4H.
- inline VecD h4() const noexcept;
- //! Cast this register to V.8H.
- inline VecV h8() const noexcept;
- //! Cast this register to V.2S.
- inline VecD s2() const noexcept;
- //! Cast this register to V.4S.
- inline VecV s4() const noexcept;
- //! Cast this register to V.2D.
- inline VecV d2() const noexcept;
-
- static inline constexpr OperandSignature _makeElementAccessSignature(uint32_t elementType, uint32_t elementIndex) noexcept {
- return OperandSignature{
- uint32_t(RegTraits<RegType::kARM_VecV>::kSignature) |
- uint32_t(kSignatureRegElementFlagMask) |
- uint32_t(elementType << kSignatureRegElementTypeShift) |
- uint32_t(elementIndex << kSignatureRegElementIndexShift)};
- }
};
-//! 32-bit GPW (AArch64) and/or GPR (ARM/AArch32) register.
-class GpW : public Gp { ASMJIT_DEFINE_FINAL_REG(GpW, Gp, RegTraits<RegType::kARM_GpW>) };
-//! 64-bit GPX (AArch64) register.
-class GpX : public Gp { ASMJIT_DEFINE_FINAL_REG(GpX, Gp, RegTraits<RegType::kARM_GpX>) };
-
-//! 8-bit view (S) of VFP/SIMD register.
-class VecB : public Vec { ASMJIT_DEFINE_FINAL_REG(VecB, Vec, RegTraits<RegType::kARM_VecB>) };
-//! 16-bit view (S) of VFP/SIMD register.
-class VecH : public Vec { ASMJIT_DEFINE_FINAL_REG(VecH, Vec, RegTraits<RegType::kARM_VecH>) };
-//! 32-bit view (S) of VFP/SIMD register.
-class VecS : public Vec { ASMJIT_DEFINE_FINAL_REG(VecS, Vec, RegTraits<RegType::kARM_VecS>) };
-//! 64-bit view (D) of VFP/SIMD register.
-class VecD : public Vec { ASMJIT_DEFINE_FINAL_REG(VecD, Vec, RegTraits<RegType::kARM_VecD>) };
-//! 128-bit vector register (Q or V).
-class VecV : public Vec { ASMJIT_DEFINE_FINAL_REG(VecV, Vec, RegTraits<RegType::kARM_VecV>) };
-
-inline GpW Gp::w() const noexcept { return GpW(id()); }
-inline GpX Gp::x() const noexcept { return GpX(id()); }
-
-inline VecB Vec::b() const noexcept { return VecB(id()); }
-inline VecH Vec::h() const noexcept { return VecH(id()); }
-inline VecS Vec::s() const noexcept { return VecS(id()); }
-inline VecD Vec::d() const noexcept { return VecD(id()); }
-inline VecV Vec::q() const noexcept { return VecV(id()); }
-inline VecV Vec::v() const noexcept { return VecV(id()); }
-
-inline VecV Vec::b(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(kElementTypeB, elementIndex), id()); }
-inline VecV Vec::h(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(kElementTypeH, elementIndex), id()); }
-inline VecV Vec::s(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(kElementTypeS, elementIndex), id()); }
-inline VecV Vec::d(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(kElementTypeD, elementIndex), id()); }
-inline VecV Vec::h2(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(kElementTypeH2, elementIndex), id()); }
-inline VecV Vec::b4(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(kElementTypeB4, elementIndex), id()); }
-
-inline VecD Vec::b8() const noexcept { return VecD(OperandSignature{VecD::kSignature | kSignatureElementB}, id()); }
-inline VecS Vec::h2() const noexcept { return VecS(OperandSignature{VecS::kSignature | kSignatureElementH}, id()); }
-inline VecD Vec::h4() const noexcept { return VecD(OperandSignature{VecD::kSignature | kSignatureElementH}, id()); }
-inline VecD Vec::s2() const noexcept { return VecD(OperandSignature{VecD::kSignature | kSignatureElementS}, id()); }
-inline VecV Vec::b16() const noexcept { return VecV(OperandSignature{VecV::kSignature | kSignatureElementB}, id()); }
-inline VecV Vec::h8() const noexcept { return VecV(OperandSignature{VecV::kSignature | kSignatureElementH}, id()); }
-inline VecV Vec::s4() const noexcept { return VecV(OperandSignature{VecV::kSignature | kSignatureElementS}, id()); }
-inline VecV Vec::d2() const noexcept { return VecV(OperandSignature{VecV::kSignature | kSignatureElementD}, id()); }
-
-#ifndef _DOXYGEN
-namespace regs {
-#endif
-
-//! Creates a 32-bit W register operand (ARM/AArch64).
-static inline constexpr GpW w(uint32_t id) noexcept { return GpW(id); }
-//! Creates a 64-bit X register operand (AArch64).
-static inline constexpr GpX x(uint32_t id) noexcept { return GpX(id); }
-//! Creates a 32-bit S register operand (ARM/AArch64).
-static inline constexpr VecS s(uint32_t id) noexcept { return VecS(id); }
-//! Creates a 64-bit D register operand (ARM/AArch64).
-static inline constexpr VecD d(uint32_t id) noexcept { return VecD(id); }
-//! Creates a 1282-bit V register operand (ARM/AArch64).
-static inline constexpr VecV v(uint32_t id) noexcept { return VecV(id); }
-
-#ifndef _DOXYGEN
-} // {regs}
-
-// Make `arm::regs` accessible through `arm` namespace as well.
-using namespace regs;
-#endif
-
//! Memory operand (ARM).
class Mem : public BaseMem {
public:
@@ -385,64 +171,59 @@ public:
kSignatureMemShiftValueShift = 14,
kSignatureMemShiftValueMask = 0x1Fu << kSignatureMemShiftValueShift,
- // Shift operation type (4 bits).
+ // Index shift operation (4 bits).
// |........|XXXX....|........|........|
- kSignatureMemPredicateShift = 20,
- kSignatureMemPredicateMask = 0x0Fu << kSignatureMemPredicateShift
- };
- //! \endcond
+ kSignatureMemShiftOpShift = 20,
+ kSignatureMemShiftOpMask = 0x0Fu << kSignatureMemShiftOpShift,
- //! Memory offset mode.
- //!
- //! Additional constants that can be used with the `predicate`.
- enum OffsetMode : uint32_t {
- //! Pre-index "[BASE, #Offset {, <shift>}]!" with write-back.
- kOffsetPreIndex = 0xE,
- //! Post-index "[BASE], #Offset {, <shift>}" with write-back.
- kOffsetPostIndex = 0xF
+ // Offset mode type (2 bits).
+ // |......XX|........|........|........|
+ kSignatureMemOffsetModeShift = 24,
+ kSignatureMemOffsetModeMask = 0x03u << kSignatureMemOffsetModeShift
};
+ //! \endcond
//! \name Construction & Destruction
//! \{
//! Construct a default `Mem` operand, that points to [0].
- inline constexpr Mem() noexcept
+ ASMJIT_INLINE_NODEBUG constexpr Mem() noexcept
: BaseMem() {}
- inline constexpr Mem(const Mem& other) noexcept
+ ASMJIT_INLINE_NODEBUG constexpr Mem(const Mem& other) noexcept
: BaseMem(other) {}
- inline explicit Mem(Globals::NoInit_) noexcept
+ ASMJIT_INLINE_NODEBUG explicit Mem(Globals::NoInit_) noexcept
: BaseMem(Globals::NoInit) {}
- inline constexpr Mem(const Signature& signature, uint32_t baseId, uint32_t indexId, int32_t offset) noexcept
+ ASMJIT_INLINE_NODEBUG constexpr Mem(const Signature& signature, uint32_t baseId, uint32_t indexId, int32_t offset) noexcept
: BaseMem(signature, baseId, indexId, offset) {}
- inline constexpr explicit Mem(const Label& base, int32_t off = 0, Signature signature = Signature{0}) noexcept
+ ASMJIT_INLINE_NODEBUG constexpr explicit Mem(const Label& base, int32_t off = 0, Signature signature = Signature{0}) noexcept
: BaseMem(Signature::fromOpType(OperandType::kMem) |
Signature::fromMemBaseType(RegType::kLabelTag) |
signature, base.id(), 0, off) {}
- inline constexpr explicit Mem(const BaseReg& base, int32_t off = 0, Signature signature = Signature{0}) noexcept
+ ASMJIT_INLINE_NODEBUG constexpr explicit Mem(const BaseReg& base, int32_t off = 0, Signature signature = Signature{0}) noexcept
: BaseMem(Signature::fromOpType(OperandType::kMem) |
Signature::fromMemBaseType(base.type()) |
signature, base.id(), 0, off) {}
- inline constexpr Mem(const BaseReg& base, const BaseReg& index, Signature signature = Signature{0}) noexcept
+ ASMJIT_INLINE_NODEBUG constexpr Mem(const BaseReg& base, const BaseReg& index, Signature signature = Signature{0}) noexcept
: BaseMem(Signature::fromOpType(OperandType::kMem) |
Signature::fromMemBaseType(base.type()) |
Signature::fromMemIndexType(index.type()) |
signature, base.id(), index.id(), 0) {}
- inline constexpr Mem(const BaseReg& base, const BaseReg& index, const Shift& shift, Signature signature = Signature{0}) noexcept
+ ASMJIT_INLINE_NODEBUG constexpr Mem(const BaseReg& base, const BaseReg& index, const Shift& shift, Signature signature = Signature{0}) noexcept
: BaseMem(Signature::fromOpType(OperandType::kMem) |
Signature::fromMemBaseType(base.type()) |
Signature::fromMemIndexType(index.type()) |
- Signature::fromValue<kSignatureMemPredicateMask>(uint32_t(shift.op())) |
+ Signature::fromValue<kSignatureMemShiftOpMask>(uint32_t(shift.op())) |
Signature::fromValue<kSignatureMemShiftValueMask>(shift.value()) |
signature, base.id(), index.id(), 0) {}
- inline constexpr Mem(uint64_t base, Signature signature = Signature{0}) noexcept
+ ASMJIT_INLINE_NODEBUG constexpr explicit Mem(uint64_t base, Signature signature = Signature{0}) noexcept
: BaseMem(Signature::fromOpType(OperandType::kMem) |
signature, uint32_t(base >> 32), 0, int32_t(uint32_t(base & 0xFFFFFFFFu))) {}
@@ -451,7 +232,7 @@ public:
//! \name Overloaded Operators
//! \{
- inline Mem& operator=(const Mem& other) noexcept = default;
+ ASMJIT_INLINE_NODEBUG Mem& operator=(const Mem& other) noexcept = default;
//! \}
@@ -459,41 +240,41 @@ public:
//! \{
//! Clones the memory operand.
- inline constexpr Mem clone() const noexcept { return Mem(*this); }
+ ASMJIT_INLINE_NODEBUG constexpr Mem clone() const noexcept { return Mem(*this); }
//! Gets new memory operand adjusted by `off`.
- inline Mem cloneAdjusted(int64_t off) const noexcept {
+ ASMJIT_INLINE_NODEBUG Mem cloneAdjusted(int64_t off) const noexcept {
Mem result(*this);
result.addOffset(off);
return result;
}
//! Clones the memory operand and makes it pre-index.
- inline Mem pre() const noexcept {
+ ASMJIT_INLINE_NODEBUG Mem pre() const noexcept {
Mem result(*this);
- result.setPredicate(kOffsetPreIndex);
+ result.setOffsetMode(OffsetMode::kPreIndex);
return result;
}
//! Clones the memory operand, applies a given offset `off` and makes it pre-index.
- inline Mem pre(int64_t off) const noexcept {
+ ASMJIT_INLINE_NODEBUG Mem pre(int64_t off) const noexcept {
Mem result(*this);
- result.setPredicate(kOffsetPreIndex);
+ result.setOffsetMode(OffsetMode::kPreIndex);
result.addOffset(off);
return result;
}
//! Clones the memory operand and makes it post-index.
- inline Mem post() const noexcept {
+ ASMJIT_INLINE_NODEBUG Mem post() const noexcept {
Mem result(*this);
- result.setPredicate(kOffsetPreIndex);
+ result.setOffsetMode(OffsetMode::kPostIndex);
return result;
}
//! Clones the memory operand, applies a given offset `off` and makes it post-index.
- inline Mem post(int64_t off) const noexcept {
+ ASMJIT_INLINE_NODEBUG Mem post(int64_t off) const noexcept {
Mem result(*this);
- result.setPredicate(kOffsetPostIndex);
+ result.setOffsetMode(OffsetMode::kPostIndex);
result.addOffset(off);
return result;
}
@@ -506,16 +287,21 @@ public:
//! Converts memory `baseType` and `baseId` to `arm::Reg` instance.
//!
//! The memory must have a valid base register otherwise the result will be wrong.
- inline Reg baseReg() const noexcept { return Reg::fromTypeAndId(baseType(), baseId()); }
+ ASMJIT_INLINE_NODEBUG Reg baseReg() const noexcept { return Reg::fromTypeAndId(baseType(), baseId()); }
//! Converts memory `indexType` and `indexId` to `arm::Reg` instance.
//!
//! The memory must have a valid index register otherwise the result will be wrong.
- inline Reg indexReg() const noexcept { return Reg::fromTypeAndId(indexType(), indexId()); }
+ ASMJIT_INLINE_NODEBUG Reg indexReg() const noexcept { return Reg::fromTypeAndId(indexType(), indexId()); }
using BaseMem::setIndex;
- inline void setIndex(const BaseReg& index, uint32_t shift) noexcept {
+ ASMJIT_INLINE_NODEBUG void setIndex(const BaseReg& index, uint32_t shift) noexcept {
+ setIndex(index);
+ setShift(shift);
+ }
+
+ ASMJIT_INLINE_NODEBUG void setIndex(const BaseReg& index, Shift shift) noexcept {
setIndex(index);
setShift(shift);
}
@@ -525,97 +311,86 @@ public:
//! \name ARM Specific Features
//! \{
+ //! Gets offset mode.
+ ASMJIT_INLINE_NODEBUG constexpr OffsetMode offsetMode() const noexcept { return OffsetMode(_signature.getField<kSignatureMemOffsetModeMask>()); }
+ //! Sets offset mode to `mode`.
+ ASMJIT_INLINE_NODEBUG void setOffsetMode(OffsetMode mode) noexcept { _signature.setField<kSignatureMemOffsetModeMask>(uint32_t(mode)); }
+ //! Resets offset mode to default (fixed offset, without write-back).
+ ASMJIT_INLINE_NODEBUG void resetOffsetMode() noexcept { _signature.setField<kSignatureMemOffsetModeMask>(uint32_t(OffsetMode::kFixed)); }
+
+ //! Tests whether the current memory offset mode is fixed (see \ref OffsetMode::kFixed).
+ ASMJIT_INLINE_NODEBUG constexpr bool isFixedOffset() const noexcept { return offsetMode() == OffsetMode::kFixed; }
+ //! Tests whether the current memory offset mode is either pre-index or post-index (write-back is used).
+ ASMJIT_INLINE_NODEBUG constexpr bool isPreOrPost() const noexcept { return offsetMode() != OffsetMode::kFixed; }
+ //! Tests whether the current memory offset mode is pre-index (write-back is used).
+ ASMJIT_INLINE_NODEBUG constexpr bool isPreIndex() const noexcept { return offsetMode() == OffsetMode::kPreIndex; }
+ //! Tests whether the current memory offset mode is post-index (write-back is used).
+ ASMJIT_INLINE_NODEBUG constexpr bool isPostIndex() const noexcept { return offsetMode() == OffsetMode::kPostIndex; }
+
+ //! Sets offset mode of this memory operand to pre-index (write-back is used).
+ ASMJIT_INLINE_NODEBUG void makePreIndex() noexcept { setOffsetMode(OffsetMode::kPreIndex); }
+ //! Sets offset mode of this memory operand to post-index (write-back is used).
+ ASMJIT_INLINE_NODEBUG void makePostIndex() noexcept { setOffsetMode(OffsetMode::kPostIndex); }
+
+ //! Gets shift operation that is used by index register.
+ ASMJIT_INLINE_NODEBUG constexpr ShiftOp shiftOp() const noexcept { return ShiftOp(_signature.getField<kSignatureMemShiftOpMask>()); }
+ //! Sets shift operation that is used by index register.
+ ASMJIT_INLINE_NODEBUG void setShiftOp(ShiftOp sop) noexcept { _signature.setField<kSignatureMemShiftOpMask>(uint32_t(sop)); }
+ //! Resets shift operation that is used by index register to LSL (default value).
+ ASMJIT_INLINE_NODEBUG void resetShiftOp() noexcept { _signature.setField<kSignatureMemShiftOpMask>(uint32_t(ShiftOp::kLSL)); }
+
//! Gets whether the memory operand has shift (aka scale) constant.
- inline constexpr bool hasShift() const noexcept { return _signature.hasField<kSignatureMemShiftValueMask>(); }
+ ASMJIT_INLINE_NODEBUG constexpr bool hasShift() const noexcept { return _signature.hasField<kSignatureMemShiftValueMask>(); }
//! Gets the memory operand's shift (aka scale) constant.
- inline constexpr uint32_t shift() const noexcept { return _signature.getField<kSignatureMemShiftValueMask>(); }
+ ASMJIT_INLINE_NODEBUG constexpr uint32_t shift() const noexcept { return _signature.getField<kSignatureMemShiftValueMask>(); }
//! Sets the memory operand's shift (aka scale) constant.
- inline void setShift(uint32_t shift) noexcept { _signature.setField<kSignatureMemShiftValueMask>(shift); }
- //! Resets the memory operand's shift (aka scale) constant to zero.
- inline void resetShift() noexcept { _signature.setField<kSignatureMemShiftValueMask>(0); }
-
- //! Gets memory predicate (shift mode or offset mode), see \ref ShiftOp and \ref OffsetMode.
- inline constexpr uint32_t predicate() const noexcept { return _signature.getField<kSignatureMemPredicateMask>(); }
- //! Sets memory predicate to `predicate`, see `Mem::ShiftOp`.
- inline void setPredicate(uint32_t predicate) noexcept { _signature.setField<kSignatureMemPredicateMask>(predicate); }
- //! Resets shift mode to LSL (default).
- inline void resetPredicate() noexcept { _signature.setField<kSignatureMemPredicateMask>(0); }
+ ASMJIT_INLINE_NODEBUG void setShift(uint32_t shift) noexcept { _signature.setField<kSignatureMemShiftValueMask>(shift); }
- inline constexpr bool isFixedOffset() const noexcept { return predicate() < kOffsetPreIndex; }
- inline constexpr bool isPreOrPost() const noexcept { return predicate() >= kOffsetPreIndex; }
- inline constexpr bool isPreIndex() const noexcept { return predicate() == kOffsetPreIndex; }
- inline constexpr bool isPostIndex() const noexcept { return predicate() == kOffsetPostIndex; }
+ //! Sets the memory operand's shift and shift operation.
+ ASMJIT_INLINE_NODEBUG void setShift(Shift shift) noexcept {
+ _signature.setField<kSignatureMemShiftOpMask>(uint32_t(shift.op()));
+ _signature.setField<kSignatureMemShiftValueMask>(shift.value());
+ }
- inline void resetToFixedOffset() noexcept { resetPredicate(); }
- inline void makePreIndex() noexcept { setPredicate(kOffsetPreIndex); }
- inline void makePostIndex() noexcept { setPredicate(kOffsetPostIndex); }
+ //! Resets the memory operand's shift (aka scale) constant to zero.
+ ASMJIT_INLINE_NODEBUG void resetShift() noexcept { _signature.setField<kSignatureMemShiftValueMask>(0); }
//! \}
};
-//! Creates `[base.reg, offset]` memory operand (offset mode).
-static inline constexpr Mem ptr(const Gp& base, int32_t offset = 0) noexcept {
- return Mem(base, offset);
-}
-
-//! Creates `[base.reg, offset]!` memory operand (pre-index mode).
-static inline constexpr Mem ptr_pre(const Gp& base, int32_t offset = 0) noexcept {
- return Mem(base, offset, OperandSignature::fromValue<Mem::kSignatureMemPredicateMask>(Mem::kOffsetPreIndex));
-}
-
-//! Creates `[base.reg], offset` memory operand (post-index mode).
-static inline constexpr Mem ptr_post(const Gp& base, int32_t offset = 0) noexcept {
- return Mem(base, offset, OperandSignature::fromValue<Mem::kSignatureMemPredicateMask>(Mem::kOffsetPostIndex));
-}
-
-//! Creates `[base.reg, index]` memory operand.
-static inline constexpr Mem ptr(const Gp& base, const Gp& index) noexcept {
- return Mem(base, index);
-}
-
-//! Creates `[base.reg], index` memory operand (post-index mode).
-static inline constexpr Mem ptr_post(const Gp& base, const Gp& index) noexcept {
- return Mem(base, index, OperandSignature::fromValue<Mem::kSignatureMemPredicateMask>(Mem::kOffsetPostIndex));
-}
-
-//! Creates `[base.reg, index, SHIFT_OP #shift]` memory operand.
-static inline constexpr Mem ptr(const Gp& base, const Gp& index, const Shift& shift) noexcept {
- return Mem(base, index, shift);
-}
-
-//! Creates `[base + offset]` memory operand.
-static inline constexpr Mem ptr(const Label& base, int32_t offset = 0) noexcept {
- return Mem(base, offset);
-}
-
-// TODO: [ARM] PC + offset address.
-#if 0
-//! Creates `[PC + offset]` (relative) memory operand.
-static inline constexpr Mem ptr(const PC& pc, int32_t offset = 0) noexcept {
- return Mem(pc, offset);
-}
-#endif
-
-//! Creates `[base]` absolute memory operand.
+//! \name Shift Operation Construction
+//! \{
+
+//! Constructs a `LSL #value` shift (logical shift left).
+static ASMJIT_INLINE_NODEBUG constexpr Shift lsl(uint32_t value) noexcept { return Shift(ShiftOp::kLSL, value); }
+//! Constructs a `LSR #value` shift (logical shift right).
+static ASMJIT_INLINE_NODEBUG constexpr Shift lsr(uint32_t value) noexcept { return Shift(ShiftOp::kLSR, value); }
+//! Constructs a `ASR #value` shift (arithmetic shift right).
+static ASMJIT_INLINE_NODEBUG constexpr Shift asr(uint32_t value) noexcept { return Shift(ShiftOp::kASR, value); }
+//! Constructs a `ROR #value` shift (rotate right).
+static ASMJIT_INLINE_NODEBUG constexpr Shift ror(uint32_t value) noexcept { return Shift(ShiftOp::kROR, value); }
+//! Constructs a `RRX` shift (rotate with carry by 1).
+static ASMJIT_INLINE_NODEBUG constexpr Shift rrx() noexcept { return Shift(ShiftOp::kRRX, 0); }
+//! Constructs a `MSL #value` shift (logical shift left filling ones).
+static ASMJIT_INLINE_NODEBUG constexpr Shift msl(uint32_t value) noexcept { return Shift(ShiftOp::kMSL, value); }
+
+//! \}
+
+//! \name Memory Operand Construction
+//! \{
+
+//! Creates `[base]` absolute memory operand (AArch32 or AArch64).
//!
//! \note The concept of absolute memory operands doesn't exist on ARM, the ISA only provides PC relative addressing.
//! Absolute memory operands can only be used if it's known that the PC relative offset is encodable and that it
-//! would be within the limits. Absolute address is also often output from disassemblers, so AsmJit support it so it
-//! can assemble it back.
-static inline constexpr Mem ptr(uint64_t base) noexcept { return Mem(base); }
+//! would be within the limits. Absolute address is also often output from disassemblers, so AsmJit supports it to
+//! make it possible to assemble such output back.
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr(uint64_t base) noexcept { return Mem(base); }
//! \}
-ASMJIT_END_SUB_NAMESPACE
+//! \}
-//! \cond INTERNAL
-ASMJIT_BEGIN_NAMESPACE
-ASMJIT_DEFINE_TYPE_ID(arm::GpW, TypeId::kInt32);
-ASMJIT_DEFINE_TYPE_ID(arm::GpX, TypeId::kInt64);
-ASMJIT_DEFINE_TYPE_ID(arm::VecS, TypeId::kFloat32x1);
-ASMJIT_DEFINE_TYPE_ID(arm::VecD, TypeId::kFloat64x1);
-ASMJIT_DEFINE_TYPE_ID(arm::VecV, TypeId::kInt32x4);
-ASMJIT_END_NAMESPACE
-//! \endcond
+ASMJIT_END_SUB_NAMESPACE
#endif // ASMJIT_ARM_ARMOPERAND_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/arm/a64utils.h b/3rdparty/asmjit/src/asmjit/arm/armutils.h
index 4a88ca51724..8241eda052e 100644
--- a/3rdparty/asmjit/src/asmjit/arm/a64utils.h
+++ b/3rdparty/asmjit/src/asmjit/arm/armutils.h
@@ -3,20 +3,53 @@
// See asmjit.h or LICENSE.md for license and copyright information
// SPDX-License-Identifier: Zlib
-#ifndef ASMJIT_ARM_A64UTILS_H_INCLUDED
-#define ASMJIT_ARM_A64UTILS_H_INCLUDED
+#ifndef ASMJIT_ARM_ARMUTILS_H_INCLUDED
+#define ASMJIT_ARM_ARMUTILS_H_INCLUDED
-#include "../arm/a64globals.h"
+#include "../core/support.h"
+#include "../arm/armglobals.h"
-ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+ASMJIT_BEGIN_SUB_NAMESPACE(arm)
-//! \addtogroup asmjit_a64
+//! \addtogroup asmjit_arm
//! \{
-//! Public utilities and helpers for targeting AArch64 architecture.
+//! Public utilities and helpers for targeting AArch32 and AArch64 architectures.
namespace Utils {
-//! Decomposed fields of a logical immediate value (AArch64).
+//! Encodes a 12-bit immediate part of opcode that ise used by a standard 32-bit ARM encoding.
+ASMJIT_MAYBE_UNUSED
+static inline bool encodeAArch32Imm(uint64_t imm, uint32_t* encodedImmOut) noexcept {
+ if (imm & 0xFFFFFFFF00000000u)
+ return false;
+
+ uint32_t v = uint32_t(imm);
+ uint32_t r = 0;
+
+ if (v <= 0xFFu) {
+ *encodedImmOut = v;
+ return true;
+ }
+
+ // Rotate if there are bits on both ends (LSB and MSB)
+ // (otherwise we would not be able to calculate the rotation with ctz).
+ if (v & 0xFF0000FFu) {
+ v = Support::ror(v, 16);
+ r = 16u;
+ }
+
+ uint32_t n = Support::ctz(v) & ~0x1u;
+ r = (r - n) & 0x1Eu;
+ v = Support::ror(v, n);
+
+ if (v > 0xFFu)
+ return false;
+
+ *encodedImmOut = v | (r << 7);
+ return true;
+}
+
+//! Decomposed fields of a logical immediate value.
struct LogicalImm {
uint32_t n;
uint32_t s;
@@ -41,7 +74,7 @@ struct LogicalImm {
//! +---+--------+--------+------+
//! ```
ASMJIT_MAYBE_UNUSED
-static bool encodeLogicalImm(uint64_t imm, uint32_t width, a64::Utils::LogicalImm* out) noexcept {
+static bool encodeLogicalImm(uint64_t imm, uint32_t width, LogicalImm* out) noexcept {
// Determine the element width, which must be 2, 4, 8, 16, 32, or 64 bits.
do {
width /= 2;
@@ -89,24 +122,38 @@ static bool encodeLogicalImm(uint64_t imm, uint32_t width, a64::Utils::LogicalIm
//! width of the operation, and must be either 32 or 64. This function can be used to test whether an immediate
//! value can be used with AND, ANDS, BIC, BICS, EON, EOR, ORN, and ORR instruction.
ASMJIT_MAYBE_UNUSED
-static inline bool isLogicalImm(uint64_t imm, uint32_t width) noexcept {
+static ASMJIT_INLINE_NODEBUG bool isLogicalImm(uint64_t imm, uint32_t width) noexcept {
LogicalImm dummy;
return encodeLogicalImm(imm, width, &dummy);
}
+//! Returns true if the given `imm` value is encodable as an immediate with `add` and `sub` instructions on AArch64.
+//! These two instructions can encode 12-bit immediate value optionally shifted left by 12 bits.
+ASMJIT_MAYBE_UNUSED
+static ASMJIT_INLINE_NODEBUG bool isAddSubImm(uint64_t imm) noexcept {
+ return imm <= 0xFFFu || (imm & ~uint64_t(0xFFFu << 12)) == 0;
+}
+
//! Returns true if the given `imm` value is a byte mask. Byte mask has each byte part of the value set to either
//! 0x00 or 0xFF. Some ARM instructions accept immediates that form a byte-mask and this function can be used to
//! verify that the immediate is encodable before using the value.
template<typename T>
-static inline bool isByteMaskImm8(const T& imm) noexcept {
+static ASMJIT_INLINE_NODEBUG bool isByteMaskImm8(const T& imm) noexcept {
constexpr T kMask = T(0x0101010101010101 & Support::allOnes<T>());
return imm == (imm & kMask) * T(255);
}
+// [.......A|B.......|.......C|D.......|.......E|F.......|.......G|H.......]
+static ASMJIT_INLINE_NODEBUG uint32_t encodeImm64ByteMaskToImm8(uint64_t imm) noexcept {
+ return uint32_t(((imm >> (7 - 0)) & 0b00000011) | // [.......G|H.......]
+ ((imm >> (23 - 2)) & 0b00001100) | // [.......E|F.......]
+ ((imm >> (39 - 4)) & 0b00110000) | // [.......C|D.......]
+ ((imm >> (55 - 6)) & 0b11000000)); // [.......A|B.......]
+}
//! \cond
//! A generic implementation that checjs whether a floating point value can be converted to ARM Imm8.
template<typename T, uint32_t kNumBBits, uint32_t kNumCDEFGHBits, uint32_t kNumZeroBits>
-static inline bool isFPImm8Generic(T val) noexcept {
+static ASMJIT_FORCE_INLINE bool isFPImm8Generic(T val) noexcept {
constexpr uint32_t kAllBsMask = Support::lsbMask<uint32_t>(kNumBBits);
constexpr uint32_t kB0Pattern = Support::bitMask(kNumBBits - 1);
constexpr uint32_t kB1Pattern = kAllBsMask ^ kB0Pattern;
@@ -127,7 +174,7 @@ static inline bool isFPImm8Generic(T val) noexcept {
//! ```
//! [aBbbcdef|gh000000]
//! ```
-static inline bool isFP16Imm8(uint32_t val) noexcept { return isFPImm8Generic<uint32_t, 3, 6, 6>(val); }
+static ASMJIT_INLINE_NODEBUG bool isFP16Imm8(uint32_t val) noexcept { return isFPImm8Generic<uint32_t, 3, 6, 6>(val); }
//! Returns true if the given single precision floating point `val` can be encoded as ARM IMM8 value, which represents
//! a limited set of floating point immediate values, which can be used with FMOV instruction.
@@ -137,9 +184,9 @@ static inline bool isFP16Imm8(uint32_t val) noexcept { return isFPImm8Generic<ui
//! ```
//! [aBbbbbbc|defgh000|00000000|00000000]
//! ```
-static inline bool isFP32Imm8(uint32_t val) noexcept { return isFPImm8Generic<uint32_t, 6, 6, 19>(val); }
+static ASMJIT_INLINE_NODEBUG bool isFP32Imm8(uint32_t val) noexcept { return isFPImm8Generic<uint32_t, 6, 6, 19>(val); }
//! \overload
-static inline bool isFP32Imm8(float val) noexcept { return isFP32Imm8(Support::bitCast<uint32_t>(val)); }
+static ASMJIT_INLINE_NODEBUG bool isFP32Imm8(float val) noexcept { return isFP32Imm8(Support::bitCast<uint32_t>(val)); }
//! Returns true if the given double precision floating point `val` can be encoded as ARM IMM8 value, which represents
//! a limited set of floating point immediate values, which can be used with FMOV instruction.
@@ -149,13 +196,13 @@ static inline bool isFP32Imm8(float val) noexcept { return isFP32Imm8(Support::b
//! ```
//! [aBbbbbbb|bbcdefgh|00000000|00000000|00000000|00000000|00000000|00000000]
//! ```
-static inline bool isFP64Imm8(uint64_t val) noexcept { return isFPImm8Generic<uint64_t, 9, 6, 48>(val); }
+static ASMJIT_INLINE_NODEBUG bool isFP64Imm8(uint64_t val) noexcept { return isFPImm8Generic<uint64_t, 9, 6, 48>(val); }
//! \overload
-static inline bool isFP64Imm8(double val) noexcept { return isFP64Imm8(Support::bitCast<uint64_t>(val)); }
+static ASMJIT_INLINE_NODEBUG bool isFP64Imm8(double val) noexcept { return isFP64Imm8(Support::bitCast<uint64_t>(val)); }
//! \cond
template<typename T, uint32_t kNumBBits, uint32_t kNumCDEFGHBits, uint32_t kNumZeroBits>
-static inline uint32_t encodeFPToImm8Generic(T val) noexcept {
+static ASMJIT_INLINE_NODEBUG uint32_t encodeFPToImm8Generic(T val) noexcept {
uint32_t bits = uint32_t(val >> kNumZeroBits);
return ((bits >> (kNumBBits + kNumCDEFGHBits - 7)) & 0x80u) | (bits & 0x7F);
}
@@ -165,9 +212,9 @@ static inline uint32_t encodeFPToImm8Generic(T val) noexcept {
//!
//! \note This function expects that `isFP64Imm8(val) == true` so it doesn't perform any checks of the value and just
//! rearranges some bits into Imm8 order.
-static inline uint32_t encodeFP64ToImm8(uint64_t val) noexcept { return encodeFPToImm8Generic<uint64_t, 9, 6, 48>(val); }
+static ASMJIT_INLINE_NODEBUG uint32_t encodeFP64ToImm8(uint64_t val) noexcept { return encodeFPToImm8Generic<uint64_t, 9, 6, 48>(val); }
//! \overload
-static inline uint32_t encodeFP64ToImm8(double val) noexcept { return encodeFP64ToImm8(Support::bitCast<uint64_t>(val)); }
+static ASMJIT_INLINE_NODEBUG uint32_t encodeFP64ToImm8(double val) noexcept { return encodeFP64ToImm8(Support::bitCast<uint64_t>(val)); }
} // {Utils}
@@ -175,5 +222,5 @@ static inline uint32_t encodeFP64ToImm8(double val) noexcept { return encodeFP64
ASMJIT_END_SUB_NAMESPACE
-#endif // ASMJIT_ARM_A64UTILS_H_INCLUDED
+#endif // ASMJIT_ARM_ARMUTILS_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/asmjit.h b/3rdparty/asmjit/src/asmjit/asmjit.h
index 1cd0651ffe1..f5184eb5777 100644
--- a/3rdparty/asmjit/src/asmjit/asmjit.h
+++ b/3rdparty/asmjit/src/asmjit/asmjit.h
@@ -3,7 +3,7 @@
// SPDX-License-Identifier: Zlib
// Official GitHub Repository: https://github.com/asmjit/asmjit
//
-// Copyright (c) 2008-2021 The AsmJit Authors
+// Copyright (c) 2008-2024 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/3rdparty/asmjit/src/asmjit/core.h b/3rdparty/asmjit/src/asmjit/core.h
index 4406ed89f30..cb19333ac38 100644
--- a/3rdparty/asmjit/src/asmjit/core.h
+++ b/3rdparty/asmjit/src/asmjit/core.h
@@ -105,40 +105,37 @@ namespace asmjit {
//!
//! - 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).
+//! - **Clang** - Tested by GitHub Actions - Clang 10+ is officially supported and tested by CI, older Clang versions
+//! having C++11 should work, but are not tested anymore due to upgraded CI images.
//!
-//! - **GNU** - Tested by GitHub Actions - GCC 4.8+ (with C++11 enabled) is officially supported.
+//! - **GNU** - Tested by GitHub Actions - GCC 7+ is officially supported, older GCC versions from 4.8+ having C++11
+//! enabled should also work, but are not tested anymore due to upgraded CI images.
//!
-//! - **MINGW** - Should work, but it's not tested in our CI environment.
+//! - **MINGW** - Reported to work, but not tested in our CI environment (help welcome).
//!
-//! - **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.
-//!
-//! - **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).
+//! - **MSVC** - Tested by GitHub Actions - VS2019+ is officially supported, VS2015 and VS2017 is reported to work,
+//! but not tested by CI anymore.
//!
//! ### Supported Operating Systems and Platforms
//!
//! - Tested:
//!
-//! - **Linux** - Tested by GitHub Actions (any distribution is generally supported).
+//! - **BSD** - FreeBSD, NetBSD, and OpenBSD tested by GitHub Actions (only recent images are tested by CI). BSD
+//! runners only test BSD images with clang compiler.
//!
-//! - **Mac OS** - Tested by GitHub Actions (any version is supported).
+//! - **Linux** - Tested by GitHub Actions (only recent Ubuntu images are tested by CI, in general any distribution
+//! should be supported as AsmJit has no dependencies).
+//!
+//! - **Mac OS** - Tested by GitHub Actions.
//!
//! - **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.
+//! used to generate X86/X64/AArch64 code within a browser, for example.
//!
//! - Untested:
//!
-//! - **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.
+//! - **Haiku** - Reported to work, not tested by CI.
//!
//! - **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)
@@ -148,8 +145,7 @@ namespace asmjit {
//! ### Supported Backends / Architectures
//!
//! - **X86** and **X86_64** - Both 32-bit and 64-bit backends tested on CI.
-//! - **AArch64** - AArch64 backend is currently only partially tested (there is no native AArch64 runner to test
-//! AsmJit Builder/Compiler)
+//! - **AArch64** - Tested on CI (Native Apple runners and Linux emulated via QEMU).
//!
//! ### Static Builds and Embedding
//!
@@ -180,40 +176,49 @@ namespace asmjit {
//! ### 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 builds only the host backend, which is auto-detected 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.
-//!
-//! ### Features Selection
+//! - \ref ASMJIT_NO_X86 - Disables both X86 and X86_64 backends.
+//! - \ref ASMJIT_NO_AARCH64 - Disables AArch64 backend.
+//! - \ref ASMJIT_NO_FOREIGN - Disables the support for foreign architecture backends, only keeps a native backend.
//!
-//! 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 Compilation Options
//!
//! - \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_SHM_OPEN - Disables functionality that uses `shm_open()`.
//!
-//! - \ref ASMJIT_NO_COMPILER - Disables \ref asmjit_compiler functionality completely.
+//! - \ref ASMJIT_NO_ABI_NAMESPACE - Disables inline ABI namespace within `asmjit` namespace. This is only provided
+//! for users that control all the dependencies (even transitive ones) and that make sure that no two AsmJit
+//! versions are used at the same time. This option can be debugging a little simpler as there would not be ABI
+//! tag after `asmjit::` namespace. Otherwise asmjit would look like `asmjit::_abi_1_13::`, for example.
//!
-//! - \ref ASMJIT_NO_JIT - Disables JIT memory management and \ref JitRuntime.
+//! ### Features Selection
//!
-//! - \ref ASMJIT_NO_LOGGING - Disables \ref Logger and \ref Formatter.
+//! 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_JIT - Disables JIT memory management and \ref JitRuntime.
//!
//! - \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_LOGGING - Disables \ref Logger and \ref Formatter.
+//!
//! - \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_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.
+//!
//! \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.
@@ -234,7 +239,7 @@ namespace asmjit {
//!
//! 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 Chat](https://app.gitter.im/#/room/#asmjit:gitter.im) 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
@@ -242,6 +247,77 @@ namespace asmjit {
//! 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 2024-01-01
+//!
+//! Core changes:
+//!
+//! - Renamed equality functions `eq()` to `equals()` - Only related to `String`, `ZoneVector`, and `CpuFeatures`.
+//! Old function names were deprecated.
+//!
+//! - Removed `CallConvId::kNone` in favor of `CallConvId::kCDecl`, which is now the default calling convention.
+//!
+//! - Deprecated `CallConvId::kHost` in favor of `CallConvId::kCDecl` - host calling convention is now not part
+//! of CallConvId, it can be calculated from CallConvId and Environment instead.
+//!
+//! ### Changes committed at 2023-12-27
+//!
+//! Core changes:
+//!
+//! - Renamed `a64::Vec::ElementType` to `a64::VecElementType` and made it a typed enum. This enum was used mostly
+//! internally, but there is a public API using it, so it's a breaking change.
+//!
+//! - Refactored `FuncSignature`, `FuncSignatureT`, and `FuncSignatureBuilder`. There is only `FuncSignature` now,
+//! which acts as a function signature holder and builder. Replace `FuncSignatureBuilder` with `FuncSignature`
+//! and use `FuncSignature::build<args>` instead of `FuncSignatureT<args>`. The old API has been deprecated.
+//!
+//! - The maximum number of function arguments was raised from 16 to 32.
+//!
+//! ### Changes committed at 2023-12-26
+//!
+//! Core changes:
+//!
+//! - Reworked InstNode and InstExNode to be friendlier to static analysis and to not cause undefined behavior.
+//! InstNode has no operands visually embedded within the struct so there is no _opArray (which was internal).
+//! This means that sizeof(InstNode) changed, but since it's allocated by AsmJit this should be fine. Moreover,
+//! there is no longer InstExNode as that was more a hack, instead there is now InstNodeWithOperands, which is
+//! a template and specifies the number of operands embedded (InstNode accesses these). All nodes that inherited
+//! InstExNode now just inherit InstNodeWithOperands<InstNode::kBaseOpCapacity>, which would provide the same
+//! number of nodes as InstNode.
+//!
+//! - Moved GP and Vec registers from asmjit::arm namespace to asmjit::a64 namespace. At this time there was
+//! no prior deprecation as having arm::Vec would collide with a64::Vec as arm namespace is used within a64
+//! namespace. Just change `arm::Gp` to `a64::Gp` and `arm::Vec` to `a64::Vec`.
+//!
+//! ### Changes committed at 2023-09-10
+//!
+//! Core changes:
+//!
+//! - Changed allocation API to work with spans (JitAllocator).
+//!
+//! - This change is required to support more hardened platforms in the future that make it very difficult
+//! to write JIT compilers.
+//! - `JitAllocator::Span` now represents a memory that the user can access. It abstracts both regular and
+//! dual mappings.
+//! - The `Span` is mostly designed to make it possible to write into it, so in general the read+execute
+//! pointer is what user is intended to keep. Use `span.rx()` to access RX pointer. `Span` is not needed
+//! after the memory it references has been modified, only remember `span.rx()` pointer, which is then
+//! used to deallocate or change the memory the span references.
+//! - Use a new `JitAllocator::alloc()` to allocate a `Span`, then pass the populated Span to `JitAllocator`
+//! write API such as `JitAllocator::write()` - note that JitAllocator can also establish a scope, so you
+//! can use a lambda function that would perform the write, but since it's going through JitAllocator it's
+//! able to ensure that the memory is actually writable.
+//! - If you need to repopulate a `Span` from rx pointer, use `JitAllocator::query(<span-out>, rx)` to get it.
+//! - Study what JitRuntime is doing to better understand how this new API works in detail.
+//! - Users of JitRuntime do not have to do anything as JitRuntime properly abstracts the allocation.
+//!
+//! - Renamed some X86 CPU features to make them compatible with architecture manuals:
+//!
+//! - Changed `AVX512_CDI` to `AVX512_CD`.
+//! - Changed `AVX512_ERI` to `AVX512_ER`.
+//! - Changed `AVX512_PFI` to `AVX512_PF`.
+//!
+//! - Old names were deprecated.
+//!
//! ### Changes committed at 2021-12-13
//!
//! Core changes:
@@ -309,7 +385,7 @@ namespace asmjit {
//! 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 `Environment::isFamilyX86()`, etc.
-//! The reason for changing the order was support for more propertries and all the accessors now start with the
+//! The reason for changing the order was support for more properties 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.
@@ -392,7 +468,7 @@ namespace asmjit {
//! // Calling a function (Compiler) changed - use invoke() instead of call().
//! void functionInvocation(x86::Compiler& cc) {
//! InvokeNode* invokeNode;
-//! cc.invoke(&invokeNode, targetOperand, FuncSignatureT<...>(...));
+//! cc.invoke(&invokeNode, targetOperand, FuncSignature::build<...>(...));
//! }
//! ```
@@ -454,7 +530,8 @@ namespace asmjit {
//! JitRuntime rt; // Runtime specialized for JIT code execution.
//!
//! CodeHolder code; // Holds code and relocation information.
-//! code.init(rt.environment()); // Initialize code to match the JIT environment.
+//! code.init(rt.environment(), // Initialize code to match the JIT environment.
+//! rt.cpuFeatures());
//!
//! x86::Assembler a(&code); // Create and attach x86::Assembler to code.
//! a.mov(x86::eax, 1); // Move one to eax register.
@@ -599,9 +676,10 @@ namespace asmjit {
//! int main() {
//! // Create a custom environment that matches the current host environment.
//! Environment env = Environment::host();
+//! CpuFeatures cpuFeatures = CpuInfo::host().features();
//!
//! CodeHolder code; // Create a CodeHolder.
-//! code.init(env); // Initialize CodeHolder with environment.
+//! code.init(env, cpuFeatures); // Initialize CodeHolder with environment.
//!
//! x86::Assembler a(&code); // Create and attach x86::Assembler to `code`.
//!
@@ -661,15 +739,17 @@ namespace asmjit {
//! JitAllocator allocator;
//!
//! // Allocate an executable virtual memory and handle a possible failure.
-//! void* p = allocator.alloc(estimatedSize);
-//! if (!p)
+//! JitAllocator::Span span;
+//! Error err = allocator.alloc(span, estimatedSize);
+//!
+//! if (err != kErrorOk) // <- NOTE: This must be checked, always!
//! return 0;
//!
//! // Now relocate the code to the address provided by the memory allocator.
-//! // Please note that this DOESN'T COPY anything to `p`. This function will
-//! // store the address in CodeHolder and use relocation entries to patch the
-//! // existing code in all sections to respect the base address provided.
-//! code.relocateToBase((uint64_t)p);
+//! // Please note that this DOESN'T COPY anything to it. This function will
+//! // store the address in CodeHolder and use relocation entries to patch
+//! // the existing code in all sections to respect the base address provided.
+//! code.relocateToBase((uint64_t)span.rx());
//!
//! // This is purely optional. There are cases in which the relocation can omit
//! // unneeded data, which would shrink the size of address table. If that
@@ -682,12 +762,17 @@ namespace asmjit {
//! // additional options that can be used to also zero pad sections' virtual
//! // size, etc.
//! //
-//! // With some additional features, copyFlattenData() does roughly this:
-//! // for (Section* section : code.sections())
-//! // memcpy((uint8_t*)p + section->offset(),
-//! // section->data(),
-//! // section->bufferSize());
-//! code.copyFlattenedData(p, codeSize, CopySectionFlags::kPadSectionBuffer);
+//! // With some additional features, copyFlattenData() does roughly the following:
+//! //
+//! // allocator.write([&](JitAllocator::Span& span) {
+//! // for (Section* section : code.sections()) {
+//! // uint8_t* p = (uint8_t*)span.rw() + section->offset();
+//! // memcpy(p, section->data(), section->bufferSize());
+//! // }
+//! // }
+//! allocator.write([&](JitAllocator::Span& span) {
+//! code.copyFlattenedData(span.rw(), codeSize, CopySectionFlags::kPadSectionBuffer);
+//! });
//!
//! // Execute the generated function.
//! int inA[4] = { 4, 3, 2, 1 };
@@ -722,10 +807,11 @@ namespace asmjit {
//!
//! void initializeCodeHolder(CodeHolder& code) {
//! Environment env = Environment::host();
+//! CpuFeatures cpuFeatures = CpuInfo::host().features();
//! uint64_t baseAddress = uint64_t(0x1234);
//!
//! // initialize CodeHolder with environment and custom base address.
-//! code.init(env, baseAddress);
+//! code.init(env, cpuFeatures, baseAddress);
//! }
//! ```
//!
@@ -757,7 +843,7 @@ 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
+//! used labels matter. After a Label is bound it's possible to query its offset relative to the start of the
//! section where it was bound:
//!
//! ```
@@ -870,7 +956,7 @@ namespace asmjit {
//!
//! if (code.hasUnresolvedLinks()) {
//! // This would mean either unbound label or some other issue.
-//! printf("The code has %zu unbound labels\n", code.unresovedLinkCount());
+//! printf("The code has %zu unbound labels\n", code.unresolvedLinkCount());
//! exit(1);
//! }
//! }
@@ -886,12 +972,15 @@ namespace asmjit {
//! with assembler requires the knowledge of the following:
//!
//! - \ref BaseAssembler and architecture-specific assemblers:
-//! - \ref x86::Assembler - Assembler specific to X86 architecture
+//! - \ref x86::Assembler - Assembler implementation targeting X86 and X86_64 architectures.
+//! - \ref a64::Assembler - Assembler implementation targeting AArch64 architecture.
//! - \ref Operand and its variations:
//! - \ref BaseReg - Base class for a register operand, inherited by:
-//! - \ref x86::Reg - Register operand specific to X86 architecture.
+//! - \ref x86::Reg - Register operand specific to X86 and X86_64 architectures.
+//! - \ref arm::Reg - Register operand specific to AArch64 architecture.
//! - \ref BaseMem - Base class for a memory operand, inherited by:
//! - \ref x86::Mem - Memory operand specific to X86 architecture.
+//! - \ref arm::Mem - Memory operand specific to AArch64 architecture.
//! - \ref Imm - Immediate (value) operand.
//! - \ref Label - Label operand.
//!
@@ -999,7 +1088,7 @@ namespace asmjit {
//!
//! // Type-unsafe, but possible.
//! a.emit(x86::Inst::kIdMov, dst, m);
-//! // Also possible, `emit()` is typeless and can be used with raw Operand.
+//! // Also possible, `emit()` is type-less and can be used with raw Operand.
//! a.emit(x86::Inst::kIdMov, dst, op);
//! }
//! ```
@@ -1070,10 +1159,10 @@ namespace asmjit {
//!
//! void testX86Mem() {
//! // The same as: dword ptr [rax + rbx].
-//! x86::Mem a = x86::dword_ptr(rax, rbx);
+//! x86::Mem a = x86::dword_ptr(x86::rax, x86::rbx);
//!
//! // The same as: qword ptr [rdx + rsi << 0 + 1].
-//! x86::Mem b = x86::qword_ptr(rdx, rsi, 0, 1);
+//! x86::Mem b = x86::qword_ptr(x86::rdx, x86::rsi, 0, 1);
//! }
//! ```
//!
@@ -1086,18 +1175,18 @@ namespace asmjit {
//!
//! void testX86Mem() {
//! // The same as: dword ptr [rax + 12].
-//! x86::Mem mem = x86::dword_ptr(rax, 12);
+//! x86::Mem mem = x86::dword_ptr(x86::rax, 12);
//!
//! mem.hasBase(); // true.
//! mem.hasIndex(); // false.
//! mem.size(); // 4.
//! mem.offset(); // 12.
//!
-//! mem.setSize(0); // Sets the size to 0 (makes it sizeless).
+//! mem.setSize(0); // Sets the size to 0 (makes it size-less).
//! mem.addOffset(-1); // Adds -1 to the offset and makes it 11.
//! mem.setOffset(0); // Sets the offset to 0.
-//! mem.setBase(rcx); // Changes BASE to RCX.
-//! mem.setIndex(rax); // Changes INDEX to RAX.
+//! mem.setBase(x86::rcx); // Changes BASE to RCX.
+//! mem.setIndex(x86::rax); // Changes INDEX to RAX.
//! mem.hasIndex(); // true.
//! }
//! // ...
@@ -1189,7 +1278,8 @@ namespace asmjit {
//!
//! ### Builder Examples
//!
-//! - \ref x86::Builder provides many X86/X64 examples.
+//! - \ref x86::Builder - Builder implementation targeting X86 and X86_64 architectures.
+//! - \ref a64::Builder - Builder implementation targeting AArch64 architecture.
//! \defgroup asmjit_compiler Compiler
@@ -1226,7 +1316,8 @@ namespace asmjit {
//!
//! ### Compiler Examples
//!
-//! - \ref x86::Compiler provides many X86/X64 examples.
+//! - \ref x86::Compiler - Compiler implementation targeting X86 and X86_64 architectures.
+//! - \ref a64::Compiler - Compiler implementation targeting AArch64 architecture.
//!
//! ### Compiler Tips
//!
@@ -1346,7 +1437,8 @@ namespace asmjit {
//! FileLogger logger(stdout); // Logger should always survive CodeHolder.
//!
//! CodeHolder code; // Holds code and relocation information.
-//! code.init(rt.environment()); // Initialize to the same arch as JIT runtime.
+//! code.init(rt.environment(), // Initialize code to match the JIT environment.
+//! rt.cpuFeatures());
//! code.setLogger(&logger); // Attach the `logger` to `code` holder.
//!
//! // ... code as usual, everything emitted will be logged to `stdout` ...
@@ -1369,7 +1461,8 @@ namespace asmjit {
//! StringLogger logger; // Logger should always survive CodeHolder.
//!
//! CodeHolder code; // Holds code and relocation information.
-//! code.init(rt.environment()); // Initialize to the same arch as JIT runtime.
+//! code.init(rt.environment(), // Initialize code to match the JIT environment.
+//! rt.cpuFeatures());
//! code.setLogger(&logger); // Attach the `logger` to `code` holder.
//!
//! // ... code as usual, logging will be concatenated to logger string ...
@@ -1396,7 +1489,7 @@ namespace asmjit {
//! The first example illustrates how to format operands:
//!
//! ```
-//! #include <asmjit/core.h>
+//! #include <asmjit/x86.h>
//! #include <stdio.h>
//!
//! using namespace asmjit;
@@ -1421,17 +1514,17 @@ namespace asmjit {
//! // compatible with what AsmJit normally does.
//! Arch arch = Arch::kX64;
//!
-//! log(arch, rax); // Prints 'rax'.
-//! log(arch, ptr(rax, rbx, 2)); // Prints '[rax + rbx * 4]`.
-//! log(arch, dword_ptr(rax, rbx, 2)); // Prints 'dword [rax + rbx * 4]`.
-//! log(arch, imm(42)); // Prints '42'.
+//! logOperand(arch, rax); // Prints 'rax'.
+//! logOperand(arch, ptr(rax, rbx, 2)); // Prints '[rax + rbx * 4]`.
+//! logOperand(arch, dword_ptr(rax, rbx, 2)); // Prints 'dword [rax + rbx * 4]`.
+//! logOperand(arch, imm(42)); // Prints '42'.
//! }
//! ```
//!
//! Next example illustrates how to format whole instructions:
//!
//! ```
-//! #include <asmjit/core.h>
+//! #include <asmjit/x86.h>
//! #include <stdio.h>
//! #include <utility>
//!
@@ -1446,7 +1539,7 @@ namespace asmjit {
//! FormatFlags formatFlags = FormatFlags::kNone;
//!
//! // The formatter expects operands in an array.
-//! Operand_ operands { std::forward<Args>(args)... };
+//! Operand_ operands[] { std::forward<Args>(args)... };
//!
//! StringTmp<128> sb;
//! Formatter::formatInstruction(
@@ -1468,13 +1561,13 @@ namespace asmjit {
//! // Prints 'vaddpd zmm0, zmm1, [rax] {1to8}'.
//! logInstruction(arch,
//! BaseInst(Inst::kIdVaddpd),
-//! zmm0, zmm1, ptr(rax)._1toN());
+//! zmm0, zmm1, ptr(rax)._1to8());
//!
//! // BaseInst abstracts instruction id, instruction options, and extraReg.
//! // Prints 'lock add [rax], rcx'.
//! logInstruction(arch,
//! BaseInst(Inst::kIdAdd, InstOptions::kX86_Lock),
-//! x86::ptr(rax), rcx);
+//! ptr(rax), rcx);
//!
//! // Similarly an extra register (like AVX-512 selector) can be used.
//! // Prints 'vaddpd zmm0 {k2} {z}, zmm1, [rax]'.
@@ -1494,7 +1587,7 @@ namespace asmjit {
//! using namespace asmjit;
//!
//! void formattingExample(BaseBuilder* builder) {
-//! FormatFlags formatFlags = FormatFlags::kNone;
+//! FormatOptions formatOptions {};
//!
//! // This also shows how temporary strings can be used.
//! StringTmp<512> sb;
@@ -1503,7 +1596,7 @@ namespace asmjit {
//! // were zero (no extra flags), and the builder instance, which we have
//! // provided. An overloaded version also exists, which accepts begin and
//! // and end nodes, which can be used to only format a range of nodes.
-//! Formatter::formatNodeList(sb, formatFlags, builder);
+//! Formatter::formatNodeList(sb, formatOptions, builder);
//!
//! // You can do whatever else with the string, it's always null terminated,
//! // so it can be passed to C functions like printf().
@@ -1522,7 +1615,7 @@ namespace asmjit {
//! 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
+//! Errors should never be ignored, however, checking errors after each AsmJit API call would simply over-complicate
//! 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:
//!
@@ -1560,7 +1653,7 @@ namespace asmjit {
//! MyErrorHandler myErrorHandler;
//! CodeHolder code;
//!
-//! code.init(rt.environment());
+//! code.init(rt.environment(), rt.cpuFeatures());
//! code.setErrorHandler(&myErrorHandler);
//!
//! x86::Assembler a(&code);
@@ -1592,7 +1685,7 @@ namespace asmjit {
//!
//! Each instruction can be then queried for the following information:
//!
-//! - \ref InstRWInfo - Read/write information of instruction and its oprands (includes \ref OpRWInfo).
+//! - \ref InstRWInfo - Read/write information of instruction and its operands (includes \ref OpRWInfo).
//!
//! - \ref CpuFeatures - CPU features required to execute the instruction.
//!
@@ -1631,14 +1724,57 @@ namespace asmjit {
//!
//! ### Overview
//!
-//! 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.
+//! AsmJit's virtual memory management is divided into three main categories:
+//!
+//! - Low level interface that provides cross-platform abstractions for virtual memory allocation. Implemented in
+//! \ref VirtMem namespace. This API is a thin wrapper around operating system specific calls such as
+//! `VirtualAlloc()` and `mmap()` and it's intended to be used by AsmJit's higher level API. Low-level virtual
+//! memory functions can be used to allocate virtual memory, change its permissions, and to release it.
+//! Additionally, an API that allows to create dual mapping (to support hardened environments) is provided.
+//!
+//! - Middle level API that is provided by \ref JitAllocator, which uses \ref VirtMem internally and offers nicer
+//! API that can be used by users to allocate executable memory conveniently. \ref JitAllocator tries to be smart,
+//! for example automatically using dual mapping or `MAP_JIT` on hardened environments.
+//!
+//! - High level API that is provided by \ref JitRuntime, which implements \ref Target interface and uses \ref
+//! JitAllocator under the hood. Since \ref JitRuntime inherits from \ref Target it makes it easy to use with
+//! \ref CodeHolder. Many AsmJit examples use \ref JitRuntime for its simplicity and easy integration.
+//!
+//! The main difference between \ref VirtMem and \ref JitAllocator is that \ref VirtMem can only be used to allocate
+//! whole pages, whereas \ref JitAllocator has `malloc()` like API that allows to allocate smaller quantities that
+//! usually represent the size of an assembled function or a chunk of functions that can represent a module, for
+//! example. \ref JitAllocator then tracks used space of each page it maintains. Internally, \ref JitAllocator uses
+//! two bit arrays to track occupied regions in each allocated block of pages.
+//!
+//! ### Hardened Environments
+//!
+//! In the past, allocating virtual memory with Read+Write+Execute (RWX) access permissions was easy. However, modern
+//! operating systems and runtime environments often use hardening, which typically prohibits mapping pages with both
+//! Write and Execute permissions (known as the W^X policy). This presents a challenge for JIT compilers because
+//! generated code for a single function is unlikely to fit in exactly N pages without leaving some space empty. To
+//! accommodate this, the execution environment may need to temporarily change the permissions of existing pages to
+//! read+write (RW) to insert new code into them, however, sometimes it's not possible to ensure that no thread is
+//! executing code in such affected pages in a multithreaded environment, in which multiple threads may be executing
+//! generated code.
+//!
+//! Such restrictions leave a lot of complexity on the application, so AsmJit implements a dual mapping technique to
+//! make the life of AsmJit users easier. In this technique, a region of memory is mapped to two different virtual
+//! addresses with different access permissions. One virtual address is mapped with read and write (RW) access, which
+//! is used by the JIT compiler to write generated code. The other virtual address is mapped with read and execute (RX)
+//! access, which is used by the application to execute the generated code.
+//!
+//! However, implementing dual mapping can be challenging because it typically requires obtaining an anonymous file
+//! descriptor on most Unix-like operating systems. This file descriptor is then passed to mmap() twice to create
+//! the two mappings. AsmJit handles this challenge by using system-specific techniques such as `memfd_create()` on
+//! Linux, `shm_open(SHM_ANON)` on BSD, and `MAP_REMAPDUP` with `mremap()` on NetBSD. The latter approach does not
+//! require a file descriptor. If none of these options are available, AsmJit uses a plain `open()` call followed by
+//! `unlink()`.
+//!
+//! The most challenging part is actually obtaining a file descriptor that can be passed to `mmap()` with `PROT_EXEC`.
+//! This is still something that may fail, for example the environment could be hardened in a way that this would
+//! not be possible at all, and thus dual mapping would not work.
+//!
+//! Dual mapping is provided by both \ref VirtMem and \ref JitAllocator.
//! \defgroup asmjit_zone Zone Memory
diff --git a/3rdparty/asmjit/src/asmjit/core/api-build_p.h b/3rdparty/asmjit/src/asmjit/core/api-build_p.h
index 6eca971037e..3ddc9e78d22 100644
--- a/3rdparty/asmjit/src/asmjit/core/api-build_p.h
+++ b/3rdparty/asmjit/src/asmjit/core/api-build_p.h
@@ -27,6 +27,25 @@
#define NOMINMAX
#endif
#include <windows.h>
+#else
+ // Most production code is compiled with large file support, so do the same.
+ #if !defined(_WIN32) && !defined(_LARGEFILE64_SOURCE)
+ #define _LARGEFILE64_SOURCE 1
+ #endif
+
+ // These OSes use 64-bit API by default.
+ #if defined(__APPLE__ ) || \
+ defined(__HAIKU__ ) || \
+ defined(__bsdi__ ) || \
+ defined(__DragonFly__) || \
+ defined(__FreeBSD__ ) || \
+ defined(__NetBSD__ ) || \
+ defined(__OpenBSD__ )
+ #define ASMJIT_FILE64_API(NAME) NAME
+ #else
+ #define ASMJIT_FILE64_API(NAME) NAME##64
+ #endif
+
#endif
#include "./api-config.h"
diff --git a/3rdparty/asmjit/src/asmjit/core/api-config.h b/3rdparty/asmjit/src/asmjit/core/api-config.h
index 6bd5beecc0a..bbc35067778 100644
--- a/3rdparty/asmjit/src/asmjit/core/api-config.h
+++ b/3rdparty/asmjit/src/asmjit/core/api-config.h
@@ -12,20 +12,23 @@
//! \addtogroup asmjit_core
//! \{
-//! AsmJit library version in `(Major << 16) | (Minor << 8) | (Patch)` format.
-#define ASMJIT_LIBRARY_VERSION 0x010900 /* 1.9.0 */
+//! Makes a 32-bit integer that represents AsmJit version in `(major << 16) | (minor << 8) | patch` form.
+#define ASMJIT_LIBRARY_MAKE_VERSION(major, minor, patch) ((major << 16) | (minor << 8) | (patch))
+
+//! AsmJit library version, see \ref ASMJIT_LIBRARY_MAKE_VERSION for a version format reference.
+#define ASMJIT_LIBRARY_VERSION ASMJIT_LIBRARY_MAKE_VERSION(1, 13, 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_9
-#endif
+//! 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 multiple AsmJit libraries within a single project, totally
+//! controlled by users. This is useful especially in cases in which some of such library comes from third party.
+#if !defined(ASMJIT_ABI_NAMESPACE)
+ #define ASMJIT_ABI_NAMESPACE _abi_1_13
+#endif // !ASMJIT_ABI_NAMESPACE
//! \}
@@ -39,9 +42,8 @@
#include <stdlib.h>
#include <string.h>
-#include <iterator>
+#include <initializer_list>
#include <limits>
-#include <new>
#include <type_traits>
#include <utility>
@@ -52,8 +54,6 @@
// Build Options
// =============
-#define ASMJIT_STATIC
-
// 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
@@ -70,20 +70,17 @@ namespace asmjit {
//! Defined when AsmJit's build configuration is 'Debug'.
//!
-//! \note Can be defined explicitly to bypass autodetection.
+//! \note Can be defined explicitly to bypass auto-detection.
#define ASMJIT_BUILD_DEBUG
//! Defined when AsmJit's build configuration is 'Release'.
//!
-//! \note Can be defined explicitly to bypass autodetection.
+//! \note Can be defined explicitly to bypass auto-detection.
#define ASMJIT_BUILD_RELEASE
//! Disables X86/X64 backends.
#define ASMJIT_NO_X86
-//! Disables AArch32 backends (both ARM and Thumb).
-#define ASMJIT_NO_AARCH32
-
//! Disables AArch64 backend.
#define ASMJIT_NO_AARCH64
@@ -115,7 +112,7 @@ namespace asmjit {
#define ASMJIT_NO_INTROSPECTION
// Avoid doxygen preprocessor using feature-selection definitions.
-#undef ASMJIT_BUILD_EMBNED
+#undef ASMJIT_BUILD_EMBED
#undef ASMJIT_BUILD_STATIC
#undef ASMJIT_BUILD_DEBUG
#undef ASMJIT_BUILD_RELEASE
@@ -166,6 +163,41 @@ namespace asmjit {
// Target Architecture Detection
// =============================
+//! \addtogroup asmjit_core
+//! \{
+
+//! \def ASMJIT_ARCH_X86
+//!
+//! Defined to either 0, 32, or 64 depending on whether the target CPU is X86 (32) or X86_64 (64).
+
+//! \def ASMJIT_ARCH_ARM
+//!
+//! Defined to either 0, 32, or 64 depending on whether the target CPU is ARM (32) or AArch64 (64).
+
+//! \def ASMJIT_ARCH_MIPS
+//!
+//! Defined to either 0, 32, or 64 depending on whether the target CPU is MIPS (32) or MISP64 (64).
+
+//! \def ASMJIT_ARCH_RISCV
+//!
+//! Defined to either 0, 32, or 64 depending on whether the target CPU is RV32 (32) or RV64 (64).
+
+//! \def ASMJIT_ARCH_BITS
+//!
+//! Defined to either 32 or 64 depending on the target.
+
+//! \def ASMJIT_ARCH_LE
+//!
+//! Defined to 1 if the target architecture is little endian.
+
+//! \def ASMJIT_ARCH_BE
+//!
+//! Defined to 1 if the target architecture is big endian.
+
+//! \}
+
+//! \cond NONE
+
#if defined(_M_X64) || defined(__x86_64__)
#define ASMJIT_ARCH_X86 64
#elif defined(_M_IX86) || defined(__X86__) || defined(__i386__)
@@ -174,7 +206,7 @@ namespace asmjit {
#define ASMJIT_ARCH_X86 0
#endif
-#if defined(__arm64__) || defined(__aarch64__)
+#if defined(_M_ARM64) || defined(__arm64__) || defined(__aarch64__)
# define ASMJIT_ARCH_ARM 64
#elif defined(_M_ARM) || defined(_M_ARMT) || defined(__arm__) || defined(__thumb__) || defined(__thumb2__)
#define ASMJIT_ARCH_ARM 32
@@ -190,10 +222,17 @@ namespace asmjit {
#define ASMJIT_ARCH_MIPS 0
#endif
-#define ASMJIT_ARCH_BITS (ASMJIT_ARCH_X86 | ASMJIT_ARCH_ARM | ASMJIT_ARCH_MIPS)
+// NOTE `__riscv` is the correct macro in this case as specified by "RISC-V Toolchain Conventions".
+#if (defined(__riscv) || defined(__riscv__)) && defined(__riscv_xlen)
+ #define ASMJIT_ARCH_RISCV __riscv_xlen
+#else
+ #define ASMJIT_ARCH_RISCV 0
+#endif
+
+#define ASMJIT_ARCH_BITS (ASMJIT_ARCH_X86 | ASMJIT_ARCH_ARM | ASMJIT_ARCH_MIPS | ASMJIT_ARCH_RISCV)
#if ASMJIT_ARCH_BITS == 0
#undef ASMJIT_ARCH_BITS
- #if defined (__LP64__) || defined(_LP64)
+ #if defined(__LP64__) || defined(_LP64)
#define ASMJIT_ARCH_BITS 64
#else
#define ASMJIT_ARCH_BITS 32
@@ -215,62 +254,88 @@ namespace asmjit {
#define ASMJIT_NO_X86
#endif
- #if !ASMJIT_ARCH_ARM && !defined(ASMJIT_NO_AARCH64)
+ #if ASMJIT_ARCH_ARM != 64 && !defined(ASMJIT_NO_AARCH64)
#define ASMJIT_NO_AARCH64
#endif
#endif
+//! \endcond
// C++ Compiler and Features Detection
// ===================================
-#define ASMJIT_CXX_GNU 0
-#define ASMJIT_CXX_MAKE_VER(MAJOR, MINOR) ((MAJOR) * 1000 + (MINOR))
-
-// Intel Compiler [pretends to be GNU or MSC, so it must be checked first]:
-// - https://software.intel.com/en-us/articles/c0x-features-supported-by-intel-c-compiler
-// - https://software.intel.com/en-us/articles/c14-features-supported-by-intel-c-compiler
-// - https://software.intel.com/en-us/articles/c17-features-supported-by-intel-c-compiler
-#if defined(__INTEL_COMPILER)
-
-// MSC Compiler:
-// - https://msdn.microsoft.com/en-us/library/hh567368.aspx
-//
-// Version List:
-// - 16.00.0 == VS2010
-// - 17.00.0 == VS2012
-// - 18.00.0 == VS2013
-// - 19.00.0 == VS2015
-// - 19.10.0 == VS2017
-#elif defined(_MSC_VER) && defined(_MSC_FULL_VER)
-
-// Clang Compiler [Pretends to be GNU, so it must be checked before]:
-// - https://clang.llvm.org/cxx_status.html
-#elif defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__)
-
-// GNU Compiler:
-// - https://gcc.gnu.org/projects/cxx-status.html
-#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
-
- #undef ASMJIT_CXX_GNU
- #define ASMJIT_CXX_GNU ASMJIT_CXX_MAKE_VER(__GNUC__, __GNUC_MINOR__)
-
-#endif
-
-// Compiler features detection macros.
-#if defined(__clang__) && defined(__has_attribute)
+#if defined(__GNUC__) && defined(__has_attribute)
#define ASMJIT_CXX_HAS_ATTRIBUTE(NAME, CHECK) (__has_attribute(NAME))
#else
#define ASMJIT_CXX_HAS_ATTRIBUTE(NAME, CHECK) (!(!(CHECK)))
-#endif
+#endif // !ASMJIT_CXX_HAS_ATTRIBUTE
// API Decorators & C++ Extensions
// ===============================
+//! \addtogroup asmjit_core
+//! \{
+
//! \def ASMJIT_API
//!
//! A decorator that is used to decorate API that AsmJit exports when built as a shared library.
+//! \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).
+
+//! \def ASMJIT_FORCE_INLINE
+//!
+//! Decorator to force inlining of functions, uses either `__attribute__((__always_inline__))` or __forceinline,
+//! depending on C++ compiler.
+
+//! \def ASMJIT_INLINE_NODEBUG
+//!
+//! Like \ref ASMJIT_FORCE_INLINE, but uses additionally `__nodebug__` or `__artificial__` attribute to make the
+//! debugging of some AsmJit functions easier, especially getters and one-line abstractions where usually you don't
+//! want to step in.
+
+//! \def ASMJIT_NOINLINE
+//!
+//! Decorator to avoid inlining of functions, uses either `__attribute__((__noinline__))` or `__declspec(noinline)`
+//! depending on C++ compiler.
+
+//! \def ASMJIT_NORETURN
+//!
+//! Decorator that marks functions that should never return. Typically used to implement assertion handlers that
+//! terminate, so the function never returns.
+
+//! \def ASMJIT_CDECL
+//!
+//! CDECL function attribute - either `__attribute__((__cdecl__))` or `__cdecl`.
+
+//! \def ASMJIT_STDCALL
+//!
+//! STDCALL function attribute - either `__attribute__((__stdcall__))` or `__stdcall`.
+//!
+//! \note This expands to nothing on non-x86 targets as STDCALL is X86 specific.
+
+//! \def ASMJIT_FASTCALL
+//!
+//! FASTCALL function attribute - either `__attribute__((__fastcall__))` or `__fastcall`.
+//!
+//! \note Expands to nothing on non-x86 targets as FASTCALL is X86 specific.
+
+//! \def ASMJIT_REGPARM(N)
+//!
+//! Expands to `__attribute__((__regparm__(N)))` when compiled by GCC or clang, nothing otherwise.
+
+//! \def ASMJIT_VECTORCALL
+//!
+//! VECTORCALL function attribute - either `__attribute__((__vectorcall__))` or `__vectorcall`.
+//!
+//! \note Expands to nothing on non-x86 targets as VECTORCALL is X86 specific.
+
+//! \}
+
// API (Export / Import).
#if !defined(ASMJIT_STATIC)
#if defined(_WIN32) && (defined(_MSC_VER) || defined(__MINGW32__))
@@ -298,13 +363,7 @@ namespace asmjit {
#define ASMJIT_VARAPI extern ASMJIT_API
#endif
-//! \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__)
+#if defined(__GNUC__) && !defined(_WIN32)
#define ASMJIT_VIRTAPI ASMJIT_API
#else
#define ASMJIT_VIRTAPI
@@ -319,6 +378,15 @@ namespace asmjit {
#define ASMJIT_FORCE_INLINE inline
#endif
+
+#if defined(__clang__)
+ #define ASMJIT_INLINE_NODEBUG inline __attribute__((__always_inline__, __nodebug__))
+#elif defined(__GNUC__)
+ #define ASMJIT_INLINE_NODEBUG inline __attribute__((__always_inline__, __artificial__))
+#else
+ #define ASMJIT_INLINE_NODEBUG inline
+#endif
+
#if defined(__GNUC__)
#define ASMJIT_NOINLINE __attribute__((__noinline__))
#define ASMJIT_NORETURN __attribute__((__noreturn__))
@@ -452,17 +520,10 @@ namespace asmjit {
//! Marks function, class, struct, enum, or anything else as deprecated.
#if defined(__GNUC__)
#define ASMJIT_DEPRECATED(MESSAGE) __attribute__((__deprecated__(MESSAGE)))
- #if defined(__clang__)
- #define ASMJIT_DEPRECATED_STRUCT(MESSAGE) __attribute__((__deprecated__(MESSAGE)))
- #else
- #define ASMJIT_DEPRECATED_STRUCT(MESSAGE) /* not usable if a deprecated function uses it */
- #endif
#elif defined(_MSC_VER)
#define ASMJIT_DEPRECATED(MESSAGE) __declspec(deprecated(MESSAGE))
- #define ASMJIT_DEPRECATED_STRUCT(MESSAGE) /* not usable if a deprecated function uses it */
#else
#define ASMJIT_DEPRECATED(MESSAGE)
- #define ASMJIT_DEPRECATED_STRUCT(MESSAGE)
#endif
// Utilities.
@@ -471,66 +532,60 @@ namespace asmjit {
#if ASMJIT_CXX_HAS_ATTRIBUTE(no_sanitize, 0)
#define ASMJIT_ATTRIBUTE_NO_SANITIZE_UNDEF __attribute__((__no_sanitize__("undefined")))
-#elif ASMJIT_CXX_GNU >= ASMJIT_CXX_MAKE_VER(4, 9)
+#elif defined(__GNUC__) && __GNUC__ >= 5
#define ASMJIT_ATTRIBUTE_NO_SANITIZE_UNDEF __attribute__((__no_sanitize_undefined__))
#else
#define ASMJIT_ATTRIBUTE_NO_SANITIZE_UNDEF
#endif
-// Begin-Namespace & End-Namespace Macros
+// Diagnostic Macros
// ======================================
-#if defined _DOXYGEN
- #define ASMJIT_BEGIN_NAMESPACE namespace asmjit {
- #define ASMJIT_END_NAMESPACE }
-#elif defined(__clang__)
- #define ASMJIT_BEGIN_NAMESPACE \
- 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 { inline namespace ASMJIT_ABI_NAMESPACE { \
+#if !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(_DOXYGEN)
+ #if defined(__GNUC__) && __GNUC__ == 4
+ // There is a bug in GCC 4.X that has been fixed in GCC 5+, so just silence the warning.
+ #define ASMJIT_BEGIN_DIAGNOSTIC_SCOPE \
_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 { 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 { inline namespace ASMJIT_ABI_NAMESPACE { \
+ #define ASMJIT_END_DIAGNOSTIC_SCOPE \
+ _Pragma("GCC diagnostic pop")
+ #elif defined(_MSC_VER)
+ #define ASMJIT_BEGIN_DIAGNOSTIC_SCOPE \
__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)) \
- }}
+ #define ASMJIT_END_DIAGNOSTIC_SCOPE \
+ __pragma(warning(pop))
+ #endif
#endif
-#if !defined(ASMJIT_BEGIN_NAMESPACE) && !defined(ASMJIT_END_NAMESPACE)
- #define ASMJIT_BEGIN_NAMESPACE namespace asmjit { inline namespace ASMJIT_ABI_NAMESPACE {
- #define ASMJIT_END_NAMESPACE }}
+#if !defined(ASMJIT_BEGIN_DIAGNOSTIC_SCOPE) && !defined(ASMJIT_END_DIAGNOSTIC_SCOPE)
+ #define ASMJIT_BEGIN_DIAGNOSTIC_SCOPE
+ #define ASMJIT_END_DIAGNOSTIC_SCOPE
#endif
-#define ASMJIT_BEGIN_SUB_NAMESPACE(NAMESPACE) \
- ASMJIT_BEGIN_NAMESPACE \
- namespace NAMESPACE {
+// Begin-Namespace & End-Namespace Macros
+// ======================================
-#define ASMJIT_END_SUB_NAMESPACE \
- } \
- ASMJIT_END_NAMESPACE
+#if !defined(ASMJIT_NO_ABI_NAMESPACE) && !defined(_DOXYGEN)
+ #define ASMJIT_BEGIN_NAMESPACE \
+ ASMJIT_BEGIN_DIAGNOSTIC_SCOPE \
+ namespace asmjit { \
+ inline namespace ASMJIT_ABI_NAMESPACE {
+ #define ASMJIT_END_NAMESPACE \
+ }} \
+ ASMJIT_END_DIAGNOSTIC_SCOPE
+#else
+ #define ASMJIT_BEGIN_NAMESPACE \
+ ASMJIT_BEGIN_DIAGNOSTIC_SCOPE \
+ namespace asmjit {
+ #define ASMJIT_END_NAMESPACE \
+ } \
+ ASMJIT_END_DIAGNOSTIC_SCOPE
+#endif
+
+#define ASMJIT_BEGIN_SUB_NAMESPACE(NAMESPACE) ASMJIT_BEGIN_NAMESPACE namespace NAMESPACE {
+#define ASMJIT_END_SUB_NAMESPACE } ASMJIT_END_NAMESPACE
// C++ Utilities
// =============
@@ -551,34 +606,34 @@ namespace asmjit {
#define ASMJIT_DEFINE_ENUM_FLAGS(T)
#else
#define ASMJIT_DEFINE_ENUM_FLAGS(T) \
- static ASMJIT_FORCE_INLINE constexpr T operator~(T a) noexcept { \
+ static ASMJIT_INLINE_NODEBUG 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 { \
+ static ASMJIT_INLINE_NODEBUG 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 { \
+ static ASMJIT_INLINE_NODEBUG 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 { \
+ static ASMJIT_INLINE_NODEBUG 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 { \
+ static ASMJIT_INLINE_NODEBUG 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 { \
+ static ASMJIT_INLINE_NODEBUG 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 { \
+ static ASMJIT_INLINE_NODEBUG T& operator^=(T& a, T b) noexcept { \
a = T((std::underlying_type<T>::type)(a) ^ \
(std::underlying_type<T>::type)(b)); \
return a; \
@@ -588,28 +643,22 @@ namespace asmjit {
//! \def ASMJIT_DEFINE_ENUM_COMPARE(T)
//!
//! Defines comparison operations for enumeration flags.
-#ifdef _DOXYGEN
+#if defined(_DOXYGEN) || (defined(_MSC_VER) && _MSC_VER <= 1900)
#define ASMJIT_DEFINE_ENUM_COMPARE(T)
#else
#define ASMJIT_DEFINE_ENUM_COMPARE(T) \
- static ASMJIT_FORCE_INLINE bool operator<(T a, T b) noexcept { \
+ static ASMJIT_INLINE_NODEBUG 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 { \
+ static ASMJIT_INLINE_NODEBUG 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 { \
+ static ASMJIT_INLINE_NODEBUG 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 { \
+ static ASMJIT_INLINE_NODEBUG 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
-// ==================================
-
-#undef ASMJIT_CXX_GNU
-#undef ASMJIT_CXX_MAKE_VER
-
#endif // ASMJIT_CORE_API_CONFIG_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/core/archcommons.h b/3rdparty/asmjit/src/asmjit/core/archcommons.h
index e9d2c84d722..2b47d17c1b4 100644
--- a/3rdparty/asmjit/src/asmjit/core/archcommons.h
+++ b/3rdparty/asmjit/src/asmjit/core/archcommons.h
@@ -29,8 +29,8 @@ enum class CondCode : uint8_t {
kNE = 0x03u, //!< Z==0 (any_sign !=)
kCS = 0x04u, //!< C==1 (unsigned >=)
kHS = 0x04u, //!< C==1 (unsigned >=)
- kCC = 0x05u, //!< C==0 (unsigned < )
kLO = 0x05u, //!< C==0 (unsigned < )
+ kCC = 0x05u, //!< C==0 (unsigned < )
kMI = 0x06u, //!< N==1 (is negative)
kPL = 0x07u, //!< N==0 (is positive or zero)
kVS = 0x08u, //!< V==1 (is overflow)
@@ -42,21 +42,24 @@ enum class CondCode : uint8_t {
kGT = 0x0Eu, //!< Z==0 & N==V (signed > )
kLE = 0x0Fu, //!< Z==1 | N!=V (signed <=)
- kSign = kMI, //!< Sign.
- kNotSign = kPL, //!< Not sign.
-
- kOverflow = kVS, //!< Signed overflow.
- kNotOverflow = kVC, //!< Not signed overflow.
+ kZero = kEQ, //!< Zero flag (alias to equal).
+ kNotZero = kNE, //!< Not zero (alias to Not Equal).
kEqual = kEQ, //!< Equal `a == b`.
kNotEqual = kNE, //!< Not Equal `a != b`.
- kZero = kEQ, //!< Zero (alias to equal).
- kNotZero = kNE, //!< Not Zero (alias to Not Equal).
+ kCarry = kCS, //!< Carry flag.
+ kNotCarry = kCC, //!< Not carry.
+
+ kSign = kMI, //!< Sign flag.
+ kNotSign = kPL, //!< Not sign.
kNegative = kMI, //!< Negative.
kPositive = kPL, //!< Positive or zero.
+ kOverflow = kVS, //!< Signed overflow.
+ kNotOverflow = kVC, //!< Not signed overflow.
+
kSignedLT = kLT, //!< Signed `a < b`.
kSignedLE = kLE, //!< Signed `a <= b`.
kSignedGT = kGT, //!< Signed `a > b`.
@@ -67,47 +70,51 @@ enum class CondCode : uint8_t {
kUnsignedGT = kHI, //!< Unsigned `a > b`.
kUnsignedGE = kHS, //!< Unsigned `a >= b`.
+ kBTZero = kZero, //!< Tested bit is zero.
+ kBTNotZero = kNotZero, //!< Tested bit is not zero.
+
kAlways = kAL, //!< No condition code (always).
kMaxValue = 0x0Fu //!< Maximum value of `CondCode`.
};
-//! Negates a condition code.
-static inline constexpr CondCode negateCond(CondCode cond) noexcept { return CondCode(uint8_t(cond) ^ uint8_t(1)); }
-//! Data type that can be encoded with the instruction (AArch32 only).
-enum class DataType : uint32_t {
- //! No data type specified (default for all general purpose instructions).
- kNone = 0,
- //! 8-bit signed integer, specified as `.s8` in assembly.
- kS8 = 1,
- //! 16-bit signed integer, specified as `.s16` in assembly.
- kS16 = 2,
- //! 32-bit signed integer, specified as `.s32` in assembly.
- kS32 = 3,
- //! 64-bit signed integer, specified as `.s64` in assembly.
- kS64 = 4,
- //! 8-bit unsigned integer, specified as `.u8` in assembly.
- kU8 = 5,
- //! 16-bit unsigned integer, specified as `.u16` in assembly.
- kU16 = 6,
- //! 32-bit unsigned integer, specified as `.u32` in assembly.
- kU32 = 7,
- //! 64-bit unsigned integer, specified as `.u64` in assembly.
- kU64 = 8,
- //! 16-bit floating point (half precision), specified as `.f16` in assembly.
- kF16 = 10,
- //! 32-bit floating point (single precision), specified as `.f32` in assembly.
- kF32 = 11,
- //! 64-bit floating point (double precision), specified as `.f64` in assembly.
- kF64 = 12,
- //! 8-bit polynomial.
- kP8 = 13,
- //! 64-bit polynomial.
- kP64 = 15,
+//! \cond
+static constexpr CondCode _reverseCondTable[] = {
+ CondCode::kAL, // AL <- AL
+ CondCode::kNA, // NA <- NA
+ CondCode::kEQ, // EQ <- EQ
+ CondCode::kNE, // NE <- NE
+ CondCode::kLS, // LS <- CS
+ CondCode::kHI, // HI <- LO
+ CondCode::kMI, // MI <- MI
+ CondCode::kPL, // PL <- PL
+ CondCode::kVS, // VS <- VS
+ CondCode::kVC, // VC <- VC
+ CondCode::kLO, // LO <- HI
+ CondCode::kCS, // CS <- LS
+ CondCode::kLE, // LE <- GE
+ CondCode::kGT, // GT <- LT
+ CondCode::kLT, // LT <- GT
+ CondCode::kGE // GE <- LE
+};
+//! \endcond
- //! Maximum value of `DataType`.
- kMaxValue = 15
+//! Reverses a condition code (reverses the corresponding operands of a comparison).
+static ASMJIT_INLINE_NODEBUG constexpr CondCode reverseCond(CondCode cond) noexcept { return _reverseCondTable[uint8_t(cond)]; }
+//! Negates a condition code.
+static ASMJIT_INLINE_NODEBUG constexpr CondCode negateCond(CondCode cond) noexcept { return CondCode(uint8_t(cond) ^ uint8_t(1)); }
+
+//! Memory offset mode.
+//!
+//! Describes either fixed, pre-index, or post-index offset modes.
+enum class OffsetMode : uint32_t {
+ //! Fixed offset mode (either no index at all or a regular index without a write-back).
+ kFixed = 0u,
+ //! Pre-index "[BASE, #Offset {, <shift>}]!" with write-back.
+ kPreIndex = 1u,
+ //! Post-index "[BASE], #Offset {, <shift>}" with write-back.
+ kPostIndex = 2u
};
//! Shift operation predicate (ARM) describes either SHIFT or EXTEND operation.
@@ -170,60 +177,85 @@ public:
uint32_t _value;
//! Default constructed Shift is not initialized.
- inline Shift() noexcept = default;
+ ASMJIT_INLINE_NODEBUG Shift() noexcept = default;
//! Copy constructor (default)
- constexpr Shift(const Shift& other) noexcept = default;
+ ASMJIT_INLINE_NODEBUG constexpr Shift(const Shift& other) noexcept = default;
//! Constructs Shift from operation `op` and shift `value`.
- constexpr Shift(ShiftOp op, uint32_t value) noexcept
+ ASMJIT_INLINE_NODEBUG constexpr Shift(ShiftOp op, uint32_t value) noexcept
: _op(op),
_value(value) {}
//! Returns the shift operation.
- constexpr ShiftOp op() const noexcept { return _op; }
+ ASMJIT_INLINE_NODEBUG constexpr ShiftOp op() const noexcept { return _op; }
//! Sets shift operation to `op`.
- inline void setOp(ShiftOp op) noexcept { _op = op; }
+ ASMJIT_INLINE_NODEBUG void setOp(ShiftOp op) noexcept { _op = op; }
- //! Returns the shift smount.
- constexpr uint32_t value() const noexcept { return _value; }
+ //! Returns the shift amount.
+ ASMJIT_INLINE_NODEBUG constexpr uint32_t value() const noexcept { return _value; }
//! Sets shift amount to `value`.
- inline void setValue(uint32_t value) noexcept { _value = value; }
+ ASMJIT_INLINE_NODEBUG 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(ShiftOp::kLSL, value); }
-//! Constructs a `LSR #value` shift (logical shift right).
-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(ShiftOp::kASR, value); }
-//! Constructs a `ROR #value` shift (rotate right).
-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(ShiftOp::kRRX, 0); }
-//! Constructs a `MSL #value` shift (logical shift left filling ones).
-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(ShiftOp::kUXTB, value); }
-//! Constructs a `UXTH #value` extend and shift (unsigned hword extend).
-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(ShiftOp::kUXTW, value); }
-//! Constructs a `UXTX #value` extend and shift (unsigned dword extend).
-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(ShiftOp::kSXTB, value); }
-//! Constructs a `SXTH #value` extend and shift (signed hword extend).
-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(ShiftOp::kSXTW, value); }
-//! Constructs a `SXTX #value` extend and shift (signed dword extend).
-static constexpr Shift sxtx(uint32_t value) noexcept { return Shift(ShiftOp::kSXTX, value); }
-
//! \}
ASMJIT_END_SUB_NAMESPACE
+ASMJIT_BEGIN_SUB_NAMESPACE(a32)
+
+using namespace arm;
+
+//! Data type that can be encoded with AArch32 instruction identifier.
+//!
+//! \note Data types are frequently used with AArch32 SIMD instructions. For example `VMAX` instruction can
+//! use almost all datatypes in a form `VMAX.F32`, `VMAX.S16`, `VMAX.U32`, etc... Emitter automatically adds
+//! the required data type at emit level.
+enum class DataType : uint32_t {
+ //! No data type specified (default for all general purpose instructions).
+ kNone = 0,
+ //! 8-bit signed integer, specified as `.s8` in assembly.
+ kS8 = 1,
+ //! 16-bit signed integer, specified as `.s16` in assembly.
+ kS16 = 2,
+ //! 32-bit signed integer, specified as `.s32` in assembly.
+ kS32 = 3,
+ //! 64-bit signed integer, specified as `.s64` in assembly.
+ kS64 = 4,
+ //! 8-bit unsigned integer, specified as `.u8` in assembly.
+ kU8 = 5,
+ //! 16-bit unsigned integer, specified as `.u16` in assembly.
+ kU16 = 6,
+ //! 32-bit unsigned integer, specified as `.u32` in assembly.
+ kU32 = 7,
+ //! 64-bit unsigned integer, specified as `.u64` in assembly.
+ kU64 = 8,
+ //! 16-bit floating point (half precision), specified as `.f16` in assembly.
+ kF16 = 10,
+ //! 32-bit floating point (single precision), specified as `.f32` in assembly.
+ kF32 = 11,
+ //! 64-bit floating point (double precision), specified as `.f64` in assembly.
+ kF64 = 12,
+ //! 8-bit polynomial.
+ kP8 = 13,
+ //! 16-bit BF16 floating point.
+ kBF16 = 14,
+ //! 64-bit polynomial.
+ kP64 = 15,
+
+ //! Maximum value of `DataType`.
+ kMaxValue = 15
+};
+
+static ASMJIT_INLINE_NODEBUG uint32_t dataTypeSize(DataType dt) noexcept {
+ static constexpr uint8_t table[] = { 0, 1, 2, 4, 8, 1, 2, 4, 8, 2, 4, 8, 1, 2, 8 };
+ return table[size_t(dt)];
+}
+
+ASMJIT_END_SUB_NAMESPACE
+
+ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+using namespace arm;
+ASMJIT_END_SUB_NAMESPACE
+
#endif // ASMJIT_CORE_ARCHCOMMONS_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/core/archtraits.cpp b/3rdparty/asmjit/src/asmjit/core/archtraits.cpp
index fc825df8009..a15a00c048b 100644
--- a/3rdparty/asmjit/src/asmjit/core/archtraits.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/archtraits.cpp
@@ -5,6 +5,7 @@
#include "../core/api-build_p.h"
#include "../core/archtraits.h"
+#include "../core/environment.h"
#include "../core/misc_p.h"
#if !defined(ASMJIT_NO_X86)
diff --git a/3rdparty/asmjit/src/asmjit/core/archtraits.h b/3rdparty/asmjit/src/asmjit/core/archtraits.h
index 192a826e511..9f08dea523f 100644
--- a/3rdparty/asmjit/src/asmjit/core/archtraits.h
+++ b/3rdparty/asmjit/src/asmjit/core/archtraits.h
@@ -74,6 +74,9 @@ enum class Arch : uint8_t {
ASMJIT_ARCH_X86 == 32 ? kX86 :
ASMJIT_ARCH_X86 == 64 ? kX64 :
+ ASMJIT_ARCH_RISCV == 32 ? kRISCV32 :
+ ASMJIT_ARCH_RISCV == 64 ? kRISCV64 :
+
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 :
@@ -202,50 +205,50 @@ struct ArchTraits {
//! \{
//! Returns stack pointer register id.
- inline uint32_t spRegId() const noexcept { return _spRegId; }
+ ASMJIT_INLINE_NODEBUG uint32_t spRegId() const noexcept { return _spRegId; }
//! Returns stack frame register id.
- inline uint32_t fpRegId() const noexcept { return _fpRegId; }
+ ASMJIT_INLINE_NODEBUG uint32_t fpRegId() const noexcept { return _fpRegId; }
//! Returns link register id, if the architecture provides it.
- inline uint32_t linkRegId() const noexcept { return _linkRegId; }
+ ASMJIT_INLINE_NODEBUG uint32_t linkRegId() const noexcept { return _linkRegId; }
//! Returns instruction pointer register id, if the architecture provides it.
- inline uint32_t ipRegId() const noexcept { return _ipRegId; }
+ ASMJIT_INLINE_NODEBUG 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 uint32_t hwStackAlignment() const noexcept { return _hwStackAlignment; }
+ ASMJIT_INLINE_NODEBUG 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 bool hasLinkReg() const noexcept { return _linkRegId != BaseReg::kIdBad; }
+ ASMJIT_INLINE_NODEBUG bool hasLinkReg() const noexcept { return _linkRegId != BaseReg::kIdBad; }
//! Returns minimum addressable offset on stack guaranteed for all instructions.
- inline uint32_t minStackOffset() const noexcept { return _minStackOffset; }
+ ASMJIT_INLINE_NODEBUG uint32_t minStackOffset() const noexcept { return _minStackOffset; }
//! Returns maximum addressable offset on stack depending on specific instruction.
- inline uint32_t maxStackOffset() const noexcept { return _maxStackOffset; }
+ ASMJIT_INLINE_NODEBUG uint32_t maxStackOffset() const noexcept { return _maxStackOffset; }
//! Returns ISA flags of the given register `group`.
- inline InstHints instFeatureHints(RegGroup group) const noexcept { return _instHints[group]; }
+ ASMJIT_INLINE_NODEBUG InstHints instFeatureHints(RegGroup group) const noexcept { return _instHints[group]; }
//! Tests whether the given register `group` has the given `flag` set.
- inline bool hasInstHint(RegGroup group, InstHints feature) const noexcept { return Support::test(_instHints[group], feature); }
+ ASMJIT_INLINE_NODEBUG 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 bool hasInstRegSwap(RegGroup group) const noexcept { return hasInstHint(group, InstHints::kRegSwap); }
+ ASMJIT_INLINE_NODEBUG 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 bool hasInstPushPop(RegGroup group) const noexcept { return hasInstHint(group, InstHints::kPushPop); }
+ ASMJIT_INLINE_NODEBUG bool hasInstPushPop(RegGroup group) const noexcept { return hasInstHint(group, InstHints::kPushPop); }
- inline bool hasRegType(RegType type) const noexcept {
+ ASMJIT_INLINE_NODEBUG bool hasRegType(RegType type) const noexcept {
return type <= RegType::kMaxValue && _regSignature[type].isValid();
}
//! Returns an operand signature from the given register `type` of this architecture.
- inline OperandSignature regTypeToSignature(RegType type) const noexcept { return _regSignature[type]; }
+ ASMJIT_INLINE_NODEBUG 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(); }
+ ASMJIT_INLINE_NODEBUG 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(); }
+ ASMJIT_INLINE_NODEBUG 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]; }
+ ASMJIT_INLINE_NODEBUG 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.
//!
@@ -254,10 +257,10 @@ struct ArchTraits {
//! - [1] 16-bits
//! - [2] 32-bits
//! - [3] 64-bits
- inline const ArchTypeNameId* typeNameIdTable() const noexcept { return _typeNameIdTable; }
+ ASMJIT_INLINE_NODEBUG const ArchTypeNameId* typeNameIdTable() const noexcept { return _typeNameIdTable; }
//! 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]; }
+ ASMJIT_INLINE_NODEBUG ArchTypeNameId typeNameIdByIndex(uint32_t index) const noexcept { return _typeNameIdTable[index]; }
//! \}
@@ -265,7 +268,7 @@ struct ArchTraits {
//! \{
//! Returns a const reference to `ArchTraits` for the given architecture `arch`.
- static inline const ArchTraits& byArch(Arch arch) noexcept;
+ static ASMJIT_INLINE_NODEBUG const ArchTraits& byArch(Arch arch) noexcept;
//! \}
};
@@ -273,7 +276,7 @@ struct ArchTraits {
ASMJIT_VARAPI const ArchTraits _archTraits[uint32_t(Arch::kMaxValue) + 1];
//! \cond
-inline const ArchTraits& ArchTraits::byArch(Arch arch) noexcept { return _archTraits[uint32_t(arch)]; }
+ASMJIT_INLINE_NODEBUG const ArchTraits& ArchTraits::byArch(Arch arch) noexcept { return _archTraits[uint32_t(arch)]; }
//! \endcond
//! Architecture utilities.
diff --git a/3rdparty/asmjit/src/asmjit/core/assembler.h b/3rdparty/asmjit/src/asmjit/core/assembler.h
index 7ea2505f046..d53d9e53764 100644
--- a/3rdparty/asmjit/src/asmjit/core/assembler.h
+++ b/3rdparty/asmjit/src/asmjit/core/assembler.h
@@ -25,6 +25,7 @@ ASMJIT_BEGIN_NAMESPACE
//! Check out architecture specific assemblers for more details and examples:
//!
//! - \ref x86::Assembler - X86/X64 assembler implementation.
+//! - \ref a64::Assembler - AArch64 assembler implementation.
class ASMJIT_VIRTAPI BaseAssembler : public BaseEmitter {
public:
ASMJIT_NONCOPYABLE(BaseAssembler)
@@ -45,7 +46,7 @@ public:
//! Creates a new `BaseAssembler` instance.
ASMJIT_API BaseAssembler() noexcept;
//! Destroys the `BaseAssembler` instance.
- ASMJIT_API virtual ~BaseAssembler() noexcept;
+ ASMJIT_API ~BaseAssembler() noexcept override;
//! \}
@@ -53,12 +54,12 @@ public:
//! \{
//! Returns the capacity of the current CodeBuffer.
- inline size_t bufferCapacity() const noexcept { return (size_t)(_bufferEnd - _bufferData); }
+ ASMJIT_INLINE_NODEBUG size_t bufferCapacity() const noexcept { return (size_t)(_bufferEnd - _bufferData); }
//! Returns the number of remaining bytes in the current CodeBuffer.
- inline size_t remainingSpace() const noexcept { return (size_t)(_bufferEnd - _bufferPtr); }
+ ASMJIT_INLINE_NODEBUG size_t remainingSpace() const noexcept { return (size_t)(_bufferEnd - _bufferPtr); }
//! Returns the current position in the CodeBuffer.
- inline size_t offset() const noexcept { return (size_t)(_bufferPtr - _bufferData); }
+ ASMJIT_INLINE_NODEBUG size_t offset() const noexcept { return (size_t)(_bufferPtr - _bufferData); }
//! Sets the current position in the CodeBuffer to `offset`.
//!
@@ -67,11 +68,11 @@ public:
ASMJIT_API Error setOffset(size_t offset);
//! Returns the start of the CodeBuffer in the current section.
- inline uint8_t* bufferData() const noexcept { return _bufferData; }
+ ASMJIT_INLINE_NODEBUG uint8_t* bufferData() const noexcept { return _bufferData; }
//! Returns the end (first invalid byte) in the current section.
- inline uint8_t* bufferEnd() const noexcept { return _bufferEnd; }
+ ASMJIT_INLINE_NODEBUG uint8_t* bufferEnd() const noexcept { return _bufferEnd; }
//! Returns the current pointer in the CodeBuffer in the current section.
- inline uint8_t* bufferPtr() const noexcept { return _bufferPtr; }
+ ASMJIT_INLINE_NODEBUG uint8_t* bufferPtr() const noexcept { return _bufferPtr; }
//! \}
@@ -79,7 +80,7 @@ public:
//! \{
//! Returns the current section.
- inline Section* currentSection() const noexcept { return _section; }
+ ASMJIT_INLINE_NODEBUG Section* currentSection() const noexcept { return _section; }
ASMJIT_API Error section(Section* section) override;
diff --git a/3rdparty/asmjit/src/asmjit/core/builder.cpp b/3rdparty/asmjit/src/asmjit/core/builder.cpp
index 5df243e7b8a..25433b9a0d8 100644
--- a/3rdparty/asmjit/src/asmjit/core/builder.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/builder.cpp
@@ -65,7 +65,7 @@ Error BaseBuilder::newInstNode(InstNode** out, InstId instId, InstOptions instOp
if (ASMJIT_UNLIKELY(!node))
return reportError(DebugUtils::errored(kErrorOutOfMemory));
- *out = new(node) InstNode(this, instId, instOptions, opCount, opCapacity);
+ *out = new(Support::PlacementNew{node}) InstNode(this, instId, instOptions, opCount, opCapacity);
return kErrorOk;
}
@@ -151,14 +151,13 @@ BaseNode* BaseBuilder::addNode(BaseNode* node) noexcept {
ASMJIT_ASSERT(!node->isActive());
if (!_cursor) {
- if (!_firstNode) {
- _firstNode = node;
- _lastNode = node;
+ if (_nodeList.empty()) {
+ _nodeList.reset(node, node);
}
else {
- node->_next = _firstNode;
- _firstNode->_prev = node;
- _firstNode = node;
+ node->_next = _nodeList.first();
+ _nodeList._first->_prev = node;
+ _nodeList._first = node;
}
}
else {
@@ -172,7 +171,7 @@ BaseNode* BaseBuilder::addNode(BaseNode* node) noexcept {
if (next)
next->_prev = node;
else
- _lastNode = node;
+ _nodeList._last = node;
}
node->addFlags(NodeFlags::kIsActive);
@@ -201,7 +200,7 @@ BaseNode* BaseBuilder::addAfter(BaseNode* node, BaseNode* ref) noexcept {
if (next)
next->_prev = node;
else
- _lastNode = node;
+ _nodeList._last = node;
return node;
}
@@ -226,7 +225,7 @@ BaseNode* BaseBuilder::addBefore(BaseNode* node, BaseNode* ref) noexcept {
if (prev)
prev->_next = node;
else
- _firstNode = node;
+ _nodeList._first = node;
return node;
}
@@ -238,13 +237,13 @@ BaseNode* BaseBuilder::removeNode(BaseNode* node) noexcept {
BaseNode* prev = node->prev();
BaseNode* next = node->next();
- if (_firstNode == node)
- _firstNode = next;
+ if (_nodeList._first == node)
+ _nodeList._first = next;
else
prev->_next = next;
- if (_lastNode == node)
- _lastNode = prev;
+ if (_nodeList._last == node)
+ _nodeList._last = prev;
else
next->_prev = prev;
@@ -272,13 +271,13 @@ void BaseBuilder::removeNodes(BaseNode* first, BaseNode* last) noexcept {
BaseNode* prev = first->prev();
BaseNode* next = last->next();
- if (_firstNode == first)
- _firstNode = next;
+ if (_nodeList._first == first)
+ _nodeList._first = next;
else
prev->_next = next;
- if (_lastNode == last)
- _lastNode = prev;
+ if (_nodeList._last == last)
+ _nodeList._last = prev;
else
next->_prev = prev;
@@ -368,7 +367,7 @@ Error BaseBuilder::section(Section* section) {
if (node->_nextSection)
_cursor = node->_nextSection->_prev;
else
- _cursor = _lastNode;
+ _cursor = _nodeList.last();
}
return kErrorOk;
@@ -378,7 +377,7 @@ void BaseBuilder::updateSectionLinks() noexcept {
if (!_dirtySectionLinks)
return;
- BaseNode* node_ = _firstNode;
+ BaseNode* node_ = _nodeList.first();
SectionNode* currentSection = nullptr;
while (node_) {
@@ -591,13 +590,15 @@ Error BaseBuilder::_emit(InstId instId, const Operand_& o0, const Operand_& o1,
EmitterUtils::opArrayFromEmitArgs(opArray, o0, o1, o2, opExt);
ValidationFlags validationFlags = isCompiler() ? ValidationFlags::kEnableVirtRegs : ValidationFlags::kNone;
- Error err = _funcs.validate(arch(), BaseInst(instId, options, _extraReg), opArray, opCount, validationFlags);
+ Error err = _funcs.validate(BaseInst(instId, options, _extraReg), opArray, opCount, validationFlags);
if (ASMJIT_UNLIKELY(err)) {
- resetInstOptions();
- resetExtraReg();
- resetInlineComment();
+#ifndef ASMJIT_NO_LOGGING
+ return EmitterUtils::logInstructionFailed(this, err, instId, options, o0, o1, o2, opExt);
+#else
+ resetState();
return reportError(err);
+#endif
}
}
#endif
@@ -620,7 +621,7 @@ Error BaseBuilder::_emit(InstId instId, const Operand_& o0, const Operand_& o1,
return reportError(DebugUtils::errored(kErrorOutOfMemory));
}
- node = new(node) InstNode(this, instId, options, opCount, opCapacity);
+ node = new(Support::PlacementNew{node}) InstNode(this, instId, options, opCount, opCapacity);
node->setExtraReg(extraReg());
node->setOp(0, o0);
node->setOp(1, o1);
@@ -756,7 +757,7 @@ Error BaseBuilder::comment(const char* data, size_t size) {
Error BaseBuilder::serializeTo(BaseEmitter* dst) {
Error err = kErrorOk;
- BaseNode* node_ = _firstNode;
+ BaseNode* node_ = _nodeList.first();
Operand_ opArray[Globals::kMaxOpCount];
@@ -852,8 +853,7 @@ Error BaseBuilder::onAttach(CodeHolder* code) noexcept {
ASMJIT_ASSUME(initialSection != nullptr);
_cursor = initialSection;
- _firstNode = initialSection;
- _lastNode = initialSection;
+ _nodeList.reset(initialSection, initialSection);
initialSection->setFlags(NodeFlags::kIsActive);
return kErrorOk;
@@ -871,8 +871,7 @@ Error BaseBuilder::onDetach(CodeHolder* code) noexcept {
_nodeFlags = NodeFlags::kNone;
_cursor = nullptr;
- _firstNode = nullptr;
- _lastNode = nullptr;
+ _nodeList.reset();
return Base::onDetach(code);
}
@@ -884,6 +883,15 @@ Pass::Pass(const char* name) noexcept
: _name(name) {}
Pass::~Pass() noexcept {}
+// Pass - Interface
+// ================
+
+// [[pure virtual]]
+Error Pass::run(Zone* zone, Logger* logger) {
+ DebugUtils::unused(zone, logger);
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
ASMJIT_END_NAMESPACE
#endif // !ASMJIT_NO_BUILDER
diff --git a/3rdparty/asmjit/src/asmjit/core/builder.h b/3rdparty/asmjit/src/asmjit/core/builder.h
index 3575de2fbb8..0de19234cb6 100644
--- a/3rdparty/asmjit/src/asmjit/core/builder.h
+++ b/3rdparty/asmjit/src/asmjit/core/builder.h
@@ -48,7 +48,7 @@ enum class NodeType : uint8_t {
// [BaseBuilder]
- //! Node is \ref InstNode or \ref InstExNode.
+ //! Node is \ref InstNode.
kInst = 1,
//! Node is \ref SectionNode.
kSection = 2,
@@ -109,7 +109,7 @@ enum class NodeFlags : uint8_t {
};
ASMJIT_DEFINE_ENUM_FLAGS(NodeFlags)
-//! Type of the sentinel (purery informative purpose).
+//! Type of the sentinel (purely informative purpose).
enum class SentinelType : uint8_t {
//! Type of the sentinel is not known.
kUnknown = 0u,
@@ -117,6 +117,60 @@ enum class SentinelType : uint8_t {
kFuncEnd = 1u
};
+//! Node list.
+//!
+//! A double-linked list of pointers to \ref BaseNode, managed by \ref BaseBuilder or \ref BaseCompiler.
+//!
+//! \note At the moment NodeList is just a view, but it's planned that it will get more functionality in the future.
+class NodeList {
+public:
+ //! \name Members
+ //! \{
+
+ //! First node in the list or nullptr if there are no nodes in the list.
+ BaseNode* _first = nullptr;
+ //! Last node in the list or nullptr if there are no nodes in the list.
+ BaseNode* _last = nullptr;
+
+ //! \}
+
+ //! \name Construction & Destruction
+ //! \{
+
+ ASMJIT_INLINE_NODEBUG NodeList() noexcept {}
+
+ ASMJIT_INLINE_NODEBUG NodeList(BaseNode* first, BaseNode* last) noexcept
+ : _first(first),
+ _last(last) {}
+
+ //! \}
+
+ //! \name Reset
+ //! \{
+
+ ASMJIT_INLINE_NODEBUG void reset() noexcept {
+ _first = nullptr;
+ _last = nullptr;
+ }
+
+ ASMJIT_INLINE_NODEBUG void reset(BaseNode* first, BaseNode* last) noexcept {
+ _first = first;
+ _last = last;
+ }
+
+ //! \}
+
+ //! \name Accessors
+ //! \{
+
+ ASMJIT_INLINE_NODEBUG bool empty() const noexcept { return _first == nullptr; }
+
+ ASMJIT_INLINE_NODEBUG BaseNode* first() const noexcept { return _first; }
+ ASMJIT_INLINE_NODEBUG BaseNode* last() const noexcept { return _last; }
+
+ //! \}
+};
+
//! Builder interface.
//!
//! `BaseBuilder` interface was designed to be used as a \ref BaseAssembler replacement in case pre-processing or
@@ -127,6 +181,7 @@ enum class SentinelType : uint8_t {
//! Check out architecture specific builders for more details and examples:
//!
//! - \ref x86::Builder - X86/X64 builder implementation.
+//! - \ref a64::Builder - AArch64 builder implementation.
class ASMJIT_VIRTAPI BaseBuilder : public BaseEmitter {
public:
ASMJIT_NONCOPYABLE(BaseBuilder)
@@ -153,10 +208,8 @@ public:
//! Current node (cursor).
BaseNode* _cursor = nullptr;
- //! First node of the current section.
- BaseNode* _firstNode = nullptr;
- //! Last node of the current section.
- BaseNode* _lastNode = nullptr;
+ //! First and last nodes.
+ NodeList _nodeList;
//! Flags assigned to each new node.
NodeFlags _nodeFlags = NodeFlags::kNone;
@@ -171,17 +224,19 @@ public:
//! Creates a new `BaseBuilder` instance.
ASMJIT_API BaseBuilder() noexcept;
//! Destroys the `BaseBuilder` instance.
- ASMJIT_API virtual ~BaseBuilder() noexcept;
+ ASMJIT_API ~BaseBuilder() noexcept override;
//! \}
//! \name Node Management
//! \{
+ ASMJIT_INLINE_NODEBUG NodeList nodeList() const noexcept { return _nodeList; }
+
//! Returns the first node.
- inline BaseNode* firstNode() const noexcept { return _firstNode; }
+ ASMJIT_INLINE_NODEBUG BaseNode* firstNode() const noexcept { return _nodeList.first(); }
//! Returns the last node.
- inline BaseNode* lastNode() const noexcept { return _lastNode; }
+ ASMJIT_INLINE_NODEBUG BaseNode* lastNode() const noexcept { return _nodeList.last(); }
//! Allocates and instantiates a new node of type `T` and returns its instance. If the allocation fails `nullptr`
//! is returned.
@@ -227,7 +282,7 @@ public:
//! 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; }
+ ASMJIT_INLINE_NODEBUG BaseNode* cursor() const noexcept { return _cursor; }
//! Sets the current node to `node` and return the previous one.
ASMJIT_API BaseNode* setCursor(BaseNode* node) noexcept;
@@ -236,7 +291,7 @@ public:
//!
//! 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; }
+ ASMJIT_INLINE_NODEBUG void _setCursor(BaseNode* node) noexcept { _cursor = node; }
//! \}
@@ -247,12 +302,12 @@ public:
//!
//! \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 {
+ ASMJIT_INLINE_NODEBUG const ZoneVector<SectionNode*>& sectionNodes() const noexcept {
return _sectionNodes;
}
//! Tests whether the `SectionNode` of the given `sectionId` was registered.
- inline bool hasRegisteredSectionNode(uint32_t sectionId) const noexcept {
+ ASMJIT_INLINE_NODEBUG bool hasRegisteredSectionNode(uint32_t sectionId) const noexcept {
return sectionId < _sectionNodes.size() && _sectionNodes[sectionId] != nullptr;
}
@@ -266,7 +321,7 @@ public:
//! 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; }
+ ASMJIT_INLINE_NODEBUG bool hasDirtySectionLinks() const noexcept { return _dirtySectionLinks; }
//! Updates links of all active section nodes.
ASMJIT_API void updateSectionLinks() noexcept;
@@ -280,15 +335,15 @@ public:
//!
//! \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; }
+ ASMJIT_INLINE_NODEBUG const ZoneVector<LabelNode*>& labelNodes() const noexcept { return _labelNodes; }
//! Tests whether the `LabelNode` of the given `labelId` was registered.
- inline bool hasRegisteredLabelNode(uint32_t labelId) const noexcept {
+ ASMJIT_INLINE_NODEBUG bool hasRegisteredLabelNode(uint32_t labelId) const noexcept {
return labelId < _labelNodes.size() && _labelNodes[labelId] != nullptr;
}
//! \overload
- inline bool hasRegisteredLabelNode(const Label& label) const noexcept {
+ ASMJIT_INLINE_NODEBUG bool hasRegisteredLabelNode(const Label& label) const noexcept {
return hasRegisteredLabelNode(label.id());
}
@@ -299,7 +354,7 @@ public:
ASMJIT_API Error labelNodeOf(LabelNode** ASMJIT_NONNULL(out), uint32_t labelId);
//! \overload
- inline Error labelNodeOf(LabelNode** ASMJIT_NONNULL(out), const Label& label) {
+ ASMJIT_INLINE_NODEBUG Error labelNodeOf(LabelNode** ASMJIT_NONNULL(out), const Label& label) {
return labelNodeOf(out, label.id());
}
@@ -319,7 +374,7 @@ public:
//! \{
//! Returns a vector of `Pass` instances that will be executed by `runPasses()`.
- inline const ZoneVector<Pass*>& passes() const noexcept { return _passes; }
+ ASMJIT_INLINE_NODEBUG 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.
@@ -492,7 +547,7 @@ public:
uint8_t _reserved1;
};
- //! Data that can have different meaning dependning on \ref NodeType.
+ //! Data that can have different meaning depending on \ref NodeType.
union {
//! Data useful by any node type.
AnyData _any;
@@ -529,7 +584,7 @@ public:
//! \{
//! Creates a new `BaseNode` - always use `BaseBuilder` to allocate nodes.
- inline BaseNode(BaseBuilder* cb, NodeType nodeType, NodeFlags nodeFlags = NodeFlags::kNone) noexcept {
+ ASMJIT_INLINE_NODEBUG BaseNode(BaseBuilder* cb, NodeType nodeType, NodeFlags nodeFlags = NodeFlags::kNone) noexcept {
_prev = nullptr;
_next = nullptr;
_any._nodeType = nodeType;
@@ -549,85 +604,85 @@ public:
//! Casts this node to `T*`.
template<typename T>
- inline T* as() noexcept { return static_cast<T*>(this); }
+ ASMJIT_INLINE_NODEBUG T* as() noexcept { return static_cast<T*>(this); }
//! Casts this node to `const T*`.
template<typename T>
- inline const T* as() const noexcept { return static_cast<const T*>(this); }
+ ASMJIT_INLINE_NODEBUG const T* as() const noexcept { return static_cast<const T*>(this); }
//! Returns previous node or `nullptr` if this node is either first or not
//! part of Builder/Compiler node-list.
- inline BaseNode* prev() const noexcept { return _prev; }
+ ASMJIT_INLINE_NODEBUG BaseNode* prev() const noexcept { return _prev; }
//! Returns next node or `nullptr` if this node is either last or not part
//! of Builder/Compiler node-list.
- inline BaseNode* next() const noexcept { return _next; }
+ ASMJIT_INLINE_NODEBUG BaseNode* next() const noexcept { return _next; }
//! Returns the type of the node, see `NodeType`.
- inline NodeType type() const noexcept { return _any._nodeType; }
+ ASMJIT_INLINE_NODEBUG 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(NodeType type) noexcept { _any._nodeType = type; }
+ ASMJIT_INLINE_NODEBUG 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(NodeFlags::kActsAsInst); }
+ ASMJIT_INLINE_NODEBUG bool isInst() const noexcept { return hasFlag(NodeFlags::kActsAsInst); }
//! Tests whether this node is `SectionNode`.
- inline bool isSection() const noexcept { return type() == NodeType::kSection; }
+ ASMJIT_INLINE_NODEBUG 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(NodeFlags::kActsAsLabel); }
+ ASMJIT_INLINE_NODEBUG bool isLabel() const noexcept { return hasFlag(NodeFlags::kActsAsLabel); }
//! Tests whether this node is `AlignNode`.
- inline bool isAlign() const noexcept { return type() == NodeType::kAlign; }
+ ASMJIT_INLINE_NODEBUG bool isAlign() const noexcept { return type() == NodeType::kAlign; }
//! Tests whether this node is `EmbedDataNode`.
- inline bool isEmbedData() const noexcept { return type() == NodeType::kEmbedData; }
+ ASMJIT_INLINE_NODEBUG bool isEmbedData() const noexcept { return type() == NodeType::kEmbedData; }
//! Tests whether this node is `EmbedLabelNode`.
- inline bool isEmbedLabel() const noexcept { return type() == NodeType::kEmbedLabel; }
+ ASMJIT_INLINE_NODEBUG bool isEmbedLabel() const noexcept { return type() == NodeType::kEmbedLabel; }
//! Tests whether this node is `EmbedLabelDeltaNode`.
- inline bool isEmbedLabelDelta() const noexcept { return type() == NodeType::kEmbedLabelDelta; }
+ ASMJIT_INLINE_NODEBUG bool isEmbedLabelDelta() const noexcept { return type() == NodeType::kEmbedLabelDelta; }
//! Tests whether this node is `ConstPoolNode`.
- inline bool isConstPool() const noexcept { return type() == NodeType::kConstPool; }
+ ASMJIT_INLINE_NODEBUG bool isConstPool() const noexcept { return type() == NodeType::kConstPool; }
//! Tests whether this node is `CommentNode`.
- inline bool isComment() const noexcept { return type() == NodeType::kComment; }
+ ASMJIT_INLINE_NODEBUG bool isComment() const noexcept { return type() == NodeType::kComment; }
//! Tests whether this node is `SentinelNode`.
- inline bool isSentinel() const noexcept { return type() == NodeType::kSentinel; }
+ ASMJIT_INLINE_NODEBUG bool isSentinel() const noexcept { return type() == NodeType::kSentinel; }
//! Tests whether this node is `FuncNode`.
- inline bool isFunc() const noexcept { return type() == NodeType::kFunc; }
+ ASMJIT_INLINE_NODEBUG bool isFunc() const noexcept { return type() == NodeType::kFunc; }
//! Tests whether this node is `FuncRetNode`.
- inline bool isFuncRet() const noexcept { return type() == NodeType::kFuncRet; }
+ ASMJIT_INLINE_NODEBUG bool isFuncRet() const noexcept { return type() == NodeType::kFuncRet; }
//! Tests whether this node is `InvokeNode`.
- inline bool isInvoke() const noexcept { return type() == NodeType::kInvoke; }
+ ASMJIT_INLINE_NODEBUG bool isInvoke() const noexcept { return type() == NodeType::kInvoke; }
//! Returns the node flags.
- inline NodeFlags flags() const noexcept { return _any._nodeFlags; }
+ ASMJIT_INLINE_NODEBUG NodeFlags flags() const noexcept { return _any._nodeFlags; }
//! Tests whether the node has the given `flag` set.
- inline bool hasFlag(NodeFlags flag) const noexcept { return Support::test(_any._nodeFlags, flag); }
+ ASMJIT_INLINE_NODEBUG bool hasFlag(NodeFlags flag) const noexcept { return Support::test(_any._nodeFlags, flag); }
//! Replaces node flags with `flags`.
- inline void setFlags(NodeFlags flags) noexcept { _any._nodeFlags = flags; }
+ ASMJIT_INLINE_NODEBUG void setFlags(NodeFlags flags) noexcept { _any._nodeFlags = flags; }
//! Adds the given `flags` to node flags.
- inline void addFlags(NodeFlags flags) noexcept { _any._nodeFlags |= flags; }
+ ASMJIT_INLINE_NODEBUG void addFlags(NodeFlags flags) noexcept { _any._nodeFlags |= flags; }
//! Clears the given `flags` from node flags.
- inline void clearFlags(NodeFlags flags) noexcept { _any._nodeFlags &= ~flags; }
+ ASMJIT_INLINE_NODEBUG 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(NodeFlags::kIsCode); }
+ ASMJIT_INLINE_NODEBUG 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(NodeFlags::kIsData); }
+ ASMJIT_INLINE_NODEBUG 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(NodeFlags::kIsInformative); }
+ ASMJIT_INLINE_NODEBUG 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(NodeFlags::kIsRemovable); }
+ ASMJIT_INLINE_NODEBUG 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(NodeFlags::kHasNoEffect); }
+ ASMJIT_INLINE_NODEBUG bool hasNoEffect() const noexcept { return hasFlag(NodeFlags::kHasNoEffect); }
//! Tests whether the node is part of the code.
- inline bool isActive() const noexcept { return hasFlag(NodeFlags::kIsActive); }
+ ASMJIT_INLINE_NODEBUG bool isActive() const noexcept { return hasFlag(NodeFlags::kIsActive); }
//! Tests whether the node has a position assigned.
//!
//! \remarks Returns `true` if node position is non-zero.
- inline bool hasPosition() const noexcept { return _position != 0; }
+ ASMJIT_INLINE_NODEBUG bool hasPosition() const noexcept { return _position != 0; }
//! Returns node position.
- inline uint32_t position() const noexcept { return _position; }
+ ASMJIT_INLINE_NODEBUG 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
@@ -636,49 +691,50 @@ public:
//!
//! 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; }
+ ASMJIT_INLINE_NODEBUG 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 dedicated to be used only by AsmJit users and not touched by the library. The data is of a pointer
+ //! size so you can either store a pointer or `int64_t` value through `setUserDataAsPtr()`, `setUserDataAsInt64()`
+ //! and `setUserDataAsUInt64()`.
template<typename T>
- inline T* userDataAsPtr() const noexcept { return static_cast<T*>(_userDataPtr); }
+ ASMJIT_INLINE_NODEBUG T* userDataAsPtr() const noexcept { return static_cast<T*>(_userDataPtr); }
//! Returns user data casted to `int64_t`.
- inline int64_t userDataAsInt64() const noexcept { return int64_t(_userDataU64); }
+ ASMJIT_INLINE_NODEBUG int64_t userDataAsInt64() const noexcept { return int64_t(_userDataU64); }
//! Returns user data casted to `uint64_t`.
- inline uint64_t userDataAsUInt64() const noexcept { return _userDataU64; }
+ ASMJIT_INLINE_NODEBUG uint64_t userDataAsUInt64() const noexcept { return _userDataU64; }
//! Sets user data to `data`.
template<typename T>
- inline void setUserDataAsPtr(T* data) noexcept { _userDataPtr = static_cast<void*>(data); }
+ ASMJIT_INLINE_NODEBUG void setUserDataAsPtr(T* data) noexcept { _userDataPtr = static_cast<void*>(data); }
//! Sets used data to the given 64-bit signed `value`.
- inline void setUserDataAsInt64(int64_t value) noexcept { _userDataU64 = uint64_t(value); }
+ ASMJIT_INLINE_NODEBUG void setUserDataAsInt64(int64_t value) noexcept { _userDataU64 = uint64_t(value); }
//! Sets used data to the given 64-bit unsigned `value`.
- inline void setUserDataAsUInt64(uint64_t value) noexcept { _userDataU64 = value; }
+ ASMJIT_INLINE_NODEBUG void setUserDataAsUInt64(uint64_t value) noexcept { _userDataU64 = value; }
//! Resets user data to zero / nullptr.
- inline void resetUserData() noexcept { _userDataU64 = 0; }
+ ASMJIT_INLINE_NODEBUG void resetUserData() noexcept { _userDataU64 = 0; }
//! Tests whether the node has an associated pass data.
- inline bool hasPassData() const noexcept { return _passData != nullptr; }
+ ASMJIT_INLINE_NODEBUG bool hasPassData() const noexcept { return _passData != nullptr; }
//! Returns the node pass data - data used during processing & transformations.
template<typename T>
- inline T* passData() const noexcept { return (T*)_passData; }
+ ASMJIT_INLINE_NODEBUG T* passData() const noexcept { return (T*)_passData; }
//! Sets the node pass data to `data`.
template<typename T>
- inline void setPassData(T* data) noexcept { _passData = (void*)data; }
+ ASMJIT_INLINE_NODEBUG void setPassData(T* data) noexcept { _passData = (void*)data; }
//! Resets the node pass data to nullptr.
- inline void resetPassData() noexcept { _passData = nullptr; }
+ ASMJIT_INLINE_NODEBUG void resetPassData() noexcept { _passData = nullptr; }
//! Tests whether the node has an inline comment/annotation.
- inline bool hasInlineComment() const noexcept { return _inlineComment != nullptr; }
+ ASMJIT_INLINE_NODEBUG bool hasInlineComment() const noexcept { return _inlineComment != nullptr; }
//! Returns an inline comment/annotation string.
- inline const char* inlineComment() const noexcept { return _inlineComment; }
+ ASMJIT_INLINE_NODEBUG const char* inlineComment() const noexcept { return _inlineComment; }
//! Sets an inline comment/annotation string to `s`.
- inline void setInlineComment(const char* s) noexcept { _inlineComment = s; }
+ ASMJIT_INLINE_NODEBUG void setInlineComment(const char* s) noexcept { _inlineComment = s; }
//! Resets an inline comment/annotation string to nullptr.
- inline void resetInlineComment() noexcept { _inlineComment = nullptr; }
+ ASMJIT_INLINE_NODEBUG void resetInlineComment() noexcept { _inlineComment = nullptr; }
//! \}
};
@@ -693,12 +749,15 @@ public:
//! \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)
- //! is always stored in `InstExNode`.
- kBaseOpCapacity = uint32_t((128 - sizeof(BaseNode) - sizeof(BaseInst)) / sizeof(Operand_))
- };
+ //! The number of embedded operands for a default \ref InstNode instance that are always allocated as a part of
+ //! the instruction itself. 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 considered extended.
+ //!
+ //! The number of operands InstNode holds is decided when \ref InstNode is created.
+ static constexpr uint32_t kBaseOpCapacity = uint32_t((128 - sizeof(BaseNode) - sizeof(BaseInst)) / sizeof(Operand_));
+
+ //! Count of maximum number of operands \ref InstNode can hold.
+ static constexpr uint32_t kFullOpCapacity = Globals::kMaxOpCount;
//! \}
@@ -707,8 +766,6 @@ public:
//! Base instruction data.
BaseInst _baseInst;
- //! First 4 or 5 operands (indexed from 0).
- Operand_ _opArray[kBaseOpCapacity];
//! \}
@@ -716,7 +773,7 @@ public:
//! \{
//! Creates a new `InstNode` instance.
- inline InstNode(BaseBuilder* cb, InstId instId, InstOptions options, uint32_t opCount, uint32_t opCapacity = kBaseOpCapacity) noexcept
+ ASMJIT_INLINE_NODEBUG 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);
@@ -725,7 +782,7 @@ public:
//! \cond INTERNAL
//! Reset all built-in operands, including `extraReg`.
- inline void _resetOps() noexcept {
+ ASMJIT_INLINE_NODEBUG void _resetOps() noexcept {
_baseInst.resetExtraReg();
resetOpRange(0, opCapacity());
}
@@ -736,8 +793,8 @@ public:
//! \name Instruction Object
//! \{
- inline BaseInst& baseInst() noexcept { return _baseInst; }
- inline const BaseInst& baseInst() const noexcept { return _baseInst; }
+ ASMJIT_INLINE_NODEBUG BaseInst& baseInst() noexcept { return _baseInst; }
+ ASMJIT_INLINE_NODEBUG const BaseInst& baseInst() const noexcept { return _baseInst; }
//! \}
@@ -745,24 +802,30 @@ public:
//! \{
//! Returns the instruction id, see `BaseInst::Id`.
- inline InstId id() const noexcept { return _baseInst.id(); }
+ ASMJIT_INLINE_NODEBUG InstId id() const noexcept { return _baseInst.id(); }
//! Returns the instruction real id, see `BaseInst::Id`.
- inline InstId realId() const noexcept { return _baseInst.realId(); }
+ ASMJIT_INLINE_NODEBUG InstId realId() const noexcept { return _baseInst.realId(); }
//! Sets the instruction id to `id`, see `BaseInst::Id`.
- inline void setId(InstId id) noexcept { _baseInst.setId(id); }
+ ASMJIT_INLINE_NODEBUG void setId(InstId id) noexcept { _baseInst.setId(id); }
//! \}
//! \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(); }
+ //! Returns instruction options, see \ref InstOptions for more details.
+ ASMJIT_INLINE_NODEBUG InstOptions options() const noexcept { return _baseInst.options(); }
+ //! Tests whether instruction has the given \option` set/enabled.
+ ASMJIT_INLINE_NODEBUG bool hasOption(InstOptions option) const noexcept { return _baseInst.hasOption(option); }
+ //! Sets instruction `options` to the provided value, resetting all others.
+ ASMJIT_INLINE_NODEBUG void setOptions(InstOptions options) noexcept { _baseInst.setOptions(options); }
+ //! Adds instruction `options` to the instruction.
+ ASMJIT_INLINE_NODEBUG void addOptions(InstOptions options) noexcept { _baseInst.addOptions(options); }
+ //! Clears instruction `options` of the instruction (disables the given options).
+ ASMJIT_INLINE_NODEBUG void clearOptions(InstOptions options) noexcept { _baseInst.clearOptions(options); }
+ //! Resets instruction options to none - disabling all instruction options.
+ ASMJIT_INLINE_NODEBUG void resetOptions() noexcept { _baseInst.resetOptions(); }
//! \}
@@ -770,17 +833,17 @@ public:
//! \{
//! Tests whether the node has an extra register operand.
- inline bool hasExtraReg() const noexcept { return _baseInst.hasExtraReg(); }
+ ASMJIT_INLINE_NODEBUG bool hasExtraReg() const noexcept { return _baseInst.hasExtraReg(); }
//! Returns extra register operand.
- inline RegOnly& extraReg() noexcept { return _baseInst.extraReg(); }
+ ASMJIT_INLINE_NODEBUG RegOnly& extraReg() noexcept { return _baseInst.extraReg(); }
//! \overload
- inline const RegOnly& extraReg() const noexcept { return _baseInst.extraReg(); }
+ ASMJIT_INLINE_NODEBUG const RegOnly& extraReg() const noexcept { return _baseInst.extraReg(); }
//! Sets extra register operand to `reg`.
- inline void setExtraReg(const BaseReg& reg) noexcept { _baseInst.setExtraReg(reg); }
+ ASMJIT_INLINE_NODEBUG void setExtraReg(const BaseReg& reg) noexcept { _baseInst.setExtraReg(reg); }
//! Sets extra register operand to `reg`.
- inline void setExtraReg(const RegOnly& reg) noexcept { _baseInst.setExtraReg(reg); }
+ ASMJIT_INLINE_NODEBUG void setExtraReg(const RegOnly& reg) noexcept { _baseInst.setExtraReg(reg); }
//! Resets extra register operand.
- inline void resetExtraReg() noexcept { _baseInst.resetExtraReg(); }
+ ASMJIT_INLINE_NODEBUG void resetExtraReg() noexcept { _baseInst.resetExtraReg(); }
//! \}
@@ -788,46 +851,60 @@ public:
//! \{
//! Returns operand count.
- inline uint32_t opCount() const noexcept { return _inst._opCount; }
+ ASMJIT_INLINE_NODEBUG uint32_t opCount() const noexcept { return _inst._opCount; }
//! Returns operand capacity.
- inline uint32_t opCapacity() const noexcept { return _inst._opCapacity; }
+ ASMJIT_INLINE_NODEBUG uint32_t opCapacity() const noexcept { return _inst._opCapacity; }
//! Sets operand count.
- inline void setOpCount(uint32_t opCount) noexcept { _inst._opCount = uint8_t(opCount); }
+ ASMJIT_INLINE_NODEBUG void setOpCount(uint32_t opCount) noexcept { _inst._opCount = uint8_t(opCount); }
//! Returns operands array.
- inline Operand* operands() noexcept { return (Operand*)_opArray; }
+ ASMJIT_INLINE_NODEBUG Operand* operands() noexcept {
+ return reinterpret_cast<Operand*>(reinterpret_cast<uint8_t*>(this) + sizeof(InstNode));
+ }
+
//! Returns operands array (const).
- inline const Operand* operands() const noexcept { return (const Operand*)_opArray; }
+ ASMJIT_INLINE_NODEBUG const Operand* operands() const noexcept {
+ return reinterpret_cast<const Operand*>(reinterpret_cast<const uint8_t*>(this) + sizeof(InstNode));
+ }
//! Returns operand at the given `index`.
inline Operand& op(uint32_t index) noexcept {
ASMJIT_ASSERT(index < opCapacity());
- return _opArray[index].as<Operand>();
+
+ Operand* ops = operands();
+ return ops[index].as<Operand>();
}
//! Returns operand at the given `index` (const).
inline const Operand& op(uint32_t index) const noexcept {
ASMJIT_ASSERT(index < opCapacity());
- return _opArray[index].as<Operand>();
+
+ const Operand* ops = operands();
+ return ops[index].as<Operand>();
}
//! Sets operand at the given `index` to `op`.
inline void setOp(uint32_t index, const Operand_& op) noexcept {
ASMJIT_ASSERT(index < opCapacity());
- _opArray[index].copyFrom(op);
+
+ Operand* ops = operands();
+ ops[index].copyFrom(op);
}
//! Resets operand at the given `index` to none.
inline void resetOp(uint32_t index) noexcept {
ASMJIT_ASSERT(index < opCapacity());
- _opArray[index].reset();
+
+ Operand* ops = operands();
+ ops[index].reset();
}
//! Resets operands at `[start, end)` range.
inline void resetOpRange(uint32_t start, uint32_t end) noexcept {
+ Operand* ops = operands();
for (uint32_t i = start; i < end; i++)
- _opArray[i].reset();
+ ops[i].reset();
}
//! \}
@@ -835,33 +912,47 @@ public:
//! \name Utilities
//! \{
+ //! Tests whether the given operand type `opType` is used by the instruction.
inline bool hasOpType(OperandType opType) const noexcept {
+ const Operand* ops = operands();
for (uint32_t i = 0, count = opCount(); i < count; i++)
- if (_opArray[i].opType() == opType)
+ if (ops[i].opType() == opType)
return true;
return false;
}
+ //! Tests whether the instruction uses at least one register operand.
inline bool hasRegOp() const noexcept { return hasOpType(OperandType::kReg); }
+ //! Tests whether the instruction uses at least one memory operand.
inline bool hasMemOp() const noexcept { return hasOpType(OperandType::kMem); }
+ //! Tests whether the instruction uses at least one immediate operand.
inline bool hasImmOp() const noexcept { return hasOpType(OperandType::kImm); }
+ //! Tests whether the instruction uses at least one label operand.
inline bool hasLabelOp() const noexcept { return hasOpType(OperandType::kLabel); }
+ //! Returns the index of the given operand type `opType`.
+ //!
+ //! \note If the operand type wa found, the value returned represents its index in \ref operands()
+ //! array, otherwise \ref Globals::kNotFound is returned to signalize that the operand was not found.
inline uint32_t indexOfOpType(OperandType opType) const noexcept {
uint32_t i = 0;
uint32_t count = opCount();
+ const Operand* ops = operands();
while (i < count) {
- if (_opArray[i].opType() == opType)
- break;
+ if (ops[i].opType() == opType)
+ return i;
i++;
}
- return i;
+ return Globals::kNotFound;
}
+ //! A shortcut that calls `indexOfOpType(OperandType::kMem)`.
inline uint32_t indexOfMemOp() const noexcept { return indexOfOpType(OperandType::kMem); }
+ //! A shortcut that calls `indexOfOpType(OperandType::kImm)`.
inline uint32_t indexOfImmOp() const noexcept { return indexOfOpType(OperandType::kImm); }
+ //! A shortcut that calls `indexOfOpType(OperandType::kLabel)`.
inline uint32_t indexOfLabelOp() const noexcept { return indexOfOpType(OperandType::kLabel); }
//! \}
@@ -870,20 +961,40 @@ public:
//! \{
//! \cond INTERNAL
- inline uint32_t* _getRewriteArray() noexcept { return &_baseInst._extraReg._id; }
- inline const uint32_t* _getRewriteArray() const noexcept { return &_baseInst._extraReg._id; }
+ //! Returns uint32_t[] view that represents BaseInst::RegOnly and instruction operands.
+ ASMJIT_INLINE_NODEBUG uint32_t* _getRewriteArray() noexcept { return &_baseInst._extraReg._id; }
+ //! \overload
+ ASMJIT_INLINE_NODEBUG const uint32_t* _getRewriteArray() const noexcept { return &_baseInst._extraReg._id; }
+
+ //! Maximum value of rewrite id - 6 operands each having 4 slots is 24, one RegOnly having 2 slots => 26.
+ static constexpr uint32_t kMaxRewriteId = 26 - 1;
+
+ //! Returns a rewrite index of the given pointer to `id`.
+ //!
+ //! This function returns a value that can be then passed to `\ref rewriteIdAtIndex() function. It can address
+ //! any id from any operand that is used by the instruction in addition to \ref BaseInst::regOnly field, which
+ //! can also be used by the register allocator.
inline uint32_t getRewriteIndex(const uint32_t* id) const noexcept {
const uint32_t* array = _getRewriteArray();
ASMJIT_ASSERT(array <= id);
size_t index = (size_t)(id - array);
- ASMJIT_ASSERT(index < 32);
+ ASMJIT_ASSERT(index <= kMaxRewriteId);
return uint32_t(index);
}
+ //! Rewrites the given `index` to the provided identifier `id`.
+ //!
+ //! \note This is an internal function that is used by a \ref BaseCompiler implementation to rewrite virtual
+ //! registers to physical registers. The rewriter in this case sees all operands as array of uint32 values
+ //! and the given `index` describes a position in this array. For example a single \ref Operand would be
+ //! decomposed to 4 uint32_t values, where the first at index 0 would be operand signature, next would be
+ //! base id, etc... This is a comfortable way of patching operands without having to check for their types.
inline void rewriteIdAtIndex(uint32_t index, uint32_t id) noexcept {
+ ASMJIT_ASSERT(index <= kMaxRewriteId);
+
uint32_t* array = _getRewriteArray();
array[index] = id;
}
@@ -895,43 +1006,40 @@ public:
//! \{
//! \cond INTERNAL
- static inline uint32_t capacityOfOpCount(uint32_t opCount) noexcept {
- return opCount <= kBaseOpCapacity ? kBaseOpCapacity : Globals::kMaxOpCount;
+
+ //! Returns the capacity required for the given operands count `opCount`.
+ //!
+ //! There are only two capacities used - \ref kBaseOpCapacity and \ref kFullOpCapacity, so this function
+ //! is used to decide between these two. The general rule is that instructions that can be represented with
+ //! \ref kBaseOpCapacity would use this value, and all others would take \ref kFullOpCapacity.
+ static ASMJIT_INLINE_NODEBUG constexpr uint32_t capacityOfOpCount(uint32_t opCount) noexcept {
+ return opCount <= kBaseOpCapacity ? kBaseOpCapacity : kFullOpCapacity;
}
- static inline size_t nodeSizeOfOpCapacity(uint32_t opCapacity) noexcept {
- size_t base = sizeof(InstNode) - kBaseOpCapacity * sizeof(Operand);
- return base + opCapacity * sizeof(Operand);
+ //! Calculates the size of \ref InstNode required to hold at most `opCapacity` operands.
+ //!
+ //! This function is used internally to allocate \ref InstNode.
+ static ASMJIT_INLINE_NODEBUG constexpr size_t nodeSizeOfOpCapacity(uint32_t opCapacity) noexcept {
+ return sizeof(InstNode) + opCapacity * sizeof(Operand);
}
//! \endcond
//! \}
};
-//! Instruction node with maximum number of operands.
+//! Instruction node with embedded operands following \ref InstNode layout.
//!
-//! 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 {
+//! \note This is used to make tools such as static analysis and compilers happy about the layout. There were two
+//! instruction nodes in the past, having the second extend the operand array of the first, but that has caused
+//! undefined behavior and made recent tools unhappy about that.
+template<uint32_t kN>
+class InstNodeWithOperands : public InstNode {
public:
- ASMJIT_NONCOPYABLE(InstExNode)
-
- //! \name Members
- //! \{
+ Operand_ _operands[kN];
- //! 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, InstId instId, InstOptions options, uint32_t opCapacity = Globals::kMaxOpCount) noexcept
- : InstNode(cb, instId, options, opCapacity) {}
-
- //! \}
+ //! Creates a new `InstNodeWithOperands` instance.
+ ASMJIT_INLINE_NODEBUG InstNodeWithOperands(BaseBuilder* cb, InstId instId, InstOptions options, uint32_t opCount) noexcept
+ : InstNode(cb, instId, options, opCount, kN) {}
};
//! Section node.
@@ -958,9 +1066,9 @@ public:
//! \{
//! Creates a new `SectionNode` instance.
- inline SectionNode(BaseBuilder* cb, uint32_t secionId = 0) noexcept
+ ASMJIT_INLINE_NODEBUG SectionNode(BaseBuilder* cb, uint32_t sectionId = 0) noexcept
: BaseNode(cb, NodeType::kSection, NodeFlags::kHasNoEffect),
- _id(secionId),
+ _id(sectionId),
_nextSection(nullptr) {}
//! \}
@@ -969,7 +1077,7 @@ public:
//! \{
//! Returns the section id.
- inline uint32_t id() const noexcept { return _id; }
+ ASMJIT_INLINE_NODEBUG uint32_t id() const noexcept { return _id; }
//! \}
};
@@ -991,7 +1099,7 @@ public:
//! \{
//! Creates a new `LabelNode` instance.
- inline LabelNode(BaseBuilder* cb, uint32_t labelId = 0) noexcept
+ ASMJIT_INLINE_NODEBUG LabelNode(BaseBuilder* cb, uint32_t labelId = 0) noexcept
: BaseNode(cb, NodeType::kLabel, NodeFlags::kHasNoEffect | NodeFlags::kActsAsLabel),
_labelId(labelId) {}
@@ -1001,9 +1109,9 @@ public:
//! \{
//! Returns \ref Label representation of the \ref LabelNode.
- inline Label label() const noexcept { return Label(_labelId); }
+ ASMJIT_INLINE_NODEBUG Label label() const noexcept { return Label(_labelId); }
//! Returns the id of the label.
- inline uint32_t labelId() const noexcept { return _labelId; }
+ ASMJIT_INLINE_NODEBUG uint32_t labelId() const noexcept { return _labelId; }
//! \}
};
@@ -1027,7 +1135,7 @@ public:
//! \{
//! Creates a new `AlignNode` instance.
- inline AlignNode(BaseBuilder* cb, AlignMode alignMode, uint32_t alignment) noexcept
+ ASMJIT_INLINE_NODEBUG AlignNode(BaseBuilder* cb, AlignMode alignMode, uint32_t alignment) noexcept
: BaseNode(cb, NodeType::kAlign, NodeFlags::kIsCode | NodeFlags::kHasNoEffect) {
_alignData._alignMode = alignMode;
@@ -1040,14 +1148,14 @@ public:
//! \{
//! Returns align mode.
- inline AlignMode alignMode() const noexcept { return _alignData._alignMode; }
+ ASMJIT_INLINE_NODEBUG AlignMode alignMode() const noexcept { return _alignData._alignMode; }
//! Sets align mode to `alignMode`.
- inline void setAlignMode(AlignMode alignMode) noexcept { _alignData._alignMode = alignMode; }
+ ASMJIT_INLINE_NODEBUG void setAlignMode(AlignMode alignMode) noexcept { _alignData._alignMode = alignMode; }
//! Returns align offset in bytes.
- inline uint32_t alignment() const noexcept { return _alignment; }
+ ASMJIT_INLINE_NODEBUG uint32_t alignment() const noexcept { return _alignment; }
//! Sets align offset in bytes to `offset`.
- inline void setAlignment(uint32_t alignment) noexcept { _alignment = alignment; }
+ ASMJIT_INLINE_NODEBUG void setAlignment(uint32_t alignment) noexcept { _alignment = alignment; }
//! \}
};
@@ -1083,7 +1191,7 @@ public:
//! \{
//! Creates a new `EmbedDataNode` instance.
- inline EmbedDataNode(BaseBuilder* cb) noexcept
+ ASMJIT_INLINE_NODEBUG EmbedDataNode(BaseBuilder* cb) noexcept
: BaseNode(cb, NodeType::kEmbedData, NodeFlags::kIsData),
_itemCount(0),
_repeatCount(0) {
@@ -1098,31 +1206,31 @@ public:
//! \{
//! Returns data type as \ref TypeId.
- inline TypeId typeId() const noexcept { return _embed._typeId; }
+ ASMJIT_INLINE_NODEBUG TypeId typeId() const noexcept { return _embed._typeId; }
//! Returns the size of a single data element.
- inline uint32_t typeSize() const noexcept { return _embed._typeSize; }
+ ASMJIT_INLINE_NODEBUG uint32_t typeSize() const noexcept { return _embed._typeSize; }
//! Returns a pointer to the data casted to `uint8_t`.
- inline uint8_t* data() const noexcept {
+ ASMJIT_INLINE_NODEBUG uint8_t* data() const noexcept {
return dataSize() <= kInlineBufferSize ? const_cast<uint8_t*>(_inlineData) : _externalData;
}
//! Returns a pointer to the data casted to `T`.
template<typename T>
- inline T* dataAs() const noexcept { return reinterpret_cast<T*>(data()); }
+ ASMJIT_INLINE_NODEBUG T* dataAs() const noexcept { return reinterpret_cast<T*>(data()); }
//! Returns the number of (typed) items in the array.
- inline size_t itemCount() const noexcept { return _itemCount; }
+ ASMJIT_INLINE_NODEBUG size_t itemCount() const noexcept { return _itemCount; }
//! Returns how many times the data is repeated (default 1).
//!
//! Repeated data is useful when defining constants for SIMD, for example.
- inline size_t repeatCount() const noexcept { return _repeatCount; }
+ ASMJIT_INLINE_NODEBUG size_t repeatCount() const noexcept { return _repeatCount; }
//! Returns the size of the data, not considering the number of times it repeats.
//!
//! \note The returned value is the same as `typeSize() * itemCount()`.
- inline size_t dataSize() const noexcept { return typeSize() * _itemCount; }
+ ASMJIT_INLINE_NODEBUG size_t dataSize() const noexcept { return typeSize() * _itemCount; }
//! \}
};
@@ -1144,7 +1252,7 @@ public:
//! \{
//! Creates a new `EmbedLabelNode` instance.
- inline EmbedLabelNode(BaseBuilder* cb, uint32_t labelId = 0, uint32_t dataSize = 0) noexcept
+ ASMJIT_INLINE_NODEBUG EmbedLabelNode(BaseBuilder* cb, uint32_t labelId = 0, uint32_t dataSize = 0) noexcept
: BaseNode(cb, NodeType::kEmbedLabel, NodeFlags::kIsData),
_labelId(labelId),
_dataSize(dataSize) {}
@@ -1155,19 +1263,19 @@ public:
//! \{
//! Returns the label to embed as \ref Label operand.
- inline Label label() const noexcept { return Label(_labelId); }
+ ASMJIT_INLINE_NODEBUG Label label() const noexcept { return Label(_labelId); }
//! Returns the id of the label.
- inline uint32_t labelId() const noexcept { return _labelId; }
+ ASMJIT_INLINE_NODEBUG uint32_t labelId() const noexcept { return _labelId; }
//! Sets the label id from `label` operand.
- inline void setLabel(const Label& label) noexcept { setLabelId(label.id()); }
+ ASMJIT_INLINE_NODEBUG void setLabel(const Label& label) noexcept { setLabelId(label.id()); }
//! Sets the label id (use with caution, improper use can break a lot of things).
- inline void setLabelId(uint32_t labelId) noexcept { _labelId = labelId; }
+ ASMJIT_INLINE_NODEBUG void setLabelId(uint32_t labelId) noexcept { _labelId = labelId; }
//! Returns the data size.
- inline uint32_t dataSize() const noexcept { return _dataSize; }
+ ASMJIT_INLINE_NODEBUG uint32_t dataSize() const noexcept { return _dataSize; }
//! Sets the data size.
- inline void setDataSize(uint32_t dataSize) noexcept { _dataSize = dataSize; }
+ ASMJIT_INLINE_NODEBUG void setDataSize(uint32_t dataSize) noexcept { _dataSize = dataSize; }
//! \}
};
@@ -1190,7 +1298,7 @@ public:
//! \{
//! Creates a new `EmbedLabelDeltaNode` instance.
- inline EmbedLabelDeltaNode(BaseBuilder* cb, uint32_t labelId = 0, uint32_t baseLabelId = 0, uint32_t dataSize = 0) noexcept
+ ASMJIT_INLINE_NODEBUG EmbedLabelDeltaNode(BaseBuilder* cb, uint32_t labelId = 0, uint32_t baseLabelId = 0, uint32_t dataSize = 0) noexcept
: BaseNode(cb, NodeType::kEmbedLabelDelta, NodeFlags::kIsData),
_labelId(labelId),
_baseLabelId(baseLabelId),
@@ -1202,29 +1310,29 @@ public:
//! \{
//! Returns the label as `Label` operand.
- inline Label label() const noexcept { return Label(_labelId); }
+ ASMJIT_INLINE_NODEBUG Label label() const noexcept { return Label(_labelId); }
//! Returns the id of the label.
- inline uint32_t labelId() const noexcept { return _labelId; }
+ ASMJIT_INLINE_NODEBUG uint32_t labelId() const noexcept { return _labelId; }
//! Sets the label id from `label` operand.
- inline void setLabel(const Label& label) noexcept { setLabelId(label.id()); }
+ ASMJIT_INLINE_NODEBUG void setLabel(const Label& label) noexcept { setLabelId(label.id()); }
//! Sets the label id.
- inline void setLabelId(uint32_t labelId) noexcept { _labelId = labelId; }
+ ASMJIT_INLINE_NODEBUG void setLabelId(uint32_t labelId) noexcept { _labelId = labelId; }
//! Returns the base label as `Label` operand.
- inline Label baseLabel() const noexcept { return Label(_baseLabelId); }
+ ASMJIT_INLINE_NODEBUG Label baseLabel() const noexcept { return Label(_baseLabelId); }
//! Returns the id of the base label.
- inline uint32_t baseLabelId() const noexcept { return _baseLabelId; }
+ ASMJIT_INLINE_NODEBUG uint32_t baseLabelId() const noexcept { return _baseLabelId; }
//! Sets the base label id from `label` operand.
- inline void setBaseLabel(const Label& baseLabel) noexcept { setBaseLabelId(baseLabel.id()); }
+ ASMJIT_INLINE_NODEBUG void setBaseLabel(const Label& baseLabel) noexcept { setBaseLabelId(baseLabel.id()); }
//! Sets the base label id.
- inline void setBaseLabelId(uint32_t baseLabelId) noexcept { _baseLabelId = baseLabelId; }
+ ASMJIT_INLINE_NODEBUG void setBaseLabelId(uint32_t baseLabelId) noexcept { _baseLabelId = baseLabelId; }
//! Returns the size of the embedded label address.
- inline uint32_t dataSize() const noexcept { return _dataSize; }
+ ASMJIT_INLINE_NODEBUG uint32_t dataSize() const noexcept { return _dataSize; }
//! Sets the size of the embedded label address.
- inline void setDataSize(uint32_t dataSize) noexcept { _dataSize = dataSize; }
+ ASMJIT_INLINE_NODEBUG void setDataSize(uint32_t dataSize) noexcept { _dataSize = dataSize; }
//! \}
};
@@ -1245,7 +1353,7 @@ public:
//! \{
//! Creates a new `ConstPoolNode` instance.
- inline ConstPoolNode(BaseBuilder* cb, uint32_t id = 0) noexcept
+ ASMJIT_INLINE_NODEBUG ConstPoolNode(BaseBuilder* cb, uint32_t id = 0) noexcept
: LabelNode(cb, id),
_constPool(&cb->_codeZone) {
@@ -1260,16 +1368,16 @@ public:
//! \{
//! Tests whether the constant-pool is empty.
- inline bool empty() const noexcept { return _constPool.empty(); }
+ ASMJIT_INLINE_NODEBUG bool empty() const noexcept { return _constPool.empty(); }
//! Returns the size of the constant-pool in bytes.
- inline size_t size() const noexcept { return _constPool.size(); }
+ ASMJIT_INLINE_NODEBUG size_t size() const noexcept { return _constPool.size(); }
//! Returns minimum alignment.
- inline size_t alignment() const noexcept { return _constPool.alignment(); }
+ ASMJIT_INLINE_NODEBUG size_t alignment() const noexcept { return _constPool.alignment(); }
//! Returns the wrapped `ConstPool` instance.
- inline ConstPool& constPool() noexcept { return _constPool; }
+ ASMJIT_INLINE_NODEBUG ConstPool& constPool() noexcept { return _constPool; }
//! Returns the wrapped `ConstPool` instance (const).
- inline const ConstPool& constPool() const noexcept { return _constPool; }
+ ASMJIT_INLINE_NODEBUG const ConstPool& constPool() const noexcept { return _constPool; }
//! \}
@@ -1277,7 +1385,7 @@ public:
//! \{
//! See `ConstPool::add()`.
- inline Error add(const void* data, size_t size, size_t& dstOffset) noexcept {
+ ASMJIT_INLINE_NODEBUG Error add(const void* data, size_t size, size_t& dstOffset) noexcept {
return _constPool.add(data, size, dstOffset);
}
@@ -1293,7 +1401,7 @@ public:
//! \{
//! Creates a new `CommentNode` instance.
- inline CommentNode(BaseBuilder* cb, const char* comment) noexcept
+ ASMJIT_INLINE_NODEBUG CommentNode(BaseBuilder* cb, const char* comment) noexcept
: BaseNode(cb, NodeType::kComment, NodeFlags::kIsInformative | NodeFlags::kHasNoEffect | NodeFlags::kIsRemovable) {
_inlineComment = comment;
}
@@ -1313,7 +1421,7 @@ public:
//! \{
//! Creates a new `SentinelNode` instance.
- inline SentinelNode(BaseBuilder* cb, SentinelType sentinelType = SentinelType::kUnknown) noexcept
+ ASMJIT_INLINE_NODEBUG SentinelNode(BaseBuilder* cb, SentinelType sentinelType = SentinelType::kUnknown) noexcept
: BaseNode(cb, NodeType::kSentinel, NodeFlags::kIsInformative | NodeFlags::kHasNoEffect) {
_sentinel._sentinelType = sentinelType;
@@ -1325,12 +1433,12 @@ public:
//! \{
//! Returns the type of the sentinel.
- inline SentinelType sentinelType() const noexcept {
+ ASMJIT_INLINE_NODEBUG SentinelType sentinelType() const noexcept {
return _sentinel._sentinelType;
}
//! Sets the type of the sentinel.
- inline void setSentinelType(SentinelType type) noexcept {
+ ASMJIT_INLINE_NODEBUG void setSentinelType(SentinelType type) noexcept {
_sentinel._sentinelType = type;
}
@@ -1365,9 +1473,9 @@ public:
//! \{
//! Returns \ref BaseBuilder associated with the pass.
- inline const BaseBuilder* cb() const noexcept { return _cb; }
+ ASMJIT_INLINE_NODEBUG const BaseBuilder* cb() const noexcept { return _cb; }
//! Returns the name of the pass.
- inline const char* name() const noexcept { return _name; }
+ ASMJIT_INLINE_NODEBUG const char* name() const noexcept { return _name; }
//! \}
@@ -1378,7 +1486,7 @@ public:
//!
//! 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;
+ ASMJIT_API virtual Error run(Zone* zone, Logger* logger);
//! \}
};
diff --git a/3rdparty/asmjit/src/asmjit/core/builder_p.h b/3rdparty/asmjit/src/asmjit/core/builder_p.h
new file mode 100644
index 00000000000..98790fdf95f
--- /dev/null
+++ b/3rdparty/asmjit/src/asmjit/core/builder_p.h
@@ -0,0 +1,37 @@
+// 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_BUILDER_P_H_INCLUDED
+#define ASMJIT_CORE_BUILDER_P_H_INCLUDED
+
+#include "../core/api-config.h"
+#ifndef ASMJIT_NO_BUILDER
+
+#include "../core/builder.h"
+
+ASMJIT_BEGIN_NAMESPACE
+
+//! \cond INTERNAL
+//! \addtogroup asmjit_builder
+//! \{
+
+static inline void BaseBuilder_assignInlineComment(BaseBuilder* self, BaseNode* node, const char* comment) noexcept {
+ if (comment)
+ node->setInlineComment(static_cast<char*>(self->_dataZone.dup(comment, strlen(comment), true)));
+}
+
+static inline void BaseBuilder_assignInstState(BaseBuilder* self, InstNode* node, const BaseEmitter::State& state) noexcept {
+ node->setOptions(state.options);
+ node->setExtraReg(state.extraReg);
+ BaseBuilder_assignInlineComment(self, node, state.comment);
+}
+
+//! \}
+//! \endcond
+
+ASMJIT_END_NAMESPACE
+
+#endif // !ASMJIT_NO_BUILDER
+#endif // ASMJIT_CORE_BUILDER_P_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/core/codebuffer.h b/3rdparty/asmjit/src/asmjit/core/codebuffer.h
index 4946e7a06a1..d4b7cebbcef 100644
--- a/3rdparty/asmjit/src/asmjit/core/codebuffer.h
+++ b/3rdparty/asmjit/src/asmjit/core/codebuffer.h
@@ -44,7 +44,7 @@ struct CodeBuffer {
//! \name Overloaded Operators
//! \{
- //! Returns a referebce to the byte at the given `index`.
+ //! Returns a reference to the byte at the given `index`.
inline uint8_t& operator[](size_t index) noexcept {
ASMJIT_ASSERT(index < _size);
return _data[index];
@@ -61,46 +61,46 @@ struct CodeBuffer {
//! \{
//! Returns code buffer flags.
- inline CodeBufferFlags flags() const noexcept { return _flags; }
+ ASMJIT_INLINE_NODEBUG CodeBufferFlags flags() const noexcept { return _flags; }
//! Tests whether the code buffer has the given `flag` set.
- inline bool hasFlag(CodeBufferFlags flag) const noexcept { return Support::test(_flags, flag); }
+ ASMJIT_INLINE_NODEBUG 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(CodeBufferFlags::kIsFixed); }
+ ASMJIT_INLINE_NODEBUG 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(CodeBufferFlags::kIsExternal); }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG bool isAllocated() const noexcept { return _data != nullptr; }
//! Tests whether the code buffer is empty.
- inline bool empty() const noexcept { return !_size; }
+ ASMJIT_INLINE_NODEBUG bool empty() const noexcept { return !_size; }
//! Returns the size of the data.
- inline size_t size() const noexcept { return _size; }
+ ASMJIT_INLINE_NODEBUG size_t size() const noexcept { return _size; }
//! Returns the capacity of the data.
- inline size_t capacity() const noexcept { return _capacity; }
+ ASMJIT_INLINE_NODEBUG size_t capacity() const noexcept { return _capacity; }
//! Returns the pointer to the data the buffer references.
- inline uint8_t* data() noexcept { return _data; }
+ ASMJIT_INLINE_NODEBUG uint8_t* data() noexcept { return _data; }
//! \overload
- inline const uint8_t* data() const noexcept { return _data; }
+ ASMJIT_INLINE_NODEBUG const uint8_t* data() const noexcept { return _data; }
//! \}
//! \name Iterators
//! \{
- inline uint8_t* begin() noexcept { return _data; }
- inline const uint8_t* begin() const noexcept { return _data; }
+ ASMJIT_INLINE_NODEBUG uint8_t* begin() noexcept { return _data; }
+ ASMJIT_INLINE_NODEBUG const uint8_t* begin() const noexcept { return _data; }
- inline uint8_t* end() noexcept { return _data + _size; }
- inline const uint8_t* end() const noexcept { return _data + _size; }
+ ASMJIT_INLINE_NODEBUG uint8_t* end() noexcept { return _data + _size; }
+ ASMJIT_INLINE_NODEBUG const uint8_t* end() const noexcept { return _data + _size; }
//! \}
};
diff --git a/3rdparty/asmjit/src/asmjit/core/codeholder.cpp b/3rdparty/asmjit/src/asmjit/core/codeholder.cpp
index cf763cfff12..63b15a3ada3 100644
--- a/3rdparty/asmjit/src/asmjit/core/codeholder.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/codeholder.cpp
@@ -74,6 +74,7 @@ static void CodeHolder_resetInternal(CodeHolder* self, ResetPolicy resetPolicy)
// Reset everything into its construction state.
self->_environment.reset();
+ self->_cpuFeatures.reset();
self->_baseAddress = Globals::kNoBaseAddress;
self->_logger = nullptr;
self->_errorHandler = nullptr;
@@ -118,6 +119,7 @@ static void CodeHolder_onSettingsUpdated(CodeHolder* self) noexcept {
CodeHolder::CodeHolder(const Support::Temporary* temporary) noexcept
: _environment(),
+ _cpuFeatures{},
_baseAddress(Globals::kNoBaseAddress),
_logger(nullptr),
_errorHandler(nullptr),
@@ -130,8 +132,8 @@ CodeHolder::~CodeHolder() noexcept {
CodeHolder_resetInternal(this, ResetPolicy::kHard);
}
-// CodeHolder - Init & Reset
-// =========================
+// CodeHolder - Initialization & Reset
+// ===================================
inline void CodeHolder_setSectionDefaultName(
Section* section,
@@ -143,6 +145,10 @@ inline void CodeHolder_setSectionDefaultName(
}
Error CodeHolder::init(const Environment& environment, uint64_t baseAddress) noexcept {
+ return init(environment, CpuFeatures{}, baseAddress);
+}
+
+Error CodeHolder::init(const Environment& environment, const CpuFeatures& cpuFeatures, uint64_t baseAddress) noexcept {
// Cannot reinitialize if it's locked or there is one or more emitter attached.
if (isInitialized())
return DebugUtils::errored(kErrorAlreadyInitialized);
@@ -172,6 +178,7 @@ Error CodeHolder::init(const Environment& environment, uint64_t baseAddress) noe
}
else {
_environment = environment;
+ _cpuFeatures = cpuFeatures;
_baseAddress = baseAddress;
return kErrorOk;
}
@@ -901,7 +908,7 @@ size_t CodeHolder::codeSize() const noexcept {
}
}
- if ((sizeof(uint64_t) > sizeof(size_t) && offset > SIZE_MAX) || of)
+ if ((sizeof(uint64_t) > sizeof(size_t) && offset > uint64_t(SIZE_MAX)) || of)
return SIZE_MAX;
return size_t(offset);
@@ -1119,30 +1126,30 @@ UNIT(code_holder) {
env.init(Arch::kX86);
code.init(env);
- EXPECT(code.arch() == Arch::kX86);
+ EXPECT_EQ(code.arch(), Arch::kX86);
INFO("Verifying named labels");
LabelEntry* le;
- EXPECT(code.newNamedLabelEntry(&le, "NamedLabel", SIZE_MAX, LabelType::kGlobal) == kErrorOk);
- EXPECT(strcmp(le->name(), "NamedLabel") == 0);
- EXPECT(code.labelIdByName("NamedLabel") == le->id());
+ EXPECT_EQ(code.newNamedLabelEntry(&le, "NamedLabel", SIZE_MAX, LabelType::kGlobal), kErrorOk);
+ EXPECT_EQ(strcmp(le->name(), "NamedLabel"), 0);
+ EXPECT_EQ(code.labelIdByName("NamedLabel"), le->id());
INFO("Verifying section ordering");
Section* section1;
- EXPECT(code.newSection(&section1, "high-priority", SIZE_MAX, SectionFlags::kNone, 1, -1) == kErrorOk);
- EXPECT(code.sections()[1] == section1);
- EXPECT(code.sectionsByOrder()[0] == section1);
+ EXPECT_EQ(code.newSection(&section1, "high-priority", SIZE_MAX, SectionFlags::kNone, 1, -1), kErrorOk);
+ EXPECT_EQ(code.sections()[1], section1);
+ EXPECT_EQ(code.sectionsByOrder()[0], section1);
Section* section0;
- 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);
+ EXPECT_EQ(code.newSection(&section0, "higher-priority", SIZE_MAX, SectionFlags::kNone, 1, -2), kErrorOk);
+ EXPECT_EQ(code.sections()[2], section0);
+ EXPECT_EQ(code.sectionsByOrder()[0], section0);
+ EXPECT_EQ(code.sectionsByOrder()[1], section1);
Section* section3;
- EXPECT(code.newSection(&section3, "low-priority", SIZE_MAX, SectionFlags::kNone, 1, 2) == kErrorOk);
- EXPECT(code.sections()[3] == section3);
- EXPECT(code.sectionsByOrder()[3] == section3);
+ EXPECT_EQ(code.newSection(&section3, "low-priority", SIZE_MAX, SectionFlags::kNone, 1, 2), kErrorOk);
+ EXPECT_EQ(code.sections()[3], section3);
+ EXPECT_EQ(code.sectionsByOrder()[3], section3);
}
#endif
diff --git a/3rdparty/asmjit/src/asmjit/core/codeholder.h b/3rdparty/asmjit/src/asmjit/core/codeholder.h
index 6ed2ddf9426..3f2d1d70745 100644
--- a/3rdparty/asmjit/src/asmjit/core/codeholder.h
+++ b/3rdparty/asmjit/src/asmjit/core/codeholder.h
@@ -45,7 +45,7 @@ enum class ExpressionOpType : uint8_t {
kSra = 5
};
-//! Value tyoe that can be used within an \ref Expression.
+//! Value type that can be used within an \ref Expression.
enum class ExpressionValueType : uint8_t {
//! No value or invalid.
kNone = 0,
@@ -89,22 +89,22 @@ struct Expression {
//! Resets the whole expression.
//!
//! Changes both values to \ref ExpressionValueType::kNone.
- inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
+ ASMJIT_INLINE_NODEBUG void reset() noexcept { *this = Expression{}; }
//! 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 {
+ ASMJIT_INLINE_NODEBUG void setValueAsConstant(size_t index, uint64_t constant) noexcept {
valueType[index] = ExpressionValueType::kConstant;
value[index].constant = constant;
}
//! Sets the value type at `index` to \ref ExpressionValueType::kLabel and its content to `labelEntry`.
- inline void setValueAsLabel(size_t index, LabelEntry* labelEntry) noexcept {
+ ASMJIT_INLINE_NODEBUG void setValueAsLabel(size_t index, LabelEntry* labelEntry) noexcept {
valueType[index] = ExpressionValueType::kLabel;
value[index].label = labelEntry;
}
//! Sets the value type at `index` to \ref ExpressionValueType::kExpression and its content to `expression`.
- inline void setValueAsExpression(size_t index, Expression* expression) noexcept {
+ ASMJIT_INLINE_NODEBUG void setValueAsExpression(size_t index, Expression* expression) noexcept {
valueType[index] = ExpressionValueType::kExpression;
value[index].expression = expression;
}
@@ -175,36 +175,36 @@ public:
//! \{
//! Returns the section id.
- inline uint32_t id() const noexcept { return _id; }
+ ASMJIT_INLINE_NODEBUG uint32_t id() const noexcept { return _id; }
//! Returns the section name, as a null terminated string.
- inline const char* name() const noexcept { return _name.str; }
+ ASMJIT_INLINE_NODEBUG const char* name() const noexcept { return _name.str; }
//! Returns the section data.
- inline uint8_t* data() noexcept { return _buffer.data(); }
+ ASMJIT_INLINE_NODEBUG uint8_t* data() noexcept { return _buffer.data(); }
//! \overload
- inline const uint8_t* data() const noexcept { return _buffer.data(); }
+ ASMJIT_INLINE_NODEBUG const uint8_t* data() const noexcept { return _buffer.data(); }
//! Returns the section flags.
- inline SectionFlags flags() const noexcept { return _flags; }
+ ASMJIT_INLINE_NODEBUG SectionFlags flags() const noexcept { return _flags; }
//! Tests whether the section has the given `flag`.
- inline bool hasFlag(SectionFlags flag) const noexcept { return Support::test(_flags, flag); }
+ ASMJIT_INLINE_NODEBUG bool hasFlag(SectionFlags flag) const noexcept { return Support::test(_flags, flag); }
//! Adds `flags` to the section flags.
- inline void addFlags(SectionFlags flags) noexcept { _flags |= flags; }
+ ASMJIT_INLINE_NODEBUG void addFlags(SectionFlags flags) noexcept { _flags |= flags; }
//! Removes `flags` from the section flags.
- inline void clearFlags(SectionFlags flags) noexcept { _flags &= ~flags; }
+ ASMJIT_INLINE_NODEBUG void clearFlags(SectionFlags flags) noexcept { _flags &= ~flags; }
//! Returns the minimum section alignment
- inline uint32_t alignment() const noexcept { return _alignment; }
+ ASMJIT_INLINE_NODEBUG uint32_t alignment() const noexcept { return _alignment; }
//! Sets the minimum section alignment
- inline void setAlignment(uint32_t alignment) noexcept { _alignment = alignment; }
+ ASMJIT_INLINE_NODEBUG void setAlignment(uint32_t alignment) noexcept { _alignment = alignment; }
//! Returns the section order, which has a higher priority than section id.
- inline int32_t order() const noexcept { return _order; }
+ ASMJIT_INLINE_NODEBUG int32_t order() const noexcept { return _order; }
//! Returns the section offset, relative to base.
- inline uint64_t offset() const noexcept { return _offset; }
+ ASMJIT_INLINE_NODEBUG uint64_t offset() const noexcept { return _offset; }
//! Set the section offset.
- inline void setOffset(uint64_t offset) noexcept { _offset = offset; }
+ ASMJIT_INLINE_NODEBUG void setOffset(uint64_t offset) noexcept { _offset = offset; }
//! Returns the virtual size of the section.
//!
@@ -212,19 +212,19 @@ public:
//! 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; }
+ ASMJIT_INLINE_NODEBUG uint64_t virtualSize() const noexcept { return _virtualSize; }
//! Sets the virtual size of the section.
- inline void setVirtualSize(uint64_t virtualSize) noexcept { _virtualSize = virtualSize; }
+ ASMJIT_INLINE_NODEBUG void setVirtualSize(uint64_t virtualSize) noexcept { _virtualSize = virtualSize; }
//! Returns the buffer size of the section.
- inline size_t bufferSize() const noexcept { return _buffer.size(); }
+ ASMJIT_INLINE_NODEBUG size_t bufferSize() const noexcept { return _buffer.size(); }
//! Returns the real size of the section calculated from virtual and buffer sizes.
- inline uint64_t realSize() const noexcept { return Support::max<uint64_t>(virtualSize(), bufferSize()); }
+ ASMJIT_INLINE_NODEBUG uint64_t realSize() const noexcept { return Support::max<uint64_t>(virtualSize(), bufferSize()); }
//! Returns the `CodeBuffer` used by this section.
- inline CodeBuffer& buffer() noexcept { return _buffer; }
+ ASMJIT_INLINE_NODEBUG CodeBuffer& buffer() noexcept { return _buffer; }
//! Returns the `CodeBuffer` used by this section (const).
- inline const CodeBuffer& buffer() const noexcept { return _buffer; }
+ ASMJIT_INLINE_NODEBUG const CodeBuffer& buffer() const noexcept { return _buffer; }
//! \}
};
@@ -247,7 +247,7 @@ public:
//! \name Construction & Destruction
//! \{
- inline explicit AddressTableEntry(uint64_t address) noexcept
+ ASMJIT_INLINE_NODEBUG explicit AddressTableEntry(uint64_t address) noexcept
: _address(address),
_slot(0xFFFFFFFFu) {}
@@ -256,22 +256,25 @@ public:
//! \name Accessors
//! \{
- inline uint64_t address() const noexcept { return _address; }
- inline uint32_t slot() const noexcept { return _slot; }
+ ASMJIT_INLINE_NODEBUG uint64_t address() const noexcept { return _address; }
+ ASMJIT_INLINE_NODEBUG uint32_t slot() const noexcept { return _slot; }
- inline bool hasAssignedSlot() const noexcept { return _slot != 0xFFFFFFFFu; }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG bool operator<(const AddressTableEntry& other) const noexcept { return _address < other._address; }
+ ASMJIT_INLINE_NODEBUG 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_INLINE_NODEBUG bool operator<(uint64_t queryAddress) const noexcept { return _address < queryAddress; }
+ ASMJIT_INLINE_NODEBUG bool operator>(uint64_t queryAddress) const noexcept { return _address > queryAddress; }
//! \}
};
//! Offset format type, used by \ref OffsetFormat.
enum class OffsetType : uint8_t {
+ // Common Offset Formats
+ // ---------------------
+
//! 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
@@ -284,14 +287,82 @@ enum class OffsetType : uint8_t {
// AArch64 Specific Offset Formats
// -------------------------------
- //! AARCH64 ADR format of `[.|immlo:2|.....|immhi:19|.....]`.
+ //! AArch64 ADR format of `[.|immlo:2|.....|immhi:19|.....]`.
kAArch64_ADR,
- //! AARCH64 ADRP format of `[.|immlo:2|.....|immhi:19|.....]` (4kB pages).
+ //! AArch64 ADRP format of `[.|immlo:2|.....|immhi:19|.....]` (4kB pages).
kAArch64_ADRP,
+ // AArch32 Specific Offset Formats (T16 & T32)
+ // -------------------------------------------
+
+ //! AArch32 THUMBv2 immediate encoding of 'ADR' instruction (12-bit payload and sign bit):
+ //!
+ //! `|.....|imm:1|..N.N|......|imm:3|....|imm:8|`
+ //!
+ //! Where `N` is one if the offset is negative. The immediate is encoded as absolute value of the offset if negative.
+ kThumb32_ADR,
+
+ //! AArch32 THUMBv2 immediate encoding of 'BLX' instruction (23-bit immediate payload, multiplied by 4):
+ //!
+ //! `|.....|imm[22]|imm[19:10]|..|ja|1|jb|imm[9:0]|0`
+ //!
+ //! Where:
+ //!
+ //! - `ja` is calculated as imm[22] ^ imm[21] ^ 1.
+ //! - `jb` is calculated as imm[22] ^ imm[20] ^ 1.
+ kThumb32_BLX,
+
+ //! AArch32 THUMBv2 immediate encoding of 'B' instruction without `<cond>` (24-bit immediate payload, multiplied by 2):
+ //!
+ //! `|.....|imm[23]|imm[20:11]|..|ja|1|jb|imm[10:0]`
+ //!
+ //! Where:
+ //!
+ //! - `ja` is calculated as imm[23] ^ imm[22] ^ 1.
+ //! - `jb` is calculated as imm[23] ^ imm[21] ^ 1.
+ kThumb32_B,
+
+ //! AArch32 THUMBv2 immediate encoding of 'B' instruction with `<cond>` (20-bit immediate payload, multiplied by 2).
+ //!
+ //! `|.....|imm[19]|....|imm[16:11]|..|ja|1|jb|imm[10:0]`
+ //!
+ //! Where:
+ //!
+ //! - `ja` is calculated as imm[19] ^ imm[18] ^ 1.
+ //! - `jb` is calculated as imm[19] ^ imm[17] ^ 1.
+ kThumb32_BCond,
+
+ // AArch32 Specific Offset Formats (A32)
+ // -------------------------------------
+
+ //! AArch32 ADR instruction, which uses a standard 12-bit immediate encoding that is used by other ARM instructions.
+ kAArch32_ADR,
+
+ //! AArch32 signed offset that is similar to `kSignedOffset`, however it uses absolute value of the offset and its
+ //! sign is encoded in 23rd bit of the opcode.
+ //!
+ //! `|........|U.......|........|........|`
+ //!
+ kAArch32_U23_SignedOffset,
+
+ //! AArch32 offset format that encodes 8-bit offset as:
+ //!
+ //! `|........|U.......|....|imm[7:4]|....|imm[3:0]|`
+ //!
+ //! in a 32-bit word, where U is a sign of the displacement and the displacement itself is encoded as its absolute
+ //! value.
+ kAArch32_U23_0To3At0_4To7At8,
+
+ //! AArch32 offset format that encodes a signed 25-bit offset as:
+ //!
+ //! `|.......|imm[0]|imm[24:1]|`
+ //!
+ //! in a 32-bit word.
+ kAArch32_1To24At0_0At24,
+
//! Maximum value of `OffsetFormatType`.
- kMaxValue = kAArch64_ADRP
+ kMaxValue = kAArch32_1To24At0_0At24
};
//! Provides information about formatting offsets, absolute addresses, or their parts. Offset format is used by both
@@ -348,26 +419,35 @@ struct OffsetFormat {
//! \{
//! Returns the type of the offset.
- inline OffsetType type() const noexcept { return _type; }
+ ASMJIT_INLINE_NODEBUG OffsetType type() const noexcept { return _type; }
- //! Returns flags.
- inline uint32_t flags() const noexcept { return _flags; }
+ //! Returns whether the offset is encoded as an absolute value of the offset with additional field(s) that represent
+ //! the sign (AArch32 U/N fields in the opcode).
+ //!
+ //! If true, the offset itself is always positive and a separate U/N field is used to indicate the sign of the offset
+ //! (usually `U==1` means ADD, but sometimes `N==1` means negative offset, which implies SUB).
+ ASMJIT_INLINE_NODEBUG bool hasSignBit() const noexcept {
+ return _type == OffsetType::kThumb32_ADR ||
+ _type == OffsetType::kAArch32_ADR ||
+ _type == OffsetType::kAArch32_U23_SignedOffset ||
+ _type == OffsetType::kAArch32_U23_0To3At0_4To7At8;
+ }
+ //! Returns flags.
+ ASMJIT_INLINE_NODEBUG uint32_t flags() const noexcept { return _flags; }
//! Returns the size of the region/instruction where the offset is encoded.
- inline uint32_t regionSize() const noexcept { return _regionSize; }
-
+ ASMJIT_INLINE_NODEBUG uint32_t regionSize() const noexcept { return _regionSize; }
//! Returns the offset of the word relative to the start of the region where the offset is.
- inline uint32_t valueOffset() const noexcept { return _valueOffset; }
-
+ ASMJIT_INLINE_NODEBUG uint32_t valueOffset() const noexcept { return _valueOffset; }
//! Returns the size of the data-type (word) that contains the offset, in bytes.
- inline uint32_t valueSize() const noexcept { return _valueSize; }
+ ASMJIT_INLINE_NODEBUG uint32_t valueSize() const noexcept { return _valueSize; }
//! Returns the count of bits of the offset value in the data it's stored in.
- inline uint32_t immBitCount() const noexcept { return _immBitCount; }
+ ASMJIT_INLINE_NODEBUG uint32_t immBitCount() const noexcept { return _immBitCount; }
//! Returns the bit-shift of the offset value in the data it's stored in.
- inline uint32_t immBitShift() const noexcept { return _immBitShift; }
+ ASMJIT_INLINE_NODEBUG uint32_t immBitShift() const noexcept { return _immBitShift; }
//! 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; }
+ ASMJIT_INLINE_NODEBUG uint32_t immDiscardLsb() const noexcept { return _immDiscardLsb; }
//! Resets this offset format to a simple data value of `dataSize` bytes.
//!
@@ -456,18 +536,18 @@ struct RelocEntry {
//! \name Accessors
//! \{
- inline uint32_t id() const noexcept { return _id; }
+ ASMJIT_INLINE_NODEBUG uint32_t id() const noexcept { return _id; }
- inline RelocType relocType() const noexcept { return _relocType; }
- inline const OffsetFormat& format() const noexcept { return _format; }
+ ASMJIT_INLINE_NODEBUG RelocType relocType() const noexcept { return _relocType; }
+ ASMJIT_INLINE_NODEBUG const OffsetFormat& format() const noexcept { return _format; }
- inline uint32_t sourceSectionId() const noexcept { return _sourceSectionId; }
- inline uint32_t targetSectionId() const noexcept { return _targetSectionId; }
+ ASMJIT_INLINE_NODEBUG uint32_t sourceSectionId() const noexcept { return _sourceSectionId; }
+ ASMJIT_INLINE_NODEBUG uint32_t targetSectionId() const noexcept { return _targetSectionId; }
- inline uint64_t sourceOffset() const noexcept { return _sourceOffset; }
- inline uint64_t payload() const noexcept { return _payload; }
+ ASMJIT_INLINE_NODEBUG uint64_t sourceOffset() const noexcept { return _sourceOffset; }
+ ASMJIT_INLINE_NODEBUG uint64_t payload() const noexcept { return _payload; }
- Expression* payloadAsExpression() const noexcept {
+ ASMJIT_INLINE_NODEBUG Expression* payloadAsExpression() const noexcept {
return reinterpret_cast<Expression*>(uintptr_t(_payload));
}
@@ -562,53 +642,53 @@ public:
// 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; }
+ ASMJIT_INLINE_NODEBUG uint32_t id() const noexcept { return _customData; }
//! Sets label id (internal, used only by `CodeHolder`).
- inline void _setId(uint32_t id) noexcept { _customData = id; }
+ ASMJIT_INLINE_NODEBUG void _setId(uint32_t id) noexcept { _customData = id; }
//! Returns label type.
- inline LabelType type() const noexcept { return _type; }
+ ASMJIT_INLINE_NODEBUG LabelType type() const noexcept { return _type; }
//! Tests whether the label has a parent label.
- inline bool hasParent() const noexcept { return _parentId != Globals::kInvalidId; }
+ ASMJIT_INLINE_NODEBUG bool hasParent() const noexcept { return _parentId != Globals::kInvalidId; }
//! Returns label's parent id.
- inline uint32_t parentId() const noexcept { return _parentId; }
+ ASMJIT_INLINE_NODEBUG uint32_t parentId() const noexcept { return _parentId; }
//! Returns the section where the label was bound.
//!
//! If the label was not yet bound the return value is `nullptr`.
- inline Section* section() const noexcept { return _section; }
+ ASMJIT_INLINE_NODEBUG Section* section() const noexcept { return _section; }
//! Tests whether the label has name.
- inline bool hasName() const noexcept { return !_name.empty(); }
+ ASMJIT_INLINE_NODEBUG bool hasName() const noexcept { return !_name.empty(); }
//! Returns the label's name.
//!
//! \note Local labels will return their local name without their parent part, for example ".L1".
- inline const char* name() const noexcept { return _name.data(); }
+ ASMJIT_INLINE_NODEBUG 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()`.
- inline uint32_t nameSize() const noexcept { return _name.size(); }
+ ASMJIT_INLINE_NODEBUG uint32_t nameSize() const noexcept { return _name.size(); }
//! Returns links associated with this label.
- inline LabelLink* links() const noexcept { return _links; }
+ ASMJIT_INLINE_NODEBUG LabelLink* links() const noexcept { return _links; }
//! Tests whether the label is bound.
- inline bool isBound() const noexcept { return _section != nullptr; }
+ ASMJIT_INLINE_NODEBUG bool isBound() const noexcept { return _section != nullptr; }
//! Tests whether the label is bound to a the given `sectionId`.
- inline bool isBoundTo(Section* section) const noexcept { return _section == section; }
+ ASMJIT_INLINE_NODEBUG bool isBoundTo(Section* section) const noexcept { return _section == section; }
//! Returns the label offset (only useful if the label is bound).
- inline uint64_t offset() const noexcept { return _offset; }
+ ASMJIT_INLINE_NODEBUG uint64_t offset() const noexcept { return _offset; }
//! 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()`.
- inline uint32_t hashCode() const noexcept { return _hashCode; }
+ ASMJIT_INLINE_NODEBUG uint32_t hashCode() const noexcept { return _hashCode; }
//! \}
};
@@ -640,6 +720,8 @@ public:
//! Environment information.
Environment _environment;
+ //! CPU features of the target architecture.
+ CpuFeatures _cpuFeatures;
//! Base address or \ref Globals::kNoBaseAddress.
uint64_t _baseAddress;
@@ -685,7 +767,7 @@ public:
ASMJIT_API explicit CodeHolder(const Support::Temporary* temporary = nullptr) noexcept;
//! \overload
- inline explicit CodeHolder(const Support::Temporary& temporary) noexcept
+ ASMJIT_INLINE_NODEBUG explicit CodeHolder(const Support::Temporary& temporary) noexcept
: CodeHolder(&temporary) {}
//! Destroys the CodeHolder and frees all resources it has allocated.
@@ -694,10 +776,12 @@ public:
//! Tests whether the `CodeHolder` has been initialized.
//!
//! Emitters can be only attached to initialized `CodeHolder` instances.
- inline bool isInitialized() const noexcept { return _environment.isInitialized(); }
+ ASMJIT_INLINE_NODEBUG bool isInitialized() const noexcept { return _environment.isInitialized(); }
//! 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;
+ //! Initializes CodeHolder to hold code described by the given `environment`, `cpuFeatures`, and `baseAddress`.
+ ASMJIT_API Error init(const Environment& environment, const CpuFeatures& cpuFeatures, uint64_t baseAddress = Globals::kNoBaseAddress) noexcept;
//! Detaches all code-generators attached and resets the `CodeHolder`.
ASMJIT_API void reset(ResetPolicy resetPolicy = ResetPolicy::kSoft) noexcept;
@@ -721,7 +805,7 @@ public:
//! \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); }
+ ASMJIT_INLINE_NODEBUG ZoneAllocator* allocator() const noexcept { return const_cast<ZoneAllocator*>(&_allocator); }
//! \}
@@ -729,17 +813,20 @@ public:
//! \{
//! Returns the target environment information.
- inline const Environment& environment() const noexcept { return _environment; }
+ ASMJIT_INLINE_NODEBUG const Environment& environment() const noexcept { return _environment; }
//! Returns the target architecture.
- inline Arch arch() const noexcept { return environment().arch(); }
+ ASMJIT_INLINE_NODEBUG Arch arch() const noexcept { return environment().arch(); }
//! Returns the target sub-architecture.
- inline SubArch subArch() const noexcept { return environment().subArch(); }
+ ASMJIT_INLINE_NODEBUG SubArch subArch() const noexcept { return environment().subArch(); }
+
+ //! Returns the minimum CPU features of the target architecture.
+ ASMJIT_INLINE_NODEBUG const CpuFeatures& cpuFeatures() const noexcept { return _cpuFeatures; }
//! Tests whether a static base-address is set.
- inline bool hasBaseAddress() const noexcept { return _baseAddress != Globals::kNoBaseAddress; }
+ ASMJIT_INLINE_NODEBUG bool hasBaseAddress() const noexcept { return _baseAddress != Globals::kNoBaseAddress; }
//! Returns a static base-address or \ref Globals::kNoBaseAddress, if not set.
- inline uint64_t baseAddress() const noexcept { return _baseAddress; }
+ ASMJIT_INLINE_NODEBUG uint64_t baseAddress() const noexcept { return _baseAddress; }
//! \}
@@ -747,7 +834,7 @@ public:
//! \{
//! Returns a vector of attached emitters.
- inline const ZoneVector<BaseEmitter*>& emitters() const noexcept { return _emitters; }
+ ASMJIT_INLINE_NODEBUG const ZoneVector<BaseEmitter*>& emitters() const noexcept { return _emitters; }
//! \}
@@ -755,23 +842,23 @@ public:
//! \{
//! Returns the attached logger.
- inline Logger* logger() const noexcept { return _logger; }
+ ASMJIT_INLINE_NODEBUG 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;
//! Resets the logger to none.
- inline void resetLogger() noexcept { setLogger(nullptr); }
+ ASMJIT_INLINE_NODEBUG void resetLogger() noexcept { setLogger(nullptr); }
//! \name Error Handling
//! \{
//! Tests whether the CodeHolder has an attached error handler, see \ref ErrorHandler.
- inline bool hasErrorHandler() const noexcept { return _errorHandler != nullptr; }
+ ASMJIT_INLINE_NODEBUG bool hasErrorHandler() const noexcept { return _errorHandler != nullptr; }
//! Returns the attached error handler.
- inline ErrorHandler* errorHandler() const noexcept { return _errorHandler; }
+ ASMJIT_INLINE_NODEBUG ErrorHandler* errorHandler() const noexcept { return _errorHandler; }
//! Attach an error handler to this `CodeHolder`.
ASMJIT_API void setErrorHandler(ErrorHandler* errorHandler) noexcept;
//! Resets the error handler to none.
- inline void resetErrorHandler() noexcept { setErrorHandler(nullptr); }
+ ASMJIT_INLINE_NODEBUG void resetErrorHandler() noexcept { setErrorHandler(nullptr); }
//! \}
@@ -794,14 +881,14 @@ public:
//! \{
//! Returns an array of `Section*` records.
- inline const ZoneVector<Section*>& sections() const noexcept { return _sections; }
+ ASMJIT_INLINE_NODEBUG const ZoneVector<Section*>& sections() const noexcept { return _sections; }
//! Returns an array of `Section*` records sorted according to section order first, then section id.
- inline const ZoneVector<Section*>& sectionsByOrder() const noexcept { return _sectionsByOrder; }
+ ASMJIT_INLINE_NODEBUG const ZoneVector<Section*>& sectionsByOrder() const noexcept { return _sectionsByOrder; }
//! Returns the number of sections.
- inline uint32_t sectionCount() const noexcept { return _sections.size(); }
+ ASMJIT_INLINE_NODEBUG uint32_t sectionCount() const noexcept { return _sections.size(); }
//! Tests whether the given `sectionId` is valid.
- inline bool isSectionValid(uint32_t sectionId) const noexcept { return sectionId < _sections.size(); }
+ ASMJIT_INLINE_NODEBUG bool isSectionValid(uint32_t sectionId) const noexcept { return sectionId < _sections.size(); }
//! Creates a new section and return its pointer in `sectionOut`.
//!
@@ -809,7 +896,7 @@ public:
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]; }
+ ASMJIT_INLINE_NODEBUG Section* sectionById(uint32_t sectionId) const noexcept { return _sections[sectionId]; }
//! Returns section-id that matches the given `name`.
//!
@@ -819,10 +906,10 @@ public:
//! Returns '.text' section (section that commonly represents code).
//!
//! \note Text section is always the first section in \ref CodeHolder::sections() array.
- inline Section* textSection() const noexcept { return _sections[0]; }
+ ASMJIT_INLINE_NODEBUG Section* textSection() const noexcept { return _sections[0]; }
//! Tests whether '.addrtab' section exists.
- inline bool hasAddressTable() const noexcept { return _addressTableSection != nullptr; }
+ ASMJIT_INLINE_NODEBUG bool hasAddressTable() const noexcept { return _addressTableSection != nullptr; }
//! Returns '.addrtab' section.
//!
@@ -830,7 +917,7 @@ public:
//! addresses that cannot be encoded in instructions like 'jmp' or 'call'.
//!
//! \note This section is created on demand, the returned pointer can be null.
- inline Section* addressTableSection() const noexcept { return _addressTableSection; }
+ ASMJIT_INLINE_NODEBUG Section* addressTableSection() const noexcept { return _addressTableSection; }
//! Ensures that '.addrtab' section exists (creates it if it doesn't) and
//! returns it. Can return `nullptr` on out of memory condition.
@@ -843,7 +930,7 @@ public:
//! 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.
+ //! address table. Inserting address into address table without creating a particular relocation entry makes no sense.
ASMJIT_API Error addAddressToAddressTable(uint64_t address) noexcept;
//! \}
@@ -852,40 +939,40 @@ public:
//! \{
//! Returns array of `LabelEntry*` records.
- inline const ZoneVector<LabelEntry*>& labelEntries() const noexcept { return _labelEntries; }
+ ASMJIT_INLINE_NODEBUG const ZoneVector<LabelEntry*>& labelEntries() const noexcept { return _labelEntries; }
//! Returns number of labels created.
- inline uint32_t labelCount() const noexcept { return _labelEntries.size(); }
+ ASMJIT_INLINE_NODEBUG uint32_t labelCount() const noexcept { return _labelEntries.size(); }
//! Tests whether the label having `id` is valid (i.e. created by `newLabelEntry()`).
- inline bool isLabelValid(uint32_t labelId) const noexcept {
+ ASMJIT_INLINE_NODEBUG bool isLabelValid(uint32_t labelId) const noexcept {
return labelId < _labelEntries.size();
}
//! Tests whether the `label` is valid (i.e. created by `newLabelEntry()`).
- inline bool isLabelValid(const Label& label) const noexcept {
+ ASMJIT_INLINE_NODEBUG bool isLabelValid(const Label& label) const noexcept {
return label.id() < _labelEntries.size();
}
//! \overload
- inline bool isLabelBound(uint32_t labelId) const noexcept {
+ ASMJIT_INLINE_NODEBUG bool isLabelBound(uint32_t labelId) const noexcept {
return isLabelValid(labelId) && _labelEntries[labelId]->isBound();
}
//! Tests whether the `label` is already bound.
//!
//! Returns `false` if the `label` is not valid.
- inline bool isLabelBound(const Label& label) const noexcept {
+ ASMJIT_INLINE_NODEBUG bool isLabelBound(const Label& label) const noexcept {
return isLabelBound(label.id());
}
//! Returns LabelEntry of the given label `id`.
- inline LabelEntry* labelEntry(uint32_t labelId) const noexcept {
+ ASMJIT_INLINE_NODEBUG LabelEntry* labelEntry(uint32_t labelId) const noexcept {
return isLabelValid(labelId) ? _labelEntries[labelId] : static_cast<LabelEntry*>(nullptr);
}
//! Returns LabelEntry of the given `label`.
- inline LabelEntry* labelEntry(const Label& label) const noexcept {
+ ASMJIT_INLINE_NODEBUG LabelEntry* labelEntry(const Label& label) const noexcept {
return labelEntry(label.id());
}
@@ -893,13 +980,13 @@ public:
//!
//! 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_INLINE_NODEBUG uint64_t labelOffset(uint32_t labelId) const noexcept {
ASMJIT_ASSERT(isLabelValid(labelId));
return _labelEntries[labelId]->offset();
}
//! \overload
- inline uint64_t labelOffset(const Label& label) const noexcept {
+ ASMJIT_INLINE_NODEBUG uint64_t labelOffset(const Label& label) const noexcept {
return labelOffset(label.id());
}
@@ -944,7 +1031,7 @@ public:
//!
//! If the named label doesn't a default constructed \ref Label is returned,
//! which has its id set to \ref Globals::kInvalidId.
- inline Label labelByName(const char* name, size_t nameSize = SIZE_MAX, uint32_t parentId = Globals::kInvalidId) noexcept {
+ ASMJIT_INLINE_NODEBUG Label labelByName(const char* name, size_t nameSize = SIZE_MAX, uint32_t parentId = Globals::kInvalidId) noexcept {
return Label(labelIdByName(name, nameSize, parentId));
}
@@ -954,9 +1041,9 @@ public:
ASMJIT_API uint32_t labelIdByName(const char* name, size_t nameSize = SIZE_MAX, uint32_t parentId = Globals::kInvalidId) noexcept;
//! Tests whether there are any unresolved label links.
- inline bool hasUnresolvedLinks() const noexcept { return _unresolvedLinkCount != 0; }
+ ASMJIT_INLINE_NODEBUG bool hasUnresolvedLinks() const noexcept { return _unresolvedLinkCount != 0; }
//! Returns the number of label links, which are unresolved.
- inline size_t unresolvedLinkCount() const noexcept { return _unresolvedLinkCount; }
+ ASMJIT_INLINE_NODEBUG size_t unresolvedLinkCount() const noexcept { return _unresolvedLinkCount; }
//! Creates a new label-link used to store information about yet unbound labels.
//!
@@ -979,12 +1066,12 @@ public:
//! \{
//! Tests whether the code contains relocation entries.
- inline bool hasRelocEntries() const noexcept { return !_relocations.empty(); }
+ ASMJIT_INLINE_NODEBUG bool hasRelocEntries() const noexcept { return !_relocations.empty(); }
//! Returns array of `RelocEntry*` records.
- inline const ZoneVector<RelocEntry*>& relocEntries() const noexcept { return _relocations; }
+ ASMJIT_INLINE_NODEBUG const ZoneVector<RelocEntry*>& relocEntries() const noexcept { return _relocations; }
//! Returns a RelocEntry of the given `id`.
- inline RelocEntry* relocEntry(uint32_t id) const noexcept { return _relocations[id]; }
+ ASMJIT_INLINE_NODEBUG RelocEntry* relocEntry(uint32_t id) const noexcept { return _relocations[id]; }
//! Creates a new relocation entry of type `relocType`.
//!
@@ -1011,7 +1098,8 @@ public:
//! 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.
+ //! copied to such base address, it's just an absolute value used by the relocation code to resolve all stored
+ //! relocations.
//!
//! \note This should never be called more than once.
ASMJIT_API Error relocateToBase(uint64_t baseAddress) noexcept;
diff --git a/3rdparty/asmjit/src/asmjit/core/codewriter.cpp b/3rdparty/asmjit/src/asmjit/core/codewriter.cpp
index 1babc5f172e..2ee5b38cda5 100644
--- a/3rdparty/asmjit/src/asmjit/core/codewriter.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/codewriter.cpp
@@ -6,6 +6,7 @@
#include "../core/api-build_p.h"
#include "../core/codeholder.h"
#include "../core/codewriter_p.h"
+#include "../arm/armutils.h"
ASMJIT_BEGIN_NAMESPACE
@@ -19,9 +20,20 @@ bool CodeWriterUtils::encodeOffset32(uint32_t* dst, int64_t offset64, const Offs
return false;
uint32_t value;
+ uint32_t u = 0;
+ bool unsignedLogic = format.type() == OffsetType::kUnsignedOffset;
+
+ // First handle all offsets that use additional field for their sign and the offset is encoded as its
+ // absolute value.
+ if (format.hasSignBit()) {
+ u = uint32_t(offset64 >= 0);
+ if (u == 0)
+ offset64 = -offset64;
+ unsignedLogic = true;
+ }
// First handle all unsigned offset types.
- if (format.type() == OffsetType::kUnsignedOffset) {
+ if (unsignedLogic) {
if (discardLsb) {
ASMJIT_ASSERT(discardLsb <= 32);
if ((offset64 & Support::lsbMask<uint32_t>(discardLsb)) != 0)
@@ -57,6 +69,97 @@ bool CodeWriterUtils::encodeOffset32(uint32_t* dst, int64_t offset64, const Offs
return true;
}
+ // Opcode: {.....|imm:1|..N.N|......|imm:3|....|imm:8}
+ case OffsetType::kThumb32_ADR: {
+ // Sanity checks.
+ if (format.valueSize() != 4 || bitCount != 12 || bitShift != 0)
+ return false;
+
+ uint32_t imm8 = (value & 0x00FFu);
+ uint32_t imm3 = (value & 0x0700u) << (12 - 8);
+ uint32_t imm1 = (value & 0x0800u) << (26 - 11);
+ uint32_t n = u ^ 1u;
+
+ *dst = imm8 | imm3 | imm1 | (n << 21) | (n << 23);
+ return true;
+ }
+
+ // Opcode: {....|.|imm[22]|imm[19:10]|..|ja|.|jb|imm[9:0]|.}
+ case OffsetType::kThumb32_BLX:
+ // The calculation is the same as `B`, but the first LSB bit must be zero, so account for that.
+ value <<= 1;
+ ASMJIT_FALLTHROUGH;
+
+ // Opcode: {....|.|imm[23]|imm[20:11]|..|ja|.|jb|imm[10:0]}
+ case OffsetType::kThumb32_B: {
+ // Sanity checks.
+ if (format.valueSize() != 4)
+ return false;
+
+ uint32_t ia = (value & 0x0007FFu);
+ uint32_t ib = (value & 0x1FF800u) << (16 - 11);
+ uint32_t ic = (value & 0x800000u) << (26 - 23);
+ uint32_t ja = ((~value >> 23) ^ (value >> 22)) & 1u;
+ uint32_t jb = ((~value >> 23) ^ (value >> 21)) & 1u;
+
+ *dst = ia | ib | ic | (ja << 14) | (jb << 11);
+ return true;
+ }
+
+ // Opcode: {....|.|imm[19]|....|imm[16:11]|..|ja|.|jb|imm[10:0]}
+ case OffsetType::kThumb32_BCond: {
+ // Sanity checks.
+ if (format.valueSize() != 4 || bitCount != 20 || bitShift != 0)
+ return false;
+
+ uint32_t ia = (value & 0x0007FFu);
+ uint32_t ib = (value & 0x01F800u) << (16 - 11);
+ uint32_t ic = (value & 0x080000u) << (26 - 19);
+ uint32_t ja = ((~value >> 19) ^ (value >> 22)) & 1u;
+ uint32_t jb = ((~value >> 19) ^ (value >> 21)) & 1u;
+
+ *dst = ia | ib | ic | (ja << 14) | (jb << 11);
+ return true;
+ }
+
+ case OffsetType::kAArch32_ADR: {
+ uint32_t encodedImm;
+ if (!arm::Utils::encodeAArch32Imm(value, &encodedImm))
+ return false;
+
+ *dst = (Support::bitMask(22) << u) | (encodedImm << bitShift);
+ return true;
+ }
+
+ case OffsetType::kAArch32_U23_SignedOffset: {
+ *dst = (value << bitShift) | (u << 23);
+ return true;
+ }
+
+ case OffsetType::kAArch32_U23_0To3At0_4To7At8: {
+ // Sanity checks.
+ if (format.valueSize() != 4 || bitCount != 8 || bitShift != 0)
+ return false;
+
+ uint32_t immLo = (value & 0x0Fu);
+ uint32_t immHi = (value & 0xF0u) << (8 - 4);
+
+ *dst = immLo | immHi | (u << 23);
+ return true;
+ }
+
+ case OffsetType::kAArch32_1To24At0_0At24: {
+ // Sanity checks.
+ if (format.valueSize() != 4 || bitCount != 25 || bitShift != 0)
+ return false;
+
+ uint32_t immLo = (value & 0x0000001u) << 24;
+ uint32_t immHi = (value & 0x1FFFFFEu) >> 1;
+
+ *dst = immLo | immHi;
+ return true;
+ }
+
case OffsetType::kAArch64_ADR:
case OffsetType::kAArch64_ADRP: {
// Sanity checks.
diff --git a/3rdparty/asmjit/src/asmjit/core/compiler.cpp b/3rdparty/asmjit/src/asmjit/core/compiler.cpp
index b1c6b803b29..b09ae396608 100644
--- a/3rdparty/asmjit/src/asmjit/core/compiler.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/compiler.cpp
@@ -7,6 +7,7 @@
#ifndef ASMJIT_NO_COMPILER
#include "../core/assembler.h"
+#include "../core/builder_p.h"
#include "../core/compiler.h"
#include "../core/cpuinfo.h"
#include "../core/logger.h"
@@ -103,9 +104,13 @@ Error BaseCompiler::newFuncNode(FuncNode** out, const FuncSignature& signature)
}
Error BaseCompiler::addFuncNode(FuncNode** out, const FuncSignature& signature) {
+ State state = _grabState();
+
ASMJIT_PROPAGATE(newFuncNode(out, signature));
ASMJIT_ASSUME(*out != nullptr);
+ BaseBuilder_assignInlineComment(this, *out, state.comment);
+
addFunc(*out);
return kErrorOk;
}
@@ -127,7 +132,13 @@ Error BaseCompiler::newFuncRetNode(FuncRetNode** out, const Operand_& o0, const
}
Error BaseCompiler::addFuncRetNode(FuncRetNode** out, const Operand_& o0, const Operand_& o1) {
+ State state = _grabState();
+
ASMJIT_PROPAGATE(newFuncRetNode(out, o0, o1));
+ ASMJIT_ASSUME(*out != nullptr);
+
+ BaseBuilder_assignInlineComment(this, *out, state.comment);
+
addNode(*out);
return kErrorOk;
}
@@ -146,6 +157,7 @@ FuncNode* BaseCompiler::addFunc(FuncNode* func) {
Error BaseCompiler::endFunc() {
FuncNode* func = _func;
+ resetState();
if (ASMJIT_UNLIKELY(!func))
return reportError(DebugUtils::errored(kErrorInvalidState));
@@ -196,7 +208,12 @@ Error BaseCompiler::newInvokeNode(InvokeNode** out, InstId instId, const Operand
}
Error BaseCompiler::addInvokeNode(InvokeNode** out, InstId instId, const Operand_& o0, const FuncSignature& signature) {
+ State state = _grabState();
+
ASMJIT_PROPAGATE(newInvokeNode(out, instId, o0, signature));
+ ASMJIT_ASSUME(*out != nullptr);
+
+ BaseBuilder_assignInstState(this, *out, state);
addNode(*out);
return kErrorOk;
}
@@ -231,7 +248,7 @@ Error BaseCompiler::newVirtReg(VirtReg** out, TypeId typeId, OperandSignature si
uint32_t size = TypeUtils::sizeOf(typeId);
uint32_t alignment = Support::min<uint32_t>(size, 64);
- vReg = new(vReg) VirtReg(signature, Operand::indexToVirtId(index), size, alignment, typeId);
+ vReg = new(Support::PlacementNew{vReg}) VirtReg(signature, Operand::indexToVirtId(index), size, alignment, typeId);
#ifndef ASMJIT_NO_LOGGING
if (name && name[0] != '\0')
@@ -473,7 +490,7 @@ Error BaseCompiler::newJumpNode(JumpNode** out, InstId instId, InstOptions instO
if (ASMJIT_UNLIKELY(!node))
return reportError(DebugUtils::errored(kErrorOutOfMemory));
- node = new(node) JumpNode(this, instId, instOptions, opCount, annotation);
+ node = new(Support::PlacementNew{node}) JumpNode(this, instId, instOptions, opCount, annotation);
node->setOp(0, o0);
node->resetOpRange(opCount, JumpNode::kBaseOpCapacity);
@@ -481,20 +498,13 @@ Error BaseCompiler::newJumpNode(JumpNode** out, InstId instId, InstOptions instO
}
Error BaseCompiler::emitAnnotatedJump(InstId instId, const Operand_& o0, JumpAnnotation* annotation) {
- InstOptions options = instOptions() | forcedInstOptions();
- RegOnly extra = extraReg();
- const char* comment = inlineComment();
-
- resetInstOptions();
- resetInlineComment();
- resetExtraReg();
+ State state = _grabState();
JumpNode* node;
- ASMJIT_PROPAGATE(newJumpNode(&node, instId, options, o0, annotation));
+ ASMJIT_PROPAGATE(newJumpNode(&node, instId, state.options, o0, annotation));
- node->setExtraReg(extra);
- if (comment)
- node->setInlineComment(static_cast<char*>(_dataZone.dup(comment, strlen(comment), true)));
+ node->setExtraReg(state.extraReg);
+ BaseBuilder_assignInlineComment(this, node, state.comment);
addNode(node);
return kErrorOk;
@@ -577,6 +587,12 @@ Error FuncPass::run(Zone* zone, Logger* logger) {
return kErrorOk;
}
+// [[pure virtual]]
+Error FuncPass::runOnFunction(Zone* zone, Logger* logger, FuncNode* func) {
+ DebugUtils::unused(zone, logger, func);
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
ASMJIT_END_NAMESPACE
#endif // !ASMJIT_NO_COMPILER
diff --git a/3rdparty/asmjit/src/asmjit/core/compiler.h b/3rdparty/asmjit/src/asmjit/core/compiler.h
index 709fd952acc..7d4b47c4597 100644
--- a/3rdparty/asmjit/src/asmjit/core/compiler.h
+++ b/3rdparty/asmjit/src/asmjit/core/compiler.h
@@ -47,6 +47,7 @@ class InvokeNode;
//! Check out architecture specific compilers for more details and examples:
//!
//! - \ref x86::Compiler - X86/X64 compiler implementation.
+//! - \ref a64::Compiler - AArch64 compiler implementation.
class ASMJIT_VIRTAPI BaseCompiler : public BaseBuilder {
public:
ASMJIT_NONCOPYABLE(BaseCompiler)
@@ -77,7 +78,7 @@ public:
//! Creates a new `BaseCompiler` instance.
ASMJIT_API BaseCompiler() noexcept;
//! Destroys the `BaseCompiler` instance.
- ASMJIT_API virtual ~BaseCompiler() noexcept;
+ ASMJIT_API ~BaseCompiler() noexcept override;
//! \}
@@ -95,7 +96,7 @@ public:
ASMJIT_API Error addFuncRetNode(FuncRetNode** ASMJIT_NONNULL(out), const Operand_& o0, const Operand_& o1);
//! Returns the current function.
- inline FuncNode* func() const noexcept { return _func; }
+ ASMJIT_INLINE_NODEBUG FuncNode* func() const noexcept { return _func; }
//! Creates a new \ref FuncNode with the given `signature` and returns it.
inline FuncNode* newFunc(const FuncSignature& signature) {
@@ -162,6 +163,8 @@ public:
//!
//! \note This version accepts a snprintf() format `fmt` followed by a variadic arguments.
ASMJIT_API Error _newRegFmt(BaseReg* ASMJIT_NONNULL(out), TypeId typeId, const char* fmt, ...);
+ //! \overload
+ inline Error _newRegFmt(BaseReg* ASMJIT_NONNULL(out), TypeId typeId) { return _newRegFmt(out, typeId, nullptr); }
//! Creates a new virtual register compatible with the provided reference register `ref`.
ASMJIT_API Error _newReg(BaseReg* ASMJIT_NONNULL(out), const BaseReg& ref, const char* name = nullptr);
@@ -172,12 +175,12 @@ public:
ASMJIT_API Error _newRegFmt(BaseReg* ASMJIT_NONNULL(out), const BaseReg& ref, const char* fmt, ...);
//! Tests whether the given `id` is a valid virtual register id.
- inline bool isVirtIdValid(uint32_t id) const noexcept {
+ ASMJIT_INLINE_NODEBUG bool isVirtIdValid(uint32_t id) const noexcept {
uint32_t index = Operand::virtIdToIndex(id);
return index < _vRegArray.size();
}
//! Tests whether the given `reg` is a virtual register having a valid id.
- inline bool isVirtRegValid(const BaseReg& reg) const noexcept {
+ ASMJIT_INLINE_NODEBUG bool isVirtRegValid(const BaseReg& reg) const noexcept {
return isVirtIdValid(reg.id());
}
@@ -188,16 +191,16 @@ public:
}
//! Returns \ref VirtReg associated with the given `reg`.
- inline VirtReg* virtRegByReg(const BaseReg& reg) const noexcept { return virtRegById(reg.id()); }
+ ASMJIT_INLINE_NODEBUG VirtReg* virtRegByReg(const BaseReg& reg) const noexcept { return virtRegById(reg.id()); }
//! 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.
- inline VirtReg* virtRegByIndex(uint32_t index) const noexcept { return _vRegArray[index]; }
+ ASMJIT_INLINE_NODEBUG VirtReg* virtRegByIndex(uint32_t index) const noexcept { return _vRegArray[index]; }
//! Returns an array of all virtual registers managed by the Compiler.
- inline const ZoneVector<VirtReg*>& virtRegs() const noexcept { return _vRegArray; }
+ ASMJIT_INLINE_NODEBUG const ZoneVector<VirtReg*>& virtRegs() const noexcept { return _vRegArray; }
//! \name Stack
//! \{
@@ -211,7 +214,7 @@ public:
ASMJIT_API Error setStackSize(uint32_t virtId, uint32_t newSize, uint32_t newAlignment = 0);
//! Updates the stack size of a stack created by `_newStack()`.
- inline Error setStackSize(const BaseMem& mem, uint32_t newSize, uint32_t newAlignment = 0) {
+ ASMJIT_INLINE_NODEBUG Error setStackSize(const BaseMem& mem, uint32_t newSize, uint32_t newAlignment = 0) {
return setStackSize(mem.id(), newSize, newAlignment);
}
@@ -239,7 +242,7 @@ public:
//! \name Jump Annotations
//! \{
- inline const ZoneVector<JumpAnnotation*>& jumpAnnotations() const noexcept {
+ ASMJIT_INLINE_NODEBUG const ZoneVector<JumpAnnotation*>& jumpAnnotations() const noexcept {
return _jumpAnnotations;
}
@@ -286,7 +289,7 @@ public:
//! \name Construction & Destruction
//! \{
- inline JumpAnnotation(BaseCompiler* ASMJIT_NONNULL(compiler), uint32_t annotationId) noexcept
+ ASMJIT_INLINE_NODEBUG JumpAnnotation(BaseCompiler* ASMJIT_NONNULL(compiler), uint32_t annotationId) noexcept
: _compiler(compiler),
_annotationId(annotationId) {}
@@ -296,16 +299,16 @@ public:
//! \{
//! Returns the compiler that owns this JumpAnnotation.
- inline BaseCompiler* compiler() const noexcept { return _compiler; }
+ ASMJIT_INLINE_NODEBUG BaseCompiler* compiler() const noexcept { return _compiler; }
//! Returns the annotation id.
- inline uint32_t annotationId() const noexcept { return _annotationId; }
+ ASMJIT_INLINE_NODEBUG uint32_t annotationId() const noexcept { return _annotationId; }
//! Returns a vector of label identifiers that lists all targets of the jump.
- const ZoneVector<uint32_t>& labelIds() const noexcept { return _labelIds; }
+ ASMJIT_INLINE_NODEBUG const ZoneVector<uint32_t>& labelIds() const noexcept { return _labelIds; }
//! Tests whether the given `label` is a target of this JumpAnnotation.
- inline bool hasLabel(const Label& label) const noexcept { return hasLabelId(label.id()); }
+ ASMJIT_INLINE_NODEBUG bool hasLabel(const Label& label) const noexcept { return hasLabelId(label.id()); }
//! Tests whether the given `labelId` is a target of this JumpAnnotation.
- inline bool hasLabelId(uint32_t labelId) const noexcept { return _labelIds.contains(labelId); }
+ ASMJIT_INLINE_NODEBUG bool hasLabelId(uint32_t labelId) const noexcept { return _labelIds.contains(labelId); }
//! \}
@@ -313,9 +316,9 @@ public:
//! \{
//! Adds the `label` to the list of targets of this JumpAnnotation.
- inline Error addLabel(const Label& label) noexcept { return addLabelId(label.id()); }
+ ASMJIT_INLINE_NODEBUG 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_INLINE_NODEBUG Error addLabelId(uint32_t labelId) noexcept { return _labelIds.append(&_compiler->_allocator, labelId); }
//! \}
};
@@ -325,7 +328,7 @@ public:
//! \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 {
+class JumpNode : public InstNodeWithOperands<InstNode::kBaseOpCapacity> {
public:
ASMJIT_NONCOPYABLE(JumpNode)
@@ -340,7 +343,7 @@ public:
//! \{
inline JumpNode(BaseCompiler* ASMJIT_NONNULL(cc), InstId instId, InstOptions options, uint32_t opCount, JumpAnnotation* annotation) noexcept
- : InstNode(cc, instId, options, opCount, kBaseOpCapacity),
+ : InstNodeWithOperands(cc, instId, options, opCount),
_annotation(annotation) {
setType(NodeType::kJump);
}
@@ -351,11 +354,11 @@ public:
//! \{
//! Tests whether this JumpNode has associated a \ref JumpAnnotation.
- inline bool hasAnnotation() const noexcept { return _annotation != nullptr; }
+ ASMJIT_INLINE_NODEBUG bool hasAnnotation() const noexcept { return _annotation != nullptr; }
//! Returns the \ref JumpAnnotation associated with this jump, or `nullptr`.
- inline JumpAnnotation* annotation() const noexcept { return _annotation; }
+ ASMJIT_INLINE_NODEBUG JumpAnnotation* annotation() const noexcept { return _annotation; }
//! Sets the \ref JumpAnnotation associated with this jump to `annotation`.
- inline void setAnnotation(JumpAnnotation* annotation) noexcept { _annotation = annotation; }
+ ASMJIT_INLINE_NODEBUG void setAnnotation(JumpAnnotation* annotation) noexcept { _annotation = annotation; }
//! \}
};
@@ -455,35 +458,35 @@ public:
//! \name Accessors
//! Returns function exit `LabelNode`.
- inline LabelNode* exitNode() const noexcept { return _exitNode; }
+ ASMJIT_INLINE_NODEBUG LabelNode* exitNode() const noexcept { return _exitNode; }
//! Returns function exit label.
- inline Label exitLabel() const noexcept { return _exitNode->label(); }
+ ASMJIT_INLINE_NODEBUG Label exitLabel() const noexcept { return _exitNode->label(); }
//! Returns "End of Func" sentinel node.
- inline SentinelNode* endNode() const noexcept { return _end; }
+ ASMJIT_INLINE_NODEBUG SentinelNode* endNode() const noexcept { return _end; }
//! Returns function detail.
- inline FuncDetail& detail() noexcept { return _funcDetail; }
+ ASMJIT_INLINE_NODEBUG FuncDetail& detail() noexcept { return _funcDetail; }
//! Returns function detail.
- inline const FuncDetail& detail() const noexcept { return _funcDetail; }
+ ASMJIT_INLINE_NODEBUG const FuncDetail& detail() const noexcept { return _funcDetail; }
//! Returns function frame.
- inline FuncFrame& frame() noexcept { return _frame; }
+ ASMJIT_INLINE_NODEBUG FuncFrame& frame() noexcept { return _frame; }
//! Returns function frame.
- inline const FuncFrame& frame() const noexcept { return _frame; }
+ ASMJIT_INLINE_NODEBUG const FuncFrame& frame() const noexcept { return _frame; }
//! Returns function attributes.
- inline FuncAttributes attributes() const noexcept { return _frame.attributes(); }
+ ASMJIT_INLINE_NODEBUG FuncAttributes attributes() const noexcept { return _frame.attributes(); }
//! Adds `attrs` to the function attributes.
- inline void addAttributes(FuncAttributes attrs) noexcept { _frame.addAttributes(attrs); }
+ ASMJIT_INLINE_NODEBUG void addAttributes(FuncAttributes attrs) noexcept { _frame.addAttributes(attrs); }
//! Returns arguments count.
- inline uint32_t argCount() const noexcept { return _funcDetail.argCount(); }
+ ASMJIT_INLINE_NODEBUG uint32_t argCount() const noexcept { return _funcDetail.argCount(); }
//! Returns argument packs.
- inline ArgPack* argPacks() const noexcept { return _args; }
+ ASMJIT_INLINE_NODEBUG ArgPack* argPacks() const noexcept { return _args; }
//! Tests whether the function has a return value.
- inline bool hasRet() const noexcept { return _funcDetail.hasRet(); }
+ ASMJIT_INLINE_NODEBUG bool hasRet() const noexcept { return _funcDetail.hasRet(); }
//! Returns argument pack at `argIndex`.
inline ArgPack& argPack(size_t argIndex) const noexcept {
@@ -531,7 +534,7 @@ public:
};
//! Function return, used by \ref BaseCompiler.
-class FuncRetNode : public InstNode {
+class FuncRetNode : public InstNodeWithOperands<InstNode::kBaseOpCapacity> {
public:
ASMJIT_NONCOPYABLE(FuncRetNode)
@@ -539,7 +542,8 @@ public:
//! \{
//! Creates a new `FuncRetNode` instance.
- inline FuncRetNode(BaseBuilder* ASMJIT_NONNULL(cb)) noexcept : InstNode(cb, BaseInst::kIdAbstract, InstOptions::kNone, 0) {
+ inline FuncRetNode(BaseBuilder* ASMJIT_NONNULL(cb)) noexcept
+ : InstNodeWithOperands(cb, BaseInst::kIdAbstract, InstOptions::kNone, 0) {
_any._nodeType = NodeType::kFuncRet;
}
@@ -547,12 +551,12 @@ public:
};
//! Function invocation, used by \ref BaseCompiler.
-class InvokeNode : public InstNode {
+class InvokeNode : public InstNodeWithOperands<InstNode::kBaseOpCapacity> {
public:
ASMJIT_NONCOPYABLE(InvokeNode)
//! 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
+ //! 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.
struct OperandPack {
//! Operands.
@@ -594,7 +598,7 @@ public:
//! Creates a new `InvokeNode` instance.
inline InvokeNode(BaseBuilder* ASMJIT_NONNULL(cb), InstId instId, InstOptions options) noexcept
- : InstNode(cb, instId, options, kBaseOpCapacity),
+ : InstNodeWithOperands(cb, instId, options, 0),
_funcDetail(),
_args(nullptr) {
setType(NodeType::kInvoke);
@@ -614,29 +618,29 @@ public:
}
//! Returns the function detail.
- inline FuncDetail& detail() noexcept { return _funcDetail; }
+ ASMJIT_INLINE_NODEBUG FuncDetail& detail() noexcept { return _funcDetail; }
//! Returns the function detail.
- inline const FuncDetail& detail() const noexcept { return _funcDetail; }
+ ASMJIT_INLINE_NODEBUG const FuncDetail& detail() const noexcept { return _funcDetail; }
//! Returns the target operand.
- inline Operand& target() noexcept { return _opArray[0].as<Operand>(); }
+ ASMJIT_INLINE_NODEBUG Operand& target() noexcept { return op(0); }
//! \overload
- inline const Operand& target() const noexcept { return _opArray[0].as<Operand>(); }
+ ASMJIT_INLINE_NODEBUG const Operand& target() const noexcept { return op(0); }
//! Returns the number of function return values.
- inline bool hasRet() const noexcept { return _funcDetail.hasRet(); }
+ ASMJIT_INLINE_NODEBUG bool hasRet() const noexcept { return _funcDetail.hasRet(); }
//! Returns the number of function arguments.
- inline uint32_t argCount() const noexcept { return _funcDetail.argCount(); }
+ ASMJIT_INLINE_NODEBUG uint32_t argCount() const noexcept { return _funcDetail.argCount(); }
//! Returns operand pack representing function return value(s).
- inline OperandPack& retPack() noexcept { return _rets; }
+ ASMJIT_INLINE_NODEBUG OperandPack& retPack() noexcept { return _rets; }
//! Returns operand pack representing function return value(s).
- inline const OperandPack& retPack() const noexcept { return _rets; }
+ ASMJIT_INLINE_NODEBUG const OperandPack& retPack() const noexcept { return _rets; }
//! Returns the return value at the given `valueIndex`.
- inline Operand& ret(size_t valueIndex = 0) noexcept { return _rets[valueIndex]; }
+ ASMJIT_INLINE_NODEBUG Operand& ret(size_t valueIndex = 0) noexcept { return _rets[valueIndex]; }
//! \overload
- inline const Operand& ret(size_t valueIndex = 0) const noexcept { return _rets[valueIndex]; }
+ ASMJIT_INLINE_NODEBUG const Operand& ret(size_t valueIndex = 0) const noexcept { return _rets[valueIndex]; }
//! Returns operand pack representing function return value(s).
inline OperandPack& argPack(size_t argIndex) noexcept {
@@ -669,17 +673,17 @@ public:
}
//! Sets the function return value at `valueIndex` to `reg`.
- inline void setRet(size_t valueIndex, const BaseReg& reg) noexcept { _setRet(valueIndex, reg); }
+ ASMJIT_INLINE_NODEBUG void setRet(size_t valueIndex, const BaseReg& reg) noexcept { _setRet(valueIndex, reg); }
//! Sets the first function argument in a value-pack at `argIndex` to `reg`.
- inline void setArg(size_t argIndex, const BaseReg& reg) noexcept { _setArg(argIndex, 0, reg); }
+ ASMJIT_INLINE_NODEBUG void setArg(size_t argIndex, const BaseReg& reg) noexcept { _setArg(argIndex, 0, reg); }
//! Sets the first function argument in a value-pack at `argIndex` to `imm`.
- inline void setArg(size_t argIndex, const Imm& imm) noexcept { _setArg(argIndex, 0, imm); }
+ ASMJIT_INLINE_NODEBUG void setArg(size_t argIndex, const Imm& imm) noexcept { _setArg(argIndex, 0, imm); }
//! Sets the function argument at `argIndex` and `valueIndex` to `reg`.
- inline void setArg(size_t argIndex, size_t valueIndex, const BaseReg& reg) noexcept { _setArg(argIndex, valueIndex, reg); }
+ ASMJIT_INLINE_NODEBUG void setArg(size_t argIndex, size_t valueIndex, const BaseReg& reg) noexcept { _setArg(argIndex, valueIndex, reg); }
//! Sets the function argument at `argIndex` and `valueIndex` to `imm`.
- inline void setArg(size_t argIndex, size_t valueIndex, const Imm& imm) noexcept { _setArg(argIndex, valueIndex, imm); }
+ ASMJIT_INLINE_NODEBUG void setArg(size_t argIndex, size_t valueIndex, const Imm& imm) noexcept { _setArg(argIndex, valueIndex, imm); }
//! \}
};
@@ -701,7 +705,7 @@ public:
//! \{
//! Returns the associated `BaseCompiler`.
- inline BaseCompiler* cc() const noexcept { return static_cast<BaseCompiler*>(_cb); }
+ ASMJIT_INLINE_NODEBUG BaseCompiler* cc() const noexcept { return static_cast<BaseCompiler*>(_cb); }
//! \}
@@ -712,7 +716,7 @@ public:
ASMJIT_API Error run(Zone* zone, Logger* logger) override;
//! Called once per `FuncNode`.
- virtual Error runOnFunction(Zone* zone, Logger* logger, FuncNode* func) = 0;
+ ASMJIT_API virtual Error runOnFunction(Zone* zone, Logger* logger, FuncNode* func);
//! \}
};
diff --git a/3rdparty/asmjit/src/asmjit/core/compilerdefs.h b/3rdparty/asmjit/src/asmjit/core/compilerdefs.h
index 1870e688bc9..e2e74ce6790 100644
--- a/3rdparty/asmjit/src/asmjit/core/compilerdefs.h
+++ b/3rdparty/asmjit/src/asmjit/core/compilerdefs.h
@@ -66,18 +66,16 @@ public:
//! \name Construction & Destruction
//! \{
- inline VirtReg(OperandSignature signature, uint32_t id, uint32_t virtSize, uint32_t alignment, TypeId typeId) noexcept
+ ASMJIT_INLINE_NODEBUG VirtReg(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(typeId),
- _isFixed(false),
- _isStack(false),
- _hasStackSlot(false),
- _reservedBits(0),
- _stackOffset(0),
- _reservedU32(0) {}
+ _isFixed(0),
+ _isStack(0),
+ _hasStackSlot(0),
+ _reservedBits(0) {}
//! \}
@@ -85,64 +83,64 @@ public:
//! \{
//! Returns the virtual register id.
- inline uint32_t id() const noexcept { return _id; }
+ ASMJIT_INLINE_NODEBUG uint32_t id() const noexcept { return _id; }
//! Returns the virtual register name.
- inline const char* name() const noexcept { return _name.data(); }
+ ASMJIT_INLINE_NODEBUG const char* name() const noexcept { return _name.data(); }
//! Returns the size of the virtual register name.
- inline uint32_t nameSize() const noexcept { return _name.size(); }
+ ASMJIT_INLINE_NODEBUG uint32_t nameSize() const noexcept { return _name.size(); }
//! Returns a register signature of this virtual register.
- inline OperandSignature signature() const noexcept { return _signature; }
+ ASMJIT_INLINE_NODEBUG OperandSignature signature() const noexcept { return _signature; }
//! Returns a virtual register type (maps to the physical register type as well).
- inline RegType type() const noexcept { return _signature.regType(); }
+ ASMJIT_INLINE_NODEBUG RegType type() const noexcept { return _signature.regType(); }
//! Returns a virtual register group (maps to the physical register group as well).
- inline RegGroup group() const noexcept { return _signature.regGroup(); }
+ ASMJIT_INLINE_NODEBUG 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
//! of that register type.
- inline uint32_t regSize() const noexcept { return _signature.size(); }
+ ASMJIT_INLINE_NODEBUG 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()`.
- inline uint32_t virtSize() const noexcept { return _virtSize; }
+ ASMJIT_INLINE_NODEBUG uint32_t virtSize() const noexcept { return _virtSize; }
//! Returns the virtual register alignment.
- inline uint32_t alignment() const noexcept { return _alignment; }
+ ASMJIT_INLINE_NODEBUG uint32_t alignment() const noexcept { return _alignment; }
//! Returns the virtual register type id.
- inline TypeId typeId() const noexcept { return _typeId; }
+ ASMJIT_INLINE_NODEBUG TypeId typeId() const noexcept { return _typeId; }
//! 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; }
+ ASMJIT_INLINE_NODEBUG 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.
- inline void setWeight(uint32_t weight) noexcept { _weight = uint8_t(weight); }
+ ASMJIT_INLINE_NODEBUG 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).
//!
//! \note This is only used for special purposes and it's mostly internal.
- inline bool isFixed() const noexcept { return bool(_isFixed); }
+ ASMJIT_INLINE_NODEBUG bool isFixed() const noexcept { return bool(_isFixed); }
//! 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); }
+ ASMJIT_INLINE_NODEBUG bool isStack() const noexcept { return bool(_isStack); }
//! Tests whether this virtual register (or stack) has assigned a stack offset.
//!
//! If this is a virtual register that was never allocated on stack, it would return false, otherwise if
//! it's a virtual register that was spilled or explicitly allocated stack, the return value would be true.
- inline bool hasStackSlot() const noexcept { return bool(_hasStackSlot); }
+ ASMJIT_INLINE_NODEBUG bool hasStackSlot() const noexcept { return bool(_hasStackSlot); }
//! Assigns a stack offset of this virtual register to `stackOffset` and sets `_hasStackSlot` to true.
- inline void assignStackSlot(int32_t stackOffset) noexcept {
+ ASMJIT_INLINE_NODEBUG void assignStackSlot(int32_t stackOffset) noexcept {
_hasStackSlot = 1;
_stackOffset = stackOffset;
}
@@ -151,16 +149,16 @@ public:
//!
//! \note Always verify that the stack offset has been assigned by calling \ref hasStackSlot(). The return
//! value will be zero when the stack offset was not assigned.
- inline int32_t stackOffset() const noexcept { return _stackOffset; }
+ ASMJIT_INLINE_NODEBUG int32_t stackOffset() const noexcept { return _stackOffset; }
//! Tests whether the virtual register has an associated `RAWorkReg` at the moment.
- inline bool hasWorkReg() const noexcept { return _workReg != nullptr; }
+ ASMJIT_INLINE_NODEBUG bool hasWorkReg() const noexcept { return _workReg != nullptr; }
//! Returns an associated RAWorkReg with this virtual register (only valid during register allocation).
- inline RAWorkReg* workReg() const noexcept { return _workReg; }
+ ASMJIT_INLINE_NODEBUG RAWorkReg* workReg() const noexcept { return _workReg; }
//! Associates a RAWorkReg with this virtual register (used by register allocator).
- inline void setWorkReg(RAWorkReg* workReg) noexcept { _workReg = workReg; }
+ ASMJIT_INLINE_NODEBUG void setWorkReg(RAWorkReg* workReg) noexcept { _workReg = workReg; }
//! Reset the RAWorkReg association (used by register allocator).
- inline void resetWorkReg() noexcept { _workReg = nullptr; }
+ ASMJIT_INLINE_NODEBUG void resetWorkReg() noexcept { _workReg = nullptr; }
//! \}
};
diff --git a/3rdparty/asmjit/src/asmjit/core/constpool.cpp b/3rdparty/asmjit/src/asmjit/core/constpool.cpp
index ad5fe4f2fc0..2ac5edf33c6 100644
--- a/3rdparty/asmjit/src/asmjit/core/constpool.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/constpool.cpp
@@ -252,18 +252,18 @@ UNIT(const_pool) {
size_t curOffset;
uint64_t c = 0x0101010101010101u;
- EXPECT(pool.add(&c, 8, prevOffset) == kErrorOk);
- EXPECT(prevOffset == 0);
+ EXPECT_EQ(pool.add(&c, 8, prevOffset), kErrorOk);
+ EXPECT_EQ(prevOffset, 0u);
for (i = 1; i < kCount; i++) {
c++;
- EXPECT(pool.add(&c, 8, curOffset) == kErrorOk);
- EXPECT(prevOffset + 8 == curOffset);
- EXPECT(pool.size() == (i + 1) * 8);
+ EXPECT_EQ(pool.add(&c, 8, curOffset), kErrorOk);
+ EXPECT_EQ(prevOffset + 8, curOffset);
+ EXPECT_EQ(pool.size(), (i + 1) * 8);
prevOffset = curOffset;
}
- EXPECT(pool.alignment() == 8);
+ EXPECT_EQ(pool.alignment(), 8u);
}
INFO("Retrieving %u constants from the pool", kCount);
@@ -272,20 +272,27 @@ UNIT(const_pool) {
for (i = 0; i < kCount; i++) {
size_t offset;
- EXPECT(pool.add(&c, 8, offset) == kErrorOk);
- EXPECT(offset == i * 8);
+ EXPECT_EQ(pool.add(&c, 8, offset), kErrorOk);
+ EXPECT_EQ(offset, i * 8);
c++;
}
}
INFO("Checking if the constants were split into 4-byte patterns");
{
- uint32_t c = 0x01010101;
- for (i = 0; i < kCount; i++) {
- size_t offset;
- EXPECT(pool.add(&c, 4, offset) == kErrorOk);
- EXPECT(offset == i * 8);
+ uint32_t c = 0x01010101u;
+ size_t offset;
+
+ EXPECT_EQ(pool.add(&c, 4, offset), kErrorOk);
+ EXPECT_EQ(offset, 0u);
+
+ // NOTE: We have to adjust the offset to successfully test this on big endian architectures.
+ size_t baseOffset = size_t(ASMJIT_ARCH_BE ? 4 : 0);
+
+ for (i = 1; i < kCount; i++) {
c++;
+ EXPECT_EQ(pool.add(&c, 4, offset), kErrorOk);
+ EXPECT_EQ(offset, baseOffset + i * 8);
}
}
@@ -294,9 +301,9 @@ UNIT(const_pool) {
uint16_t c = 0xFFFF;
size_t offset;
- EXPECT(pool.add(&c, 2, offset) == kErrorOk);
- EXPECT(offset == kCount * 8);
- EXPECT(pool.alignment() == 8);
+ EXPECT_EQ(pool.add(&c, 2, offset), kErrorOk);
+ EXPECT_EQ(offset, kCount * 8);
+ EXPECT_EQ(pool.alignment(), 8u);
}
INFO("Adding 8 byte constant to check if pool gets aligned again");
@@ -304,8 +311,8 @@ UNIT(const_pool) {
uint64_t c = 0xFFFFFFFFFFFFFFFFu;
size_t offset;
- EXPECT(pool.add(&c, 8, offset) == kErrorOk);
- EXPECT(offset == kCount * 8 + 8);
+ EXPECT_EQ(pool.add(&c, 8, offset), kErrorOk);
+ EXPECT_EQ(offset, kCount * 8 + 8u);
}
INFO("Adding 2 byte constant to verify the gap is filled");
@@ -313,9 +320,9 @@ UNIT(const_pool) {
uint16_t c = 0xFFFE;
size_t offset;
- EXPECT(pool.add(&c, 2, offset) == kErrorOk);
- EXPECT(offset == kCount * 8 + 2);
- EXPECT(pool.alignment() == 8);
+ EXPECT_EQ(pool.add(&c, 2, offset), kErrorOk);
+ EXPECT_EQ(offset, kCount * 8 + 2);
+ EXPECT_EQ(pool.alignment(), 8u);
}
INFO("Checking reset functionality");
@@ -323,8 +330,8 @@ UNIT(const_pool) {
pool.reset(&zone);
zone.reset();
- EXPECT(pool.size() == 0);
- EXPECT(pool.alignment() == 0);
+ EXPECT_EQ(pool.size(), 0u);
+ EXPECT_EQ(pool.alignment(), 0u);
}
INFO("Checking pool alignment when combined constants are added");
@@ -333,29 +340,29 @@ UNIT(const_pool) {
size_t offset;
pool.add(bytes, 1, offset);
- EXPECT(pool.size() == 1);
- EXPECT(pool.alignment() == 1);
- EXPECT(offset == 0);
+ EXPECT_EQ(pool.size(), 1u);
+ EXPECT_EQ(pool.alignment(), 1u);
+ EXPECT_EQ(offset, 0u);
pool.add(bytes, 2, offset);
- EXPECT(pool.size() == 4);
- EXPECT(pool.alignment() == 2);
- EXPECT(offset == 2);
+ EXPECT_EQ(pool.size(), 4u);
+ EXPECT_EQ(pool.alignment(), 2u);
+ EXPECT_EQ(offset, 2u);
pool.add(bytes, 4, offset);
- EXPECT(pool.size() == 8);
- EXPECT(pool.alignment() == 4);
- EXPECT(offset == 4);
+ EXPECT_EQ(pool.size(), 8u);
+ EXPECT_EQ(pool.alignment(), 4u);
+ EXPECT_EQ(offset, 4u);
pool.add(bytes, 4, offset);
- EXPECT(pool.size() == 8);
- EXPECT(pool.alignment() == 4);
- EXPECT(offset == 4);
+ EXPECT_EQ(pool.size(), 8u);
+ EXPECT_EQ(pool.alignment(), 4u);
+ EXPECT_EQ(offset, 4u);
pool.add(bytes, 32, offset);
- EXPECT(pool.size() == 64);
- EXPECT(pool.alignment() == 32);
- EXPECT(offset == 32);
+ EXPECT_EQ(pool.size(), 64u);
+ EXPECT_EQ(pool.alignment(), 32u);
+ EXPECT_EQ(offset, 32u);
}
}
#endif
diff --git a/3rdparty/asmjit/src/asmjit/core/constpool.h b/3rdparty/asmjit/src/asmjit/core/constpool.h
index 32b84b1065d..673c11d6a93 100644
--- a/3rdparty/asmjit/src/asmjit/core/constpool.h
+++ b/3rdparty/asmjit/src/asmjit/core/constpool.h
@@ -27,6 +27,9 @@ enum class ConstPoolScope : uint32_t {
};
//! Constant pool.
+//!
+//! Constant pool is designed to hold 1, 2, 4, 8, 16, 32, and 64 byte constants. It's not designed to hold constants
+//! having arbitrary length like strings and arrays.
class ConstPool {
public:
ASMJIT_NONCOPYABLE(ConstPool)
@@ -65,12 +68,12 @@ public:
//! Data offset from the beginning of the pool.
uint32_t _offset;
- inline Node(size_t offset, bool shared) noexcept
+ ASMJIT_INLINE_NODEBUG Node(size_t offset, bool shared) noexcept
: ZoneTreeNodeT<Node>(),
_shared(shared),
_offset(uint32_t(offset)) {}
- inline void* data() const noexcept {
+ ASMJIT_INLINE_NODEBUG void* data() const noexcept {
return static_cast<void*>(const_cast<ConstPool::Node*>(this) + 1);
}
};
@@ -80,14 +83,14 @@ public:
public:
size_t _dataSize;
- inline Compare(size_t dataSize) noexcept
+ ASMJIT_INLINE_NODEBUG Compare(size_t dataSize) noexcept
: _dataSize(dataSize) {}
- inline int operator()(const Node& a, const Node& b) const noexcept {
+ ASMJIT_INLINE_NODEBUG int operator()(const Node& a, const Node& b) const noexcept {
return ::memcmp(a.data(), b.data(), _dataSize);
}
- inline int operator()(const Node& a, const void* data) const noexcept {
+ ASMJIT_INLINE_NODEBUG int operator()(const Node& a, const void* data) const noexcept {
return ::memcmp(a.data(), data, _dataSize);
}
};
@@ -101,30 +104,30 @@ public:
//! Size of the data.
size_t _dataSize;
- inline explicit Tree(size_t dataSize = 0) noexcept
+ ASMJIT_INLINE_NODEBUG explicit Tree(size_t dataSize = 0) noexcept
: _tree(),
_size(0),
_dataSize(dataSize) {}
- inline void reset() noexcept {
+ ASMJIT_INLINE_NODEBUG void reset() noexcept {
_tree.reset();
_size = 0;
}
- inline bool empty() const noexcept { return _size == 0; }
- inline size_t size() const noexcept { return _size; }
+ ASMJIT_INLINE_NODEBUG bool empty() const noexcept { return _size == 0; }
+ ASMJIT_INLINE_NODEBUG size_t size() const noexcept { return _size; }
inline void setDataSize(size_t dataSize) noexcept {
ASMJIT_ASSERT(empty());
_dataSize = dataSize;
}
- inline Node* get(const void* data) noexcept {
+ ASMJIT_INLINE_NODEBUG Node* get(const void* data) noexcept {
Compare cmp(_dataSize);
return _tree.get(data, cmp);
}
- inline void insert(Node* node) noexcept {
+ ASMJIT_INLINE_NODEBUG void insert(Node* node) noexcept {
Compare cmp(_dataSize);
_tree.insert(node, cmp);
_size++;
@@ -167,7 +170,7 @@ public:
Node* node = zone->allocT<Node>(sizeof(Node) + size);
if (ASMJIT_UNLIKELY(!node)) return nullptr;
- node = new(node) Node(offset, shared);
+ node = new(Support::PlacementNew{node}) Node(offset, shared);
memcpy(node->data(), data, size);
return node;
}
@@ -199,9 +202,17 @@ public:
//! \name Construction & Destruction
//! \{
- ASMJIT_API ConstPool(Zone* zone) noexcept;
+ //! Creates a new constant pool that would use `zone` as a memory allocator.
+ ASMJIT_API explicit ConstPool(Zone* zone) noexcept;
+ //! Destroys this constant pool.
ASMJIT_API ~ConstPool() noexcept;
+ //! \}
+
+ //! \name Reset
+ //! \{
+
+ //! Resets this constant pool and its allocator to `zone`.
ASMJIT_API void reset(Zone* zone) noexcept;
//! \}
@@ -210,13 +221,13 @@ public:
//! \{
//! Tests whether the constant-pool is empty.
- inline bool empty() const noexcept { return _size == 0; }
+ ASMJIT_INLINE_NODEBUG bool empty() const noexcept { return _size == 0; }
//! Returns the size of the constant-pool in bytes.
- inline size_t size() const noexcept { return _size; }
+ ASMJIT_INLINE_NODEBUG size_t size() const noexcept { return _size; }
//! Returns minimum alignment.
- inline size_t alignment() const noexcept { return _alignment; }
+ ASMJIT_INLINE_NODEBUG size_t alignment() const noexcept { return _alignment; }
//! Returns the minimum size of all items added to the constant pool.
- inline size_t minItemSize() const noexcept { return _minItemSize; }
+ ASMJIT_INLINE_NODEBUG size_t minItemSize() const noexcept { return _minItemSize; }
//! \}
diff --git a/3rdparty/asmjit/src/asmjit/core/cpuinfo.cpp b/3rdparty/asmjit/src/asmjit/core/cpuinfo.cpp
index 7bf7407f005..88f85e0f82e 100644
--- a/3rdparty/asmjit/src/asmjit/core/cpuinfo.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/cpuinfo.cpp
@@ -7,31 +7,93 @@
#include "../core/cpuinfo.h"
#include "../core/support.h"
-#if !defined(_WIN32)
- #include <errno.h>
- #include <sys/utsname.h>
- #include <unistd.h>
-#endif
+#include <atomic>
-// Required by `getauxval()` on Linux.
-#if defined(__linux__)
- #include <sys/auxv.h>
-#endif
+// Required by `__cpuidex()` and `_xgetbv()`.
+#if ASMJIT_ARCH_X86
+ #if defined(_MSC_VER)
+ #include <intrin.h>
+ #endif
+#endif // ASMJIT_ARCH_X86
-//! Required to detect CPU and features on Apple platforms.
-#if defined(__APPLE__)
- #include <mach/machine.h>
- #include <sys/types.h>
- #include <sys/sysctl.h>
+#if ASMJIT_ARCH_ARM
+ // Required by various utilities that are required by features detection.
+ #if !defined(_WIN32)
+ #include <errno.h>
+ #include <sys/utsname.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
+
+ #if (defined(__linux__) || defined(__FreeBSD__))
+ // Required by `getauxval()` on Linux and FreeBSD.
+ #include <sys/auxv.h>
+ #define ASMJIT_ARM_DETECT_VIA_HWCAPS
+ #endif
+
+ #if ASMJIT_ARCH_ARM >= 64 && defined(__GNUC__) && defined(__linux__) && 0
+ // This feature is disabled at the moment - it works, but it seems linux supports ARM features
+ // via HWCAPS pretty well and the most recent features need to access more registers that were
+ // not originally accessible, which would break on some systems.
+ #define ASMJIT_ARM_DETECT_VIA_CPUID
+ #endif
+
+ #if ASMJIT_ARCH_ARM >= 64 && defined(__OpenBSD__)
+ #include <sys/sysctl.h>
+ #include <machine/cpu.h>
+ #endif
+#endif // ASMJIT_ARCH_ARM
+
+#if !defined(_WIN32) && (ASMJIT_ARCH_X86 || ASMJIT_ARCH_ARM)
+ #include <unistd.h>
#endif
-// Required by `__cpuidex()` and `_xgetbv()`.
+// Unfortunately when compiling in C++11 mode MSVC would warn about unused functions as
+// [[maybe_unused]] attribute is not used in that case (it's used only by C++17 mode and later).
#if defined(_MSC_VER)
- #include <intrin.h>
-#endif
+ #pragma warning(push)
+ #pragma warning(disable: 4505) // unreferenced local function has been removed.
+#endif // _MSC_VER
ASMJIT_BEGIN_NAMESPACE
+// CpuInfo - Detect - Compatibility
+// ================================
+
+// CPU features detection is a minefield on non-X86 platforms. The following list describes which
+// operating systems and architectures are supported and the status of the implementation:
+//
+// * X86, X86_64:
+// - All OSes supported
+// - Detection is based on using a CPUID instruction, which is a user-space instruction, so there
+// is no need to use any OS specific APIs or syscalls to detect all features provided by the CPU.
+//
+// * ARM32:
+// - Linux - HWCAPS based detection.
+// - FreeBSD - HWCAPS based detection (shared with Linux code).
+// - NetBSD - NOT IMPLEMENTED!
+// - OpenBSD - NOT IMPLEMENTED!
+// - Apple - sysctlbyname() based detection (this architecture is deprecated on Apple HW).
+// - Windows - IsProcessorFeaturePresent() based detection (only detects a subset of features).
+// - Others - NOT IMPLEMENTED!
+//
+// * ARM64:
+// - Linux - HWCAPS and CPUID based detection.
+// - FreeBSD - HWCAPS and CPUID based detection (shared with Linux code).
+// - NetBSD - NOT IMPLEMENTED!
+// - OpenBSD - CPUID based detection (reading CPUID via sysctl's CTL_MACHDEP).
+// - Apple - sysctlbyname() based detection with FamilyId matrix (record for each family id).
+// - Windows - IsProcessorFeaturePresent() based detection (only detects a subset of features).
+// - Others - NOT IMPLEMENTED!
+//
+// * Others
+// - NOT IMPLEMENTED!
+
// CpuInfo - Detect - HW-Thread Count
// ==================================
@@ -55,8 +117,14 @@ static inline uint32_t detectHWThreadCount() noexcept {
// CpuInfo - Detect - X86
// ======================
+// X86 and X86_64 detection is based on CPUID.
+
#if ASMJIT_ARCH_X86
+namespace x86 {
+
+typedef CpuFeatures::X86 Ext;
+
struct cpuid_t { uint32_t eax, ebx, ecx, edx; };
struct xgetbv_t { uint32_t eax, edx; };
@@ -137,7 +205,7 @@ static ASMJIT_FAVOR_SIZE void simplifyCpuBrand(char* s) noexcept {
if (!c)
break;
- if (!(c == ' ' && (prev == '@' || s[1] == ' ' || s[1] == '@'))) {
+ if (!(c == ' ' && (prev == '@' || s[1] == ' ' || s[1] == '@' || s[1] == '\0'))) {
*d++ = c;
prev = c;
}
@@ -160,7 +228,7 @@ static ASMJIT_FAVOR_SIZE void detectX86Cpu(CpuInfo& cpu) noexcept {
cpu._maxLogicalProcessors = 1;
// We are gonna execute CPUID, which was introduced by I486, so it's the requirement.
- features.add(CpuFeatures::X86::kI486);
+ features.add(Ext::kI486);
// CPUID EAX=0
// -----------
@@ -191,40 +259,40 @@ static ASMJIT_FAVOR_SIZE void detectX86Cpu(CpuInfo& cpu) noexcept {
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);
+ 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), Ext::kSSE3);
+ features.addIf(bitTest(regs.ecx, 1), Ext::kPCLMULQDQ);
+ features.addIf(bitTest(regs.ecx, 3), Ext::kMONITOR);
+ features.addIf(bitTest(regs.ecx, 5), Ext::kVMX);
+ features.addIf(bitTest(regs.ecx, 6), Ext::kSMX);
+ features.addIf(bitTest(regs.ecx, 9), Ext::kSSSE3);
+ features.addIf(bitTest(regs.ecx, 13), Ext::kCMPXCHG16B);
+ features.addIf(bitTest(regs.ecx, 19), Ext::kSSE4_1);
+ features.addIf(bitTest(regs.ecx, 20), Ext::kSSE4_2);
+ features.addIf(bitTest(regs.ecx, 22), Ext::kMOVBE);
+ features.addIf(bitTest(regs.ecx, 23), Ext::kPOPCNT);
+ features.addIf(bitTest(regs.ecx, 25), Ext::kAESNI);
+ features.addIf(bitTest(regs.ecx, 26), Ext::kXSAVE);
+ features.addIf(bitTest(regs.ecx, 27), Ext::kOSXSAVE);
+ features.addIf(bitTest(regs.ecx, 30), Ext::kRDRAND);
+ features.addIf(bitTest(regs.edx, 0), Ext::kFPU);
+ features.addIf(bitTest(regs.edx, 4), Ext::kRDTSC);
+ features.addIf(bitTest(regs.edx, 5), Ext::kMSR);
+ features.addIf(bitTest(regs.edx, 8), Ext::kCMPXCHG8B);
+ features.addIf(bitTest(regs.edx, 15), Ext::kCMOV);
+ features.addIf(bitTest(regs.edx, 19), Ext::kCLFLUSH);
+ features.addIf(bitTest(regs.edx, 23), Ext::kMMX);
+ features.addIf(bitTest(regs.edx, 24), Ext::kFXSR);
+ features.addIf(bitTest(regs.edx, 25), Ext::kSSE, Ext::kMMX2);
+ features.addIf(bitTest(regs.edx, 26), Ext::kSSE2, Ext::kSSE);
+ features.addIf(bitTest(regs.edx, 28), Ext::kMT);
// Get the content of XCR0 if supported by the CPU and enabled by the OS.
if (features.hasXSAVE() && features.hasOSXSAVE()) {
@@ -236,9 +304,9 @@ static ASMJIT_FAVOR_SIZE void detectX86Cpu(CpuInfo& cpu) noexcept {
// - 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);
+ features.add(Ext::kAVX);
+ features.addIf(bitTest(regs.ecx, 12), Ext::kFMA);
+ features.addIf(bitTest(regs.ecx, 29), Ext::kF16C);
}
}
}
@@ -270,84 +338,114 @@ static ASMJIT_FAVOR_SIZE void detectX86Cpu(CpuInfo& cpu) noexcept {
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);
+ features.addIf(bitTest(regs.ebx, 0), Ext::kFSGSBASE);
+ features.addIf(bitTest(regs.ebx, 3), Ext::kBMI);
+ features.addIf(bitTest(regs.ebx, 4), Ext::kHLE);
+ features.addIf(bitTest(regs.ebx, 7), Ext::kSMEP);
+ features.addIf(bitTest(regs.ebx, 8), Ext::kBMI2);
+ features.addIf(bitTest(regs.ebx, 9), Ext::kERMS);
+ features.addIf(bitTest(regs.ebx, 11), Ext::kRTM);
+ features.addIf(bitTest(regs.ebx, 18), Ext::kRDSEED);
+ features.addIf(bitTest(regs.ebx, 19), Ext::kADX);
+ features.addIf(bitTest(regs.ebx, 20), Ext::kSMAP);
+ features.addIf(bitTest(regs.ebx, 23), Ext::kCLFLUSHOPT);
+ features.addIf(bitTest(regs.ebx, 24), Ext::kCLWB);
+ features.addIf(bitTest(regs.ebx, 29), Ext::kSHA);
+ features.addIf(bitTest(regs.ecx, 0), Ext::kPREFETCHWT1);
+ features.addIf(bitTest(regs.ecx, 4), Ext::kOSPKE);
+ features.addIf(bitTest(regs.ecx, 5), Ext::kWAITPKG);
+ features.addIf(bitTest(regs.ecx, 7), Ext::kCET_SS);
+ features.addIf(bitTest(regs.ecx, 8), Ext::kGFNI);
+ features.addIf(bitTest(regs.ecx, 9), Ext::kVAES);
+ features.addIf(bitTest(regs.ecx, 10), Ext::kVPCLMULQDQ);
+ features.addIf(bitTest(regs.ecx, 22), Ext::kRDPID);
+ features.addIf(bitTest(regs.ecx, 25), Ext::kCLDEMOTE);
+ features.addIf(bitTest(regs.ecx, 27), Ext::kMOVDIRI);
+ features.addIf(bitTest(regs.ecx, 28), Ext::kMOVDIR64B);
+ features.addIf(bitTest(regs.ecx, 29), Ext::kENQCMD);
+ features.addIf(bitTest(regs.edx, 4), Ext::kFSRM);
+ features.addIf(bitTest(regs.edx, 5), Ext::kUINTR);
+ features.addIf(bitTest(regs.edx, 14), Ext::kSERIALIZE);
+ features.addIf(bitTest(regs.edx, 16), Ext::kTSXLDTRK);
+ features.addIf(bitTest(regs.edx, 18), Ext::kPCONFIG);
+ features.addIf(bitTest(regs.edx, 20), Ext::kCET_IBT);
// Detect 'TSX' - Requires at least one of `HLE` and `RTM` features.
- if (features.hasHLE() || features.hasRTM())
- features.add(CpuFeatures::X86::kTSX);
+ if (features.hasHLE() || features.hasRTM()) {
+ features.add(Ext::kTSX);
+ }
- // Detect 'AVX2' - Requires AVX as well.
- if (bitTest(regs.ebx, 5) && features.hasAVX())
- features.add(CpuFeatures::X86::kAVX2);
+ if (bitTest(regs.ebx, 5) && features.hasAVX()) {
+ features.add(Ext::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);
+ features.add(Ext::kAVX512_F);
+
+ features.addIf(bitTest(regs.ebx, 17), Ext::kAVX512_DQ);
+ features.addIf(bitTest(regs.ebx, 21), Ext::kAVX512_IFMA);
+ features.addIf(bitTest(regs.ebx, 26), Ext::kAVX512_PF);
+ features.addIf(bitTest(regs.ebx, 27), Ext::kAVX512_ER);
+ features.addIf(bitTest(regs.ebx, 28), Ext::kAVX512_CD);
+ features.addIf(bitTest(regs.ebx, 30), Ext::kAVX512_BW);
+ features.addIf(bitTest(regs.ebx, 31), Ext::kAVX512_VL);
+ features.addIf(bitTest(regs.ecx, 1), Ext::kAVX512_VBMI);
+ features.addIf(bitTest(regs.ecx, 6), Ext::kAVX512_VBMI2);
+ features.addIf(bitTest(regs.ecx, 11), Ext::kAVX512_VNNI);
+ features.addIf(bitTest(regs.ecx, 12), Ext::kAVX512_BITALG);
+ features.addIf(bitTest(regs.ecx, 14), Ext::kAVX512_VPOPCNTDQ);
+ features.addIf(bitTest(regs.edx, 2), Ext::kAVX512_4VNNIW);
+ features.addIf(bitTest(regs.edx, 3), Ext::kAVX512_4FMAPS);
+ features.addIf(bitTest(regs.edx, 8), Ext::kAVX512_VP2INTERSECT);
+ features.addIf(bitTest(regs.edx, 23), Ext::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);
+ features.addIf(bitTest(regs.edx, 22), Ext::kAMX_BF16);
+ features.addIf(bitTest(regs.edx, 24), Ext::kAMX_TILE);
+ features.addIf(bitTest(regs.edx, 25), Ext::kAMX_INT8);
}
}
// CPUID EAX=7 ECX=1
// -----------------
- if (features.hasAVX512_F() && maxSubLeafId_0x7 >= 1) {
+ if (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);
+ features.addIf(bitTest(regs.eax, 0), Ext::kSHA512);
+ features.addIf(bitTest(regs.eax, 1), Ext::kSM3);
+ features.addIf(bitTest(regs.eax, 2), Ext::kSM4);
+ features.addIf(bitTest(regs.eax, 3), Ext::kRAO_INT);
+ features.addIf(bitTest(regs.eax, 7), Ext::kCMPCCXADD);
+ features.addIf(bitTest(regs.eax, 10), Ext::kFZRM);
+ features.addIf(bitTest(regs.eax, 11), Ext::kFSRS);
+ features.addIf(bitTest(regs.eax, 12), Ext::kFSRC);
+ features.addIf(bitTest(regs.eax, 19), Ext::kWRMSRNS);
+ features.addIf(bitTest(regs.eax, 22), Ext::kHRESET);
+ features.addIf(bitTest(regs.eax, 26), Ext::kLAM);
+ features.addIf(bitTest(regs.eax, 27), Ext::kMSRLIST);
+ features.addIf(bitTest(regs.ebx, 1), Ext::kTSE);
+ features.addIf(bitTest(regs.edx, 14), Ext::kPREFETCHI);
+ features.addIf(bitTest(regs.edx, 18), Ext::kCET_SSS);
+ features.addIf(bitTest(regs.edx, 21), Ext::kAPX_F);
+
+ if (features.hasAVX2()) {
+ features.addIf(bitTest(regs.eax, 4), Ext::kAVX_VNNI);
+ features.addIf(bitTest(regs.eax, 23), Ext::kAVX_IFMA);
+ features.addIf(bitTest(regs.edx, 4), Ext::kAVX_VNNI_INT8);
+ features.addIf(bitTest(regs.edx, 5), Ext::kAVX_NE_CONVERT);
+ features.addIf(bitTest(regs.edx, 10), Ext::kAVX_VNNI_INT16);
+ }
+
+ if (features.hasAVX512_F()) {
+ features.addIf(bitTest(regs.eax, 5), Ext::kAVX512_BF16);
+ }
+
+ if (amxEnabledByOS) {
+ features.addIf(bitTest(regs.eax, 21), Ext::kAMX_FP16);
+ features.addIf(bitTest(regs.edx, 8), Ext::kAMX_COMPLEX);
+ }
}
// CPUID EAX=13 ECX=0
@@ -358,13 +456,13 @@ static ASMJIT_FAVOR_SIZE void detectX86Cpu(CpuInfo& cpu) noexcept {
// 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);
+ features.add(Ext::kMPX);
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);
+ features.addIf(bitTest(regs.eax, 0), Ext::kXSAVEOPT);
+ features.addIf(bitTest(regs.eax, 1), Ext::kXSAVEC);
+ features.addIf(bitTest(regs.eax, 3), Ext::kXSAVES);
}
// CPUID EAX=14 ECX=0
@@ -373,7 +471,7 @@ static ASMJIT_FAVOR_SIZE void detectX86Cpu(CpuInfo& cpu) noexcept {
if (maxId >= 0xE) {
cpuidQuery(&regs, 0xE, 0);
- features.addIf(bitTest(regs.ebx, 4), CpuFeatures::X86::kPTWRITE);
+ features.addIf(bitTest(regs.ebx, 4), Ext::kPTWRITE);
}
// CPUID EAX=0x80000000...maxId
@@ -396,32 +494,32 @@ static ASMJIT_FAVOR_SIZE void detectX86Cpu(CpuInfo& cpu) noexcept {
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);
+ features.addIf(bitTest(regs.ecx, 0), Ext::kLAHFSAHF);
+ features.addIf(bitTest(regs.ecx, 2), Ext::kSVM);
+ features.addIf(bitTest(regs.ecx, 5), Ext::kLZCNT);
+ features.addIf(bitTest(regs.ecx, 6), Ext::kSSE4A);
+ features.addIf(bitTest(regs.ecx, 7), Ext::kMSSE);
+ features.addIf(bitTest(regs.ecx, 8), Ext::kPREFETCHW);
+ features.addIf(bitTest(regs.ecx, 12), Ext::kSKINIT);
+ features.addIf(bitTest(regs.ecx, 15), Ext::kLWP);
+ features.addIf(bitTest(regs.ecx, 21), Ext::kTBM);
+ features.addIf(bitTest(regs.ecx, 29), Ext::kMONITORX);
+ features.addIf(bitTest(regs.edx, 20), Ext::kNX);
+ features.addIf(bitTest(regs.edx, 21), Ext::kFXSROPT);
+ features.addIf(bitTest(regs.edx, 22), Ext::kMMX2);
+ features.addIf(bitTest(regs.edx, 27), Ext::kRDTSCP);
+ features.addIf(bitTest(regs.edx, 29), Ext::kPREFETCHW);
+ features.addIf(bitTest(regs.edx, 30), Ext::k3DNOW2, Ext::kMMX2);
+ features.addIf(bitTest(regs.edx, 31), Ext::kPREFETCHW);
if (features.hasAVX()) {
- features.addIf(bitTest(regs.ecx, 11), CpuFeatures::X86::kXOP);
- features.addIf(bitTest(regs.ecx, 16), CpuFeatures::X86::kFMA4);
+ features.addIf(bitTest(regs.ecx, 11), Ext::kXOP);
+ features.addIf(bitTest(regs.ecx, 16), Ext::kFMA4);
}
// This feature seems to be only supported by AMD.
if (cpu.isVendor("AMD")) {
- features.addIf(bitTest(regs.ecx, 4), CpuFeatures::X86::kALTMOVCR8);
+ features.addIf(bitTest(regs.ecx, 4), Ext::kALTMOVCR8);
}
break;
@@ -439,17 +537,21 @@ static ASMJIT_FAVOR_SIZE void detectX86Cpu(CpuInfo& cpu) noexcept {
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);
+ features.addIf(bitTest(regs.ebx, 0), Ext::kCLZERO);
+ features.addIf(bitTest(regs.ebx, 0), Ext::kRDPRU);
+ features.addIf(bitTest(regs.ebx, 8), Ext::kMCOMMIT);
+ features.addIf(bitTest(regs.ebx, 9), Ext::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);
+ features.addIf(bitTest(regs.eax, 0), Ext::kSME);
+ features.addIf(bitTest(regs.eax, 1), Ext::kSEV);
+ features.addIf(bitTest(regs.eax, 3), Ext::kSEV_ES);
+ features.addIf(bitTest(regs.eax, 4), Ext::kSEV_SNP);
+ features.addIf(bitTest(regs.eax, 6), Ext::kRMPQUERY);
break;
}
} while (++i <= maxId);
@@ -458,11 +560,17 @@ static ASMJIT_FAVOR_SIZE void detectX86Cpu(CpuInfo& cpu) noexcept {
simplifyCpuBrand(cpu._brand.str);
}
+} // {x86}
+
#endif // ASMJIT_ARCH_X86
// CpuInfo - Detect - ARM
// ======================
+// Implement the most code outside the platform specific #ifdefs to minimize breaking the detection on
+// platforms that don't run on our CI infrastructure. The problem with the detection is that every OS
+// requires a specific implementation as ARM features cannot be detected in user-mode without OS enablement.
+
// 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)
@@ -470,277 +578,921 @@ static ASMJIT_FAVOR_SIZE void detectX86Cpu(CpuInfo& cpu) noexcept {
// Other resources:
// https://en.wikipedia.org/wiki/AArch64
// https://en.wikipedia.org/wiki/Apple_silicon#List_of_Apple_processors
+// https://developer.arm.com/downloads/-/exploration-tools/feature-names-for-a-profile
// https://developer.arm.com/architectures/learn-the-architecture/understanding-the-armv8-x-extensions/single-page
#if ASMJIT_ARCH_ARM
+namespace arm {
+
+// ARM commonly refers to CPU features using FEAT_ prefix, we use Ext:: to make it compatible with other parts.
+typedef CpuFeatures::ARM Ext;
+
+// CpuInfo - Detect - ARM - OS Kernel Version
+// ==========================================
+
+#if defined(__linux__)
+struct UNameKernelVersion {
+ int parts[3];
+
+ inline bool atLeast(int major, int minor, int patch = 0) const noexcept {
+ if (parts[0] >= major) {
+ if (parts[0] > major)
+ return true;
+
+ if (parts[1] >= minor) {
+ if (parts[1] > minor)
+ return true;
+
+ return parts[2] >= patch;
+ }
+ }
+
+ return false;
+ }
+};
+
+ASMJIT_MAYBE_UNUSED
+static UNameKernelVersion getUNameKernelVersion() noexcept {
+ UNameKernelVersion ver{};
+ ver.parts[0] = -1;
+
+ utsname buffer;
+ if (uname(&buffer) != 0)
+ return ver;
+
+ size_t count = 0;
+ char* p = buffer.release;
+ while (*p) {
+ uint32_t c = uint8_t(*p);
+ if (c >= uint32_t('0') && c <= uint32_t('9')) {
+ ver.parts[count] = int(strtol(p, &p, 10));
+ if (++count == 3)
+ break;
+ }
+ else if (c == '.' || c == '-') {
+ p++;
+ }
+ else {
+ break;
+ }
+ }
+
+ return ver;
+}
+#endif // __linux__
+
+// CpuInfo - Detect - ARM - Baseline Features of ARM Architectures
+// ===============================================================
+
+ASMJIT_MAYBE_UNUSED
+static inline void populateBaseAArch32Features(CpuFeatures::ARM& features) noexcept {
+ // No baseline flags at the moment.
+ DebugUtils::unused(features);
+}
+
+ASMJIT_MAYBE_UNUSED
+static inline void populateBaseAArch64Features(CpuFeatures::ARM& features) noexcept {
+ // AArch64 is based on ARMv8.0 and later.
+ features.add(Ext::kARMv6);
+ features.add(Ext::kARMv7);
+ features.add(Ext::kARMv8a);
+
+ // AArch64 comes with these features by default.
+ features.add(Ext::kASIMD);
+ features.add(Ext::kFP);
+ features.add(Ext::kIDIVA);
+}
+
static inline void populateBaseARMFeatures(CpuInfo& cpu) noexcept {
#if ASMJIT_ARCH_ARM == 32
- // No baseline flags at the moment.
- DebugUtils::unused(cpu);
+ populateBaseAArch32Features(cpu.features().arm());
#else
- // AArch64 is based on ARMv8-A and later.
- cpu.addFeature(CpuFeatures::ARM::kARMv6);
- cpu.addFeature(CpuFeatures::ARM::kARMv7);
- cpu.addFeature(CpuFeatures::ARM::kARMv8a);
+ populateBaseAArch64Features(cpu.features().arm());
+#endif
+}
- // 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);
+// CpuInfo - Detect - ARM - Mandatory Features of ARM Architectures
+// ================================================================
+
+// Populates mandatory ARMv8.[v]A features.
+ASMJIT_MAYBE_UNUSED
+static ASMJIT_FAVOR_SIZE void populateARMv8AFeatures(CpuFeatures::ARM& features, uint32_t v) noexcept {
+ switch (v) {
+ default:
+ ASMJIT_FALLTHROUGH;
+ case 9: // ARMv8.9
+ features.add(Ext::kCLRBHB, Ext::kCSSC, Ext::kPRFMSLC, Ext::kSPECRES2, Ext::kRAS2);
+ ASMJIT_FALLTHROUGH;
+ case 8: // ARMv8.8
+ features.add(Ext::kHBC, Ext::kMOPS, Ext::kNMI);
+ ASMJIT_FALLTHROUGH;
+ case 7: // ARMv8.7
+ features.add(Ext::kHCX, Ext::kPAN3, Ext::kWFXT, Ext::kXS);
+ ASMJIT_FALLTHROUGH;
+ case 6: // ARMv8.6
+ features.add(Ext::kAMU1_1, Ext::kBF16, Ext::kECV, Ext::kFGT, Ext::kI8MM);
+ ASMJIT_FALLTHROUGH;
+ case 5: // ARMv8.5
+ features.add(Ext::kBTI, Ext::kCSV2, Ext::kDPB2, Ext::kFLAGM2, Ext::kFRINTTS, Ext::kSB, Ext::kSPECRES, Ext::kSSBS);
+ ASMJIT_FALLTHROUGH;
+ case 4: // ARMv8.4
+ features.add(Ext::kAMU1, Ext::kDIT, Ext::kDOTPROD, Ext::kFLAGM,
+ Ext::kLRCPC2, Ext::kLSE2, Ext::kMPAM, Ext::kNV,
+ Ext::kSEL2, Ext::kTLBIOS, Ext::kTLBIRANGE, Ext::kTRF);
+ ASMJIT_FALLTHROUGH;
+ case 3: // ARMv8.3
+ features.add(Ext::kCCIDX, Ext::kFCMA, Ext::kJSCVT, Ext::kLRCPC, Ext::kPAUTH);
+ ASMJIT_FALLTHROUGH;
+ case 2: // ARMv8.2
+ features.add(Ext::kDPB, Ext::kPAN2, Ext::kRAS, Ext::kUAO);
+ ASMJIT_FALLTHROUGH;
+ case 1: // ARMv8.1
+ features.add(Ext::kCRC32, Ext::kLOR, Ext::kLSE, Ext::kPAN, Ext::kRDM, Ext::kVHE);
+ ASMJIT_FALLTHROUGH;
+ case 0: // ARMv8.0
+ features.add(Ext::kASIMD, Ext::kFP, Ext::kIDIVA, Ext::kVFP_D32);
+ break;
+ }
+}
+
+// Populates mandatory ARMv9.[v] features.
+ASMJIT_MAYBE_UNUSED
+static ASMJIT_FAVOR_SIZE void populateARMv9AFeatures(CpuFeatures::ARM& features, uint32_t v) noexcept {
+ populateARMv8AFeatures(features, v <= 4u ? 5u + v : 9u);
+
+ switch (v) {
+ default:
+ ASMJIT_FALLTHROUGH;
+ case 4: // ARMv9.4 - based on ARMv8.9.
+ ASMJIT_FALLTHROUGH;
+ case 3: // ARMv9.3 - based on ARMv8.8.
+ ASMJIT_FALLTHROUGH;
+ case 2: // ARMv9.2 - based on ARMv8.7.
+ ASMJIT_FALLTHROUGH;
+ case 1: // ARMv9.1 - based on ARMv8.6.
+ ASMJIT_FALLTHROUGH;
+ case 0: // ARMv9.0 - based on ARMv8.5.
+ features.add(Ext::kRME, Ext::kSVE, Ext::kSVE2);
+ break;
+ }
+}
+
+// CpuInfo - Detect - ARM - CPUID Based Features
+// =============================================
+
+// This implements detection based on the content of CPUID registers. The following code doesn't actually read any
+// of the registers so it's an implementation that can theoretically be tested / used in mocks.
+
+// Merges a feature that contains 0b1111 when it doesn't exist and starts at 0b0000 when it does.
+ASMJIT_MAYBE_UNUSED
+static ASMJIT_FORCE_INLINE void mergeAArch64CPUIDFeatureNA(CpuFeatures::ARM& features, uint64_t regBits, uint32_t offset,
+ Ext::Id f0,
+ Ext::Id f1 = Ext::kNone,
+ Ext::Id f2 = Ext::kNone,
+ Ext::Id f3 = Ext::kNone) noexcept {
+
+ uint32_t val = uint32_t((regBits >> offset) & 0xFu);
+
+ // If val == 0b1111 then the feature is not implemented in this case (some early extensions).
+ if (val == 0xFu)
+ return;
+
+ if (f0 != Ext::kNone) features.add(f0);
+ if (f1 != Ext::kNone) features.addIf(val >= 1, f1);
+ if (f2 != Ext::kNone) features.addIf(val >= 2, f2);
+ if (f3 != Ext::kNone) features.addIf(val >= 3, f3);
+}
+
+// Merges a feature identified by a single bit at `offset`.
+ASMJIT_MAYBE_UNUSED
+static ASMJIT_FORCE_INLINE void mergeAArch64CPUIDFeature1B(CpuFeatures::ARM& features, uint64_t regBits, uint32_t offset, Ext::Id f1) noexcept {
+ features.addIf((regBits & (uint64_t(1) << offset)) != 0, f1);
+}
+
+// Merges a feature-list starting from 0b01 when it does (0b00 means feature not supported).
+ASMJIT_MAYBE_UNUSED
+static ASMJIT_FORCE_INLINE void mergeAArch64CPUIDFeature2B(CpuFeatures::ARM& features, uint64_t regBits, uint32_t offset, Ext::Id f1, Ext::Id f2, Ext::Id f3) noexcept {
+ uint32_t val = uint32_t((regBits >> offset) & 0x3u);
+
+ if (f1 != Ext::kNone) features.addIf(val >= 1, f1);
+ if (f2 != Ext::kNone) features.addIf(val >= 2, f2);
+ if (f3 != Ext::kNone) features.addIf(val == 3, f3);
+}
+
+// Merges a feature-list starting from 0b0001 when it does (0b0000 means feature not supported).
+ASMJIT_MAYBE_UNUSED
+static ASMJIT_FORCE_INLINE void mergeAArch64CPUIDFeature4B(CpuFeatures::ARM& features, uint64_t regBits, uint32_t offset,
+ Ext::Id f1,
+ Ext::Id f2 = Ext::kNone,
+ Ext::Id f3 = Ext::kNone,
+ Ext::Id f4 = Ext::kNone) noexcept {
+
+ uint32_t val = uint32_t((regBits >> offset) & 0xFu);
+
+ // if val == 0 it means that this feature is not supported.
+
+ if (f1 != Ext::kNone) features.addIf(val >= 1, f1);
+ if (f2 != Ext::kNone) features.addIf(val >= 2, f2);
+ if (f3 != Ext::kNone) features.addIf(val >= 3, f3);
+ if (f4 != Ext::kNone) features.addIf(val >= 4, f4);
+}
+
+// Merges a feature that is identified by an exact bit-combination of 4 bits.
+ASMJIT_MAYBE_UNUSED
+static ASMJIT_FORCE_INLINE void mergeAArch64CPUIDFeature4S(CpuFeatures::ARM& features, uint64_t regBits, uint32_t offset, uint32_t value, Ext::Id f1) noexcept {
+ features.addIf(uint32_t((regBits >> offset) & 0xFu) == value, f1);
+}
+
+#define MERGE_FEATURE_NA(identifier, reg, offset, ...) mergeAArch64CPUIDFeatureNA(cpu.features().arm(), reg, offset, __VA_ARGS__)
+#define MERGE_FEATURE_1B(identifier, reg, offset, ...) mergeAArch64CPUIDFeature1B(cpu.features().arm(), reg, offset, __VA_ARGS__)
+#define MERGE_FEATURE_2B(identifier, reg, offset, ...) mergeAArch64CPUIDFeature2B(cpu.features().arm(), reg, offset, __VA_ARGS__)
+#define MERGE_FEATURE_4B(identifier, reg, offset, ...) mergeAArch64CPUIDFeature4B(cpu.features().arm(), reg, offset, __VA_ARGS__)
+#define MERGE_FEATURE_4S(identifier, reg, offset, ...) mergeAArch64CPUIDFeature4S(cpu.features().arm(), reg, offset, __VA_ARGS__)
+
+// Detects features based on the content of ID_AA64PFR0_EL1 and ID_AA64PFR1_EL1 registers.
+ASMJIT_MAYBE_UNUSED
+static inline void detectAArch64FeaturesViaCPUID_AA64PFR0_AA64PFR1(CpuInfo& cpu, uint64_t fpr0, uint64_t fpr1) noexcept {
+ // ID_AA64PFR0_EL1
+ // ===============
+
+ // FP and AdvSIMD bits should match (i.e. if FP features FP16, ASIMD must feature it too).
+ MERGE_FEATURE_NA("FP bits [19:16]" , fpr0, 16, Ext::kFP, Ext::kFP16);
+ MERGE_FEATURE_NA("AdvSIMD bits [23:20]" , fpr0, 20, Ext::kASIMD, Ext::kFP16);
+ /*
+ MERGE_FEATURE_4B("GIC bits [27:24]" , fpr0, 24, ...);
+ */
+ MERGE_FEATURE_4B("RAS bits [31:28]" , fpr0, 28, Ext::kRAS, Ext::kRAS1_1, Ext::kRAS2);
+ MERGE_FEATURE_4B("SVE bits [35:32]" , fpr0, 32, Ext::kSVE);
+ MERGE_FEATURE_4B("SEL2 bits [39:36]" , fpr0, 36, Ext::kSEL2);
+ MERGE_FEATURE_4B("MPAM bits [43:40]" , fpr0, 40, Ext::kMPAM);
+ MERGE_FEATURE_4B("AMU bits [47:44]" , fpr0, 44, Ext::kAMU1, Ext::kAMU1_1);
+ MERGE_FEATURE_4B("DIT bits [51:48]" , fpr0, 48, Ext::kDIT);
+ MERGE_FEATURE_4B("RME bits [55:52]" , fpr0, 52, Ext::kRME);
+ MERGE_FEATURE_4B("CSV2 bits [59:56]" , fpr0, 56, Ext::kCSV2, Ext::kCSV2, Ext::kCSV2, Ext::kCSV2_3);
+ MERGE_FEATURE_4B("CSV3 bits [63:60]" , fpr0, 60, Ext::kCSV3);
+
+ // ID_AA64PFR1_EL1
+ // ===============
+
+ MERGE_FEATURE_4B("BT bits [3:0]" , fpr1, 0, Ext::kBTI);
+ MERGE_FEATURE_4B("SSBS bits [7:4]" , fpr1, 4, Ext::kSSBS, Ext::kSSBS2);
+ MERGE_FEATURE_4B("MTE bits [11:8]" , fpr1, 8, Ext::kMTE, Ext::kMTE2, Ext::kMTE3);
+ /*
+ MERGE_FEATURE_4B("RAS_frac bits [15:12]" , fpr1, 12, ...);
+ MERGE_FEATURE_4B("MPAM_frac bits [19:16]" , fpr1, 16, ...);
+ */
+ MERGE_FEATURE_4B("SME bits [27:24]" , fpr1, 24, Ext::kSME, Ext::kSME2);
+ MERGE_FEATURE_4B("RNDR_trap bits [31:28]" , fpr1, 28, Ext::kRNG_TRAP);
+ /*
+ MERGE_FEATURE_4B("CSV2_frac bits [35:32]" , fpr1, 32, ...);
+ */
+ MERGE_FEATURE_4B("NMI bits [39:36]" , fpr1, 36, Ext::kNMI);
+ /*
+ MERGE_FEATURE_4B("MTE_frac bits [43:40]" , fpr1, 40, ...);
+ */
+ MERGE_FEATURE_4B("GCS bits [47:44]" , fpr1, 44, Ext::kGCS);
+ MERGE_FEATURE_4B("THE bits [51:48]" , fpr1, 48, Ext::kTHE);
+
+ // MTEX extensions are only available when MTE3 is available.
+ if (cpu.features().arm().hasMTE3())
+ MERGE_FEATURE_4B("MTEX bits [55:52]" , fpr1, 52, Ext::kMTE4);
+
+ /*
+ MERGE_FEATURE_4B("DF2 bits [59:56]" , fpr1, 56, ...);
+ */
+ MERGE_FEATURE_4B("PFAR bits [63:60]" , fpr1, 60, Ext::kPFAR);
+
+ // ID_AA64PFR0_EL1 + ID_AA64PFR1_EL1
+ // =================================
+
+ uint32_t rasMain = uint32_t((fpr0 >> 28) & 0xFu);
+ uint32_t rasFrac = uint32_t((fpr1 >> 12) & 0xFu);
+
+ if (rasMain == 1 && rasFrac == 1) {
+ cpu.features().arm().add(Ext::kRAS1_1);
+ }
+
+ uint32_t mpamMain = uint32_t((fpr0 >> 40) & 0xFu);
+ uint32_t mpamFrac = uint32_t((fpr1 >> 16) & 0xFu);
+
+ if (mpamMain || mpamFrac)
+ cpu.features().arm().add(Ext::kMPAM);
+}
+
+// Detects features based on the content of ID_AA64ISAR0_EL1 and ID_AA64ISAR1_EL1 registers.
+ASMJIT_MAYBE_UNUSED
+static inline void detectAArch64FeaturesViaCPUID_AA64ISAR0_AA64ISAR1(CpuInfo& cpu, uint64_t isar0, uint64_t isar1) noexcept {
+ // ID_AA64ISAR0_EL1
+ // ================
+
+ MERGE_FEATURE_4B("AES bits [7:4]" , isar0, 4, Ext::kAES, Ext::kPMULL);
+ MERGE_FEATURE_4B("SHA1 bits [11:8]" , isar0, 8, Ext::kSHA1);
+ MERGE_FEATURE_4B("SHA2 bits [15:12]" , isar0, 12, Ext::kSHA256, Ext::kSHA512);
+ MERGE_FEATURE_4B("CRC32 bits [19:16]" , isar0, 16, Ext::kCRC32);
+ MERGE_FEATURE_4B("Atomic bits [23:20]" , isar0, 20, Ext::kNone, Ext::kLSE, Ext::kLSE128);
+ MERGE_FEATURE_4B("TME bits [27:24]" , isar0, 24, Ext::kTME);
+ MERGE_FEATURE_4B("RDM bits [31:28]" , isar0, 28, Ext::kRDM);
+ MERGE_FEATURE_4B("SHA3 bits [35:32]" , isar0, 32, Ext::kSHA3);
+ MERGE_FEATURE_4B("SM3 bits [39:36]" , isar0, 36, Ext::kSM3);
+ MERGE_FEATURE_4B("SM4 bits [43:40]" , isar0, 40, Ext::kSM4);
+ MERGE_FEATURE_4B("DP bits [47:44]" , isar0, 44, Ext::kDOTPROD);
+ MERGE_FEATURE_4B("FHM bits [51:48]" , isar0, 48, Ext::kFHM);
+ MERGE_FEATURE_4B("TS bits [55:52]" , isar0, 52, Ext::kFLAGM, Ext::kFLAGM2);
+ /*
+ MERGE_FEATURE_4B("TLB bits [59:56]" , isar0, 56, ...);
+ */
+ MERGE_FEATURE_4B("RNDR bits [63:60]" , isar0, 60, Ext::kFLAGM, Ext::kRNG);
+
+ // ID_AA64ISAR1_EL1
+ // ================
+
+ MERGE_FEATURE_4B("DPB bits [3:0]" , isar1, 0, Ext::kDPB, Ext::kDPB2);
+ /*
+ MERGE_FEATURE_4B("APA bits [7:4]" , isar1, 4, ...);
+ MERGE_FEATURE_4B("API bits [11:8]" , isar1, 8, ...);
+ */
+ MERGE_FEATURE_4B("JSCVT bits [15:12]" , isar1, 12, Ext::kJSCVT);
+ MERGE_FEATURE_4B("FCMA bits [19:16]" , isar1, 16, Ext::kFCMA);
+ MERGE_FEATURE_4B("LRCPC bits [23:20]" , isar1, 20, Ext::kLRCPC, Ext::kLRCPC2, Ext::kLRCPC3);
+ /*
+ MERGE_FEATURE_4B("GPA bits [27:24]" , isar1, 24, ...);
+ MERGE_FEATURE_4B("GPI bits [31:28]" , isar1, 28, ...);
+ */
+ MERGE_FEATURE_4B("FRINTTS bits [35:32]" , isar1, 32, Ext::kFRINTTS);
+ MERGE_FEATURE_4B("SB bits [39:36]" , isar1, 36, Ext::kSB);
+ MERGE_FEATURE_4B("SPECRES bits [43:40]" , isar1, 40, Ext::kSPECRES, Ext::kSPECRES2);
+ MERGE_FEATURE_4B("BF16 bits [47:44]" , isar1, 44, Ext::kBF16, Ext::kEBF16);
+ MERGE_FEATURE_4B("DGH bits [51:48]" , isar1, 48, Ext::kDGH);
+ MERGE_FEATURE_4B("I8MM bits [55:52]" , isar1, 52, Ext::kI8MM);
+ MERGE_FEATURE_4B("XS bits [59:56]" , isar1, 56, Ext::kXS);
+ MERGE_FEATURE_4B("LS64 bits [63:60]" , isar1, 60, Ext::kLS64, Ext::kLS64_V, Ext::kLS64_ACCDATA);
+}
+
+// Detects features based on the content of ID_AA64ISAR2_EL1 register.
+ASMJIT_MAYBE_UNUSED
+static inline void detectAArch64FeaturesViaCPUID_AA64ISAR2(CpuInfo& cpu, uint64_t isar2) noexcept {
+ MERGE_FEATURE_4B("WFxT bits [3:0]" , isar2, 0, Ext::kNone, Ext::kWFXT);
+ MERGE_FEATURE_4B("RPRES bits [7:4]" , isar2, 4, Ext::kRPRES);
+ /*
+ MERGE_FEATURE_4B("GPA3 bits [11:8]" , isar2, 8, ...);
+ MERGE_FEATURE_4B("APA3 bits [15:12]" , isar2, 12, ...);
+ */
+ MERGE_FEATURE_4B("MOPS bits [19:16]" , isar2, 16, Ext::kMOPS);
+ MERGE_FEATURE_4B("BC bits [23:20]" , isar2, 20, Ext::kHBC);
+ MERGE_FEATURE_4B("PAC_frac bits [27:24]" , isar2, 24, Ext::kCONSTPACFIELD);
+ MERGE_FEATURE_4B("CLRBHB bits [31:28]" , isar2, 28, Ext::kCLRBHB);
+ MERGE_FEATURE_4B("SYSREG128 bits [35:32]" , isar2, 32, Ext::kSYSREG128);
+ MERGE_FEATURE_4B("SYSINSTR128 bits [39:36]" , isar2, 36, Ext::kSYSINSTR128);
+ MERGE_FEATURE_4B("PRFMSLC bits [43:40]" , isar2, 40, Ext::kPRFMSLC);
+ MERGE_FEATURE_4B("RPRFM bits [51:48]" , isar2, 48, Ext::kRPRFM);
+ MERGE_FEATURE_4B("CSSC bits [55:52]" , isar2, 52, Ext::kCSSC);
+ MERGE_FEATURE_4B("LUT bits [59:56]" , isar2, 56, Ext::kLUT);
+}
+
+// TODO: This register is not accessed at the moment.
+#if 0
+// Detects features based on the content of ID_AA64ISAR3_EL1register.
+ASMJIT_MAYBE_UNUSED
+static inline void detectAArch64FeaturesViaCPUID_AA64ISAR3(CpuInfo& cpu, uint64_t isar3) noexcept {
+ // ID_AA64ISAR3_EL1
+ // ================
+
+ MERGE_FEATURE_4B("CPA bits [3:0]" , isar3, 0, Ext::kCPA, Ext::kCPA2);
+ MERGE_FEATURE_4B("FAMINMAX bits [7:4]" , isar3, 4, Ext::kFAMINMAX);
+ MERGE_FEATURE_4B("TLBIW bits [11:8]" , isar3, 8, Ext::kTLBIW);
+}
#endif
+
+ASMJIT_MAYBE_UNUSED
+static inline void detectAArch64FeaturesViaCPUID_AA64MMFR0(CpuInfo& cpu, uint64_t mmfr0) noexcept {
+ // ID_AA64MMFR0_EL1
+ // ================
+
+ /*
+ MERGE_FEATURE_4B("PARange bits [3:0]" , mmfr0, 0, ...);
+ MERGE_FEATURE_4B("ASIDBits bits [7:4]" , mmfr0, 4, ...);
+ MERGE_FEATURE_4B("BigEnd bits [11:8]" , mmfr0, 8, ...);
+ MERGE_FEATURE_4B("SNSMem bits [15:12]" , mmfr0, 12, ...);
+ MERGE_FEATURE_4B("BigEndEL0 bits [19:16]" , mmfr0, 16, ...);
+ MERGE_FEATURE_4B("TGran16 bits [23:20]" , mmfr0, 20, ...);
+ MERGE_FEATURE_4B("TGran64 bits [27:24]" , mmfr0, 24, ...);
+ MERGE_FEATURE_4B("TGran4 bits [31:28]" , mmfr0, 28, ...);
+ MERGE_FEATURE_4B("TGran16_2 bits [35:32]" , mmfr0, 32, ...);
+ MERGE_FEATURE_4B("TGran64_2 bits [39:36]" , mmfr0, 36, ...);
+ MERGE_FEATURE_4B("TGran4_2 bits [43:40]" , mmfr0, 40, ...);
+ MERGE_FEATURE_4B("ExS bits [47:44]" , mmfr0, 44, ...);
+ */
+ MERGE_FEATURE_4B("FGT bits [59:56]" , mmfr0, 56, Ext::kFGT, Ext::kFGT2);
+ MERGE_FEATURE_4B("ECV bits [63:60]" , mmfr0, 60, Ext::kECV);
+}
+
+ASMJIT_MAYBE_UNUSED
+static inline void detectAArch64FeaturesViaCPUID_AA64MMFR1(CpuInfo& cpu, uint64_t mmfr1) noexcept {
+ // ID_AA64MMFR1_EL1
+ // ================
+
+ MERGE_FEATURE_4B("HAFDBS bits [3:0]" , mmfr1, 0, Ext::kHAFDBS, Ext::kNone, Ext::kHAFT, Ext::kHDBSS);
+ MERGE_FEATURE_4B("VMIDBits bits [7:4]" , mmfr1, 4, Ext::kVMID16);
+ MERGE_FEATURE_4B("VH bits [11:8]" , mmfr1, 8, Ext::kVHE);
+ MERGE_FEATURE_4B("HPDS bits [15:12]" , mmfr1, 12, Ext::kHPDS, Ext::kHPDS2);
+ MERGE_FEATURE_4B("LO bits [19:16]" , mmfr1, 16, Ext::kLOR);
+ MERGE_FEATURE_4B("PAN bits [23:20]" , mmfr1, 20, Ext::kPAN, Ext::kPAN2, Ext::kPAN3);
+ /*
+ MERGE_FEATURE_4B("SpecSEI bits [27:24]" , mmfr1, 24, ...);
+ */
+ MERGE_FEATURE_4B("XNX bits [31:28]" , mmfr1, 28, Ext::kXNX);
+ /*
+ MERGE_FEATURE_4B("TWED bits [35:32]" , mmfr1, 32, ...);
+ MERGE_FEATURE_4B("ETS bits [39:36]" , mmfr1, 36, ...);
+ */
+ MERGE_FEATURE_4B("HCX bits [43:40]" , mmfr1, 40, Ext::kHCX);
+ MERGE_FEATURE_4B("AFP bits [47:44]" , mmfr1, 44, Ext::kAFP);
+ /*
+ MERGE_FEATURE_4B("nTLBPA bits [51:48]" , mmfr1, 48, ...);
+ MERGE_FEATURE_4B("TIDCP1 bits [55:52]" , mmfr1, 52, ...);
+ */
+ MERGE_FEATURE_4B("CMOW bits [59:56]" , mmfr1, 56, Ext::kCMOW);
+ MERGE_FEATURE_4B("ECBHB bits [63:60]" , mmfr1, 60, Ext::kECBHB);
+}
+
+ASMJIT_MAYBE_UNUSED
+static inline void detectAArch64FeaturesViaCPUID_AA64MMFR2(CpuInfo& cpu, uint64_t mmfr2) noexcept {
+ // ID_AA64MMFR2_EL1
+ // ================
+
+ /*
+ MERGE_FEATURE_4B("CnP bits [3:0]" , mmfr2, 0, ...);
+ */
+ MERGE_FEATURE_4B("UAO bits [7:4]" , mmfr2, 4, Ext::kUAO);
+ /*
+ MERGE_FEATURE_4B("LSM bits [11:8]" , mmfr2, 8, ...);
+ MERGE_FEATURE_4B("IESB bits [15:12]" , mmfr2, 12, ...);
+ */
+ MERGE_FEATURE_4B("VARange bits [19:16]" , mmfr2, 16, Ext::kLVA, Ext::kLVA3);
+ MERGE_FEATURE_4B("CCIDX bits [23:20]" , mmfr2, 20, Ext::kCCIDX);
+ MERGE_FEATURE_4B("NV bits [27:24]" , mmfr2, 24, Ext::kNV, Ext::kNV2);
+ /*
+ MERGE_FEATURE_4B("ST bits [31:28]" , mmfr2, 28, ...);
+ */
+ MERGE_FEATURE_4B("AT bits [35:32]" , mmfr2, 32, Ext::kLSE2);
+ /*
+ MERGE_FEATURE_4B("IDS bits [39:36]" , mmfr2, 36, ...);
+ MERGE_FEATURE_4B("FWB bits [43:40]" , mmfr2, 40, ...);
+ MERGE_FEATURE_4B("TTL bits [51:48]" , mmfr2, 48, ...);
+ MERGE_FEATURE_4B("BBM bits [55:52]" , mmfr2, 52, ...);
+ MERGE_FEATURE_4B("EVT bits [59:56]" , mmfr2, 56, ...);
+ MERGE_FEATURE_4B("E0PD bits [63:60]" , mmfr2, 60, ...);
+ */
+}
+
+// Detects features based on the content of ID_AA64ZFR0_EL1 register.
+ASMJIT_MAYBE_UNUSED
+static inline void detectAArch64FeaturesViaCPUID_AA64ZFR0(CpuInfo& cpu, uint64_t zfr0) noexcept {
+ MERGE_FEATURE_4B("SVEver bits [3:0]" , zfr0, 0, Ext::kSVE2, Ext::kSVE2_1);
+ MERGE_FEATURE_4B("AES bits [7:4]" , zfr0, 4, Ext::kSVE_AES, Ext::kSVE_PMULL128);
+ MERGE_FEATURE_4B("BitPerm bits [19:16]" , zfr0, 16, Ext::kSVE_BITPERM);
+ MERGE_FEATURE_4B("BF16 bits [23:20]" , zfr0, 20, Ext::kSVE_BF16, Ext::kSVE_EBF16);
+ MERGE_FEATURE_4B("B16B16 bits [27:24]" , zfr0, 24, Ext::kSVE_B16B16);
+ MERGE_FEATURE_4B("SHA3 bits [35:32]" , zfr0, 32, Ext::kSVE_SHA3);
+ MERGE_FEATURE_4B("SM4 bits [43:40]" , zfr0, 40, Ext::kSVE_SM4);
+ MERGE_FEATURE_4B("I8MM bits [47:44]" , zfr0, 44, Ext::kSVE_I8MM);
+ MERGE_FEATURE_4B("F32MM bits [55:52]" , zfr0, 52, Ext::kSVE_F32MM);
+ MERGE_FEATURE_4B("F64MM bits [59:56]" , zfr0, 56, Ext::kSVE_F64MM);
+}
+
+ASMJIT_MAYBE_UNUSED
+static inline void detectAArch64FeaturesViaCPUID_AA64SMFR0(CpuInfo& cpu, uint64_t smfr0) noexcept {
+ MERGE_FEATURE_1B("SF8DP2 bit [28]" , smfr0, 29, Ext::kSSVE_FP8DOT2);
+ MERGE_FEATURE_1B("SF8DP4 bit [29]" , smfr0, 29, Ext::kSSVE_FP8DOT4);
+ MERGE_FEATURE_1B("SF8FMA bit [30]" , smfr0, 30, Ext::kSSVE_FP8FMA);
+ MERGE_FEATURE_1B("F32F32 bit [32]" , smfr0, 32, Ext::kSME_F32F32);
+ MERGE_FEATURE_1B("BI32I32 bit [33]" , smfr0, 33, Ext::kSME_BI32I32);
+ MERGE_FEATURE_1B("B16F32 bit [34]" , smfr0, 34, Ext::kSME_B16F32);
+ MERGE_FEATURE_1B("F16F32 bit [35]" , smfr0, 35, Ext::kSME_F16F32);
+ MERGE_FEATURE_4S("I8I32 bits [39:36]" , smfr0, 36, 0xF, Ext::kSME_I8I32);
+ MERGE_FEATURE_1B("F8F32 bit [40]" , smfr0, 40, Ext::kSME_F8F32);
+ MERGE_FEATURE_1B("F8F16 bit [41]" , smfr0, 41, Ext::kSME_F8F16);
+ MERGE_FEATURE_1B("F16F16 bit [42]" , smfr0, 42, Ext::kSME_F16F16);
+ MERGE_FEATURE_1B("B16B16 bit [43]" , smfr0, 43, Ext::kSME_B16B16);
+ MERGE_FEATURE_4S("I16I32 bits [47:44]" , smfr0, 44, 0x5, Ext::kSME_I16I32);
+ MERGE_FEATURE_1B("F64F64 bit [48]" , smfr0, 48, Ext::kSME_F64F64);
+ MERGE_FEATURE_4S("I16I64 bits [55:52]" , smfr0, 52, 0xF, Ext::kSME_I16I64);
+ MERGE_FEATURE_4B("SMEver bits [59:56]" , smfr0, 56, Ext::kSME2, Ext::kSME2_1);
+ MERGE_FEATURE_1B("LUTv2 bit [60]" , smfr0, 60, Ext::kSME_LUTv2);
+ MERGE_FEATURE_1B("FA64 bit [63]" , smfr0, 63, Ext::kSME_FA64);
+}
+
+#undef MERGE_FEATURE_4S
+#undef MERGE_FEATURE_4B
+#undef MERGE_FEATURE_2B
+#undef MERGE_FEATURE_1B
+#undef MERGE_FEATURE_NA
+
+// CpuInfo - Detect - ARM - CPU Vendor Features
+// ============================================
+
+// CPU features detection based on Apple family ID.
+enum class AppleFamilyId : uint32_t {
+ // Apple design.
+ kSWIFT = 0x1E2D6381u, // Apple A6/A6X (ARMv7s).
+ kCYCLONE = 0x37A09642u, // Apple A7 (ARMv8.0-A).
+ kTYPHOON = 0x2C91A47Eu, // Apple A8 (ARMv8.0-A).
+ kTWISTER = 0x92FB37C8u, // Apple A9 (ARMv8.0-A).
+ kHURRICANE = 0x67CEEE93u, // Apple A10 (ARMv8.1-A).
+ kMONSOON_MISTRAL = 0xE81E7EF6u, // Apple A11 (ARMv8.2-A).
+ kVORTEX_TEMPEST = 0x07D34B9Fu, // Apple A12 (ARMv8.3-A).
+ kLIGHTNING_THUNDER = 0x462504D2u, // Apple A13 (ARMv8.4-A).
+ kFIRESTORM_ICESTORM = 0x1B588BB3u, // Apple A14/M1 (ARMv8.5-A).
+ kAVALANCHE_BLIZZARD = 0XDA33D83Du, // Apple A15/M2.
+ kEVEREST_SAWTOOTH = 0X8765EDEAu // Apple A16.
+};
+
+ASMJIT_MAYBE_UNUSED
+static ASMJIT_FAVOR_SIZE bool detectARMFeaturesViaAppleFamilyId(CpuInfo& cpu) noexcept {
+ typedef AppleFamilyId Id;
+ CpuFeatures::ARM& features = cpu.features().arm();
+
+ switch (cpu.familyId()) {
+ // Apple A7-A9 (ARMv8.0-A).
+ case uint32_t(Id::kCYCLONE):
+ case uint32_t(Id::kTYPHOON):
+ case uint32_t(Id::kTWISTER):
+ populateARMv8AFeatures(features, 0);
+ features.add(Ext::kAES, Ext::kPMU, Ext::kPMULL, Ext::kSHA1, Ext::kSHA256);
+ return true;
+
+ // Apple A10 (ARMv8.0-A).
+ case uint32_t(Id::kHURRICANE):
+ populateARMv8AFeatures(features, 0);
+ features.add(Ext::kAES, Ext::kCRC32, Ext::kLOR, Ext::kPAN, Ext::kPMU, Ext::kPMULL, Ext::kRDM, Ext::kSHA1,
+ Ext::kSHA256, Ext::kVHE);
+ return true;
+
+ // Apple A11 (ARMv8.2-A).
+ case uint32_t(Id::kMONSOON_MISTRAL):
+ populateARMv8AFeatures(features, 2);
+ features.add(Ext::kAES, Ext::kFP16, Ext::kFP16CONV, Ext::kPMU, Ext::kPMULL, Ext::kSHA1, Ext::kSHA256);
+ return true;
+
+ // Apple A12 (ARMv8.3-A).
+ case uint32_t(Id::kVORTEX_TEMPEST):
+ populateARMv8AFeatures(features, 3);
+ features.add(Ext::kAES, Ext::kFP16, Ext::kFP16CONV, Ext::kPMU, Ext::kPMULL, Ext::kSHA1, Ext::kSHA256);
+ return true;
+
+ // Apple A13 (ARMv8.4-A).
+ case uint32_t(Id::kLIGHTNING_THUNDER):
+ populateARMv8AFeatures(features, 4);
+ features.add(Ext::kAES, Ext::kFHM, Ext::kFP16, Ext::kFP16CONV, Ext::kPMU, Ext::kPMULL, Ext::kSHA1,
+ Ext::kSHA256, Ext::kSHA3, Ext::kSHA512);
+ return true;
+
+ // Apple A14/M1 (ARMv8.5-A).
+ case uint32_t(Id::kFIRESTORM_ICESTORM):
+ populateARMv8AFeatures(features, 4);
+ features.add(Ext::kAES, Ext::kCSV2, Ext::kCSV3, Ext::kDPB2, Ext::kECV, Ext::kFHM, Ext::kFLAGM2,
+ Ext::kFP16, Ext::kFP16CONV, Ext::kFRINTTS, Ext::kPMU, Ext::kPMULL, Ext::kSB,
+ Ext::kSHA1, Ext::kSHA256, Ext::kSHA3, Ext::kSHA512, Ext::kSSBS);
+ return true;
+
+ // Apple A15/M2.
+ case uint32_t(Id::kAVALANCHE_BLIZZARD):
+ populateARMv8AFeatures(features, 6);
+ features.add(Ext::kAES, Ext::kFHM, Ext::kFP16, Ext::kFP16CONV, Ext::kPMU, Ext::kPMULL, Ext::kSHA1,
+ Ext::kSHA256, Ext::kSHA3, Ext::kSHA512);
+ return true;
+
+ // Apple A16.
+ case uint32_t(Id::kEVEREST_SAWTOOTH):
+ populateARMv8AFeatures(features, 6);
+ features.add(Ext::kAES, Ext::kFHM, Ext::kFP16, Ext::kFP16CONV, Ext::kHCX, Ext::kPMU, Ext::kPMULL,
+ Ext::kSHA1, Ext::kSHA256, Ext::kSHA3, Ext::kSHA512);
+ return true;
+
+ default:
+ return false;
+ }
}
+// CpuInfo - Detect - ARM - Compile Flags Features
+// ===============================================
+
// 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
+ASMJIT_MAYBE_UNUSED
+static ASMJIT_FAVOR_SIZE void detectAArch32FeaturesViaCompilerFlags(CpuInfo& cpu) noexcept {
+ DebugUtils::unused(cpu);
// ARM targets have no baseline at the moment.
-# if defined(__ARM_ARCH_7A__)
+#if defined(__ARM_ARCH_7A__)
cpu.addFeature(CpuFeatures::ARM::kARMv7);
-# endif
-# if defined(__ARM_ARCH_8A__)
+#endif
+
+#if defined(__ARM_ARCH_8A__)
cpu.addFeature(CpuFeatures::ARM::kARMv8a);
-# endif
+#endif
-# if defined(__TARGET_ARCH_THUMB)
+#if defined(__TARGET_ARCH_THUMB)
cpu.addFeature(CpuFeatures::ARM::kTHUMB);
-# if __TARGET_ARCH_THUMB >= 4
+#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);
+#if defined(__ARM_FEATURE_FMA)
+ cpu.addFeature(Ext::kFP);
#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);
+
+#if defined(__ARM_NEON)
+ cpu.addFeature(Ext::kASIMD);
#endif
-#if defined(__ARM_ARCH_8_5A__)
- cpu.addFeature(CpuFeatures::ARM::kARMv8_5a);
+
+#if defined(__ARM_FEATURE_IDIV) && defined(__TARGET_ARCH_THUMB)
+ cpu.addFeature(Ext::kIDIVT);
#endif
-#if defined(__ARM_ARCH_8_6A__)
- cpu.addFeature(CpuFeatures::ARM::kARMv8_6a);
+#if defined(__ARM_FEATURE_IDIV) && !defined(__TARGET_ARCH_THUMB)
+ cpu.addFeature(Ext::kIDIVA);
#endif
-#if defined(__ARM_ARCH_8_7A__)
- cpu.addFeature(CpuFeatures::ARM::kARMv8_7a);
+}
+#endif // ASMJIT_ARCH_ARM == 32
+
+#if ASMJIT_ARCH_ARM == 64
+ASMJIT_MAYBE_UNUSED
+static ASMJIT_FAVOR_SIZE void detectAArch64FeaturesViaCompilerFlags(CpuInfo& cpu) noexcept {
+ DebugUtils::unused(cpu);
+
+#if defined(__ARM_ARCH_9_5A__)
+ populateARMv9AFeatures(cpu.features().arm(), 5);
+#elif defined(__ARM_ARCH_9_4A__)
+ populateARMv9AFeatures(cpu.features().arm(), 4);
+#elif defined(__ARM_ARCH_9_3A__)
+ populateARMv9AFeatures(cpu.features().arm(), 3);
+#elif defined(__ARM_ARCH_9_2A__)
+ populateARMv9AFeatures(cpu.features().arm(), 2);
+#elif defined(__ARM_ARCH_9_1A__)
+ populateARMv9AFeatures(cpu.features().arm(), 1);
+#elif defined(__ARM_ARCH_9A__)
+ populateARMv9AFeatures(cpu.features().arm(), 0);
+#elif defined(__ARM_ARCH_8_9A__)
+ populateARMv8AFeatures(cpu.features().arm(), 9);
+#elif defined(__ARM_ARCH_8_8A__)
+ populateARMv8AFeatures(cpu.features().arm(), 8);
+#elif defined(__ARM_ARCH_8_7A__)
+ populateARMv8AFeatures(cpu.features().arm(), 7);
+#elif defined(__ARM_ARCH_8_6A__)
+ populateARMv8AFeatures(cpu.features().arm(), 6);
+#elif defined(__ARM_ARCH_8_5A__)
+ populateARMv8AFeatures(cpu.features().arm(), 5);
+#elif defined(__ARM_ARCH_8_4A__)
+ populateARMv8AFeatures(cpu.features().arm(), 4);
+#elif defined(__ARM_ARCH_8_3A__)
+ populateARMv8AFeatures(cpu.features().arm(), 3);
+#elif defined(__ARM_ARCH_8_2A__)
+ populateARMv8AFeatures(cpu.features().arm(), 2);
+#elif defined(__ARM_ARCH_8_1A__)
+ populateARMv8AFeatures(cpu.features().arm(), 1);
+#else
+ populateARMv8AFeatures(cpu.features().arm(), 0);
#endif
#if defined(__ARM_FEATURE_AES)
- cpu.addFeature(CpuFeatures::ARM::kAES);
+ cpu.addFeature(Ext::kAES);
#endif
#if defined(__ARM_FEATURE_BF16_SCALAR_ARITHMETIC) && defined(__ARM_FEATURE_BF16_VECTOR_ARITHMETIC)
- cpu.addFeature(CpuFeatures::ARM::kBF16);
+ cpu.addFeature(Ext::kBF16);
#endif
#if defined(__ARM_FEATURE_CRC32)
- cpu.addFeature(CpuFeatures::ARM::kCRC32);
+ cpu.addFeature(Ext::kCRC32);
#endif
#if defined(__ARM_FEATURE_CRYPTO)
- cpu.addFeature(CpuFeatures::ARM::kAES,
- CpuFeatures::ARM::kSHA1,
- CpuFeatures::ARM::kSHA2);
+ cpu.addFeature(Ext::kAES, Ext::kSHA1, Ext::kSHA256);
#endif
#if defined(__ARM_FEATURE_DOTPROD)
- cpu.addFeature(CpuFeatures::ARM::kDOTPROD);
+ cpu.addFeature(Ext::kDOTPROD);
#endif
#if defined(__ARM_FEATURE_FP16FML) || defined(__ARM_FEATURE_FP16_FML)
- cpu.addFeature(CpuFeatures::ARM::kFP16FML);
+ cpu.addFeature(Ext::kFHM);
#endif
#if defined(__ARM_FEATURE_FP16_SCALAR_ARITHMETIC)
- cpu.addFeature(CpuFeatures::ARM::kFP16FULL);
+ cpu.addFeature(Ext::kFP16);
#endif
#if defined(__ARM_FEATURE_FRINT)
- cpu.addFeature(CpuFeatures::ARM::kFRINT);
+ cpu.addFeature(Ext::kFRINTTS);
#endif
#if defined(__ARM_FEATURE_JCVT)
- cpu.addFeature(CpuFeatures::ARM::kFJCVTZS);
+ cpu.addFeature(Ext::kJSCVT);
#endif
#if defined(__ARM_FEATURE_MATMUL_INT8)
- cpu.addFeature(CpuFeatures::ARM::kI8MM);
+ cpu.addFeature(Ext::kI8MM);
#endif
#if defined(__ARM_FEATURE_ATOMICS)
- cpu.addFeature(CpuFeatures::ARM::kLSE);
+ cpu.addFeature(Ext::kLSE);
#endif
#if defined(__ARM_FEATURE_MEMORY_TAGGING)
- cpu.addFeature(CpuFeatures::ARM::kMTE);
+ cpu.addFeature(Ext::kMTE);
#endif
#if defined(__ARM_FEATURE_QRDMX)
- cpu.addFeature(CpuFeatures::ARM::kRDM);
+ cpu.addFeature(Ext::kRDM);
#endif
#if defined(__ARM_FEATURE_RNG)
- cpu.addFeature(CpuFeatures::ARM::kRNG);
+ cpu.addFeature(Ext::kRNG);
#endif
#if defined(__ARM_FEATURE_SHA2)
- cpu.addFeature(CpuFeatures::ARM::kSHA2);
+ cpu.addFeature(Ext::kSHA256);
#endif
#if defined(__ARM_FEATURE_SHA3)
- cpu.addFeature(CpuFeatures::ARM::kSHA3);
+ cpu.addFeature(Ext::kSHA3);
#endif
#if defined(__ARM_FEATURE_SHA512)
- cpu.addFeature(CpuFeatures::ARM::kSHA512);
+ cpu.addFeature(Ext::kSHA512);
#endif
#if defined(__ARM_FEATURE_SM3)
- cpu.addFeature(CpuFeatures::ARM::kSM3);
+ cpu.addFeature(Ext::kSM3);
#endif
#if defined(__ARM_FEATURE_SM4)
- cpu.addFeature(CpuFeatures::ARM::kSM4);
+ cpu.addFeature(Ext::kSM4);
#endif
#if defined(__ARM_FEATURE_SVE) || defined(__ARM_FEATURE_SVE_VECTOR_OPERATORS)
- cpu.addFeature(CpuFeatures::ARM::kSVE);
+ cpu.addFeature(Ext::kSVE);
#endif
#if defined(__ARM_FEATURE_SVE_MATMUL_INT8)
- cpu.addFeature(CpuFeatures::ARM::kSVE_I8MM);
+ cpu.addFeature(Ext::kSVE_I8MM);
#endif
#if defined(__ARM_FEATURE_SVE_MATMUL_FP32)
- cpu.addFeature(CpuFeatures::ARM::kSVE_F32MM);
+ cpu.addFeature(Ext::kSVE_F32MM);
#endif
#if defined(__ARM_FEATURE_SVE_MATMUL_FP64)
- cpu.addFeature(CpuFeatures::ARM::kSVE_F64MM);
+ cpu.addFeature(Ext::kSVE_F64MM);
#endif
#if defined(__ARM_FEATURE_SVE2)
- cpu.addFeature(CpuFeatures::ARM::kSVE2);
+ cpu.addFeature(Ext::kSVE2);
#endif
#if defined(__ARM_FEATURE_SVE2_AES)
- cpu.addFeature(CpuFeatures::ARM::kSVE2_AES);
+ cpu.addFeature(Ext::kSVE_AES);
#endif
#if defined(__ARM_FEATURE_SVE2_BITPERM)
- cpu.addFeature(CpuFeatures::ARM::kSVE2_BITPERM);
+ cpu.addFeature(Ext::kSVE_BITPERM);
#endif
#if defined(__ARM_FEATURE_SVE2_SHA3)
- cpu.addFeature(CpuFeatures::ARM::kSVE2_SHA3);
+ cpu.addFeature(Ext::kSVE_SHA3);
#endif
#if defined(__ARM_FEATURE_SVE2_SM4)
- cpu.addFeature(CpuFeatures::ARM::kSVE2_SM4);
+ cpu.addFeature(Ext::kSVE_SM4);
#endif
#if defined(__ARM_FEATURE_TME)
- cpu.addFeature(CpuFeatures::ARM::kTME);
+ cpu.addFeature(Ext::kTME);
#endif
}
+#endif // ASMJIT_ARCH_ARM == 64
ASMJIT_MAYBE_UNUSED
-static ASMJIT_FAVOR_SIZE void expandARMFeaturesByVersion(CpuInfo& cpu) noexcept {
- CpuFeatures::ARM& features = cpu.features().arm();
+static ASMJIT_FAVOR_SIZE void detectARMFeaturesViaCompilerFlags(CpuInfo& cpu) noexcept {
+#if ASMJIT_ARCH_ARM == 32
+ detectAArch32FeaturesViaCompilerFlags(cpu);
+#else
+ detectAArch64FeaturesViaCompilerFlags(cpu);
+#endif // ASMJIT_ARCH_ARM
+}
- if (features.hasARMv8_7a()) {
- features.add(CpuFeatures::ARM::kARMv8_6a);
- }
+// CpuInfo - Detect - ARM - Post Processing ARM Features
+// =====================================================
- if (features.hasARMv8_6a()) {
- features.add(CpuFeatures::ARM::kARMv8_5a,
- CpuFeatures::ARM::kBF16);
+// Postprocesses AArch32 features.
+ASMJIT_MAYBE_UNUSED
+static ASMJIT_FAVOR_SIZE void postProcessAArch32Features(CpuFeatures::ARM& features) noexcept {
+ DebugUtils::unused(features);
+}
- if (features.hasSVE())
- features.add(CpuFeatures::ARM::kSVE_I8MM);
- }
+// Postprocesses AArch64 features.
+//
+// The only reason to use this function is to deduce some flags from others.
+ASMJIT_MAYBE_UNUSED
+static ASMJIT_FAVOR_SIZE void postProcessAArch64Features(CpuFeatures::ARM& features) noexcept {
+ if (features.hasFP16())
+ features.add(Ext::kFP16CONV);
- 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.hasMTE3())
+ features.add(Ext::kMTE2);
- 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.hasMTE2())
+ features.add(Ext::kMTE);
- if (features.hasARMv8_3a()) {
- features.add(CpuFeatures::ARM::kARMv8_2a,
- CpuFeatures::ARM::kFCMA,
- CpuFeatures::ARM::kFJCVTZS);
- }
+ if (features.hasSSBS2())
+ features.add(Ext::kSSBS);
+}
- if (features.hasARMv8_2a()) {
- features.add(CpuFeatures::ARM::kARMv8_1a);
- }
+ASMJIT_MAYBE_UNUSED
+static ASMJIT_FAVOR_SIZE void postProcessARMCpuInfo(CpuInfo& cpu) noexcept {
+#if ASMJIT_ARCH_ARM == 32
+ postProcessAArch32Features(cpu.features().arm());
+#else
+ postProcessAArch64Features(cpu.features().arm());
+#endif // ASMJIT_ARCH_ARM
+}
+
+// CpuInfo - Detect - ARM - Detect by Reading CPUID Registers
+// ==========================================================
- if (features.hasARMv8_1a()) {
- features.add(CpuFeatures::ARM::kARMv8a,
- CpuFeatures::ARM::kCRC32,
- CpuFeatures::ARM::kLSE,
- CpuFeatures::ARM::kRDM);
+// Support CPUID-based detection on AArch64.
+#if defined(ASMJIT_ARM_DETECT_VIA_CPUID)
+
+// Since the register ID is encoded with the instruction we have to create a function for each register ID to read.
+#define ASMJIT_AARCH64_DEFINE_CPUID_READ_FN(func, regId) \
+ASMJIT_MAYBE_UNUSED \
+static inline uint64_t func() noexcept { \
+ uint64_t output; \
+ __asm__ __volatile__("mrs %0, " #regId : "=r"(output)); \
+ return output; \
+}
+
+// NOTE: Older tools don't know the IDs. For example Ubuntu on RPI (GCC 9) won't compile ID_AA64ISAR2_EL1 in 2023.
+ASMJIT_AARCH64_DEFINE_CPUID_READ_FN(aarch64ReadPFR0, ID_AA64PFR0_EL1)
+ASMJIT_AARCH64_DEFINE_CPUID_READ_FN(aarch64ReadPFR1, ID_AA64PFR1_EL1)
+ASMJIT_AARCH64_DEFINE_CPUID_READ_FN(aarch64ReadISAR0, ID_AA64ISAR0_EL1)
+ASMJIT_AARCH64_DEFINE_CPUID_READ_FN(aarch64ReadISAR1, ID_AA64ISAR1_EL1)
+ASMJIT_AARCH64_DEFINE_CPUID_READ_FN(aarch64ReadISAR2, S3_0_C0_C6_2) // ID_AA64ISAR2_EL1
+ASMJIT_AARCH64_DEFINE_CPUID_READ_FN(aarch64ReadZFR0, S3_0_C0_C4_4) // ID_AA64ZFR0_EL1
+
+#undef ASMJIT_AARCH64_DEFINE_CPUID_READ_FN
+
+// Detects AArch64 features by reading CPUID bits directly from CPUID registers. This is the most reliable method
+// as the OS doesn't have to know all supported extensions this way (if there is something missing in HWCAPS then
+// there is no way to detect such feature without reading CPUID bits).
+//
+// This function uses MSR instructions, which means that it reads registers that cannot be read in user-mode. The
+// OS typically implements this feature by handling SIGILL internally and providing a filtered content of these
+// registers back to the user - at least this is what Linux documentation states - everything implementation
+// dependent is zeroed, only the bits that are used for CPU feature identification would be present.
+//
+// References:
+// - https://docs.kernel.org/arch/arm64/cpu-feature-registers.html
+ASMJIT_MAYBE_UNUSED
+static ASMJIT_FAVOR_SIZE void detectAArch64FeaturesViaCPUID(CpuInfo& cpu) noexcept {
+ populateBaseARMFeatures(cpu);
+
+ detectAArch64FeaturesViaCPUID_AA64PFR0_AA64PFR1(cpu,
+ aarch64ReadPFR0(),
+ aarch64ReadPFR1());
+
+ detectAArch64FeaturesViaCPUID_AA64ISAR0_AA64ISAR1(cpu,
+ aarch64ReadISAR0(),
+ aarch64ReadISAR1());
+
+ // TODO: Fix this on FreeBSD - I don't know what kernel version allows to access the registers below...
+
+#if defined(__linux__)
+ UNameKernelVersion kVer = getUNameKernelVersion();
+
+ // Introduced in Linux 4.19 by "arm64: add ID_AA64ISAR2_EL1 sys register"), so we want at least 4.20.
+ if (kVer.atLeast(4, 20)) {
+ detectAArch64FeaturesViaCPUID_AA64ISAR2(cpu, aarch64ReadISAR2());
}
- 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);
+ // Introduced in Linux 5.10 by "arm64: Expose SVE2 features for userspace", so we want at least 5.11.
+ if (kVer.atLeast(5, 11) && cpu.features().arm().hasAny(Ext::kSVE, Ext::kSME)) {
+ // Only read CPU_ID_AA64ZFR0 when either SVE or SME is available.
+ detectAArch64FeaturesViaCPUID_AA64ZFR0(cpu, aarch64ReadZFR0());
}
+#endif
}
-// CpuInfo - Detect - ARM [Windows]
-// ================================
+#endif // ASMJIT_ARM_DETECT_VIA_CPUID
+
+// CpuInfo - Detect - ARM - Detect by Windows API
+// ==============================================
#if defined(_WIN32)
struct WinPFPMapping {
@@ -749,9 +1501,11 @@ struct WinPFPMapping {
};
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))
+ for (size_t i = 0; i < size; i++) {
+ if (::IsProcessorFeaturePresent(mapping[i].pfpFeatureId)) {
cpu.addFeature(mapping[i].featureId);
+ }
+ }
}
//! Detect ARM CPU features on Windows.
@@ -763,400 +1517,495 @@ static ASMJIT_FAVOR_SIZE void detectARMCpu(CpuInfo& cpu) noexcept {
CpuFeatures::ARM& features = cpu.features().arm();
- // Win32 for ARM requires ARMv7 with DSP extensions, VFPv3, and uses THUMBv2 by default.
+ // Win32 for ARM requires ARMv7 with DSP extensions, VFPv3 (FP), 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);
+ features.add(Ext::kTHUMB);
+ features.add(Ext::kTHUMBv2);
+ features.add(Ext::kARMv6);
+ features.add(Ext::kARMv7);
+ features.add(Ext::kEDSP);
#endif
- // Windows for ARM requires ASIMD.
- features.add(CpuFeatures::ARM::kASIMD);
+ // Windows for ARM requires FP and ASIMD.
+ features.add(Ext::kFP);
+ features.add(Ext::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
+ { uint8_t(Ext::kVFP_D32) , 18 }, // PF_ARM_VFP_32_REGISTERS_AVAILABLE
+ { uint8_t(Ext::kIDIVT) , 24 }, // PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE
+ { uint8_t(Ext::kFMAC) , 27 }, // PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE
+ { uint8_t(Ext::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
-
+ { uint8_t(Ext::kAES) , 30 }, // PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE
+ { uint8_t(Ext::kCRC32) , 31 }, // PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE
+ { uint8_t(Ext::kLSE) , 34 }, // PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE
+ { uint8_t(Ext::kDOTPROD) , 43 }, // PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE
+ { uint8_t(Ext::kJSCVT) , 44 }, // PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE
+ { uint8_t(Ext::kLRCPC) , 45 } // PF_ARM_V83_LRCPC_INSTRUCTIONS_AVAILABLE
};
detectPFPFeatures(cpu, mapping, ASMJIT_ARRAY_SIZE(mapping));
+ // Windows can only report ARMv8A at the moment.
+ if (features.hasARMv8a()) {
+ populateARMv8AFeatures(cpu.features().arm(), 0);
+ }
+
// Windows provides several instructions under a single flag:
if (features.hasAES()) {
- features.add(CpuFeatures::ARM::kSHA1,
- CpuFeatures::ARM::kSHA2);
+ features.add(Ext::kPMULL, Ext::kSHA1, Ext::kSHA256);
}
- expandARMFeaturesByVersion(cpu);
+ postProcessARMCpuInfo(cpu);
}
-// CpuInfo - Detect - ARM [Linux]
-// ==============================
+// CpuInfo - Detect - ARM - Detect by Reading HWCAPS
+// =================================================
+
+#elif defined(ASMJIT_ARM_DETECT_VIA_HWCAPS)
+
+#ifndef AT_HWCAP
+ #define AT_HWCAP 16
+#endif // !AT_HWCAP
-#elif defined(__linux__)
+#ifndef AT_HWCAP2
+ #define AT_HWCAP2 26
+#endif // !AT_HWCAP2
+
+#if defined(__linux__)
+static void getAuxValues(unsigned long* vals, const unsigned long* tags, size_t count) noexcept {
+ for (size_t i = 0; i < count; i++) {
+ vals[i] = getauxval(tags[i]);
+ }
+}
+#elif defined(__FreeBSD__)
+static void getAuxValues(unsigned long* vals, const unsigned long* tags, size_t count) noexcept {
+ for (size_t i = 0; i < count; i++) {
+ unsigned long result = 0;
+ if (elf_aux_info(int(tags[i]), &result, int(sizeof(unsigned long))) != 0)
+ result = 0;
+ vals[i] = result;
+ }
+}
+#else
+#error "[asmjit] getAuxValues() - Unsupported OS."
+#endif
-struct LinuxHWCapMapping {
+struct HWCapMapping {
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++)
+static const unsigned long hwCapTags[2] = { AT_HWCAP, AT_HWCAP2 };
+
+static ASMJIT_FAVOR_SIZE void mergeHWCaps(CpuInfo& cpu, unsigned long mask, const HWCapMapping* mapping, size_t size) noexcept {
+ 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
+// Reference:
+// - https://github.com/torvalds/linux/blob/master/arch/arm/include/uapi/asm/hwcap.h
+static const HWCapMapping hwCapMapping[] = {
+ { uint8_t(Ext::kEDSP) , 7 }, // HWCAP_EDSP
+ { uint8_t(Ext::kASIMD) , 12 }, // HWCAP_NEON
+ { uint8_t(Ext::kFP) , 13 }, // HWCAP_VFPv3
+ { uint8_t(Ext::kFMAC) , 16 }, // HWCAP_VFPv4
+ { uint8_t(Ext::kIDIVA) , 17 }, // HWCAP_IDIVA
+ { uint8_t(Ext::kIDIVT) , 18 }, // HWCAP_IDIVT
+ { uint8_t(Ext::kVFP_D32) , 19 }, // HWCAP_VFPD32
+ { uint8_t(Ext::kFP16CONV) , 22 }, // HWCAP_FPHP
+ { uint8_t(Ext::kFP16) , 23 }, // HWCAP_ASIMDHP
+ { uint8_t(Ext::kDOTPROD) , 24 }, // HWCAP_ASIMDDP
+ { uint8_t(Ext::kFHM) , 25 }, // HWCAP_ASIMDFHM
+ { uint8_t(Ext::kBF16) , 26 }, // HWCAP_ASIMDBF16
+ { uint8_t(Ext::kI8MM) , 27 } // HWCAP_I8MM
};
-// `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 const HWCapMapping hwCap2Mapping[] = {
+ { uint8_t(Ext::kAES) , 0 }, // HWCAP2_AES
+ { uint8_t(Ext::kPMULL) , 1 }, // HWCAP2_PMULL
+ { uint8_t(Ext::kSHA1) , 2 }, // HWCAP2_SHA1
+ { uint8_t(Ext::kSHA256) , 3 }, // HWCAP2_SHA2
+ { uint8_t(Ext::kCRC32) , 4 }, // HWCAP2_CRC32
+ { uint8_t(Ext::kSB) , 5 }, // HWCAP2_SB
+ { uint8_t(Ext::kSSBS) , 6 } // HWCAP2_SSBS
};
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));
+ unsigned long hwCapMasks[2] {};
+ getAuxValues(hwCapMasks, hwCapTags, 2u);
- // VFPv3 implies VFPv2.
- if (features.hasVFPv3())
- features.add(CpuFeatures::ARM::kVFPv2);
+ mergeHWCaps(cpu, hwCapMasks[0], hwCapMapping, ASMJIT_ARRAY_SIZE(hwCapMapping));
+ mergeHWCaps(cpu, hwCapMasks[1], hwCap2Mapping, ASMJIT_ARRAY_SIZE(hwCap2Mapping));
- // VFPv2 implies ARMv6.
- if (features.hasVFPv2())
- features.add(CpuFeatures::ARM::kARMv6);
+ CpuFeatures::ARM& features = cpu.features().arm();
- // ARMv7 provides VFPv3|ASIMD.
- if (features.hasVFPv3() || features.hasASIMD())
+ // ARMv7 provides FP|ASIMD.
+ if (features.hasFP() || 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())
+ // ARMv8 provives AES, CRC32, PMULL, SHA1, and SHA256.
+ if (features.hasAES() || features.hasCRC32() || features.hasPMULL() || features.hasSHA1() || features.hasSHA256())
features.add(CpuFeatures::ARM::kARMv8a);
+
+ postProcessARMCpuInfo(cpu);
}
#else
-// `AT_HWCAP` provides ARMv8+ related flags.
-static const LinuxHWCapMapping hwCapMapping[] = {
+// Reference:
+// - https://docs.kernel.org/arch/arm64/elf_hwcaps.html
+// - https://github.com/torvalds/linux/blob/master/arch/arm64/include/uapi/asm/hwcap.h
+static const HWCapMapping hwCapMapping[] = {
+ { uint8_t(Ext::kFP) , 0 }, // HWCAP_FP
+ { uint8_t(Ext::kASIMD) , 1 }, // HWCAP_ASIMD
/*
- { uint8_t(CpuFeatures::ARM::k) , 0 }, // HWCAP_FP
+ { uint8_t(Ext::k) , 2 }, // HWCAP_EVTSTRM
*/
- { uint8_t(CpuFeatures::ARM::kASIMD) , 1 }, // HWCAP_ASIMD
+ { uint8_t(Ext::kAES) , 3 }, // HWCAP_AES
+ { uint8_t(Ext::kPMULL) , 4 }, // HWCAP_PMULL
+ { uint8_t(Ext::kSHA1) , 5 }, // HWCAP_SHA1
+ { uint8_t(Ext::kSHA256) , 6 }, // HWCAP_SHA2
+ { uint8_t(Ext::kCRC32) , 7 }, // HWCAP_CRC32
+ { uint8_t(Ext::kLSE) , 8 }, // HWCAP_ATOMICS
+ { uint8_t(Ext::kFP16CONV) , 9 }, // HWCAP_FPHP
+ { uint8_t(Ext::kFP16) , 10 }, // HWCAP_ASIMDHP
+ { uint8_t(Ext::kCPUID) , 11 }, // HWCAP_CPUID
+ { uint8_t(Ext::kRDM) , 12 }, // HWCAP_ASIMDRDM
+ { uint8_t(Ext::kJSCVT) , 13 }, // HWCAP_JSCVT
+ { uint8_t(Ext::kFCMA) , 14 }, // HWCAP_FCMA
+ { uint8_t(Ext::kLRCPC) , 15 }, // HWCAP_LRCPC
+ { uint8_t(Ext::kDPB) , 16 }, // HWCAP_DCPOP
+ { uint8_t(Ext::kSHA3) , 17 }, // HWCAP_SHA3
+ { uint8_t(Ext::kSM3) , 18 }, // HWCAP_SM3
+ { uint8_t(Ext::kSM4) , 19 }, // HWCAP_SM4
+ { uint8_t(Ext::kDOTPROD) , 20 }, // HWCAP_ASIMDDP
+ { uint8_t(Ext::kSHA512) , 21 }, // HWCAP_SHA512
+ { uint8_t(Ext::kSVE) , 22 }, // HWCAP_SVE
+ { uint8_t(Ext::kFHM) , 23 }, // HWCAP_ASIMDFHM
+ { uint8_t(Ext::kDIT) , 24 }, // HWCAP_DIT
+ { uint8_t(Ext::kLSE2) , 25 }, // HWCAP_USCAT
+ { uint8_t(Ext::kLRCPC2) , 26 }, // HWCAP_ILRCPC
+ { uint8_t(Ext::kFLAGM) , 27 }, // HWCAP_FLAGM
+ { uint8_t(Ext::kSSBS) , 28 }, // HWCAP_SSBS
+ { uint8_t(Ext::kSB) , 29 } // HWCAP_SB
/*
- { 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
+ { uint8_t(Ext::k) , 30 }, // HWCAP_PACA
+ { uint8_t(Ext::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 const HWCapMapping hwCap2Mapping[] = {
+ { uint8_t(Ext::kDPB2) , 0 }, // HWCAP2_DCPODP
+ { uint8_t(Ext::kSVE2) , 1 }, // HWCAP2_SVE2
+ { uint8_t(Ext::kSVE_AES) , 2 }, // HWCAP2_SVEAES
+ { uint8_t(Ext::kSVE_PMULL128) , 3 }, // HWCAP2_SVEPMULL
+ { uint8_t(Ext::kSVE_BITPERM) , 4 }, // HWCAP2_SVEBITPERM
+ { uint8_t(Ext::kSVE_SHA3) , 5 }, // HWCAP2_SVESHA3
+ { uint8_t(Ext::kSVE_SM4) , 6 }, // HWCAP2_SVESM4
+ { uint8_t(Ext::kFLAGM2) , 7 }, // HWCAP2_FLAGM2
+ { uint8_t(Ext::kFRINTTS) , 8 }, // HWCAP2_FRINT
+ { uint8_t(Ext::kSVE_I8MM) , 9 }, // HWCAP2_SVEI8MM
+ { uint8_t(Ext::kSVE_F32MM) , 10 }, // HWCAP2_SVEF32MM
+ { uint8_t(Ext::kSVE_F64MM) , 11 }, // HWCAP2_SVEF64MM
+ { uint8_t(Ext::kSVE_BF16) , 12 }, // HWCAP2_SVEBF16
+ { uint8_t(Ext::kI8MM) , 13 }, // HWCAP2_I8MM
+ { uint8_t(Ext::kBF16) , 14 }, // HWCAP2_BF16
+ { uint8_t(Ext::kDGH) , 15 }, // HWCAP2_DGH
+ { uint8_t(Ext::kRNG) , 16 }, // HWCAP2_RNG
+ { uint8_t(Ext::kBTI) , 17 }, // HWCAP2_BTI
+ { uint8_t(Ext::kMTE) , 18 }, // HWCAP2_MTE
+ { uint8_t(Ext::kECV) , 19 }, // HWCAP2_ECV
+ { uint8_t(Ext::kAFP) , 20 }, // HWCAP2_AFP
+ { uint8_t(Ext::kRPRES) , 21 }, // HWCAP2_RPRES
+ { uint8_t(Ext::kMTE3) , 22 }, // HWCAP2_MTE3
+ { uint8_t(Ext::kSME) , 23 }, // HWCAP2_SME
+ { uint8_t(Ext::kSME_I16I64) , 24 }, // HWCAP2_SME_I16I64
+ { uint8_t(Ext::kSME_F64F64) , 25 }, // HWCAP2_SME_F64F64
+ { uint8_t(Ext::kSME_I8I32) , 26 }, // HWCAP2_SME_I8I32
+ { uint8_t(Ext::kSME_F16F32) , 27 }, // HWCAP2_SME_F16F32
+ { uint8_t(Ext::kSME_B16F32) , 28 }, // HWCAP2_SME_B16F32
+ { uint8_t(Ext::kSME_F32F32) , 29 }, // HWCAP2_SME_F32F32
+ { uint8_t(Ext::kSME_FA64) , 30 }, // HWCAP2_SME_FA64
+ { uint8_t(Ext::kWFXT) , 31 }, // HWCAP2_WFXT
+ { uint8_t(Ext::kEBF16) , 32 }, // HWCAP2_EBF16
+ { uint8_t(Ext::kSVE_EBF16) , 33 }, // HWCAP2_SVE_EBF16
+ { uint8_t(Ext::kCSSC) , 34 }, // HWCAP2_CSSC
+ { uint8_t(Ext::kRPRFM) , 35 }, // HWCAP2_RPRFM
+ { uint8_t(Ext::kSVE2_1) , 36 }, // HWCAP2_SVE2P1
+ { uint8_t(Ext::kSME2) , 37 }, // HWCAP2_SME2
+ { uint8_t(Ext::kSME2_1) , 38 }, // HWCAP2_SME2P1
+ { uint8_t(Ext::kSME_I16I32) , 39 }, // HWCAP2_SME_I16I32
+ { uint8_t(Ext::kSME_BI32I32) , 40 }, // HWCAP2_SME_BI32I32
+ { uint8_t(Ext::kSME_B16B16) , 41 }, // HWCAP2_SME_B16B16
+ { uint8_t(Ext::kSME_F16F16) , 42 }, // HWCAP2_SME_F16F16
+ { uint8_t(Ext::kMOPS) , 43 }, // HWCAP2_MOPS
+ { uint8_t(Ext::kHBC) , 44 }, // HWCAP2_HBC
+ { uint8_t(Ext::kSVE_B16B16) , 45 }, // HWCAP2_SVE_B16B16
+ { uint8_t(Ext::kLRCPC3) , 46 }, // HWCAP2_LRCPC3
+ { uint8_t(Ext::kLSE128) , 47 }, // HWCAP2_LSE128
};
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));
-}
+ unsigned long hwCapMasks[2] {};
+ getAuxValues(hwCapMasks, hwCapTags, 2u);
-#endif
+ mergeHWCaps(cpu, hwCapMasks[0], hwCapMapping, ASMJIT_ARRAY_SIZE(hwCapMapping));
+ mergeHWCaps(cpu, hwCapMasks[1], hwCap2Mapping, ASMJIT_ARRAY_SIZE(hwCap2Mapping));
-// CpuInfo - Detect - ARM [Apple]
-// ==============================
+#if defined(ASMJIT_ARM_DETECT_VIA_CPUID)
+ if (cpu.features().arm().hasCPUID()) {
+ detectAArch64FeaturesViaCPUID(cpu);
+ return;
+ }
+#endif // ASMJIT_ARM_DETECT_VIA_CPUID
-#elif defined(__APPLE__)
+ postProcessARMCpuInfo(cpu);
+}
-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
- };
+#endif // ASMJIT_ARCH_ARM
+
+// CpuInfo - Detect - ARM - Detect by OpenBSD API That Reads CPUID
+// ===============================================================
+
+#elif defined(__OpenBSD__) && ASMJIT_ARCH_ARM >= 64
+
+// Supported CPUID registers on OpenBSD (CTL_MACHDEP definitions):
+// - https://github.com/openbsd/src/blob/master/sys/arch/arm64/include/cpu.h
+enum class OpenBSDAArch64CPUID {
+ kAA64ISAR0 = 2,
+ kAA64ISAR1 = 3,
+ kAA64ISAR2 = 4,
+ kAA64MMFR0 = 5,
+ kAA64MMFR1 = 6,
+ kAA64MMFR2 = 7,
+ kAA64PFR0 = 8,
+ kAA64PFR1 = 9,
+ kAA64SMFR0 = 10,
+ kAA64ZFR0 = 11
};
-static ASMJIT_FAVOR_SIZE uint32_t queryARMCpuFamilyId() noexcept {
- uint32_t result = 0;
- size_t size = sizeof(result);
+static uint64_t openbsdReadAArch64CPUID(OpenBSDAArch64CPUID id) noexcept {
+ uint64_t bits = 0;
+ size_t size = sizeof(bits);
+ int name[2] = { CTL_MACHDEP, int(id) };
- int res = sysctlbyname("hw.cpufamily", &result, &size, nullptr, 0);
- if (res != 0)
- return 0;
- else
- return result;
+ return (sysctl(name, 2, &bits, &size, NULL, 0) < 0) ? uint64_t(0) : bits;
}
static ASMJIT_FAVOR_SIZE void detectARMCpu(CpuInfo& cpu) noexcept {
- cpu._wasDetected = true;
+ typedef OpenBSDAArch64CPUID ID;
+
populateBaseARMFeatures(cpu);
- uint32_t cpuFamilyId = queryARMCpuFamilyId();
- CpuFeatures::ARM& features = cpu.features().arm();
+ detectAArch64FeaturesViaCPUID_AA64PFR0_AA64PFR1(cpu,
+ openbsdReadAArch64CPUID(ID::kAA64PFR0),
+ openbsdReadAArch64CPUID(ID::kAA64PFR1));
- switch (cpuFamilyId) {
- case AppleHWId::kCpuFamily_ARM_9:
- case AppleHWId::kCpuFamily_ARM_11:
- case AppleHWId::kCpuFamily_ARM_12:
- break;
+ detectAArch64FeaturesViaCPUID_AA64ISAR0_AA64ISAR1(cpu,
+ openbsdReadAArch64CPUID(ID::kAA64ISAR0),
+ openbsdReadAArch64CPUID(ID::kAA64ISAR1));
- // ARM Cortex A8.
- case AppleHWId::kCpuFamily_ARM_13:
- break;
+ detectAArch64FeaturesViaCPUID_AA64ISAR2(cpu, openbsdReadAArch64CPUID(ID::kAA64ISAR2));
+ detectAArch64FeaturesViaCPUID_AA64MMFR0(cpu, openbsdReadAArch64CPUID(ID::kAA64MMFR0));
+ detectAArch64FeaturesViaCPUID_AA64MMFR1(cpu, openbsdReadAArch64CPUID(ID::kAA64MMFR1));
+ detectAArch64FeaturesViaCPUID_AA64MMFR2(cpu, openbsdReadAArch64CPUID(ID::kAA64MMFR2));
- // ARM Cortex A9.
- case AppleHWId::kCpuFamily_ARM_14:
- break;
+ // Only read CPU_ID_AA64ZFR0 when either SVE or SME is available.
+ if (cpu.features().arm().hasAny(Ext::kSVE, Ext::kSME)) {
+ detectAArch64FeaturesViaCPUID_AA64ZFR0(cpu, openbsdReadAArch64CPUID(ID::kAA64ZFR0));
- // ARM Cortex A7 - ARMv7k.
- case AppleHWId::kCpuFamily_ARM_15:
- features.add(CpuFeatures::ARM::kARMv7);
- break;
+ if (cpu.features().arm().hasSME())
+ detectAArch64FeaturesViaCPUID_AA64SMFR0(cpu, openbsdReadAArch64CPUID(ID::kAA64SMFR0));
+ }
- // Apple A6/A6X - ARMv7s.
- case AppleHWId::kCpuFamily_SWIFT:
- features.add(CpuFeatures::ARM::kARMv7);
- break;
+ postProcessARMCpuInfo(cpu);
+}
- // Apple A7 - ARMv8.0-A.
- case AppleHWId::kCpuFamily_CYCLONE:
- features.add(CpuFeatures::ARM::kARMv8a,
- CpuFeatures::ARM::kAES,
- CpuFeatures::ARM::kSHA1,
- CpuFeatures::ARM::kSHA2);
- break;
+// CpuInfo - Detect - ARM - Detect by Apple API (sysctlbyname)
+// ===========================================================
- // Apple A8 - ARMv8.0-A.
- case AppleHWId::kCpuFamily_TYPHOON:
- features.add(CpuFeatures::ARM::kARMv8a,
- CpuFeatures::ARM::kAES,
- CpuFeatures::ARM::kSHA1,
- CpuFeatures::ARM::kSHA2);
- break;
+#elif defined(__APPLE__)
- // Apple A9 - ARMv8.0-A.
- case AppleHWId::kCpuFamily_TWISTER:
- features.add(CpuFeatures::ARM::kARMv8a,
- CpuFeatures::ARM::kAES,
- CpuFeatures::ARM::kSHA1,
- CpuFeatures::ARM::kSHA2);
- break;
+enum class AppleFeatureType : uint8_t {
+ kHWOptional,
+ kHWOptionalArmFEAT
+};
- // 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);
+struct AppleFeatureMapping {
+ AppleFeatureType type;
+ char name[18];
+ uint8_t featureId;
+};
- break;
+template<typename T>
+static inline bool appleSysctlByName(const char* sysctlName, T* dst, size_t size = sizeof(T)) noexcept {
+ return sysctlbyname(sysctlName, dst, &size, nullptr, 0) == 0;
+}
- // 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;
+static ASMJIT_FAVOR_SIZE long appleDetectARMFeatureViaSysctl(AppleFeatureType type, const char* featureName) noexcept {
+ static const char hwOptionalPrefix[] = "hw.optional.";
+ static const char hwOptionalArmFeatPrefix[] = "hw.optional.arm.FEAT_";
- // 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;
+ char sysctlName[128];
- // 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;
+ const char* prefix = type == AppleFeatureType::kHWOptional ? hwOptionalPrefix : hwOptionalArmFeatPrefix;
+ size_t prefixSize = (type == AppleFeatureType::kHWOptional ? sizeof(hwOptionalPrefix) : sizeof(hwOptionalArmFeatPrefix)) - 1u;
+ size_t featureNameSize = strlen(featureName);
- // 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;
+ if (featureNameSize < 128 - prefixSize) {
+ memcpy(sysctlName, prefix, prefixSize);
+ memcpy(sysctlName + prefixSize, featureName, featureNameSize + 1u); // Include NULL terminator.
- default:
- cpu._wasDetected = false;
- break;
+ long val = 0;
+ if (appleSysctlByName<long>(sysctlName, &val))
+ return val;
}
- expandARMFeaturesByVersion(cpu);
+ return 0;
}
-// CpuInfo - Detect - ARM [Unknown]
-// ================================
+static ASMJIT_FAVOR_SIZE void appleDetectARMFeaturesViaSysctl(CpuInfo& cpu) noexcept {
+ typedef AppleFeatureType FT;
+
+ // Based on:
+ // - https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics
+ static const AppleFeatureMapping mappings[] = {
+ // Determine Advanced SIMD and Floating Point Capabilities:
+ { FT::kHWOptional , "AdvSIMD_HPFPCvt", uint8_t(Ext::kFP16CONV) },
+ { FT::kHWOptional , "neon_hpfp" , uint8_t(Ext::kFP16CONV) },
+ { FT::kHWOptionalArmFEAT, "BF16" , uint8_t(Ext::kBF16) },
+ { FT::kHWOptionalArmFEAT, "DotProd" , uint8_t(Ext::kDOTPROD) },
+ { FT::kHWOptionalArmFEAT, "FCMA" , uint8_t(Ext::kFCMA) },
+ { FT::kHWOptional , "armv8_3_compnum", uint8_t(Ext::kFCMA) },
+ { FT::kHWOptionalArmFEAT, "FHM" , uint8_t(Ext::kFHM) },
+ { FT::kHWOptional , "armv8_2_fhm" , uint8_t(Ext::kFHM) },
+ { FT::kHWOptionalArmFEAT, "FP16" , uint8_t(Ext::kFP16) },
+ { FT::kHWOptional , "neon_fp16" , uint8_t(Ext::kFP16) },
+ { FT::kHWOptionalArmFEAT, "FRINTTS" , uint8_t(Ext::kFRINTTS) },
+ { FT::kHWOptionalArmFEAT, "I8MM" , uint8_t(Ext::kI8MM) },
+ { FT::kHWOptionalArmFEAT, "JSCVT" , uint8_t(Ext::kJSCVT) },
+ { FT::kHWOptionalArmFEAT, "RDM" , uint8_t(Ext::kRDM) },
+
+ // Determine Integer Capabilities:
+ { FT::kHWOptional , "armv8_crc32" , uint8_t(Ext::kCRC32) },
+ { FT::kHWOptionalArmFEAT, "FlagM" , uint8_t(Ext::kFLAGM) },
+ { FT::kHWOptionalArmFEAT, "FlagM2" , uint8_t(Ext::kFLAGM2) },
+
+ // Determine Atomic and Memory Ordering Instruction Capabilities:
+ { FT::kHWOptionalArmFEAT, "LRCPC" , uint8_t(Ext::kLRCPC) },
+ { FT::kHWOptionalArmFEAT, "LRCPC2" , uint8_t(Ext::kLRCPC2) },
+ { FT::kHWOptional , "armv8_1_atomics", uint8_t(Ext::kLSE) },
+ { FT::kHWOptionalArmFEAT, "LSE" , uint8_t(Ext::kLSE) },
+ { FT::kHWOptionalArmFEAT, "LSE2" , uint8_t(Ext::kLSE2) },
+
+ // Determine Encryption Capabilities:
+ { FT::kHWOptionalArmFEAT, "AES" , uint8_t(Ext::kAES) },
+ { FT::kHWOptionalArmFEAT, "PMULL" , uint8_t(Ext::kPMULL) },
+ { FT::kHWOptionalArmFEAT, "SHA1" , uint8_t(Ext::kSHA1) },
+ { FT::kHWOptionalArmFEAT, "SHA256" , uint8_t(Ext::kSHA256) },
+ { FT::kHWOptionalArmFEAT, "SHA512" , uint8_t(Ext::kSHA512) },
+ { FT::kHWOptional , "armv8_2_sha512" , uint8_t(Ext::kSHA512) },
+ { FT::kHWOptionalArmFEAT, "SHA3" , uint8_t(Ext::kSHA3) },
+ { FT::kHWOptional , "armv8_2_sha3" , uint8_t(Ext::kSHA3) },
+
+ // Determine General Capabilities:
+ { FT::kHWOptionalArmFEAT, "BTI" , uint8_t(Ext::kBTI) },
+ { FT::kHWOptionalArmFEAT, "DPB" , uint8_t(Ext::kDPB) },
+ { FT::kHWOptionalArmFEAT, "DPB2" , uint8_t(Ext::kDPB2) },
+ { FT::kHWOptionalArmFEAT, "ECV" , uint8_t(Ext::kECV) },
+ { FT::kHWOptionalArmFEAT, "SB" , uint8_t(Ext::kSB) },
+ { FT::kHWOptionalArmFEAT, "SSBS" , uint8_t(Ext::kSSBS) }
+ };
+
+ for (size_t i = 0; i < ASMJIT_ARRAY_SIZE(mappings); i++) {
+ const AppleFeatureMapping& mapping = mappings[i];
+ if (!cpu.features().arm().has(mapping.featureId) && appleDetectARMFeatureViaSysctl(mapping.type, mapping.name)) {
+ cpu.features().arm().add(mapping.featureId);
+ }
+ }
+}
+
+static ASMJIT_FAVOR_SIZE void detectARMCpu(CpuInfo& cpu) noexcept {
+ cpu._wasDetected = true;
+ populateBaseARMFeatures(cpu);
+
+ appleSysctlByName<uint32_t>("hw.cpufamily", &cpu._familyId);
+ appleSysctlByName<uint32_t>("hw.cachelinesize", &cpu._cacheLineSize);
+ appleSysctlByName<uint32_t>("machdep.cpu.logical_per_package", &cpu._maxLogicalProcessors);
+ appleSysctlByName<char>("machdep.cpu.brand_string", cpu._brand.str, sizeof(cpu._brand.str));
+
+ memcpy(cpu._vendor.str, "APPLE", 6);
+
+ bool cpuFeaturesPopulated = detectARMFeaturesViaAppleFamilyId(cpu);
+ if (!cpuFeaturesPopulated)
+ appleDetectARMFeaturesViaSysctl(cpu);
+ postProcessARMCpuInfo(cpu);
+}
+
+// CpuInfo - Detect - ARM - Detect by Fallback (Using Compiler Flags)
+// ==================================================================
#else
-#if ASMJIT_ARCH_ARM == 64
- #pragma message("[asmjit] Disabling runtime CPU detection - unsupported OS/CPU combination (Unknown OS with AArch64 CPU)")
+#if ASMJIT_ARCH_ARM == 32
+ #pragma message("[asmjit] Disabling runtime CPU detection - unsupported OS/CPU combination (Unknown OS with AArch32 CPU)")
#else
- #pragma message("[asmjit] Disabling runtime CPU detection - unsupported OS/CPU combination (Unknown OS with ARM CPU)")
+ #pragma message("[asmjit] Disabling runtime CPU detection - unsupported OS/CPU combination (Unknown OS with AArch64 CPU)")
#endif
static ASMJIT_FAVOR_SIZE void detectARMCpu(CpuInfo& cpu) noexcept {
populateBaseARMFeatures(cpu);
detectARMFeaturesViaCompilerFlags(cpu);
- expandARMFeaturesByVersion(cpu);
+ postProcessARMCpuInfo(cpu);
}
#endif
+} // {arm}
+
#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. In the worst case we
- // would just overwrite it non-atomically.
- if (!cpuInfoInitialized) {
+ static std::atomic<uint32_t> cpuInfoInitialized;
+ static CpuInfo cpuInfoGlobal(Globals::NoInit);
+
+ // This should never cause a problem as the resulting information should always
+ // be the same. In the worst case it would just be overwritten non-atomically.
+ if (!cpuInfoInitialized.load(std::memory_order_relaxed)) {
CpuInfo cpuInfoLocal;
cpuInfoLocal._arch = Arch::kHost;
cpuInfoLocal._subArch = SubArch::kHost;
#if ASMJIT_ARCH_X86
- detectX86Cpu(cpuInfoLocal);
+ x86::detectX86Cpu(cpuInfoLocal);
#elif ASMJIT_ARCH_ARM
- detectARMCpu(cpuInfoLocal);
-#else
- #pragma message("[asmjit] Disabling runtime CPU detection - unsupported OS/CPU combination (Unknown CPU)")
+ arm::detectARMCpu(cpuInfoLocal);
#endif
cpuInfoLocal._hwThreadCount = detectHWThreadCount();
cpuInfoGlobal = cpuInfoLocal;
- cpuInfoInitialized = 1;
+ cpuInfoInitialized.store(1, std::memory_order_seq_cst);
}
return cpuInfoGlobal;
}
+#if defined(_MSC_VER)
+ #pragma warning(pop)
+#endif // _MSC_VER
+
ASMJIT_END_NAMESPACE
diff --git a/3rdparty/asmjit/src/asmjit/core/cpuinfo.h b/3rdparty/asmjit/src/asmjit/core/cpuinfo.h
index 4af5c3a82f9..2638146a4cc 100644
--- a/3rdparty/asmjit/src/asmjit/core/cpuinfo.h
+++ b/3rdparty/asmjit/src/asmjit/core/cpuinfo.h
@@ -22,11 +22,6 @@ ASMJIT_BEGIN_NAMESPACE
//! 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
//! \{
@@ -37,6 +32,13 @@ public:
};
//! \endcond
+ //! 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;
+
+ typedef Support::Array<BitWord, kNumBitWords> Bits;
+
//! \}
//! \name Data
@@ -48,15 +50,15 @@ public:
//! \{
//! Data bits.
- Support::Array<BitWord, kNumBitWords> _bits;
+ Bits _bits;
//! \}
//! \name Overloaded Operators
//! \{
- inline bool operator==(const Data& other) noexcept { return eq(other); }
- inline bool operator!=(const Data& other) noexcept { return !eq(other); }
+ ASMJIT_INLINE_NODEBUG bool operator==(const Data& other) const noexcept { return equals(other); }
+ ASMJIT_INLINE_NODEBUG bool operator!=(const Data& other) const noexcept { return !equals(other); }
//! \}
@@ -64,22 +66,22 @@ public:
//! \{
//! Returns true if there are no features set.
- inline bool empty() const noexcept { return _bits.aggregate<Support::Or>(0) == 0; }
+ ASMJIT_INLINE_NODEBUG 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(); }
+ ASMJIT_INLINE_NODEBUG BitWord* bits() noexcept { return _bits.data(); }
//! Returns all features as array of bitwords (const).
- inline const BitWord* bits() const noexcept { return _bits.data(); }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG 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_INLINE_NODEBUG bool has(const FeatureId& featureId) const noexcept {
ASMJIT_ASSERT(uint32_t(featureId) < kMaxFeatures);
uint32_t idx = uint32_t(featureId) / Support::kBitWordSizeInBits;
@@ -88,12 +90,27 @@ public:
return bool((_bits[idx] >> bit) & 0x1);
}
+ //! \cond NONE
+ template<typename FeatureId>
+ ASMJIT_INLINE_NODEBUG bool hasAny(const FeatureId& featureId) const noexcept {
+ return has(featureId);
+ }
+ //! \endcond
+
+ //! Tests whether any feature given is present.
+ //!
+ //! \note This is a variadic function template that can be used with multiple features.
+ template<typename FeatureId, typename... Args>
+ ASMJIT_INLINE_NODEBUG bool hasAny(const FeatureId& featureId, Args&&... otherFeatureIds) const noexcept {
+ return bool(unsigned(has(featureId)) | unsigned(hasAny(std::forward<Args>(otherFeatureIds)...)));
+ }
+
//! Tests whether all features as defined by `other` are present.
- ASMJIT_FORCE_INLINE bool hasAll(const Data& other) const noexcept {
+ ASMJIT_INLINE_NODEBUG bool hasAll(const Data& other) const noexcept {
+ uint32_t result = 1;
for (uint32_t i = 0; i < kNumBitWords; i++)
- if ((_bits[i] & other._bits[i]) != other._bits[i])
- return false;
- return true;
+ result &= uint32_t((_bits[i] & other._bits[i]) == other._bits[i]);
+ return bool(result);
}
//! \}
@@ -101,11 +118,12 @@ public:
//! \name Manipulation
//! \{
- inline void reset() noexcept { _bits.fill(0); }
+ //! Clears all features set.
+ ASMJIT_INLINE_NODEBUG 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_INLINE_NODEBUG void add(const FeatureId& featureId) noexcept {
ASMJIT_ASSERT(uint32_t(featureId) < kMaxFeatures);
uint32_t idx = uint32_t(featureId) / Support::kBitWordSizeInBits;
@@ -115,13 +133,13 @@ public:
}
template<typename FeatureId, typename... Args>
- ASMJIT_FORCE_INLINE void add(const FeatureId& featureId, Args&&... otherFeatureIds) noexcept {
+ ASMJIT_INLINE_NODEBUG 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_INLINE_NODEBUG void addIf(bool condition, const FeatureId& featureId) noexcept {
ASMJIT_ASSERT(uint32_t(featureId) < kMaxFeatures);
uint32_t idx = uint32_t(featureId) / Support::kBitWordSizeInBits;
@@ -131,14 +149,14 @@ public:
}
template<typename FeatureId, typename... Args>
- ASMJIT_FORCE_INLINE void addIf(bool condition, const FeatureId& featureId, Args&&... otherFeatureIds) noexcept {
+ ASMJIT_INLINE_NODEBUG 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_INLINE_NODEBUG void remove(const FeatureId& featureId) noexcept {
ASMJIT_ASSERT(uint32_t(featureId) < kMaxFeatures);
uint32_t idx = uint32_t(featureId) / Support::kBitWordSizeInBits;
@@ -148,17 +166,21 @@ public:
}
template<typename FeatureId, typename... Args>
- ASMJIT_FORCE_INLINE void remove(const FeatureId& featureId, Args&&... otherFeatureIds) noexcept {
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG bool equals(const Data& other) const noexcept { return _bits == other._bits; }
- //! \}
+#if !defined(ASMJIT_NO_DEPRECATED)
+ ASMJIT_DEPRECATED("Use CpuFeatures::Data::equals() instead")
+ ASMJIT_INLINE_NODEBUG bool eq(const Data& other) const noexcept { return equals(other); }
+#endif // !ASMJIT_NO_DEPRECATED
- };
+ //! \}
+ };
//! X86 specific features data.
struct X86 : public Data {
@@ -169,68 +191,83 @@ public:
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].
+ k3DNOW, //!< CPU has 3DNOW (3DNOW base instructions) {AMD} (deprecated).
+ k3DNOW2, //!< CPU has 3DNOW2 (enhanced 3DNOW) {AMD} (deprecated).
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).
+ 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 (AMX-BF16 instructions).
+ kAMX_COMPLEX, //!< CPU has AMX_COMPLEX (AMX-COMPLEX instructions).
+ kAMX_FP16, //!< CPU has AMX_FP16 (AMX-FP16 instructions).
+ kAMX_INT8, //!< CPU has AMX_INT8 (AMX-INT8 instructions).
kAMX_TILE, //!< CPU has AMX_TILE (advanced matrix extensions).
+ kAPX_F, //!< CPU has APX_F (advanced performance extensions - 32 GP registers, REX2 prefix, ...) {X86_64}.
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_BF16, //!< CPU has AVX512_BF16 (AVX512 BFLOAT16 support instructions).
+ kAVX512_BITALG, //!< CPU has AVX512_BITALG (AVX512 VPOPCNT[B|W] and VPSHUFBITQMB instructions).
+ kAVX512_BW, //!< CPU has AVX512_BW (AVX512 integer BYTE|WORD instructions).
+ kAVX512_CD, //!< CPU has AVX512_CD (AVX512 conflict detection DWORD|QWORD instructions).
+ kAVX512_DQ, //!< CPU has AVX512_DQ (AVX512 integer DWORD|QWORD instructions).
+ kAVX512_ER, //!< CPU has AVX512_ER (AVX512 exponential and reciprocal instructions).
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_FP16, //!< CPU has AVX512_FP16 (AVX512 FP16 instructions).
+ kAVX512_IFMA, //!< CPU has AVX512_IFMA (AVX512 integer fused-multiply-add using 52-bit precision).
+ kAVX512_PF, //!< CPU has AVX512_PF (AVX512 prefetch instructions).
+ kAVX512_VBMI, //!< CPU has AVX512_VBMI (AVX152 vector byte manipulation instructions).
+ kAVX512_VBMI2, //!< CPU has AVX512_VBMI2 (AVX512 vector byte manipulation instructions v2).
+ kAVX512_VL, //!< CPU has AVX512_VL (AVX512 vector length extensions).
+ kAVX512_VNNI, //!< CPU has AVX512_VNNI (AVX512 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).
+ kAVX512_VPOPCNTDQ, //!< CPU has AVX512_VPOPCNTDQ (AVX512 VPOPCNT[D|Q] instructions).
+ kAVX_IFMA, //!< CPU has AVX_IFMA (AVX/VEX encoding of vpmadd52huq/vpmadd52luq).
+ kAVX_NE_CONVERT, //!< CPU has AVX_NE_CONVERT.
+ kAVX_VNNI, //!< CPU has AVX_VNNI (AVX/VEX encoding of vpdpbusd/vpdpbusds/vpdpwssd/vpdpwssds).
+ kAVX_VNNI_INT16, //!< CPU has AVX_VNNI_INT16.
+ kAVX_VNNI_INT8, //!< CPU has AVX_VNNI_INT8.
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.
+ kCET_SSS, //!< CPU has CET-SSS.
kCLDEMOTE, //!< CPU has CLDEMOTE (cache line demote).
- kCLFLUSH, //!< CPU has CLFUSH (Cache Line flush).
- kCLFLUSHOPT, //!< CPU has CLFUSHOPT (Cache Line flush - optimized).
+ 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].
+ kCMPCCXADD, //!< CPU has CMPCCXADD.
+ 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).
+ kF16C, //!< CPU has F16C (AVX FP16 conversion instructions).
+ kFMA, //!< CPU has FMA (AVX fused-multiply-add - 3 operand form).
+ kFMA4, //!< CPU has FMA4 (AVX fused-multiply-add - 4 operand form) (deprecated).
kFPU, //!< CPU has FPU (FPU support).
kFSGSBASE, //!< CPU has FSGSBASE.
+ kFSRM, //!< CPU has FSRM (fast short REP MOVSB).
+ kFSRC, //!< CPU has FSRC (fast short REP CMPSB|SCASB).
+ kFSRS, //!< CPU has FSRS (fast short REP STOSB)
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).
+ kFZRM, //!< CPU has FZRM (fast zero-length REP MOVSB).
+ kGEODE, //!< CPU has GEODE extensions (GEODE 3DNOW additions) (deprecated).
+ 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].
+ kINVLPGB, //!< CPU has INVLPGB.
+ kLAHFSAHF, //!< CPU has LAHF/SAHF (LAHF/SAHF in 64-bit mode) {X86_64}.
+ kLAM, //!< CPU has LAM (linear address masking) {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).
+ kMMX, //!< CPU has MMX (MMX base instructions) (deprecated).
+ kMMX2, //!< CPU has MMX2 (MMX2 extensions or initial SSE extensions) (deprecated).
kMONITOR, //!< CPU has MONITOR (MONITOR/MWAIT instructions).
kMONITORX, //!< CPU has MONITORX (MONITORX/MWAITX instructions).
kMOVBE, //!< CPU has MOVBE (move with byte-order swap).
@@ -238,58 +275,78 @@ public:
kMOVDIRI, //!< CPU has MOVDIRI (move dword/qword as direct store).
kMPX, //!< CPU has MPX (memory protection extensions).
kMSR, //!< CPU has MSR (RDMSR/WRMSR instructions).
+ kMSRLIST, //!< CPU has MSRLIST.
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).
+ kPREFETCHI, //!< CPU has PREFETCHI.
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.
+ kRAO_INT, //!< CPU has RAO_INT (AADD, AAND, AOR, AXOR instructions).
+ kRMPQUERY, //!< CPU has RMPQUERY (RMPQUERY instruction).
+ kRDPID, //!< CPU has RDPID (RDPID instruction).
+ kRDPRU, //!< CPU has RDPRU (RDPRU instruction).
+ kRDRAND, //!< CPU has RDRAND (RDRAND instruction).
+ kRDSEED, //!< CPU has RDSEED (RDSEED instruction).
kRDTSC, //!< CPU has RDTSC.
kRDTSCP, //!< CPU has RDTSCP.
kRTM, //!< CPU has RTM.
+ kSEAM, //!< CPU has SEAM.
kSERIALIZE, //!< CPU has SERIALIZE.
+ kSEV, //!< CPU has SEV (secure encrypted virtualization).
+ kSEV_ES, //!< CPU has SEV_ES (SEV encrypted state).
+ kSEV_SNP, //!< CPU has SEV_SNP (SEV secure nested paging).
kSHA, //!< CPU has SHA (SHA-1 and SHA-256 instructions).
- kSKINIT, //!< CPU has SKINIT (SKINIT/STGI instructions) [AMD].
+ kSHA512, //!< CPU has SHA512 (SHA-512 instructions).
+ kSKINIT, //!< CPU has SKINIT (SKINIT/STGI instructions) {AMD}.
+ kSM3, //!< CPU has SM3 (SM3 hash extensions).
+ kSM4, //!< CPU has SM4 (SM4 cipher extensions).
kSMAP, //!< CPU has SMAP (supervisor-mode access prevention).
+ kSME , //!< CPU has SME (secure memory encryption).
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].
+ kSSE, //!< CPU has SSE (SSE instructions).
+ kSSE2, //!< CPU has SSE2 (SSE2 instructions).
+ kSSE3, //!< CPU has SSE3 (SSE3 instructions).
+ kSSE4_1, //!< CPU has SSE4.1 (SSE4.1 instructions).
+ kSSE4_2, //!< CPU has SSE4.2 (SSE4.2 instructions).
+ kSSE4A, //!< CPU has SSE4A (SSE4.A instructions) {AMD} (deprecated).
+ kSSSE3, //!< CPU has SSSE3 (SSSE3 instructions).
+ kSVM, //!< CPU has SVM (virtualization) {AMD}.
+ kTBM, //!< CPU has TBM (trailing bit manipulation) {AMD}.
+ kTSE, //!< CPU has TSE.
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].
+ 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].
+ kWRMSRNS, //!< CPU has WRMSRNS.
+ kXOP, //!< CPU has XOP (XOP instructions) {AMD} (deprecated).
kXSAVE, //!< CPU has XSAVE.
kXSAVEC, //!< CPU has XSAVEC.
kXSAVEOPT, //!< CPU has XSAVEOPT.
kXSAVES, //!< CPU has XSAVES.
// @EnumValuesEnd@
+#ifndef ASMJIT_NO_DEPRECATED
+ kAVX512_CDI = kAVX512_CD,
+ kAVX512_ERI = kAVX512_ER,
+ kAVX512_PFI = kAVX512_PF,
+#endif
+
kMaxValue = kXSAVES
};
#define ASMJIT_X86_FEATURE(FEATURE) \
- inline bool has##FEATURE() const noexcept { return has(X86::k##FEATURE); }
+ /*! Tests whether FEATURE is present. */ \
+ ASMJIT_INLINE_NODEBUG bool has##FEATURE() const noexcept { return has(X86::k##FEATURE); }
ASMJIT_X86_FEATURE(MT)
ASMJIT_X86_FEATURE(NX)
@@ -299,8 +356,11 @@ public:
ASMJIT_X86_FEATURE(AESNI)
ASMJIT_X86_FEATURE(ALTMOVCR8)
ASMJIT_X86_FEATURE(AMX_BF16)
+ ASMJIT_X86_FEATURE(AMX_COMPLEX)
+ ASMJIT_X86_FEATURE(AMX_FP16)
ASMJIT_X86_FEATURE(AMX_INT8)
ASMJIT_X86_FEATURE(AMX_TILE)
+ ASMJIT_X86_FEATURE(APX_F)
ASMJIT_X86_FEATURE(AVX)
ASMJIT_X86_FEATURE(AVX2)
ASMJIT_X86_FEATURE(AVX512_4FMAPS)
@@ -308,24 +368,29 @@ public:
ASMJIT_X86_FEATURE(AVX512_BF16)
ASMJIT_X86_FEATURE(AVX512_BITALG)
ASMJIT_X86_FEATURE(AVX512_BW)
- ASMJIT_X86_FEATURE(AVX512_CDI)
+ ASMJIT_X86_FEATURE(AVX512_CD)
ASMJIT_X86_FEATURE(AVX512_DQ)
- ASMJIT_X86_FEATURE(AVX512_ERI)
+ ASMJIT_X86_FEATURE(AVX512_ER)
ASMJIT_X86_FEATURE(AVX512_F)
ASMJIT_X86_FEATURE(AVX512_FP16)
ASMJIT_X86_FEATURE(AVX512_IFMA)
- ASMJIT_X86_FEATURE(AVX512_PFI)
+ ASMJIT_X86_FEATURE(AVX512_PF)
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_IFMA)
+ ASMJIT_X86_FEATURE(AVX_NE_CONVERT)
ASMJIT_X86_FEATURE(AVX_VNNI)
+ ASMJIT_X86_FEATURE(AVX_VNNI_INT16)
+ ASMJIT_X86_FEATURE(AVX_VNNI_INT8)
ASMJIT_X86_FEATURE(BMI)
ASMJIT_X86_FEATURE(BMI2)
ASMJIT_X86_FEATURE(CET_IBT)
ASMJIT_X86_FEATURE(CET_SS)
+ ASMJIT_X86_FEATURE(CET_SSS)
ASMJIT_X86_FEATURE(CLDEMOTE)
ASMJIT_X86_FEATURE(CLFLUSH)
ASMJIT_X86_FEATURE(CLFLUSHOPT)
@@ -342,14 +407,20 @@ public:
ASMJIT_X86_FEATURE(FMA4)
ASMJIT_X86_FEATURE(FPU)
ASMJIT_X86_FEATURE(FSGSBASE)
+ ASMJIT_X86_FEATURE(FSRM)
+ ASMJIT_X86_FEATURE(FSRC)
+ ASMJIT_X86_FEATURE(FSRS)
ASMJIT_X86_FEATURE(FXSR)
ASMJIT_X86_FEATURE(FXSROPT)
+ ASMJIT_X86_FEATURE(FZRM)
ASMJIT_X86_FEATURE(GEODE)
ASMJIT_X86_FEATURE(GFNI)
ASMJIT_X86_FEATURE(HLE)
ASMJIT_X86_FEATURE(HRESET)
ASMJIT_X86_FEATURE(I486)
+ ASMJIT_X86_FEATURE(INVLPGB)
ASMJIT_X86_FEATURE(LAHFSAHF)
+ ASMJIT_X86_FEATURE(LAM)
ASMJIT_X86_FEATURE(LWP)
ASMJIT_X86_FEATURE(LZCNT)
ASMJIT_X86_FEATURE(MCOMMIT)
@@ -362,15 +433,19 @@ public:
ASMJIT_X86_FEATURE(MOVDIRI)
ASMJIT_X86_FEATURE(MPX)
ASMJIT_X86_FEATURE(MSR)
+ ASMJIT_X86_FEATURE(MSRLIST)
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(PREFETCHI)
ASMJIT_X86_FEATURE(PREFETCHW)
ASMJIT_X86_FEATURE(PREFETCHWT1)
ASMJIT_X86_FEATURE(PTWRITE)
+ ASMJIT_X86_FEATURE(RAO_INT)
+ ASMJIT_X86_FEATURE(RMPQUERY)
ASMJIT_X86_FEATURE(RDPID)
ASMJIT_X86_FEATURE(RDPRU)
ASMJIT_X86_FEATURE(RDRAND)
@@ -378,13 +453,16 @@ public:
ASMJIT_X86_FEATURE(RDTSC)
ASMJIT_X86_FEATURE(RDTSCP)
ASMJIT_X86_FEATURE(RTM)
+ ASMJIT_X86_FEATURE(SEAM)
ASMJIT_X86_FEATURE(SERIALIZE)
+ ASMJIT_X86_FEATURE(SEV)
+ ASMJIT_X86_FEATURE(SEV_ES)
+ ASMJIT_X86_FEATURE(SEV_SNP)
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)
@@ -394,6 +472,7 @@ public:
ASMJIT_X86_FEATURE(SSSE3)
ASMJIT_X86_FEATURE(SVM)
ASMJIT_X86_FEATURE(TBM)
+ ASMJIT_X86_FEATURE(TSE)
ASMJIT_X86_FEATURE(TSX)
ASMJIT_X86_FEATURE(TSXLDTRK)
ASMJIT_X86_FEATURE(UINTR)
@@ -402,95 +481,248 @@ public:
ASMJIT_X86_FEATURE(VPCLMULQDQ)
ASMJIT_X86_FEATURE(WAITPKG)
ASMJIT_X86_FEATURE(WBNOINVD)
+ ASMJIT_X86_FEATURE(WRMSRNS)
ASMJIT_X86_FEATURE(XOP)
ASMJIT_X86_FEATURE(XSAVE)
ASMJIT_X86_FEATURE(XSAVEC)
ASMJIT_X86_FEATURE(XSAVEOPT)
ASMJIT_X86_FEATURE(XSAVES)
+#ifndef ASMJIT_NO_DEPRECATED
+ ASMJIT_DEPRECATED("Use hasAVX512_CD() instead")
+ ASMJIT_X86_FEATURE(AVX512_CDI)
+
+ ASMJIT_DEPRECATED("Use hasAVX512_ER() instead")
+ ASMJIT_X86_FEATURE(AVX512_ERI)
+
+ ASMJIT_DEPRECATED("Use hasAVX512_PF() instead")
+ ASMJIT_X86_FEATURE(AVX512_PFI)
+#endif
+
#undef ASMJIT_X86_FEATURE
};
//! ARM specific features data.
+ //!
+ //! Naming reference:
+ //! - https://developer.arm.com/downloads/-/exploration-tools/feature-names-for-a-profile
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.7-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).
+
+ kARMv6, //!< CPU is at least ARMv6 {A32}.
+ kARMv7, //!< CPU is at least ARMv7 {A32}.
+ kARMv8a, //!< CPU is at least ARMv8A.
+ kTHUMB, //!< CPU has THUMB (16-bit THUMB encoding) {A32}.
+ kTHUMBv2, //!< CPU has THUMBv2 (32-bit THUMB encoding) {A32}.
+
+ kABLE, //!< CPU has ABLE (address breakpoint linking extension) {A64}.
+ kADERR, //!< CPU has ADERR (asynchronous device error exceptions) {A64}.
+ kAES, //!< CPU has AES (ASIMD AES instructions).
+ kAFP, //!< CPU has AFP (alternate floating-point behavior) {A64}.
+ kAIE, //!< CPU has AIE (memory attribute index enhancement) {A64}.
+ kAMU1, //!< CPU has AMUv1 (activity monitors extension version 1) {A64}.
+ kAMU1_1, //!< CPU has AMUv1p1 (activity monitors extension version 1.1) {A64}.
+ kANERR, //!< CPU has ANERR (asynchronous normal error exception) {A64}.
+ kASIMD, //!< CPU has ASIMD (NEON on ARM/THUMB).
+ kBF16, //!< CPU has BF16 (BFloat16 instructions) {A64}.
+ kBRBE, //!< CPU has BRBE (branch record buffer extension) {A64}.
+ kBTI, //!< CPU has BTI (branch target identification).
+ kBWE, //!< CPU has BWE (breakpoint mismatch and range extension) {A64}.
+ kCCIDX, //!< CPU has CCIDX (extend of the CCSIDR number of sets).
+ kCHK, //!< CPU has CHK (check feature status - CHKFEAT instruction) {A64}.
+ kCLRBHB, //!< CPU has CLRBHB (clear BHB instruction).
+ kCMOW, //!< CPU has CMOW (control for cache maintenance permission) {A64}.
+ kCONSTPACFIELD, //!< CPU has CONSTPACFIELD (PAC algorithm enhancement) {A64}.
+ kCPA, //!< CPU has CPA (instruction-only Checked Pointer Arithmetic) {A64}.
+ kCPA2, //!< CPU has CPA2 (checked Pointer Arithmetic) {A64}.
+ kCPUID, //!< CPU has CPUID (CPUID registers accessible in user-space).
+ kCRC32, //!< CPU has CRC32 (CRC32 instructions).
+ kCSSC, //!< CPU has CSSC (common short sequence compression) {A64}.
+ kCSV2, //!< CPU has CSV2 (cache speculation variant 2 version 2.1) {A64}.
+ kCSV2_3, //!< CPU has CSV2_3 (cache speculation variant 2 version 3) {A64}.
+ kCSV3, //!< CPU has CSV3 (cache speculation Variant 3) {A64}.
+ kD128, //!< CPU has D128 (128-bit translation tables, 56 bit PA) {A64}.
+ kDGH, //!< CPU has DGH (data gathering hint) {A64}.
+ kDIT, //!< CPU has DIT (data independent timing of instructions).
+ kDOTPROD, //!< CPU has DOTPROD (ASIMD Int8 dot product instructions).
+ kDPB, //!< CPU has DPB (DC CVAP instruction) {A64}.
+ kDPB2, //!< CPU has DPB2 (DC CVADP instruction) {A64}.
+ kEBEP, //!< CPU has EBEP (exception-based event profiling) {A64}.
+ kEBF16, //!< CPU has EBF16 (extended BFloat16 mode) {A64}.
+ kECBHB, //!< CPU has ECBHB (exploitative control using branch history information) {A64}.
+ kECV, //!< CPU has ECV (enhanced counter virtualization).
+ kEDHSR, //!< CPU has EDHSR (support for EDHSR) {A64}.
+ kEDSP, //!< CPU has EDSP (ARM/THUMB only).
+ kFAMINMAX, //!< CPU has FAMINMAX (floating-point maximum and minimum absolute value instructions) {A64}.
+ kFCMA, //!< CPU has FCMA (FCADD/FCMLA).
+ kFGT, //!< CPU has FGT (fine-grained traps).
+ kFGT2, //!< CPU has FGT2 (fine-grained traps 2).
+ kFHM, //!< CPU has FHM (half-precision floating-point FMLAL instructions).
+ kFLAGM, //!< CPU has FLAGM (condition flag manipulation) {A64}.
+ kFLAGM2, //!< CPU has FLAGM2 (condition flag manipulation version v2) {A64}.
+ kFMAC, //!< CPU has FMAC (ARM/THUMB only).
+ kFP, //!< CPU has FP (floating-point) (on 32-bit ARM this means VFPv3).
+ kFP16, //!< CPU has FP16 (half-precision floating-point data processing).
+ kFP16CONV, //!< CPU has FP16CONV (half-precision float conversion).
+ kFP8, //!< CPU has FP8 (FP8 convert instructions) {A64}.
+ kFP8DOT2, //!< CPU has FP8DOT2 (FP8 2-way dot product to half-precision instructions) {A64}.
+ kFP8DOT4, //!< CPU has FP8DOT4 (FP8 4-way dot product to single-precision instructions) {A64}.
+ kFP8FMA, //!< CPU has FP8FMA (FP8 multiply-accumulate to half-precision and single-precision instructions) {A64}.
+ kFPMR, //!< CPU has FPMR (floating-point Mode Register) {A64}.
+ kFRINTTS, //!< CPU has FRINTTS (FRINT[32|64][X|Z] instructions) {A64}.
+ kGCS, //!< CPU has GCS (guarded control stack extension) {A64}.
+ kHACDBS, //!< CPU has HACDBS (hardware accelerator for cleaning Dirty state) {A64}.
+ kHAFDBS, //!< CPU has HAFDBS (hardware management of the access flag and dirty state) {A64}.
+ kHAFT, //!< CPU has HAFT (hardware managed access flag for table descriptors) {A64}.
+ kHDBSS, //!< CPU has HDBSS (hardware Dirty state tracking Structure) {A64}.
+ kHBC, //!< CPU has HBC (hinted conditional branches) {A64}.
+ kHCX, //!< CPU has HCX (support for the HCRX_EL2 register) {A64}.
+ kHPDS, //!< CPU has HPDS (hierarchical permission disables in translation tables ) {A64}.
+ kHPDS2, //!< CPU has HPDS2 (hierarchical permission disables) {A64}.
+ kI8MM, //!< CPU has I8MM (int8 matrix multiplication) {A64}.
+ kIDIVA, //!< CPU has IDIV (hardware SDIV and UDIV in ARM mode).
+ kIDIVT, //!< CPU has IDIV (hardware SDIV and UDIV in THUMB mode).
+ kITE, //!< CPU has ITE (instrumentation extension) {A64}.
+ kJSCVT, //!< CPU has JSCVT (JavaScript FJCVTS conversion instruction) {A64}.
+ kLOR, //!< CPU has LOR (limited ordering regions extension).
+ kLRCPC, //!< CPU has LRCPC (load-acquire RCpc instructions) {A64}.
+ kLRCPC2, //!< CPU has LRCPC2 (load-acquire RCpc instructions v2) {A64}.
+ kLRCPC3, //!< CPU has LRCPC3 (load-Acquire RCpc instructions v3) {A64}.
+ kLS64, //!< CPU has LS64 (64 byte loads/stores without return) {A64}.
+ kLS64_ACCDATA, //!< CPU has LS64_ACCDATA (64-byte EL0 stores with return) {A64}.
+ kLS64_V, //!< CPU has LS64_V (64-byte stores with return) {A64}.
+ kLSE, //!< CPU has LSE (large system extensions) {A64}.
+ kLSE128, //!< CPU has LSE128 (128-bit atomics) {A64}.
+ kLSE2, //!< CPU has LSE2 (large system extensions v2) {A64}.
+ kLUT, //!< CPU has LUT (lookup table instructions with 2-bit and 4-bit indices) {A64}.
+ kLVA, //!< CPU has LVA (large VA support) {A64}.
+ kLVA3, //!< CPU has LVA3 (56-bit VA) {A64}.
+ kMEC, //!< CPU has MEC (memory encryption contexts) {A64}.
+ kMOPS, //!< CPU has MOPS (memcpy and memset acceleration instructions) {A64}.
+ kMPAM, //!< CPU has MPAM (memory system partitioning and monitoring extension) {A64}.
+ kMTE, //!< CPU has MTE (instruction-only memory tagging extension) {A64}.
+ kMTE2, //!< CPU has MTE2 (full memory tagging extension) {A64}.
+ kMTE3, //!< CPU has MTE3 (MTE asymmetric fault handling) {A64}.
+ kMTE4, //!< CPU has MTE4 (MTE v4) {A64}.
+ kMTE_ASYM_FAULT, //!< CPU has MTE_ASYM_FAULT (memory tagging asymmetric faults) {A64}.
+ kMTE_ASYNC, //!< CPU has MTE_ASYNC (memory tagging asynchronous faulting) {A64}.
+ kMTE_CANONICAL_TAGS, //!< CPU has MTE_CANONICAL_TAGS (canonical tag checking for untagged memory) {A64}.
+ kMTE_NO_ADDRESS_TAGS, //!< CPU has MTE_NO_ADDRESS_TAGS (memory tagging with address tagging disabled) {A64}.
+ kMTE_PERM_S1, //!< CPU has MTE_PERM_S1 (allocation tag access permission) {A64}.
+ kMTE_STORE_ONLY, //!< CPU has MTE_STORE_ONLY (store-only tag checking) {A64}.
+ kMTE_TAGGED_FAR, //!< CPU has MTE_TAGGED_FAR (FAR_ELx on a tag check fault) {A64}.
+ kMTPMU, //!< CPU has MTPMU (multi-threaded PMU extensions) {A64}.
+ kNMI, //!< CPU has NMI (non-maskable Interrupt) {A64}.
+ kNV, //!< CPU has NV (nested virtualization enchancement) {A64}.
+ kNV2, //!< CPU has NV2 (enhanced support for nested virtualization) {A64}.
+ kPAN, //!< CPU has PAN (privileged access-never extension) {A64}.
+ kPAN2, //!< CPU has PAN2 (PAN s1e1R and s1e1W variants) {A64}.
+ kPAN3, //!< CPU has PAN3 (support for SCTLR_ELx.EPAN) {A64}.
+ kPAUTH, //!< CPU has PAUTH (pointer authentication extension) {A64}.
+ kPFAR, //!< CPU has PFAR (physical fault address registers) {A64}.
+ kPMU, //!< CPU has PMU {A64}.
+ kPMULL, //!< CPU has PMULL (ASIMD PMULL instructions) {A64}.
+ kPRFMSLC, //!< CPU has PRFMSLC (PRFM instructions support the SLC target) {A64}.
+ kRAS, //!< CPU has RAS (reliability, availability and serviceability extensions).
+ kRAS1_1, //!< CPU has RASv1p1 (RAS v1.1).
+ kRAS2, //!< CPU has RASv2 (RAS v2).
+ kRASSA2, //!< CPU has RASSAv2 (RAS v2 system architecture).
+ kRDM, //!< CPU has RDM (rounding double multiply accumulate) {A64}.
+ kRME, //!< CPU has RME (memory encryption contexts extension) {A64}.
+ kRNG, //!< CPU has RNG (random number generation).
+ kRNG_TRAP, //!< CPU has RNG_TRAP (random number trap to EL3 field) {A64}.
+ kRPRES, //!< CPU has RPRES (increased precision of reciprocal estimate and RSQRT estimate) {A64}.
+ kRPRFM, //!< CPU has RPRFM (range prefetch hint instruction).
+ kS1PIE, //!< CPU has S1PIE (permission model enhancements) {A64}.
+ kS1POE, //!< CPU has S1POE (permission model enhancements) {A64}.
+ kS2PIE, //!< CPU has S2PIE (permission model enhancements) {A64}.
+ kS2POE, //!< CPU has S2POE (permission model enhancements) {A64}.
+ kSB, //!< CPU has SB (speculative barrier).
+ kSCTLR2, //!< CPU has SCTLR2 (extension to SCTLR_ELx) {A64}.
+ kSEBEP, //!< CPU has SEBEP (synchronous exception-based event profiling) {A64}.
+ kSEL2, //!< CPU has SEL2 (secure EL2) {A64}.
+ kSHA1, //!< CPU has SHA1 (ASIMD SHA1 instructions).
+ kSHA256, //!< CPU has SHA256 (ASIMD SHA256 instructions).
+ kSHA3, //!< CPU has SHA3 (ASIMD EOR3, RAX1, XAR, and BCAX instructions).
+ kSHA512, //!< CPU has SHA512 (ASIMD SHA512 instructions).
+ kSM3, //!< CPU has SM3 (ASIMD SM3 instructions).
+ kSM4, //!< CPU has SM4 (ASIMD SM4 instructions).
+ kSME, //!< CPU has SME (SME v1 - scalable matrix extension) {A64}.
+ kSME2, //!< CPU has SME2 (SME v2) {A64}.
+ kSME2_1, //!< CPU has SME2p1 (SME v2.1) {A64}.
+ kSME_B16B16, //!< CPU has SME_B16B16 (SME non-widening BFloat16 to BFloat16 arithmetic) {A64}.
+ kSME_B16F32, //!< CPU has SME_B16F32 (BFMOPA and BFMOPS instructions that accumulate BFloat16 outer products into single-precision tiles) {A64}.
+ kSME_BI32I32, //!< CPU has SME_BI32I32 (BMOPA and BMOPS instructions that accumulate 1-bit binary outer products into 32-bit integer tiles) {A64}.
+ kSME_F16F16, //!< CPU has SME_F16F16 (SME2.1 non-widening half-precision FP16 to FP16 arithmetic) {A64}.
+ kSME_F16F32, //!< CPU has SME_F16F32 {A64}.
+ kSME_F32F32, //!< CPU has SME_F32F32 {A64}.
+ kSME_F64F64, //!< CPU has SME_F64F64 {A64}.
+ kSME_F8F16, //!< CPU has SME_F8F16 (SME2 ZA-targeting FP8 multiply-accumulate, dot product, and outer product to half-precision instructions) {A64}.
+ kSME_F8F32, //!< CPU has SME_F8F32 (SME2 ZA-targeting FP8 multiply-accumulate, dot product, and outer product to single-precision instructions) {A64}.
+ kSME_FA64, //!< CPU has SME_FA64 {A64}.
+ kSME_I16I32, //!< CPU has SME_I16I32 {A64}.
+ kSME_I16I64, //!< CPU has SME_I16I64 {A64}.
+ kSME_I8I32, //!< CPU has SME_I8I32 {A64}.
+ kSME_LUTv2, //!< CPU has SME_LUTv2 (lookup table instructions with 4-bit indices and 8-bit elements) {A64}.
+ kSPE, //!< CPU has SPE (statistical profiling extension) {A64}.
+ kSPE1_1, //!< CPU has SPEv1p1 (statistical profiling extensions version 1.1) {A64}.
+ kSPE1_2, //!< CPU has SPEv1p2 (statistical profiling extensions version 1.2) {A64}.
+ kSPE1_3, //!< CPU has SPEv1p3 (statistical profiling extensions version 1.3) {A64}.
+ kSPE1_4, //!< CPU has SPEv1p4 (statistical profiling extensions version 1.4) {A64}.
+ kSPE_ALTCLK, //!< CPU has SPE_ALTCLK (statistical profiling alternate clock domain extension) {A64}.
+ kSPE_CRR, //!< CPU has SPE_CRR (statistical profiling call return branch records) {A64}.
+ kSPE_EFT, //!< CPU has SPE_EFT (statistical profiling extended filtering by type) {A64}.
+ kSPE_FDS, //!< CPU has SPE_FDS (statistical profiling data source filtering) {A64}.
+ kSPE_FPF, //!< CPU has SPE_FPF (statistical profiling floating-point flag extension) {A64}.
+ kSPE_SME, //!< CPU has SPE_SME (statistical profiling extensions for SME) {A64}.
+ kSPECRES, //!< CPU has SPECRES (speculation restriction instructions).
+ kSPECRES2, //!< CPU has SPECRES2 (clear other speculative predictions).
+ kSPMU, //!< CPU has SPMU (system performance monitors extension) {A64}.
+ kSSBS, //!< CPU has SSBS (speculative store bypass safe instruction).
+ kSSBS2, //!< CPU has SSBS2 (MRS and MSR instructions for SSBS).
+ kSSVE_FP8DOT2, //!< CPU has SSVE_FP8DOT2 (SVE2 FP8 2-way dot product to half-precision instructions in Streaming SVE mode) {A64}.
+ kSSVE_FP8DOT4, //!< CPU has SSVE_FP8DOT4 (SVE2 FP8 4-way dot product to single-precision instructions in Streaming SVE mode) {A64}.
+ kSSVE_FP8FMA, //!< CPU has SSVE_FP8FMA (SVE2 FP8 multiply-accumulate to half-precision and single-precision instructions in Streaming SVE mode) {A64}.
+ kSVE, //!< CPU has SVE (SVE v1 - scalable vector extension) {A64}.
+ kSVE2, //!< CPU has SVE2 (SVE v2) {A64}.
+ kSVE2_1, //!< CPU has SVE2p1 (SVE v2.1) {A64}.
+ kSVE_AES, //!< CPU has SVE_AES (SVE AES instructions) {A64}.
+ kSVE_B16B16, //!< CPU has SVE_B16B16 (SVE non-widening BFloat16 to BFloat16 arithmetic) {A64}.
+ kSVE_BF16, //!< CPU has SVE_BF16 (SVE BF16 instructions) {A64}.
+ kSVE_BITPERM, //!< CPU has SVE_BITPERM (SVE bit permute) {A64}.
+ kSVE_EBF16, //!< CPU has SVE_EBF16 (SVE extended BFloat16 mode) {A64}.
+ kSVE_F32MM, //!< CPU has SVE_F32MM (SVE single-precision floating-point matrix multiply instruction) {A64}.
+ kSVE_F64MM, //!< CPU has SVE_F64MM (SVE double-precision floating-point matrix multiply instruction) {A64}.
+ kSVE_I8MM, //!< CPU has SVE_I8MM (SVE int8 matrix multiplication) {A64}.
+ kSVE_PMULL128, //!< CPU has SVE_PMULL128 (SVE PMULL instructions) {A64}.
+ kSVE_SHA3, //!< CPU has SVE_SHA3 (SVE SHA-3 instructions) {A64}.
+ kSVE_SM4, //!< CPU has SVE_SM4 (SVE SM4 instructions {A64}.
+ kSYSINSTR128, //!< CPU has SYSINSTR128 (128-bit system instructions) {A64}.
+ kSYSREG128, //!< CPU has SYSREG128 (128-bit system registers) {A64}.
+ kTHE, //!< CPU has THE (translation hardening extension).
+ kTLBIOS, //!< CPU has TLBIOS (TLBI instructions in Outer Shareable domain) {A64}.
+ kTLBIRANGE, //!< CPU has TLBIRANGE (TLBI range instructions) {A64}.
+ kTLBIW, //!< CPU has TLBIW (TLBI VMALL for dirty state) {A64}.
+ kTME, //!< CPU has TME (transactional memory extensions).
+ kTRF, //!< CPU has TRF (self-hosted trace extensions).
+ kUAO, //!< CPU has UAO (AArch64 v8.2 UAO PState) {A64}.
+ kVFP_D32, //!< CPU has VFP_D32 (32 VFP-D registers) (ARM/THUMB only).
+ kVHE, //!< CPU has VHE (virtual host extension).
+ kVMID16, //!< CPU has VMID16 (16-bit VMID) {A64}.
+ kWFXT, //!< CPU has WFxT (WFE and WFI instructions with timeout) {A64}.
+ kXNX, //!< CPU has XNX (translation table stage 2 unprivileged execute-never) {A64}.
+ kXS, //!< CPU has XS (XS attribute in TLBI and DSB instructions) {A64}.
// @EnumValuesEnd@
- kMaxValue = kTME
+ kMaxValue = kXS
};
#define ASMJIT_ARM_FEATURE(FEATURE) \
- inline bool has##FEATURE() const noexcept { return has(ARM::k##FEATURE); }
+ /*! Tests whether FEATURE is present. */ \
+ ASMJIT_INLINE_NODEBUG bool has##FEATURE() const noexcept { return has(ARM::k##FEATURE); }
ASMJIT_ARM_FEATURE(THUMB)
ASMJIT_ARM_FEATURE(THUMBv2)
@@ -498,67 +730,204 @@ public:
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(ABLE)
+ ASMJIT_ARM_FEATURE(ADERR)
ASMJIT_ARM_FEATURE(AES)
- ASMJIT_ARM_FEATURE(ALTNZCV)
+ ASMJIT_ARM_FEATURE(AFP)
+ ASMJIT_ARM_FEATURE(AIE)
+ ASMJIT_ARM_FEATURE(AMU1)
+ ASMJIT_ARM_FEATURE(AMU1_1)
+ ASMJIT_ARM_FEATURE(ANERR)
ASMJIT_ARM_FEATURE(ASIMD)
ASMJIT_ARM_FEATURE(BF16)
+ ASMJIT_ARM_FEATURE(BRBE)
ASMJIT_ARM_FEATURE(BTI)
+ ASMJIT_ARM_FEATURE(BWE)
+ ASMJIT_ARM_FEATURE(CCIDX)
+ ASMJIT_ARM_FEATURE(CHK)
+ ASMJIT_ARM_FEATURE(CLRBHB)
+ ASMJIT_ARM_FEATURE(CMOW)
+ ASMJIT_ARM_FEATURE(CONSTPACFIELD)
+ ASMJIT_ARM_FEATURE(CPA)
+ ASMJIT_ARM_FEATURE(CPA2)
ASMJIT_ARM_FEATURE(CPUID)
ASMJIT_ARM_FEATURE(CRC32)
+ ASMJIT_ARM_FEATURE(CSSC)
+ ASMJIT_ARM_FEATURE(CSV2)
+ ASMJIT_ARM_FEATURE(CSV2_3)
+ ASMJIT_ARM_FEATURE(CSV3)
+ ASMJIT_ARM_FEATURE(D128)
ASMJIT_ARM_FEATURE(DGH)
ASMJIT_ARM_FEATURE(DIT)
ASMJIT_ARM_FEATURE(DOTPROD)
+ ASMJIT_ARM_FEATURE(DPB)
+ ASMJIT_ARM_FEATURE(DPB2)
+ ASMJIT_ARM_FEATURE(EBEP)
+ ASMJIT_ARM_FEATURE(EBF16)
+ ASMJIT_ARM_FEATURE(ECBHB)
+ ASMJIT_ARM_FEATURE(ECV)
+ ASMJIT_ARM_FEATURE(EDHSR)
ASMJIT_ARM_FEATURE(EDSP)
+ ASMJIT_ARM_FEATURE(FAMINMAX)
ASMJIT_ARM_FEATURE(FCMA)
+ ASMJIT_ARM_FEATURE(FGT)
+ ASMJIT_ARM_FEATURE(FGT2)
+ ASMJIT_ARM_FEATURE(FHM)
ASMJIT_ARM_FEATURE(FLAGM)
+ ASMJIT_ARM_FEATURE(FLAGM2)
+ ASMJIT_ARM_FEATURE(FMAC)
+ ASMJIT_ARM_FEATURE(FP)
+ ASMJIT_ARM_FEATURE(FP16)
ASMJIT_ARM_FEATURE(FP16CONV)
- ASMJIT_ARM_FEATURE(FP16FML)
- ASMJIT_ARM_FEATURE(FP16FULL)
- ASMJIT_ARM_FEATURE(FRINT)
+ ASMJIT_ARM_FEATURE(FP8)
+ ASMJIT_ARM_FEATURE(FP8DOT2)
+ ASMJIT_ARM_FEATURE(FP8DOT4)
+ ASMJIT_ARM_FEATURE(FP8FMA)
+ ASMJIT_ARM_FEATURE(FPMR)
+ ASMJIT_ARM_FEATURE(FRINTTS)
+ ASMJIT_ARM_FEATURE(GCS)
+ ASMJIT_ARM_FEATURE(HACDBS)
+ ASMJIT_ARM_FEATURE(HAFDBS)
+ ASMJIT_ARM_FEATURE(HAFT)
+ ASMJIT_ARM_FEATURE(HDBSS)
+ ASMJIT_ARM_FEATURE(HBC)
+ ASMJIT_ARM_FEATURE(HCX)
+ ASMJIT_ARM_FEATURE(HPDS)
+ ASMJIT_ARM_FEATURE(HPDS2)
+ ASMJIT_ARM_FEATURE(I8MM)
ASMJIT_ARM_FEATURE(IDIVA)
ASMJIT_ARM_FEATURE(IDIVT)
+ ASMJIT_ARM_FEATURE(ITE)
+ ASMJIT_ARM_FEATURE(JSCVT)
+ ASMJIT_ARM_FEATURE(LOR)
+ ASMJIT_ARM_FEATURE(LRCPC)
+ ASMJIT_ARM_FEATURE(LRCPC2)
+ ASMJIT_ARM_FEATURE(LRCPC3)
+ ASMJIT_ARM_FEATURE(LS64)
+ ASMJIT_ARM_FEATURE(LS64_ACCDATA)
+ ASMJIT_ARM_FEATURE(LS64_V)
ASMJIT_ARM_FEATURE(LSE)
+ ASMJIT_ARM_FEATURE(LSE128)
+ ASMJIT_ARM_FEATURE(LSE2)
+ ASMJIT_ARM_FEATURE(LUT)
+ ASMJIT_ARM_FEATURE(LVA)
+ ASMJIT_ARM_FEATURE(LVA3)
+ ASMJIT_ARM_FEATURE(MEC)
+ ASMJIT_ARM_FEATURE(MOPS)
+ ASMJIT_ARM_FEATURE(MPAM)
ASMJIT_ARM_FEATURE(MTE)
- ASMJIT_ARM_FEATURE(FJCVTZS)
- ASMJIT_ARM_FEATURE(I8MM)
- ASMJIT_ARM_FEATURE(RCPC_IMMO)
- ASMJIT_ARM_FEATURE(RDM)
+ ASMJIT_ARM_FEATURE(MTE2)
+ ASMJIT_ARM_FEATURE(MTE3)
+ ASMJIT_ARM_FEATURE(MTE4)
+ ASMJIT_ARM_FEATURE(MTE_ASYM_FAULT)
+ ASMJIT_ARM_FEATURE(MTE_ASYNC)
+ ASMJIT_ARM_FEATURE(MTE_CANONICAL_TAGS)
+ ASMJIT_ARM_FEATURE(MTE_NO_ADDRESS_TAGS)
+ ASMJIT_ARM_FEATURE(MTE_PERM_S1)
+ ASMJIT_ARM_FEATURE(MTE_STORE_ONLY)
+ ASMJIT_ARM_FEATURE(MTE_TAGGED_FAR)
+ ASMJIT_ARM_FEATURE(MTPMU)
+ ASMJIT_ARM_FEATURE(NMI)
+ ASMJIT_ARM_FEATURE(NV)
+ ASMJIT_ARM_FEATURE(NV2)
+ ASMJIT_ARM_FEATURE(PAN)
+ ASMJIT_ARM_FEATURE(PAN2)
+ ASMJIT_ARM_FEATURE(PAN3)
+ ASMJIT_ARM_FEATURE(PAUTH)
+ ASMJIT_ARM_FEATURE(PFAR)
ASMJIT_ARM_FEATURE(PMU)
ASMJIT_ARM_FEATURE(PMULL)
+ ASMJIT_ARM_FEATURE(PRFMSLC)
+ ASMJIT_ARM_FEATURE(RAS)
+ ASMJIT_ARM_FEATURE(RAS1_1)
+ ASMJIT_ARM_FEATURE(RAS2)
+ ASMJIT_ARM_FEATURE(RASSA2)
+ ASMJIT_ARM_FEATURE(RDM)
+ ASMJIT_ARM_FEATURE(RME)
ASMJIT_ARM_FEATURE(RNG)
+ ASMJIT_ARM_FEATURE(RNG_TRAP)
+ ASMJIT_ARM_FEATURE(RPRES)
+ ASMJIT_ARM_FEATURE(RPRFM)
+ ASMJIT_ARM_FEATURE(S1PIE)
+ ASMJIT_ARM_FEATURE(S1POE)
+ ASMJIT_ARM_FEATURE(S2PIE)
+ ASMJIT_ARM_FEATURE(S2POE)
ASMJIT_ARM_FEATURE(SB)
+ ASMJIT_ARM_FEATURE(SCTLR2)
+ ASMJIT_ARM_FEATURE(SEBEP)
+ ASMJIT_ARM_FEATURE(SEL2)
ASMJIT_ARM_FEATURE(SHA1)
- ASMJIT_ARM_FEATURE(SHA2)
+ ASMJIT_ARM_FEATURE(SHA256)
ASMJIT_ARM_FEATURE(SHA3)
ASMJIT_ARM_FEATURE(SHA512)
ASMJIT_ARM_FEATURE(SM3)
ASMJIT_ARM_FEATURE(SM4)
+ ASMJIT_ARM_FEATURE(SME)
+ ASMJIT_ARM_FEATURE(SME2)
+ ASMJIT_ARM_FEATURE(SME2_1)
+ ASMJIT_ARM_FEATURE(SME_B16B16)
+ ASMJIT_ARM_FEATURE(SME_B16F32)
+ ASMJIT_ARM_FEATURE(SME_BI32I32)
+ ASMJIT_ARM_FEATURE(SME_F16F16)
+ ASMJIT_ARM_FEATURE(SME_F16F32)
+ ASMJIT_ARM_FEATURE(SME_F32F32)
+ ASMJIT_ARM_FEATURE(SME_F64F64)
+ ASMJIT_ARM_FEATURE(SME_F8F16)
+ ASMJIT_ARM_FEATURE(SME_F8F32)
+ ASMJIT_ARM_FEATURE(SME_FA64)
+ ASMJIT_ARM_FEATURE(SME_I16I32)
+ ASMJIT_ARM_FEATURE(SME_I16I64)
+ ASMJIT_ARM_FEATURE(SME_I8I32)
+ ASMJIT_ARM_FEATURE(SME_LUTv2)
+ ASMJIT_ARM_FEATURE(SPE)
+ ASMJIT_ARM_FEATURE(SPE1_1)
+ ASMJIT_ARM_FEATURE(SPE1_2)
+ ASMJIT_ARM_FEATURE(SPE1_3)
+ ASMJIT_ARM_FEATURE(SPE1_4)
+ ASMJIT_ARM_FEATURE(SPE_ALTCLK)
+ ASMJIT_ARM_FEATURE(SPE_CRR)
+ ASMJIT_ARM_FEATURE(SPE_EFT)
+ ASMJIT_ARM_FEATURE(SPE_FDS)
+ ASMJIT_ARM_FEATURE(SPE_FPF)
+ ASMJIT_ARM_FEATURE(SPE_SME)
+ ASMJIT_ARM_FEATURE(SPECRES)
+ ASMJIT_ARM_FEATURE(SPECRES2)
+ ASMJIT_ARM_FEATURE(SPMU)
ASMJIT_ARM_FEATURE(SSBS)
+ ASMJIT_ARM_FEATURE(SSBS2)
+ ASMJIT_ARM_FEATURE(SSVE_FP8DOT2)
+ ASMJIT_ARM_FEATURE(SSVE_FP8DOT4)
+ ASMJIT_ARM_FEATURE(SSVE_FP8FMA)
ASMJIT_ARM_FEATURE(SVE)
+ ASMJIT_ARM_FEATURE(SVE2)
+ ASMJIT_ARM_FEATURE(SVE2_1)
+ ASMJIT_ARM_FEATURE(SVE_AES)
+ ASMJIT_ARM_FEATURE(SVE_B16B16)
ASMJIT_ARM_FEATURE(SVE_BF16)
+ ASMJIT_ARM_FEATURE(SVE_BITPERM)
+ ASMJIT_ARM_FEATURE(SVE_EBF16)
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(SVE_PMULL128)
+ ASMJIT_ARM_FEATURE(SVE_SHA3)
+ ASMJIT_ARM_FEATURE(SVE_SM4)
+ ASMJIT_ARM_FEATURE(SYSINSTR128)
+ ASMJIT_ARM_FEATURE(SYSREG128)
+ ASMJIT_ARM_FEATURE(THE)
+ ASMJIT_ARM_FEATURE(TLBIOS)
+ ASMJIT_ARM_FEATURE(TLBIRANGE)
+ ASMJIT_ARM_FEATURE(TLBIW)
ASMJIT_ARM_FEATURE(TME)
+ ASMJIT_ARM_FEATURE(TRF)
+ ASMJIT_ARM_FEATURE(UAO)
+ ASMJIT_ARM_FEATURE(VFP_D32)
+ ASMJIT_ARM_FEATURE(VHE)
+ ASMJIT_ARM_FEATURE(VMID16)
+ ASMJIT_ARM_FEATURE(WFXT)
+ ASMJIT_ARM_FEATURE(XNX)
+ ASMJIT_ARM_FEATURE(XS)
#undef ASMJIT_ARM_FEATURE
};
@@ -578,19 +947,20 @@ public:
//! \name Construction & Destruction
//! \{
- inline CpuFeatures() noexcept {}
- inline CpuFeatures(const CpuFeatures& other) noexcept = default;
- inline explicit CpuFeatures(Globals::NoInit_) noexcept {}
+ ASMJIT_INLINE_NODEBUG CpuFeatures() noexcept {}
+ ASMJIT_INLINE_NODEBUG CpuFeatures(const CpuFeatures& other) noexcept = default;
+ ASMJIT_INLINE_NODEBUG explicit CpuFeatures(const Data& other) noexcept : _data{other._bits} {}
+ ASMJIT_INLINE_NODEBUG explicit CpuFeatures(Globals::NoInit_) noexcept {}
//! \}
//! \name Overloaded Operators
//! \{
- inline CpuFeatures& operator=(const CpuFeatures& other) noexcept = default;
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG bool operator==(const CpuFeatures& other) const noexcept { return equals(other); }
+ ASMJIT_INLINE_NODEBUG bool operator!=(const CpuFeatures& other) const noexcept { return !equals(other); }
//! \}
@@ -598,64 +968,74 @@ public:
//! \{
//! Returns true if there are no features set.
- inline bool empty() const noexcept { return _data.empty(); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG 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>(); }
+ ASMJIT_INLINE_NODEBUG X86& x86() noexcept { return data<X86>(); }
//! Returns CpuFeatures::Data as \ref CpuFeatures::X86 (const).
- inline const X86& x86() const noexcept { return data<X86>(); }
+ ASMJIT_INLINE_NODEBUG const X86& x86() const noexcept { return data<X86>(); }
//! Returns CpuFeatures::Data as \ref CpuFeatures::ARM.
- inline ARM& arm() noexcept { return data<ARM>(); }
+ ASMJIT_INLINE_NODEBUG ARM& arm() noexcept { return data<ARM>(); }
//! Returns CpuFeatures::Data as \ref CpuFeatures::ARM (const).
- inline const ARM& arm() const noexcept { return data<ARM>(); }
+ ASMJIT_INLINE_NODEBUG 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(); }
+ ASMJIT_INLINE_NODEBUG BitWord* bits() noexcept { return _data.bits(); }
//! Returns all features as array of bitwords (const).
- inline const BitWord* bits() const noexcept { return _data.bits(); }
+ ASMJIT_INLINE_NODEBUG 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(); }
+ ASMJIT_INLINE_NODEBUG 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(); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG bool has(const FeatureId& featureId) const noexcept { return _data.has(featureId); }
+
+ //! Tests whether any of the features is present.
+ template<typename... Args>
+ ASMJIT_INLINE_NODEBUG bool hasAny(Args&&... args) const noexcept { return _data.hasAny(std::forward<Args>(args)...); }
//! Tests whether all features as defined by `other` are present.
- inline bool hasAll(const CpuFeatures& other) const noexcept { return _data.hasAll(other._data); }
+ ASMJIT_INLINE_NODEBUG bool hasAll(const CpuFeatures& other) const noexcept { return _data.hasAll(other._data); }
//! \}
//! \name Manipulation
//! \{
- inline void reset() noexcept { _data.reset(); }
+ //! Clears all features set.
+ ASMJIT_INLINE_NODEBUG 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)...); }
+ ASMJIT_INLINE_NODEBUG 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)...); }
+ ASMJIT_INLINE_NODEBUG 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)...); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG bool equals(const CpuFeatures& other) const noexcept { return _data.equals(other._data); }
+
+#if !defined(ASMJIT_NO_DEPRECATED)
+ ASMJIT_DEPRECATED("Use CpuFeatures::equals() instead")
+ ASMJIT_INLINE_NODEBUG bool eq(const CpuFeatures& other) const noexcept { return equals(other); }
+#endif // !ASMJIT_NO_DEPRECATED
//! \}
};
@@ -667,65 +1047,82 @@ public:
//! \{
//! Architecture.
- Arch _arch;
+ Arch _arch {};
//! Sub-architecture.
- SubArch _subArch;
+ SubArch _subArch {};
//! True if the CPU was detected, false if the detection failed or it's not available.
- bool _wasDetected;
+ bool _wasDetected {};
//! Reserved for future use.
- uint8_t _reserved;
+ uint8_t _reserved {};
//! CPU family ID.
- uint32_t _familyId;
+ uint32_t _familyId {};
//! CPU model ID.
- uint32_t _modelId;
+ uint32_t _modelId {};
//! CPU brand ID.
- uint32_t _brandId;
+ uint32_t _brandId {};
//! CPU stepping.
- uint32_t _stepping;
+ uint32_t _stepping {};
//! Processor type.
- uint32_t _processorType;
+ uint32_t _processorType {};
//! Maximum number of addressable IDs for logical processors.
- uint32_t _maxLogicalProcessors;
+ uint32_t _maxLogicalProcessors {};
//! Cache line size (in bytes).
- uint32_t _cacheLineSize;
+ uint32_t _cacheLineSize {};
//! Number of hardware threads.
- uint32_t _hwThreadCount;
+ uint32_t _hwThreadCount {};
//! CPU vendor string.
- FixedString<16> _vendor;
+ FixedString<16> _vendor {};
//! CPU brand string.
- FixedString<64> _brand;
+ FixedString<64> _brand {};
//! CPU features.
- CpuFeatures _features;
+ CpuFeatures _features {};
//! \}
//! \name Construction & Destruction
//! \{
- inline CpuInfo() noexcept { reset(); }
- inline CpuInfo(const CpuInfo& other) noexcept = default;
+ //! Creates a new CpuInfo instance.
+ ASMJIT_INLINE_NODEBUG CpuInfo() noexcept {}
+ //! Creates a copy of `other` instance.
+ ASMJIT_INLINE_NODEBUG CpuInfo(const CpuInfo& other) noexcept = default;
- inline explicit CpuInfo(Globals::NoInit_) noexcept
+ //! Creates an unitialized `CpuInfo` instance.
+ ASMJIT_INLINE_NODEBUG explicit CpuInfo(Globals::NoInit_) noexcept
: _features(Globals::NoInit) {};
+ //! \}
+
+ //! \name CPU Information Detection
+ //! \{
+
//! Returns the host CPU information.
+ //!
+ //! \note The returned reference is global - it's setup only once and then shared.
ASMJIT_API static const CpuInfo& host() noexcept;
- //! 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;
- }
+ //! \}
+
+ //! \name Overloaded Operators
+ //! \{
- inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
+ //! Copy assignment.
+ ASMJIT_INLINE_NODEBUG CpuInfo& operator=(const CpuInfo& other) noexcept = default;
//! \}
- //! \name Overloaded Operators
+ //! \name Initialization & Reset
//! \{
- inline CpuInfo& operator=(const CpuInfo& other) noexcept = default;
+ //! Initializes CpuInfo architecture and sub-architecture members to `arch` and `subArch`, respectively.
+ ASMJIT_INLINE_NODEBUG void initArch(Arch arch, SubArch subArch = SubArch::kUnknown) noexcept {
+ _arch = arch;
+ _subArch = subArch;
+ }
+
+ //! Resets this \ref CpuInfo to a default constructed state.
+ ASMJIT_INLINE_NODEBUG void reset() noexcept { *this = CpuInfo{}; }
//! \}
@@ -733,75 +1130,89 @@ public:
//! \{
//! Returns the CPU architecture this information relates to.
- inline Arch arch() const noexcept { return _arch; }
+ ASMJIT_INLINE_NODEBUG Arch arch() const noexcept { return _arch; }
//! Returns the CPU sub-architecture this information relates to.
- inline SubArch subArch() const noexcept { return _subArch; }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG 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; }
+ //! The information provided depends on architecture and OS:
+ //! - X86:
+ //! - Family identifier matches the FamilyId read by using CPUID.
+ //! - ARM:
+ //! - Apple - returns Apple Family identifier returned by sysctlbyname("hw.cpufamily").
+ ASMJIT_INLINE_NODEBUG uint32_t familyId() const noexcept { return _familyId; }
//! Returns the CPU model ID.
//!
- //! Family identifier matches the ModelId read by using CPUID on X86 architecture.
+ //! The information provided depends on architecture and OS:
+ //! - X86:
+ //! - Model identifier matches the ModelId read by using CPUID.
+ ASMJIT_INLINE_NODEBUG uint32_t modelId() const noexcept { return _modelId; }
- 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; }
+ //! The information provided depends on architecture and OS:
+ //! - X86:
+ //! - Brand identifier matches the BrandId read by using CPUID.
+ ASMJIT_INLINE_NODEBUG 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; }
+ //! The information provided depends on architecture and OS:
+ //! - X86:
+ //! - Stepping identifier matches the Stepping information read by using CPUID.
+ ASMJIT_INLINE_NODEBUG 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; }
+ //! The information provided depends on architecture and OS:
+ //! - X86:
+ //! - Processor type identifier matches the ProcessorType read by using CPUID.
+ ASMJIT_INLINE_NODEBUG uint32_t processorType() const noexcept { return _processorType; }
//! Returns the maximum number of logical processors.
- inline uint32_t maxLogicalProcessors() const noexcept { return _maxLogicalProcessors; }
+ ASMJIT_INLINE_NODEBUG uint32_t maxLogicalProcessors() const noexcept { return _maxLogicalProcessors; }
- //! Returns the size of a cache line flush.
- inline uint32_t cacheLineSize() const noexcept { return _cacheLineSize; }
+ //! Returns the size of a CPU cache line.
+ //!
+ //! On a multi-architecture system this should return the smallest cache line of all CPUs.
+ ASMJIT_INLINE_NODEBUG uint32_t cacheLineSize() const noexcept { return _cacheLineSize; }
//! Returns number of hardware threads available.
- inline uint32_t hwThreadCount() const noexcept { return _hwThreadCount; }
+ ASMJIT_INLINE_NODEBUG uint32_t hwThreadCount() const noexcept { return _hwThreadCount; }
//! Returns a CPU vendor string.
- inline const char* vendor() const noexcept { return _vendor.str; }
+ ASMJIT_INLINE_NODEBUG const char* vendor() const noexcept { return _vendor.str; }
//! Tests whether the CPU vendor string is equal to `s`.
- inline bool isVendor(const char* s) const noexcept { return _vendor.eq(s); }
+ ASMJIT_INLINE_NODEBUG bool isVendor(const char* s) const noexcept { return _vendor.equals(s); }
//! Returns a CPU brand string.
- inline const char* brand() const noexcept { return _brand.str; }
+ ASMJIT_INLINE_NODEBUG const char* brand() const noexcept { return _brand.str; }
//! Returns CPU features.
- inline CpuFeatures& features() noexcept { return _features; }
+ ASMJIT_INLINE_NODEBUG CpuFeatures& features() noexcept { return _features; }
//! Returns CPU features (const).
- inline const CpuFeatures& features() const noexcept { return _features; }
+ ASMJIT_INLINE_NODEBUG const CpuFeatures& features() const noexcept { return _features; }
//! Tests whether the CPU has the given `feature`.
template<typename FeatureId>
- inline bool hasFeature(const FeatureId& featureId) const noexcept { return _features.has(featureId); }
+ ASMJIT_INLINE_NODEBUG 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)...); }
+ ASMJIT_INLINE_NODEBUG 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)...); }
+ ASMJIT_INLINE_NODEBUG void removeFeature(Args&&... args) noexcept { return _features.remove(std::forward<Args>(args)...); }
//! \}
};
diff --git a/3rdparty/asmjit/src/asmjit/core/emithelper.cpp b/3rdparty/asmjit/src/asmjit/core/emithelper.cpp
index bcdf098f48b..36b984f832f 100644
--- a/3rdparty/asmjit/src/asmjit/core/emithelper.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/emithelper.cpp
@@ -61,6 +61,24 @@ static void dumpAssignment(String& sb, const FuncArgsContext& ctx) noexcept {
}
#endif
+// BaseEmitHelper - Abstract
+// =========================
+
+Error BaseEmitHelper::emitRegMove(const Operand_& dst_, const Operand_& src_, TypeId typeId, const char* comment) {
+ DebugUtils::unused(dst_, src_, typeId, comment);
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
+Error BaseEmitHelper::emitRegSwap(const BaseReg& a, const BaseReg& b, const char* comment) {
+ DebugUtils::unused(a, b, comment);
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
+Error BaseEmitHelper::emitArgMove(const BaseReg& dst_, TypeId dstTypeId, const Operand_& src_, TypeId srcTypeId, const char* comment) {
+ DebugUtils::unused(dst_, dstTypeId, src_, srcTypeId, comment);
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
// BaseEmitHelper - EmitArgsAssignment
// ===================================
@@ -198,14 +216,17 @@ ASMJIT_FAVOR_SIZE Error BaseEmitHelper::emitArgsAssignment(const FuncFrame& fram
}
else {
WorkData& wd = workData[outGroup];
- if (!wd.isAssigned(outId)) {
+ if (!wd.isAssigned(outId) || curId == outId) {
EmitMove:
ASMJIT_PROPAGATE(
emitArgMove(
BaseReg(archTraits.regTypeToSignature(out.regType()), outId), out.typeId(),
BaseReg(archTraits.regTypeToSignature(cur.regType()), curId), cur.typeId()));
- wd.reassign(varId, outId, curId);
+ // Only reassign if this is not a sign/zero extension that happens on the same in/out register.
+ if (curId != outId)
+ wd.reassign(varId, outId, curId);
+
cur.initReg(out.regType(), outId, out.typeId());
if (outId == out.regId())
diff --git a/3rdparty/asmjit/src/asmjit/core/emithelper_p.h b/3rdparty/asmjit/src/asmjit/core/emithelper_p.h
index 0333959e144..0f4a2f3ece4 100644
--- a/3rdparty/asmjit/src/asmjit/core/emithelper_p.h
+++ b/3rdparty/asmjit/src/asmjit/core/emithelper_p.h
@@ -21,22 +21,22 @@ class BaseEmitHelper {
public:
BaseEmitter* _emitter;
- inline explicit BaseEmitHelper(BaseEmitter* emitter = nullptr) noexcept
+ ASMJIT_INLINE_NODEBUG explicit BaseEmitHelper(BaseEmitter* emitter = nullptr) noexcept
: _emitter(emitter) {}
- inline BaseEmitter* emitter() const noexcept { return _emitter; }
- inline void setEmitter(BaseEmitter* emitter) noexcept { _emitter = emitter; }
+ ASMJIT_INLINE_NODEBUG BaseEmitter* emitter() const noexcept { return _emitter; }
+ ASMJIT_INLINE_NODEBUG 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.
virtual Error emitRegMove(
const Operand_& dst_,
- const Operand_& src_, TypeId typeId, const char* comment = nullptr) = 0;
+ const Operand_& src_, TypeId typeId, const char* comment = nullptr);
//! Emits swap between two registers.
virtual Error emitRegSwap(
const BaseReg& a,
- const BaseReg& b, const char* comment = nullptr) = 0;
+ const BaseReg& b, const char* comment = nullptr);
//! Emits move from a function argument (either register or stack) to a register.
//!
@@ -45,7 +45,7 @@ public:
//! (for example conversion from K to MMX on X86/X64) will fail.
virtual Error emitArgMove(
const BaseReg& dst_, TypeId dstTypeId,
- const Operand_& src_, TypeId srcTypeId, const char* comment = nullptr) = 0;
+ const Operand_& src_, TypeId srcTypeId, const char* comment = nullptr);
Error emitArgsAssignment(const FuncFrame& frame, const FuncArgsAssignment& args);
};
diff --git a/3rdparty/asmjit/src/asmjit/core/emitter.cpp b/3rdparty/asmjit/src/asmjit/core/emitter.cpp
index 92d67a7e5b5..4c855ea5688 100644
--- a/3rdparty/asmjit/src/asmjit/core/emitter.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/emitter.cpp
@@ -125,13 +125,39 @@ Error BaseEmitter::reportError(Error err, const char* message) {
return err;
}
+// BaseEmitter - Sections
+// ======================
+
+// [[pure virtual]]
+Error BaseEmitter::section(Section* section) {
+ DebugUtils::unused(section);
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
// BaseEmitter - Labels
// ====================
+// [[pure virtual]]
+Label BaseEmitter::newLabel() {
+ return Label(Globals::kInvalidId);
+}
+
+// [[pure virtual]]
+Label BaseEmitter::newNamedLabel(const char* name, size_t nameSize, LabelType type, uint32_t parentId) {
+ DebugUtils::unused(name, nameSize, type, parentId);
+ return Label(Globals::kInvalidId);
+}
+
Label BaseEmitter::labelByName(const char* name, size_t nameSize, uint32_t parentId) noexcept {
return Label(_code ? _code->labelIdByName(name, nameSize, parentId) : Globals::kInvalidId);
}
+// [[pure virtual]]
+Error BaseEmitter::bind(const Label& label) {
+ DebugUtils::unused(label);
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
bool BaseEmitter::isLabelValid(uint32_t labelId) const noexcept {
return _code && labelId < _code->labelCount();
}
@@ -172,6 +198,12 @@ Error BaseEmitter::_emitI(InstId instId, const Operand_& o0, const Operand_& o1,
return _emit(instId, o0, o1, o2, opExt);
}
+// [[pure virtual]]
+Error BaseEmitter::_emit(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* oExt) {
+ DebugUtils::unused(instId, o0, o1, o2, oExt);
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
Error BaseEmitter::_emitOpArray(InstId instId, const Operand_* operands, size_t opCount) {
const Operand_* op = operands;
Operand_ opExt[3];
@@ -233,9 +265,57 @@ Error BaseEmitter::emitArgsAssignment(const FuncFrame& frame, const FuncArgsAssi
return _funcs.emitArgsAssignment(this, frame, args);
}
+// BaseEmitter - Align
+// ===================
+
+// [[pure virtual]]
+Error BaseEmitter::align(AlignMode alignMode, uint32_t alignment) {
+ DebugUtils::unused(alignMode, alignment);
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
+// BaseEmitter - Embed
+// ===================
+
+// [[pure virtual]]
+Error BaseEmitter::embed(const void* data, size_t dataSize) {
+ DebugUtils::unused(data, dataSize);
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
+// [[pure virtual]]
+Error BaseEmitter::embedDataArray(TypeId typeId, const void* data, size_t itemCount, size_t repeatCount) {
+ DebugUtils::unused(typeId, data, itemCount, repeatCount);
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
+// [[pure virtual]]
+Error BaseEmitter::embedConstPool(const Label& label, const ConstPool& pool) {
+ DebugUtils::unused(label, pool);
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
+// [[pure virtual]]
+Error BaseEmitter::embedLabel(const Label& label, size_t dataSize) {
+ DebugUtils::unused(label, dataSize);
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
+// [[pure virtual]]
+Error BaseEmitter::embedLabelDelta(const Label& label, const Label& base, size_t dataSize) {
+ DebugUtils::unused(label, base, dataSize);
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
// BaseEmitter - Comment
// =====================
+// [[pure virtual]]
+Error BaseEmitter::comment(const char* data, size_t size) {
+ DebugUtils::unused(data, size);
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
Error BaseEmitter::commentf(const char* fmt, ...) {
if (!hasEmitterFlag(EmitterFlags::kLogComments)) {
if (!hasEmitterFlag(EmitterFlags::kAttached))
@@ -304,6 +384,7 @@ Error BaseEmitter::onDetach(CodeHolder* code) noexcept {
_errorHandler = nullptr;
_clearEmitterFlags(~kEmitterPreservedFlags);
+ _instructionAlignment = uint8_t(0);
_forcedInstOptions = InstOptions::kReserved;
_privateData = 0;
@@ -313,6 +394,7 @@ Error BaseEmitter::onDetach(CodeHolder* code) noexcept {
_instOptions = InstOptions::kNone;
_extraReg.reset();
_inlineComment = nullptr;
+ _funcs.reset();
return kErrorOk;
}
diff --git a/3rdparty/asmjit/src/asmjit/core/emitter.h b/3rdparty/asmjit/src/asmjit/core/emitter.h
index b8afd6b8e06..3053721c9c6 100644
--- a/3rdparty/asmjit/src/asmjit/core/emitter.h
+++ b/3rdparty/asmjit/src/asmjit/core/emitter.h
@@ -194,6 +194,7 @@ ASMJIT_DEFINE_ENUM_FLAGS(DiagnosticOptions)
class ASMJIT_VIRTAPI BaseEmitter {
public:
ASMJIT_BASE_CLASS(BaseEmitter)
+ ASMJIT_NONCOPYABLE(BaseEmitter)
//! \name Members
//! \{
@@ -202,6 +203,11 @@ public:
EmitterType _emitterType = EmitterType::kNone;
//! See \ref EmitterFlags.
EmitterFlags _emitterFlags = EmitterFlags::kNone;
+ //! Instruction alignment.
+ uint8_t _instructionAlignment = 0u;
+ //! \cond
+ uint8_t _reservedBaseEmitter = 0u;
+ //! \endcond
//! 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
@@ -233,6 +239,13 @@ public:
//! Native GP register signature and signature related information.
OperandSignature _gpSignature {};
+ //! Emitter state that can be used to specify options and inline comment of a next node or instruction.
+ struct State {
+ InstOptions options;
+ RegOnly extraReg;
+ const char* comment;
+ };
+
//! Next instruction options (affects the next instruction).
InstOptions _instOptions = InstOptions::kNone;
//! Extra register (op-mask {k} on AVX-512) (affects the next instruction).
@@ -255,7 +268,7 @@ public:
Arch arch,
const BaseInst& inst, const Operand_* operands, size_t opCount) ASMJIT_NOEXCEPT_TYPE;
- typedef Error (ASMJIT_CDECL* ValidateFunc)(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, ValidationFlags validationFlags) ASMJIT_NOEXCEPT_TYPE;
+ typedef Error (ASMJIT_CDECL* ValidateFunc)(const BaseInst& inst, const Operand_* operands, size_t opCount, ValidationFlags validationFlags) ASMJIT_NOEXCEPT_TYPE;
//! Emit prolog implementation.
EmitProlog emitProlog;
@@ -269,7 +282,7 @@ public:
ValidateFunc validate;
//! Resets all functions to nullptr.
- inline void reset() noexcept {
+ ASMJIT_INLINE_NODEBUG void reset() noexcept {
emitProlog = nullptr;
emitEpilog = nullptr;
emitArgsAssignment = nullptr;
@@ -293,10 +306,10 @@ public:
//! \{
template<typename T>
- inline T* as() noexcept { return reinterpret_cast<T*>(this); }
+ ASMJIT_INLINE_NODEBUG T* as() noexcept { return reinterpret_cast<T*>(this); }
template<typename T>
- inline const T* as() const noexcept { return reinterpret_cast<const T*>(this); }
+ ASMJIT_INLINE_NODEBUG const T* as() const noexcept { return reinterpret_cast<const T*>(this); }
//! \}
@@ -304,54 +317,72 @@ public:
//! \{
//! Returns the type of this emitter, see `EmitterType`.
- inline EmitterType emitterType() const noexcept { return _emitterType; }
+ ASMJIT_INLINE_NODEBUG EmitterType emitterType() const noexcept { return _emitterType; }
//! Returns emitter flags , see `Flags`.
- inline EmitterFlags emitterFlags() const noexcept { return _emitterFlags; }
+ ASMJIT_INLINE_NODEBUG EmitterFlags emitterFlags() const noexcept { return _emitterFlags; }
//! Tests whether the emitter inherits from `BaseAssembler`.
- inline bool isAssembler() const noexcept { return _emitterType == EmitterType::kAssembler; }
+ ASMJIT_INLINE_NODEBUG 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 uint32_t(_emitterType) >= uint32_t(EmitterType::kBuilder); }
+ ASMJIT_INLINE_NODEBUG 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 == EmitterType::kCompiler; }
+ ASMJIT_INLINE_NODEBUG bool isCompiler() const noexcept { return _emitterType == EmitterType::kCompiler; }
//! Tests whether the emitter has the given `flag` enabled.
- inline bool hasEmitterFlag(EmitterFlags flag) const noexcept { return Support::test(_emitterFlags, flag); }
+ ASMJIT_INLINE_NODEBUG bool hasEmitterFlag(EmitterFlags flag) const noexcept { return Support::test(_emitterFlags, flag); }
//! Tests whether the emitter is finalized.
- inline bool isFinalized() const noexcept { return hasEmitterFlag(EmitterFlags::kFinalized); }
+ ASMJIT_INLINE_NODEBUG 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(EmitterFlags::kDestroyed); }
+ ASMJIT_INLINE_NODEBUG bool isDestroyed() const noexcept { return hasEmitterFlag(EmitterFlags::kDestroyed); }
+
+ //! \}
+
+ //! \cond INTERNAL
+ //! \name Internal Functions
+ //! \{
- inline void _addEmitterFlags(EmitterFlags flags) noexcept { _emitterFlags |= flags; }
- inline void _clearEmitterFlags(EmitterFlags flags) noexcept { _emitterFlags &= _emitterFlags & ~flags; }
+ ASMJIT_INLINE_NODEBUG void _addEmitterFlags(EmitterFlags flags) noexcept { _emitterFlags |= flags; }
+ ASMJIT_INLINE_NODEBUG void _clearEmitterFlags(EmitterFlags flags) noexcept { _emitterFlags &= _emitterFlags & ~flags; }
//! \}
+ //! \endcond
//! \name Target Information
//! \{
//! Returns the CodeHolder this emitter is attached to.
- inline CodeHolder* code() const noexcept { return _code; }
+ ASMJIT_INLINE_NODEBUG CodeHolder* code() const noexcept { return _code; }
//! Returns the target environment.
//!
//! The returned \ref Environment reference matches \ref CodeHolder::environment().
- inline const Environment& environment() const noexcept { return _environment; }
+ ASMJIT_INLINE_NODEBUG const Environment& environment() const noexcept { return _environment; }
//! Tests whether the target architecture is 32-bit.
- inline bool is32Bit() const noexcept { return environment().is32Bit(); }
+ ASMJIT_INLINE_NODEBUG bool is32Bit() const noexcept { return environment().is32Bit(); }
//! Tests whether the target architecture is 64-bit.
- inline bool is64Bit() const noexcept { return environment().is64Bit(); }
+ ASMJIT_INLINE_NODEBUG bool is64Bit() const noexcept { return environment().is64Bit(); }
//! Returns the target architecture type.
- inline Arch arch() const noexcept { return environment().arch(); }
+ ASMJIT_INLINE_NODEBUG Arch arch() const noexcept { return environment().arch(); }
//! Returns the target architecture sub-type.
- inline SubArch subArch() const noexcept { return environment().subArch(); }
+ ASMJIT_INLINE_NODEBUG 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(); }
+ ASMJIT_INLINE_NODEBUG uint32_t registerSize() const noexcept { return environment().registerSize(); }
+
+ //! Returns a signature of a native general purpose register (either 32-bit or 64-bit depending on the architecture).
+ ASMJIT_INLINE_NODEBUG OperandSignature gpSignature() const noexcept { return _gpSignature; }
+
+ //! Returns instruction alignment.
+ //!
+ //! The following values are returned based on the target architecture:
+ //! - X86 and X86_64 - instruction alignment is 1
+ //! - AArch32 - instruction alignment is 4 in A32 mode and 2 in THUMB mode.
+ //! - AArch64 - instruction alignment is 4
+ ASMJIT_INLINE_NODEBUG uint32_t instructionAlignment() const noexcept { return _instructionAlignment; }
//! \}
@@ -359,7 +390,7 @@ public:
//! \{
//! Tests whether the emitter is initialized (i.e. attached to \ref CodeHolder).
- inline bool isInitialized() const noexcept { return _code != nullptr; }
+ ASMJIT_INLINE_NODEBUG bool isInitialized() const noexcept { return _code != nullptr; }
//! Finalizes this emitter.
//!
@@ -376,19 +407,19 @@ public:
//! \{
//! Tests whether the emitter has a logger.
- inline bool hasLogger() const noexcept { return _logger != nullptr; }
+ ASMJIT_INLINE_NODEBUG bool hasLogger() const noexcept { return _logger != nullptr; }
//! 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(EmitterFlags::kOwnLogger); }
+ ASMJIT_INLINE_NODEBUG 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.
- inline Logger* logger() const noexcept { return _logger; }
+ ASMJIT_INLINE_NODEBUG Logger* logger() const noexcept { return _logger; }
//! Sets or resets the logger of the emitter.
//!
@@ -401,7 +432,7 @@ public:
//!
//! 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); }
+ ASMJIT_INLINE_NODEBUG void resetLogger() noexcept { return setLogger(nullptr); }
//! \}
@@ -409,25 +440,25 @@ public:
//! \{
//! Tests whether the emitter has an error handler attached.
- inline bool hasErrorHandler() const noexcept { return _errorHandler != nullptr; }
+ ASMJIT_INLINE_NODEBUG bool hasErrorHandler() const noexcept { return _errorHandler != nullptr; }
//! 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(EmitterFlags::kOwnErrorHandler); }
+ ASMJIT_INLINE_NODEBUG 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.
- inline ErrorHandler* errorHandler() const noexcept { return _errorHandler; }
+ ASMJIT_INLINE_NODEBUG ErrorHandler* errorHandler() const noexcept { return _errorHandler; }
//! Sets or resets the error handler of the emitter.
ASMJIT_API void setErrorHandler(ErrorHandler* errorHandler) noexcept;
//! Resets the error handler.
- inline void resetErrorHandler() noexcept { setErrorHandler(nullptr); }
+ ASMJIT_INLINE_NODEBUG 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
@@ -441,14 +472,14 @@ public:
//! \{
//! Returns encoding options.
- inline EncodingOptions encodingOptions() const noexcept { return _encodingOptions; }
+ ASMJIT_INLINE_NODEBUG EncodingOptions encodingOptions() const noexcept { return _encodingOptions; }
//! Tests whether the encoding `option` is set.
- inline bool hasEncodingOption(EncodingOptions option) const noexcept { return Support::test(_encodingOptions, option); }
+ ASMJIT_INLINE_NODEBUG bool hasEncodingOption(EncodingOptions option) const noexcept { return Support::test(_encodingOptions, option); }
//! Enables the given encoding `options`.
- inline void addEncodingOptions(EncodingOptions options) noexcept { _encodingOptions |= options; }
+ ASMJIT_INLINE_NODEBUG void addEncodingOptions(EncodingOptions options) noexcept { _encodingOptions |= options; }
//! Disables the given encoding `options`.
- inline void clearEncodingOptions(EncodingOptions options) noexcept { _encodingOptions &= ~options; }
+ ASMJIT_INLINE_NODEBUG void clearEncodingOptions(EncodingOptions options) noexcept { _encodingOptions &= ~options; }
//! \}
@@ -456,10 +487,10 @@ public:
//! \{
//! Returns the emitter's diagnostic options.
- inline DiagnosticOptions diagnosticOptions() const noexcept { return _diagnosticOptions; }
+ ASMJIT_INLINE_NODEBUG DiagnosticOptions diagnosticOptions() const noexcept { return _diagnosticOptions; }
//! 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); }
+ ASMJIT_INLINE_NODEBUG bool hasDiagnosticOption(DiagnosticOptions option) const noexcept { return Support::test(_diagnosticOptions, option); }
//! Activates the given diagnostic `options`.
//!
@@ -496,44 +527,76 @@ public:
//! 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; }
+ ASMJIT_INLINE_NODEBUG InstOptions forcedInstOptions() const noexcept { return _forcedInstOptions; }
//! Returns options of the next instruction.
- inline InstOptions instOptions() const noexcept { return _instOptions; }
+ ASMJIT_INLINE_NODEBUG InstOptions instOptions() const noexcept { return _instOptions; }
//! Returns options of the next instruction.
- inline void setInstOptions(InstOptions options) noexcept { _instOptions = options; }
+ ASMJIT_INLINE_NODEBUG void setInstOptions(InstOptions options) noexcept { _instOptions = options; }
//! Adds options of the next instruction.
- inline void addInstOptions(InstOptions options) noexcept { _instOptions |= options; }
+ ASMJIT_INLINE_NODEBUG void addInstOptions(InstOptions options) noexcept { _instOptions |= options; }
//! Resets options of the next instruction.
- inline void resetInstOptions() noexcept { _instOptions = InstOptions::kNone; }
+ ASMJIT_INLINE_NODEBUG void resetInstOptions() noexcept { _instOptions = InstOptions::kNone; }
//! Tests whether the extra register operand is valid.
- inline bool hasExtraReg() const noexcept { return _extraReg.isReg(); }
+ ASMJIT_INLINE_NODEBUG bool hasExtraReg() const noexcept { return _extraReg.isReg(); }
//! Returns an extra operand that will be used by the next instruction (architecture specific).
- inline const RegOnly& extraReg() const noexcept { return _extraReg; }
+ ASMJIT_INLINE_NODEBUG const RegOnly& extraReg() const noexcept { return _extraReg; }
//! Sets an extra operand that will be used by the next instruction (architecture specific).
- inline void setExtraReg(const BaseReg& reg) noexcept { _extraReg.init(reg); }
+ ASMJIT_INLINE_NODEBUG void setExtraReg(const BaseReg& reg) noexcept { _extraReg.init(reg); }
//! Sets an extra operand that will be used by the next instruction (architecture specific).
- inline void setExtraReg(const RegOnly& reg) noexcept { _extraReg.init(reg); }
+ ASMJIT_INLINE_NODEBUG void setExtraReg(const RegOnly& reg) noexcept { _extraReg.init(reg); }
//! Resets an extra operand that will be used by the next instruction (architecture specific).
- inline void resetExtraReg() noexcept { _extraReg.reset(); }
+ ASMJIT_INLINE_NODEBUG void resetExtraReg() noexcept { _extraReg.reset(); }
//! Returns comment/annotation of the next instruction.
- inline const char* inlineComment() const noexcept { return _inlineComment; }
+ ASMJIT_INLINE_NODEBUG 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).
- inline void setInlineComment(const char* s) noexcept { _inlineComment = s; }
+ ASMJIT_INLINE_NODEBUG void setInlineComment(const char* s) noexcept { _inlineComment = s; }
//! Resets the comment/annotation to nullptr.
- inline void resetInlineComment() noexcept { _inlineComment = nullptr; }
+ ASMJIT_INLINE_NODEBUG void resetInlineComment() noexcept { _inlineComment = nullptr; }
+
+ //! \}
+
+ //! \name Emitter State
+ //! \{
+
+ //! Resets the emitter state, which contains instruction options, extra register, and inline comment.
+ //!
+ //! Emitter can have a state that describes instruction options and extra register used by the instruction. Most
+ //! instructions don't need nor use the state, however, if an instruction uses a prefix such as REX or REP prefix,
+ //! which is set explicitly, then the state would contain it. This allows to mimic the syntax of assemblers such
+ //! as X86. For example `rep().movs(...)` would map to a `REP MOVS` instuction on X86. The same applies to various
+ //! hints and the use of a mask register in AVX-512 mode.
+ ASMJIT_INLINE_NODEBUG void resetState() noexcept {
+ resetInstOptions();
+ resetExtraReg();
+ resetInlineComment();
+ }
+
+ //! \cond INTERNAL
+
+ //! Grabs the current emitter state and resets the emitter state at the same time, returning the state the emitter
+ //! had before the state was reset.
+ ASMJIT_INLINE_NODEBUG State _grabState() noexcept {
+ State s{_instOptions | _forcedInstOptions, _extraReg, _inlineComment};
+ resetState();
+ return s;
+ }
+ //! \endcond
//! \}
//! \name Sections
//! \{
- virtual Error section(Section* section) = 0;
+ //! Switches the given `section`.
+ //!
+ //! Once switched, everything is added to the given `section`.
+ ASMJIT_API virtual Error section(Section* section);
//! \}
@@ -541,14 +604,14 @@ public:
//! \{
//! Creates a new label.
- virtual Label newLabel() = 0;
+ ASMJIT_API virtual Label newLabel();
//! Creates a new named label.
- virtual Label newNamedLabel(const char* name, size_t nameSize = SIZE_MAX, LabelType type = LabelType::kGlobal, uint32_t parentId = Globals::kInvalidId) = 0;
+ ASMJIT_API virtual Label newNamedLabel(const char* name, size_t nameSize = SIZE_MAX, LabelType type = LabelType::kGlobal, uint32_t parentId = Globals::kInvalidId);
//! 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); }
+ ASMJIT_INLINE_NODEBUG 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, LabelType::kExternal); }
+ ASMJIT_INLINE_NODEBUG Label newExternalLabel(const char* name, size_t nameSize = SIZE_MAX) { return newNamedLabel(name, nameSize, LabelType::kExternal); }
//! Returns `Label` by `name`.
//!
@@ -561,12 +624,12 @@ public:
//! Binds the `label` to the current position of the current section.
//!
//! \note Attempt to bind the same label multiple times will return an error.
- virtual Error bind(const Label& label) = 0;
+ ASMJIT_API virtual Error bind(const Label& label);
//! Tests whether the label `id` is valid (i.e. registered).
ASMJIT_API bool isLabelValid(uint32_t labelId) const noexcept;
//! Tests whether the `label` is valid (i.e. registered).
- inline bool isLabelValid(const Label& label) const noexcept { return isLabelValid(label.id()); }
+ ASMJIT_INLINE_NODEBUG bool isLabelValid(const Label& label) const noexcept { return isLabelValid(label.id()); }
//! \}
@@ -596,35 +659,51 @@ public:
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`.
+ //!
+ //! This is the most universal way of emitting code, which accepts an instruction identifier and instruction
+ //! operands. This is called an "unchecked" API as emit doesn't provide any type checks at compile-time. This
+ //! allows to emit instruction with just \ref Operand instances, which could be handy in some cases - for
+ //! example emitting generic code where you don't know whether some operand is register, memory, or immediate.
template<typename... Args>
- ASMJIT_FORCE_INLINE Error emit(InstId instId, Args&&... operands) {
+ ASMJIT_INLINE_NODEBUG Error emit(InstId instId, Args&&... operands) {
return _emitI(instId, Support::ForwardOp<Args>::forward(operands)...);
}
- ASMJIT_FORCE_INLINE Error emitOpArray(InstId instId, const Operand_* operands, size_t opCount) {
+ //! Similar to \ref emit(), but uses array of `operands` instead.
+ ASMJIT_INLINE_NODEBUG Error emitOpArray(InstId instId, const Operand_* operands, size_t opCount) {
return _emitOpArray(instId, operands, opCount);
}
+ //! Similar to \ref emit(), but emits instruction with both instruction options and extra register, followed
+ //! by an array of `operands`.
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);
}
+ //! \}
+
//! \cond INTERNAL
+ //! \name Emit Internals
+ //! \{
+
//! Emits an instruction - all 6 operands must be defined.
- virtual Error _emit(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* oExt) = 0;
+ ASMJIT_API virtual Error _emit(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* oExt);
//! Emits instruction having operands stored in array.
ASMJIT_API virtual Error _emitOpArray(InstId instId, const Operand_* operands, size_t opCount);
- //! \endcond
//! \}
+ //! \endcond
//! \name Emit Utilities
//! \{
+ //! Emits a function prolog described by the given function `frame`.
ASMJIT_API Error emitProlog(const FuncFrame& frame);
+ //! Emits a function epilog described by the given function `frame`.
ASMJIT_API Error emitEpilog(const FuncFrame& frame);
+ //! Emits code that reassigns function `frame` arguments to the given `args`.
ASMJIT_API Error emitArgsAssignment(const FuncFrame& frame, const FuncArgsAssignment& args);
//! \}
@@ -637,7 +716,7 @@ public:
//! 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;
+ ASMJIT_API virtual Error align(AlignMode alignMode, uint32_t alignment);
//! \}
@@ -645,7 +724,7 @@ public:
//! \{
//! Embeds raw data into the \ref CodeBuffer.
- virtual Error embed(const void* data, size_t dataSize) = 0;
+ ASMJIT_API virtual Error embed(const void* data, size_t dataSize);
//! Embeds a typed data array.
//!
@@ -656,44 +735,44 @@ public:
//!
//! - 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;
+ ASMJIT_API virtual Error embedDataArray(TypeId typeId, const void* data, size_t itemCount, size_t repeatCount = 1);
//! Embeds int8_t `value` repeated by `repeatCount`.
- inline Error embedInt8(int8_t value, size_t repeatCount = 1) { return embedDataArray(TypeId::kInt8, &value, 1, repeatCount); }
+ ASMJIT_INLINE_NODEBUG 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(TypeId::kUInt8, &value, 1, repeatCount); }
+ ASMJIT_INLINE_NODEBUG 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(TypeId::kInt16, &value, 1, repeatCount); }
+ ASMJIT_INLINE_NODEBUG 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(TypeId::kUInt16, &value, 1, repeatCount); }
+ ASMJIT_INLINE_NODEBUG 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(TypeId::kInt32, &value, 1, repeatCount); }
+ ASMJIT_INLINE_NODEBUG 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(TypeId::kUInt32, &value, 1, repeatCount); }
+ ASMJIT_INLINE_NODEBUG 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(TypeId::kInt64, &value, 1, repeatCount); }
+ ASMJIT_INLINE_NODEBUG 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(TypeId::kUInt64, &value, 1, repeatCount); }
+ ASMJIT_INLINE_NODEBUG 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(TypeId(TypeUtils::TypeIdOfT<float>::kTypeId), &value, 1, repeatCount); }
+ ASMJIT_INLINE_NODEBUG 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(TypeId(TypeUtils::TypeIdOfT<double>::kTypeId), &value, 1, repeatCount); }
+ ASMJIT_INLINE_NODEBUG 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 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;
+ ASMJIT_API virtual Error embedConstPool(const Label& label, const ConstPool& pool);
//! 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).
- virtual Error embedLabel(const Label& label, size_t dataSize = 0) = 0;
+ ASMJIT_API virtual Error embedLabel(const Label& label, size_t dataSize = 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.
- virtual Error embedLabelDelta(const Label& label, const Label& base, size_t dataSize = 0) = 0;
+ ASMJIT_API virtual Error embedLabelDelta(const Label& label, const Label& base, size_t dataSize = 0);
//! \}
@@ -701,7 +780,7 @@ public:
//! \{
//! Emits a comment stored in `data` with an optional `size` parameter.
- virtual Error comment(const char* data, size_t size = SIZE_MAX) = 0;
+ ASMJIT_API virtual Error comment(const char* data, size_t size = SIZE_MAX);
//! Emits a formatted comment specified by `fmt` and variable number of arguments.
ASMJIT_API Error commentf(const char* fmt, ...);
@@ -714,9 +793,9 @@ public:
//! \{
//! Called after the emitter was attached to `CodeHolder`.
- virtual Error onAttach(CodeHolder* ASMJIT_NONNULL(code)) noexcept = 0;
+ ASMJIT_API virtual Error onAttach(CodeHolder* ASMJIT_NONNULL(code)) noexcept;
//! Called after the emitter was detached from `CodeHolder`.
- virtual Error onDetach(CodeHolder* ASMJIT_NONNULL(code)) noexcept = 0;
+ ASMJIT_API virtual Error onDetach(CodeHolder* ASMJIT_NONNULL(code)) noexcept;
//! Called when \ref CodeHolder has updated an important setting, which involves the following:
//!
diff --git a/3rdparty/asmjit/src/asmjit/core/emitterutils.cpp b/3rdparty/asmjit/src/asmjit/core/emitterutils.cpp
index f36a1b37745..d0a687244b3 100644
--- a/3rdparty/asmjit/src/asmjit/core/emitterutils.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/emitterutils.cpp
@@ -96,7 +96,7 @@ void logInstructionEmitted(
}
Error logInstructionFailed(
- BaseAssembler* self,
+ BaseEmitter* self,
Error err,
InstId instId,
InstOptions options,
@@ -109,16 +109,14 @@ Error logInstructionFailed(
Operand_ opArray[Globals::kMaxOpCount];
opArrayFromEmitArgs(opArray, o0, o1, o2, opExt);
- self->_funcs.formatInstruction(sb, FormatFlags::kNone, self, self->arch(), BaseInst(instId, options, self->extraReg()), opArray, Globals::kMaxOpCount);
+ self->_funcs.formatInstruction(sb, FormatFlags::kRegType, self, self->arch(), BaseInst(instId, options, self->extraReg()), opArray, Globals::kMaxOpCount);
if (self->inlineComment()) {
sb.append(" ; ");
sb.append(self->inlineComment());
}
- self->resetInstOptions();
- self->resetExtraReg();
- self->resetInlineComment();
+ self->resetState();
return self->reportError(err, sb.data());
}
diff --git a/3rdparty/asmjit/src/asmjit/core/emitterutils_p.h b/3rdparty/asmjit/src/asmjit/core/emitterutils_p.h
index b7610e70261..8b6e1e0547e 100644
--- a/3rdparty/asmjit/src/asmjit/core/emitterutils_p.h
+++ b/3rdparty/asmjit/src/asmjit/core/emitterutils_p.h
@@ -23,7 +23,7 @@ namespace EmitterUtils {
//! Default paddings used by Emitter utils and Formatter.
-static constexpr Operand noExt[3];
+static constexpr Operand noExt[3] = { {}, {}, {} };
enum kOpIndex : uint32_t {
kOp3 = 0,
@@ -71,7 +71,7 @@ void logInstructionEmitted(
uint32_t relSize, uint32_t immSize, uint8_t* afterCursor);
Error logInstructionFailed(
- BaseAssembler* self,
+ BaseEmitter* self,
Error err,
InstId instId,
InstOptions options,
diff --git a/3rdparty/asmjit/src/asmjit/core/environment.h b/3rdparty/asmjit/src/asmjit/core/environment.h
index 7e328a97c8e..c3678dc65bc 100644
--- a/3rdparty/asmjit/src/asmjit/core/environment.h
+++ b/3rdparty/asmjit/src/asmjit/core/environment.h
@@ -24,7 +24,7 @@ enum class Vendor : uint8_t {
//! Unknown or uninitialized platform vendor.
kUnknown = 0,
- //! Maximum value of `PlatformVendor`.
+ //! Maximum value of `Vendor`.
kMaxValue = kUnknown,
//! Platform vendor detected at compile-time.
@@ -116,7 +116,7 @@ enum class Platform : uint8_t {
//! Platform ABI (application binary interface).
enum class PlatformABI : uint8_t {
- //! Unknown or uninitialied environment.
+ //! Unknown or uninitialized environment.
kUnknown = 0,
//! Microsoft ABI.
kMSVC,
@@ -126,6 +126,8 @@ enum class PlatformABI : uint8_t {
kAndroid,
//! Cygwin ABI.
kCygwin,
+ //! Darwin ABI.
+ kDarwin,
//! Maximum value of `PlatformABI`.
kMaxValue,
@@ -142,11 +144,26 @@ enum class PlatformABI : uint8_t {
kGNU
#elif defined(__ANDROID__)
kAndroid
+#elif defined(__APPLE__)
+ kDarwin
#else
kUnknown
#endif
};
+//! Floating point ABI (ARM).
+enum class FloatABI : uint8_t {
+ kHardFloat = 0,
+ kSoftFloat,
+
+ kHost =
+#if ASMJIT_ARCH_ARM == 32 && defined(__SOFTFP__)
+ kSoftFloat
+#else
+ kHardFloat
+#endif
+};
+
//! Object format.
//!
//! \note AsmJit doesn't really use anything except \ref ObjectFormat::kUnknown and \ref ObjectFormat::kJIT at
@@ -186,53 +203,56 @@ public:
//! \{
//! Architecture.
- Arch _arch;
+ Arch _arch = Arch::kUnknown;
//! Sub-architecture type.
- SubArch _subArch;
+ SubArch _subArch = SubArch::kUnknown;
//! Vendor type.
- Vendor _vendor;
+ Vendor _vendor = Vendor::kUnknown;
//! Platform.
- Platform _platform;
+ Platform _platform = Platform::kUnknown;
//! Platform ABI.
- PlatformABI _platformABI;
+ PlatformABI _platformABI = PlatformABI::kUnknown;
//! Object format.
- ObjectFormat _objectFormat;
+ ObjectFormat _objectFormat = ObjectFormat::kUnknown;
+ //! Floating point ABI.
+ FloatABI _floatABI = FloatABI::kHardFloat;
//! Reserved for future use, must be zero.
- uint8_t _reserved[2];
+ uint8_t _reserved = 0;
//! \}
//! \name Construction & Destruction
//! \{
- inline Environment() noexcept :
- _arch(Arch::kUnknown),
- _subArch(SubArch::kUnknown),
- _vendor(Vendor::kUnknown),
- _platform(Platform::kUnknown),
- _platformABI(PlatformABI::kUnknown),
- _objectFormat(ObjectFormat::kUnknown),
- _reserved { 0, 0 } {}
+ //! Creates a default initialized environment (all values either unknown or set to safe defaults).
+ ASMJIT_INLINE_NODEBUG constexpr Environment() noexcept = default;
+ //! Creates a copy of `other` instance.
+ ASMJIT_INLINE_NODEBUG constexpr Environment(const Environment& other) noexcept = default;
- inline explicit Environment(
+ //! Creates \ref Environment initialized to `arch`, `subArch`, `vendor`, `platform`, `platformABI`, `objectFormat`,
+ //! and `floatABI`.
+ ASMJIT_INLINE_NODEBUG constexpr 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;
+ PlatformABI platformABI = PlatformABI::kUnknown,
+ ObjectFormat objectFormat = ObjectFormat::kUnknown,
+ FloatABI floatABI = FloatABI::kHardFloat) noexcept
+ : _arch(arch),
+ _subArch(subArch),
+ _vendor(vendor),
+ _platform(platform),
+ _platformABI(platformABI),
+ _objectFormat(objectFormat),
+ _floatABI(floatABI) {}
//! 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);
+ static ASMJIT_INLINE_NODEBUG Environment host() noexcept {
+ return Environment(Arch::kHost, SubArch::kHost, Vendor::kHost, Platform::kHost, PlatformABI::kHost, ObjectFormat::kUnknown, FloatABI::kHost);
}
//! \}
@@ -240,10 +260,10 @@ public:
//! \name Overloaded Operators
//! \{
- inline Environment& operator=(const Environment& other) noexcept = default;
+ ASMJIT_INLINE_NODEBUG Environment& operator=(const Environment& other) noexcept = default;
- inline bool operator==(const Environment& other) const noexcept { return equals(other); }
- inline bool operator!=(const Environment& other) const noexcept { return !equals(other); }
+ ASMJIT_INLINE_NODEBUG bool operator==(const Environment& other) const noexcept { return equals(other); }
+ ASMJIT_INLINE_NODEBUG bool operator!=(const Environment& other) const noexcept { return !equals(other); }
//! \}
@@ -253,59 +273,54 @@ public:
//! Tests whether the environment is not set up.
//!
//! Returns true if all members are zero, and thus unknown.
- inline bool empty() const noexcept {
+ ASMJIT_INLINE_NODEBUG bool empty() const noexcept {
// Unfortunately compilers won't optimize fields are checked one by one...
return _packed() == 0;
}
//! Tests whether the environment is initialized, which means it must have
//! a valid architecture.
- inline bool isInitialized() const noexcept {
+ ASMJIT_INLINE_NODEBUG bool isInitialized() const noexcept {
return _arch != Arch::kUnknown;
}
- inline uint64_t _packed() const noexcept {
+ ASMJIT_INLINE_NODEBUG uint64_t _packed() const noexcept {
uint64_t x;
memcpy(&x, this, 8);
return x;
}
//! Resets all members of the environment to zero / unknown.
- inline void reset() noexcept {
- _arch = Arch::kUnknown;
- _subArch = SubArch::kUnknown;
- _vendor = Vendor::kUnknown;
- _platform = Platform::kUnknown;
- _platformABI = PlatformABI::kUnknown;
- _objectFormat = ObjectFormat::kUnknown;
- _reserved[0] = 0;
- _reserved[1] = 0;
- }
+ ASMJIT_INLINE_NODEBUG void reset() noexcept { *this = Environment{}; }
- inline bool equals(const Environment& other) const noexcept {
- return _packed() == other._packed();
- }
+ //! Tests whether this environment is equal to `other`.
+ ASMJIT_INLINE_NODEBUG bool equals(const Environment& other) const noexcept { return _packed() == other._packed(); }
//! Returns the architecture.
- inline Arch arch() const noexcept { return _arch; }
+ ASMJIT_INLINE_NODEBUG Arch arch() const noexcept { return _arch; }
//! Returns the sub-architecture.
- inline SubArch subArch() const noexcept { return _subArch; }
+ ASMJIT_INLINE_NODEBUG SubArch subArch() const noexcept { return _subArch; }
//! Returns vendor.
- inline Vendor vendor() const noexcept { return _vendor; }
+ ASMJIT_INLINE_NODEBUG Vendor vendor() const noexcept { return _vendor; }
//! Returns target's platform or operating system.
- inline Platform platform() const noexcept { return _platform; }
+ ASMJIT_INLINE_NODEBUG Platform platform() const noexcept { return _platform; }
//! Returns target's ABI.
- inline PlatformABI platformABI() const noexcept { return _platformABI; }
+ ASMJIT_INLINE_NODEBUG PlatformABI platformABI() const noexcept { return _platformABI; }
//! Returns target's object format.
- inline ObjectFormat objectFormat() const noexcept { return _objectFormat; }
+ ASMJIT_INLINE_NODEBUG ObjectFormat objectFormat() const noexcept { return _objectFormat; }
+ //! Returns floating point ABI.
+ ASMJIT_INLINE_NODEBUG FloatABI floatABI() const noexcept { return _floatABI; }
+ //! Initializes \ref Environment to `arch`, `subArch`, `vendor`, `platform`, `platformABI`, `objectFormat`,
+ //! and `floatABI`.
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 {
+ ObjectFormat objectFormat = ObjectFormat::kUnknown,
+ FloatABI floatABI = FloatABI::kHardFloat) noexcept {
_arch = arch;
_subArch = subArch;
@@ -313,57 +328,63 @@ public:
_platform = platform;
_platformABI = platformABI;
_objectFormat = objectFormat;
- _reserved[0] = 0;
- _reserved[1] = 0;
+ _floatABI = floatABI;
+ _reserved = 0;
}
- 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 this environment describes a 32-bit X86.
+ ASMJIT_INLINE_NODEBUG bool isArchX86() const noexcept { return _arch == Arch::kX86; }
+ //! Tests whether this environment describes a 64-bit X86.
+ ASMJIT_INLINE_NODEBUG bool isArchX64() const noexcept { return _arch == Arch::kX64; }
+ //! Tests whether this environment describes a 32-bit ARM.
+ ASMJIT_INLINE_NODEBUG bool isArchARM() const noexcept { return isArchARM(_arch); }
+ //! Tests whether this environment describes a 32-bit ARM in THUMB mode.
+ ASMJIT_INLINE_NODEBUG bool isArchThumb() const noexcept { return isArchThumb(_arch); }
+ //! Tests whether this environment describes a 64-bit X86.
+ ASMJIT_INLINE_NODEBUG bool isArchAArch64() const noexcept { return isArchAArch64(_arch); }
+ //! Tests whether this environment describes a 32-bit MIPS.
+ ASMJIT_INLINE_NODEBUG bool isArchMIPS32() const noexcept { return isArchMIPS32(_arch); }
+ //! Tests whether this environment describes a 64-bit MIPS.
+ ASMJIT_INLINE_NODEBUG bool isArchMIPS64() const noexcept { return isArchMIPS64(_arch); }
+ //! Tests whether this environment describes a 32-bit RISC-V.
+ ASMJIT_INLINE_NODEBUG bool isArchRISCV32() const noexcept { return _arch == Arch::kRISCV32; }
+ //! Tests whether this environment describes a 64-bit RISC-V.
+ ASMJIT_INLINE_NODEBUG bool isArchRISCV64() const noexcept { return _arch == Arch::kRISCV64; }
//! Tests whether the architecture is 32-bit.
- inline bool is32Bit() const noexcept { return is32Bit(_arch); }
+ ASMJIT_INLINE_NODEBUG bool is32Bit() const noexcept { return is32Bit(_arch); }
//! Tests whether the architecture is 64-bit.
- inline bool is64Bit() const noexcept { return is64Bit(_arch); }
+ ASMJIT_INLINE_NODEBUG bool is64Bit() const noexcept { return is64Bit(_arch); }
//! Tests whether the architecture is little endian.
- inline bool isLittleEndian() const noexcept { return isLittleEndian(_arch); }
+ ASMJIT_INLINE_NODEBUG bool isLittleEndian() const noexcept { return isLittleEndian(_arch); }
//! Tests whether the architecture is big endian.
- inline bool isBigEndian() const noexcept { return isBigEndian(_arch); }
+ ASMJIT_INLINE_NODEBUG bool isBigEndian() const noexcept { return isBigEndian(_arch); }
//! Tests whether this architecture is of X86 family.
- inline bool isFamilyX86() const noexcept { return isFamilyX86(_arch); }
+ ASMJIT_INLINE_NODEBUG bool isFamilyX86() const noexcept { return isFamilyX86(_arch); }
//! Tests whether this architecture family is ARM, THUMB, or AArch64.
- inline bool isFamilyARM() const noexcept { return isFamilyARM(_arch); }
+ ASMJIT_INLINE_NODEBUG bool isFamilyARM() const noexcept { return isFamilyARM(_arch); }
//! Tests whether this architecture family is AArch32 (ARM or THUMB).
- inline bool isFamilyAArch32() const noexcept { return isFamilyAArch32(_arch); }
+ ASMJIT_INLINE_NODEBUG bool isFamilyAArch32() const noexcept { return isFamilyAArch32(_arch); }
//! Tests whether this architecture family is AArch64.
- inline bool isFamilyAArch64() const noexcept { return isFamilyAArch64(_arch); }
+ ASMJIT_INLINE_NODEBUG bool isFamilyAArch64() const noexcept { return isFamilyAArch64(_arch); }
//! Tests whether this architecture family is MISP or MIPS64.
- inline bool isFamilyMIPS() const noexcept { return isFamilyMIPS(_arch); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG bool isFamilyRISCV() const noexcept { return isFamilyRISCV(_arch); }
//! Tests whether the environment platform is Windows.
- inline bool isPlatformWindows() const noexcept { return _platform == Platform::kWindows; }
-
+ ASMJIT_INLINE_NODEBUG bool isPlatformWindows() const noexcept { return _platform == Platform::kWindows; }
//! Tests whether the environment platform is Linux.
- inline bool isPlatformLinux() const noexcept { return _platform == Platform::kLinux; }
-
+ ASMJIT_INLINE_NODEBUG bool isPlatformLinux() const noexcept { return _platform == Platform::kLinux; }
//! Tests whether the environment platform is Hurd.
- inline bool isPlatformHurd() const noexcept { return _platform == Platform::kHurd; }
-
+ ASMJIT_INLINE_NODEBUG bool isPlatformHurd() const noexcept { return _platform == Platform::kHurd; }
//! Tests whether the environment platform is Haiku.
- inline bool isPlatformHaiku() const noexcept { return _platform == Platform::kHaiku; }
+ ASMJIT_INLINE_NODEBUG bool isPlatformHaiku() const noexcept { return _platform == Platform::kHaiku; }
//! Tests whether the environment platform is any BSD.
- inline bool isPlatformBSD() const noexcept {
+ ASMJIT_INLINE_NODEBUG bool isPlatformBSD() const noexcept {
return _platform == Platform::kFreeBSD ||
_platform == Platform::kOpenBSD ||
_platform == Platform::kNetBSD ||
@@ -371,7 +392,7 @@ public:
}
//! Tests whether the environment platform is any Apple platform (OSX, iOS, TVOS, WatchOS).
- inline bool isPlatformApple() const noexcept {
+ ASMJIT_INLINE_NODEBUG bool isPlatformApple() const noexcept {
return _platform == Platform::kOSX ||
_platform == Platform::kIOS ||
_platform == Platform::kTVOS ||
@@ -379,119 +400,124 @@ public:
}
//! Tests whether the ABI is MSVC.
- inline bool isMSVC() const noexcept { return _platformABI == PlatformABI::kMSVC; }
+ ASMJIT_INLINE_NODEBUG bool isMSVC() const noexcept { return _platformABI == PlatformABI::kMSVC; }
//! Tests whether the ABI is GNU.
- inline bool isGNU() const noexcept { return _platformABI == PlatformABI::kGNU; }
+ ASMJIT_INLINE_NODEBUG bool isGNU() const noexcept { return _platformABI == PlatformABI::kGNU; }
+ //! Tests whether the ABI is GNU.
+ ASMJIT_INLINE_NODEBUG bool isDarwin() const noexcept { return _platformABI == PlatformABI::kDarwin; }
//! Returns a calculated stack alignment for this environment.
ASMJIT_API uint32_t stackAlignment() const noexcept;
//! Returns a native register size of this architecture.
- uint32_t registerSize() const noexcept { return registerSizeFromArch(_arch); }
+ ASMJIT_INLINE_NODEBUG uint32_t registerSize() const noexcept { return registerSizeFromArch(_arch); }
//! Sets the architecture to `arch`.
- inline void setArch(Arch arch) noexcept { _arch = arch; }
+ ASMJIT_INLINE_NODEBUG void setArch(Arch arch) noexcept { _arch = arch; }
//! Sets the sub-architecture to `subArch`.
- inline void setSubArch(SubArch subArch) noexcept { _subArch = subArch; }
+ ASMJIT_INLINE_NODEBUG void setSubArch(SubArch subArch) noexcept { _subArch = subArch; }
//! Sets the vendor to `vendor`.
- inline void setVendor(Vendor vendor) noexcept { _vendor = vendor; }
+ ASMJIT_INLINE_NODEBUG void setVendor(Vendor vendor) noexcept { _vendor = vendor; }
//! Sets the platform to `platform`.
- inline void setPlatform(Platform platform) noexcept { _platform = platform; }
+ ASMJIT_INLINE_NODEBUG void setPlatform(Platform platform) noexcept { _platform = platform; }
//! Sets the ABI to `platformABI`.
- inline void setPlatformABI(PlatformABI platformABI) noexcept { _platformABI = platformABI; }
+ ASMJIT_INLINE_NODEBUG void setPlatformABI(PlatformABI platformABI) noexcept { _platformABI = platformABI; }
//! Sets the object format to `objectFormat`.
- inline void setObjectFormat(ObjectFormat objectFormat) noexcept { _objectFormat = objectFormat; }
+ ASMJIT_INLINE_NODEBUG void setObjectFormat(ObjectFormat objectFormat) noexcept { _objectFormat = objectFormat; }
+
+ //! Sets floating point ABI to `floatABI`.
+ ASMJIT_INLINE_NODEBUG void setFloatABI(FloatABI floatABI) noexcept { _floatABI = floatABI; }
//! \}
//! \name Static Utilities
//! \{
- static inline bool isDefinedArch(Arch arch) noexcept {
+ static ASMJIT_INLINE_NODEBUG bool isDefinedArch(Arch arch) noexcept {
return uint32_t(arch) <= uint32_t(Arch::kMaxValue);
}
- static inline bool isValidArch(Arch arch) noexcept {
+ static ASMJIT_INLINE_NODEBUG 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(Arch arch) noexcept {
+ static ASMJIT_INLINE_NODEBUG 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(Arch arch) noexcept {
+ static ASMJIT_INLINE_NODEBUG 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(Arch arch) noexcept {
+ static ASMJIT_INLINE_NODEBUG 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(Arch arch) noexcept {
+ static ASMJIT_INLINE_NODEBUG bool isBigEndian(Arch arch) noexcept {
return uint32_t(arch) >= uint32_t(Arch::kBigEndian);
}
//! Tests whether the given architecture is Thumb or Thumb_BE.
- static inline bool isArchThumb(Arch arch) noexcept {
+ static ASMJIT_INLINE_NODEBUG bool isArchThumb(Arch arch) noexcept {
return arch == Arch::kThumb || arch == Arch::kThumb_BE;
}
//! Tests whether the given architecture is ARM or ARM_BE.
- static inline bool isArchARM(Arch arch) noexcept {
+ static ASMJIT_INLINE_NODEBUG bool isArchARM(Arch arch) noexcept {
return arch == Arch::kARM || arch == Arch::kARM_BE;
}
//! Tests whether the given architecture is AArch64 or AArch64_BE.
- static inline bool isArchAArch64(Arch arch) noexcept {
+ static ASMJIT_INLINE_NODEBUG 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 {
+ static ASMJIT_INLINE_NODEBUG 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 {
+ static ASMJIT_INLINE_NODEBUG 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 {
+ static ASMJIT_INLINE_NODEBUG 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(Arch arch) noexcept {
- return isArchARM(arch) || isArchAArch64(arch) || isArchThumb(arch);
- }
-
//! Tests whether the given architecture family is AArch32 (ARM or THUMB).
- static inline bool isFamilyAArch32(Arch arch) noexcept {
+ static ASMJIT_INLINE_NODEBUG bool isFamilyAArch32(Arch arch) noexcept {
return isArchARM(arch) || isArchThumb(arch);
}
//! Tests whether the given architecture family is AArch64.
- static inline bool isFamilyAArch64(Arch arch) noexcept {
+ static ASMJIT_INLINE_NODEBUG bool isFamilyAArch64(Arch arch) noexcept {
return isArchAArch64(arch);
}
- //! Tests whether the given architecture family is MISP or MIPS64.
- static inline bool isFamilyMIPS(Arch arch) noexcept {
+ //! Tests whether the given architecture family is ARM, THUMB, or AArch64.
+ static ASMJIT_INLINE_NODEBUG bool isFamilyARM(Arch arch) noexcept {
+ return isFamilyAArch32(arch) || isFamilyAArch64(arch);
+ }
+
+ //! Tests whether the given architecture family is MIPS or MIPS64.
+ static ASMJIT_INLINE_NODEBUG 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 {
+ static ASMJIT_INLINE_NODEBUG bool isFamilyRISCV(Arch arch) noexcept {
return arch == Arch::kRISCV32 || arch == Arch::kRISCV64;
}
//! Returns a native general purpose register size from the given architecture.
- static inline uint32_t registerSizeFromArch(Arch arch) noexcept {
+ static ASMJIT_INLINE_NODEBUG uint32_t registerSizeFromArch(Arch arch) noexcept {
return is32Bit(arch) ? 4u : 8u;
}
diff --git a/3rdparty/asmjit/src/asmjit/core/errorhandler.cpp b/3rdparty/asmjit/src/asmjit/core/errorhandler.cpp
index 5a7dac52356..ce2ad016af1 100644
--- a/3rdparty/asmjit/src/asmjit/core/errorhandler.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/errorhandler.cpp
@@ -11,4 +11,8 @@ ASMJIT_BEGIN_NAMESPACE
ErrorHandler::ErrorHandler() noexcept {}
ErrorHandler::~ErrorHandler() noexcept {}
+void ErrorHandler::handleError(Error err, const char* message, BaseEmitter* origin) {
+ DebugUtils::unused(err, message, origin);
+}
+
ASMJIT_END_NAMESPACE
diff --git a/3rdparty/asmjit/src/asmjit/core/errorhandler.h b/3rdparty/asmjit/src/asmjit/core/errorhandler.h
index 5151d43304e..a1a2dd2d5db 100644
--- a/3rdparty/asmjit/src/asmjit/core/errorhandler.h
+++ b/3rdparty/asmjit/src/asmjit/core/errorhandler.h
@@ -61,7 +61,7 @@ class BaseEmitter;
//! SimpleErrorHandler eh;
//!
//! CodeHolder code;
-//! code.init(rt.environment());
+//! code.init(rt.environment(), rt.cpuFeatures());
//! code.setErrorHandler(&eh);
//!
//! // Try to emit instruction that doesn't exist.
@@ -117,7 +117,7 @@ class BaseEmitter;
//! ThrowableErrorHandler eh;
//!
//! CodeHolder code;
-//! code.init(rt.environment());
+//! code.init(rt.environment(), rt.cpuFeatures());
//! code.setErrorHandler(&eh);
//!
//! x86::Assembler a(&code);
@@ -166,7 +166,7 @@ class BaseEmitter;
//! LongJmpErrorHandler eh;
//!
//! CodeHolder code;
-//! code.init(rt.rt.environment());
+//! code.init(rt.environment(), rt.cpuFeatures());
//! code.setErrorHandler(&eh);
//!
//! x86::Assembler a(&code);
@@ -215,7 +215,7 @@ public:
//! 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;
+ ASMJIT_API virtual void handleError(Error err, const char* message, BaseEmitter* origin);
//! \}
};
diff --git a/3rdparty/asmjit/src/asmjit/core/formatter.cpp b/3rdparty/asmjit/src/asmjit/core/formatter.cpp
index 1a9a386e3f3..0f12e416364 100644
--- a/3rdparty/asmjit/src/asmjit/core/formatter.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/formatter.cpp
@@ -57,7 +57,7 @@ Error formatTypeId(String& sb, TypeId typeId) noexcept {
if (!TypeUtils::isValid(typeId))
return sb.append("unknown");
- const char* typeName = "unknown";
+ const char* typeName = nullptr;
uint32_t typeSize = TypeUtils::sizeOf(typeId);
TypeId scalarType = TypeUtils::scalarOf(typeId);
@@ -107,7 +107,7 @@ Error formatFeature(
return x86::FormatterInternal::formatFeature(sb, featureId);
#endif
-#if !defined(ASMJIT_NO_AARCH32) && !defined(ASMJIT_NO_AARCH64)
+#if !defined(ASMJIT_NO_AARCH64)
if (Environment::isFamilyARM(arch))
return arm::FormatterInternal::formatFeature(sb, featureId);
#endif
@@ -123,32 +123,33 @@ Error formatLabel(
DebugUtils::unused(formatFlags);
- const LabelEntry* le = emitter->code()->labelEntry(labelId);
- if (ASMJIT_UNLIKELY(!le))
- return sb.appendFormat("<InvalidLabel:%u>", labelId);
+ if (emitter && emitter->code()) {
+ const LabelEntry* le = emitter->code()->labelEntry(labelId);
+ if (ASMJIT_UNLIKELY(!le))
+ return sb.appendFormat("<InvalidLabel:%u>", labelId);
- if (le->hasName()) {
- if (le->hasParent()) {
- uint32_t parentId = le->parentId();
- const LabelEntry* pe = emitter->code()->labelEntry(parentId);
+ if (le->hasName()) {
+ if (le->hasParent()) {
+ uint32_t parentId = le->parentId();
+ const LabelEntry* pe = emitter->code()->labelEntry(parentId);
- if (ASMJIT_UNLIKELY(!pe))
- ASMJIT_PROPAGATE(sb.appendFormat("<InvalidLabel:%u>", labelId));
- else if (ASMJIT_UNLIKELY(!pe->hasName()))
- ASMJIT_PROPAGATE(sb.appendFormat("L%u", parentId));
- else
- ASMJIT_PROPAGATE(sb.append(pe->name()));
+ if (ASMJIT_UNLIKELY(!pe))
+ ASMJIT_PROPAGATE(sb.appendFormat("<InvalidLabel:%u>", labelId));
+ else if (ASMJIT_UNLIKELY(!pe->hasName()))
+ ASMJIT_PROPAGATE(sb.appendFormat("L%u", parentId));
+ else
+ ASMJIT_PROPAGATE(sb.append(pe->name()));
- ASMJIT_PROPAGATE(sb.append('.'));
- }
+ ASMJIT_PROPAGATE(sb.append('.'));
+ }
- if (le->type() == LabelType::kAnonymous)
- ASMJIT_PROPAGATE(sb.appendFormat("L%u@", labelId));
- return sb.append(le->name());
- }
- else {
- return sb.appendFormat("L%u", labelId);
+ if (le->type() == LabelType::kAnonymous)
+ ASMJIT_PROPAGATE(sb.appendFormat("L%u@", labelId));
+ return sb.append(le->name());
+ }
}
+
+ return sb.appendFormat("L%u", labelId);
}
Error formatRegister(
@@ -165,8 +166,8 @@ Error formatRegister(
#endif
#if !defined(ASMJIT_NO_AARCH64)
- if (Environment::isFamilyAArch64(arch))
- return a64::FormatterInternal::formatRegister(sb, formatFlags, emitter, arch, regType, regId);
+ if (Environment::isFamilyARM(arch))
+ return arm::FormatterInternal::formatRegister(sb, formatFlags, emitter, arch, regType, regId);
#endif
return kErrorInvalidArch;
@@ -185,8 +186,8 @@ Error formatOperand(
#endif
#if !defined(ASMJIT_NO_AARCH64)
- if (Environment::isFamilyAArch64(arch))
- return a64::FormatterInternal::formatOperand(sb, formatFlags, emitter, arch, op);
+ if (Environment::isFamilyARM(arch))
+ return arm::FormatterInternal::formatOperand(sb, formatFlags, emitter, arch, op);
#endif
return kErrorInvalidArch;
@@ -283,7 +284,7 @@ Error formatInstruction(
#endif
#if !defined(ASMJIT_NO_AARCH64)
- if (Environment::isFamilyARM(arch))
+ if (Environment::isFamilyAArch64(arch))
return a64::FormatterInternal::formatInstruction(sb, formatFlags, emitter, arch, inst, operands, opCount);
#endif
@@ -471,8 +472,7 @@ Error formatNode(
case NodeType::kComment: {
const CommentNode* commentNode = node->as<CommentNode>();
- ASMJIT_PROPAGATE(sb.appendFormat("; %s", commentNode->inlineComment()));
- break;
+ return sb.appendFormat("; %s", commentNode->inlineComment());
}
case NodeType::kSentinel: {
@@ -514,7 +514,7 @@ Error formatNode(
ASMJIT_PROPAGATE(sb.append("[FuncRet]"));
for (uint32_t i = 0; i < 2; i++) {
- const Operand_& op = retNode->_opArray[i];
+ const Operand_& op = retNode->op(i);
if (!op.isNone()) {
ASMJIT_PROPAGATE(sb.append(i == 0 ? " " : ", "));
ASMJIT_PROPAGATE(formatOperand(sb, formatOptions.flags(), builder, builder->arch(), op));
diff --git a/3rdparty/asmjit/src/asmjit/core/formatter.h b/3rdparty/asmjit/src/asmjit/core/formatter.h
index d7a4b93476a..392e4787302 100644
--- a/3rdparty/asmjit/src/asmjit/core/formatter.h
+++ b/3rdparty/asmjit/src/asmjit/core/formatter.h
@@ -37,7 +37,9 @@ enum class FormatFlags : uint32_t {
//! Show casts between virtual register types (Compiler output).
kRegCasts = 0x00000010u,
//! Show positions associated with nodes (Compiler output).
- kPositions = 0x00000020u
+ kPositions = 0x00000020u,
+ //! Always format a register type (Compiler output).
+ kRegType = 0x00000040u
};
ASMJIT_DEFINE_ENUM_FLAGS(FormatFlags)
@@ -89,7 +91,7 @@ public:
//! \{
//! Resets FormatOptions to its default initialized state.
- inline void reset() noexcept {
+ ASMJIT_INLINE_NODEBUG void reset() noexcept {
_flags = FormatFlags::kNone;
_indentation.fill(uint8_t(0));
_padding.fill(uint16_t(0));
@@ -101,31 +103,31 @@ public:
//! \{
//! Returns format flags.
- inline FormatFlags flags() const noexcept { return _flags; }
+ ASMJIT_INLINE_NODEBUG FormatFlags flags() const noexcept { return _flags; }
//! Tests whether the given `flag` is set in format flags.
- inline bool hasFlag(FormatFlags flag) const noexcept { return Support::test(_flags, flag); }
+ ASMJIT_INLINE_NODEBUG bool hasFlag(FormatFlags flag) const noexcept { return Support::test(_flags, flag); }
//! Resets all format flags to `flags`.
- inline void setFlags(FormatFlags flags) noexcept { _flags = flags; }
+ ASMJIT_INLINE_NODEBUG void setFlags(FormatFlags flags) noexcept { _flags = flags; }
//! Adds `flags` to format flags.
- inline void addFlags(FormatFlags flags) noexcept { _flags |= flags; }
+ ASMJIT_INLINE_NODEBUG void addFlags(FormatFlags flags) noexcept { _flags |= flags; }
//! Removes `flags` from format flags.
- inline void clearFlags(FormatFlags flags) noexcept { _flags &= ~flags; }
+ ASMJIT_INLINE_NODEBUG 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]; }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG 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
+ //! Returns padding for the given padding `group`.
+ ASMJIT_INLINE_NODEBUG size_t padding(FormatPaddingGroup group) const noexcept { return _padding[group]; }
+ //! Sets padding for the given padding `group`.
+ ASMJIT_INLINE_NODEBUG void setPadding(FormatPaddingGroup group, size_t n) noexcept { _padding[group] = uint16_t(n); }
+ //! Resets padding 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_INLINE_NODEBUG void resetPadding(FormatPaddingGroup group) noexcept { _padding[group] = uint16_t(0); }
//! \}
};
diff --git a/3rdparty/asmjit/src/asmjit/core/func.cpp b/3rdparty/asmjit/src/asmjit/core/func.cpp
index 04dc2aaf208..a8a6d3ab932 100644
--- a/3rdparty/asmjit/src/asmjit/core/func.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/func.cpp
@@ -20,8 +20,8 @@
ASMJIT_BEGIN_NAMESPACE
-// CallConv - Init & Reset
-// =======================
+// CallConv - Initialization & Reset
+// =================================
ASMJIT_FAVOR_SIZE Error CallConv::init(CallConvId ccId, const Environment& environment) noexcept {
reset();
@@ -75,7 +75,7 @@ ASMJIT_FAVOR_SIZE Error FuncDetail::init(const FuncSignature& signature, const E
#if !defined(ASMJIT_NO_AARCH64)
if (environment.isFamilyAArch64())
- return a64::FuncInternal::initFuncDetail(*this, signature, registerSize);
+ return a64::FuncInternal::initFuncDetail(*this, signature);
#endif
// We should never bubble here as if `cc.init()` succeeded then there has to be an implementation for the current
@@ -283,4 +283,18 @@ ASMJIT_FAVOR_SIZE Error FuncArgsAssignment::updateFuncFrame(FuncFrame& frame) co
return kErrorOk;
}
+// Func API - Tests
+// ================
+
+#if defined(ASMJIT_TEST)
+UNIT(func_signature) {
+ FuncSignature signature;
+ signature.setRetT<int8_t>();
+ signature.addArgT<int16_t>();
+ signature.addArg(TypeId::kInt32);
+
+ EXPECT_EQ(signature, FuncSignature::build<int8_t, int16_t, int32_t>());
+}
+#endif
+
ASMJIT_END_NAMESPACE
diff --git a/3rdparty/asmjit/src/asmjit/core/func.h b/3rdparty/asmjit/src/asmjit/core/func.h
index 78a41f98f65..695a23bbcf0 100644
--- a/3rdparty/asmjit/src/asmjit/core/func.h
+++ b/3rdparty/asmjit/src/asmjit/core/func.h
@@ -28,58 +28,45 @@ ASMJIT_BEGIN_NAMESPACE
//! - 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
+ //! This is a universal calling convention, which is used to initialize specific calling conventions based on
//! architecture, platform, and its ABI.
- kCDecl = 1,
+ kCDecl = 0,
//! `__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,
+ kStdCall = 1,
//! `__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,
+ kFastCall = 2,
//! `__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,
+ kVectorCall = 3,
//! `__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,
+ kThisCall = 4,
//! `__attribute__((regparm(1)))` convention (GCC and Clang).
- kRegParm1 = 6,
+ kRegParm1 = 5,
//! `__attribute__((regparm(2)))` convention (GCC and Clang).
- kRegParm2 = 7,
+ kRegParm2 = 6,
//! `__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,
+ kRegParm3 = 7,
//! 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
@@ -91,28 +78,32 @@ enum class CallConvId : uint8_t {
// ABI-Specific Calling Conventions
// --------------------------------
+ //! Soft-float calling convention (AArch32).
+ //!
+ //! Floating point arguments are passed via general purpose registers.
+ kSoftFloat = 30,
+
+ //! Hard-float calling convention (AArch32).
+ //!
+ //! Floating point arguments are passed via SIMD registers.
+ kHardFloat = 31,
+
//! 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
+ kMaxValue = kX64Windows
+
+ // Deprecated Aliases
+ // ------------------
+
+#if !defined(ASMJIT_NO_DEPRECATED)
+ ,
+ kNone = kCDecl,
+ kHost = kCDecl
+#endif // !ASMJIT_NO_DEPRECATED
};
//! Strategy used by calling conventions to assign registers to function arguments.
@@ -128,6 +119,8 @@ enum class CallConvStrategy : uint8_t {
kX64Windows = 1,
//! Windows 64-bit __vectorcall register assignment strategy.
kX64VectorCall = 2,
+ //! Apple's AArch64 calling convention (differs compared to AArch64 calling convention used by Linux).
+ kAArch64Apple = 3,
//! Maximum value of `CallConvStrategy`.
kMaxValue = kX64VectorCall
@@ -163,14 +156,12 @@ struct CallConv {
//! \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
- };
+ //! Maximum number of register arguments per register group.
+ //!
+ //! \note This is not really AsmJit's limitation, 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.
+ static constexpr uint32_t kMaxRegArgsPerGroup = 16;
//! \}
@@ -191,6 +182,11 @@ struct CallConv {
//! Natural stack alignment as defined by OS/ABI.
uint8_t _naturalStackAlignment;
+ //! \cond INTERNAL
+ //! Reserved for future use.
+ uint8_t _reserved[2];
+ //! \endcond
+
//! Calling convention flags.
CallConvFlags _flags;
@@ -230,8 +226,8 @@ struct CallConv {
//! 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));
+ ASMJIT_INLINE_NODEBUG void reset() noexcept {
+ *this = CallConv{};
memset(_passedOrder.data(), 0xFF, sizeof(_passedOrder));
}
@@ -241,61 +237,61 @@ struct CallConv {
//! \{
//! Returns the target architecture of this calling convention.
- inline Arch arch() const noexcept { return _arch; }
+ ASMJIT_INLINE_NODEBUG Arch arch() const noexcept { return _arch; }
//! Sets the target architecture of this calling convention.
- inline void setArch(Arch arch) noexcept { _arch = arch; }
+ ASMJIT_INLINE_NODEBUG void setArch(Arch arch) noexcept { _arch = arch; }
//! Returns the calling convention id.
- inline CallConvId id() const noexcept { return _id; }
+ ASMJIT_INLINE_NODEBUG CallConvId id() const noexcept { return _id; }
//! Sets the calling convention id.
- inline void setId(CallConvId ccId) noexcept { _id = ccId; }
+ ASMJIT_INLINE_NODEBUG void setId(CallConvId ccId) noexcept { _id = ccId; }
//! Returns the strategy used to assign registers to arguments.
- inline CallConvStrategy strategy() const noexcept { return _strategy; }
+ ASMJIT_INLINE_NODEBUG CallConvStrategy strategy() const noexcept { return _strategy; }
//! Sets the strategy used to assign registers to arguments.
- inline void setStrategy(CallConvStrategy ccStrategy) noexcept { _strategy = ccStrategy; }
+ ASMJIT_INLINE_NODEBUG void setStrategy(CallConvStrategy ccStrategy) noexcept { _strategy = ccStrategy; }
//! Tests whether the calling convention has the given `flag` set.
- inline bool hasFlag(CallConvFlags flag) const noexcept { return Support::test(_flags, flag); }
+ ASMJIT_INLINE_NODEBUG bool hasFlag(CallConvFlags flag) const noexcept { return Support::test(_flags, flag); }
//! Returns the calling convention flags, see `Flags`.
- inline CallConvFlags flags() const noexcept { return _flags; }
+ ASMJIT_INLINE_NODEBUG CallConvFlags flags() const noexcept { return _flags; }
//! Adds the calling convention flags, see `Flags`.
- inline void setFlags(CallConvFlags flag) noexcept { _flags = flag; };
+ ASMJIT_INLINE_NODEBUG void setFlags(CallConvFlags flag) noexcept { _flags = flag; };
//! Adds the calling convention flags, see `Flags`.
- inline void addFlags(CallConvFlags flags) noexcept { _flags |= flags; };
+ ASMJIT_INLINE_NODEBUG void addFlags(CallConvFlags flags) noexcept { _flags |= flags; };
//! Tests whether this calling convention specifies 'RedZone'.
- inline bool hasRedZone() const noexcept { return _redZoneSize != 0; }
+ ASMJIT_INLINE_NODEBUG bool hasRedZone() const noexcept { return _redZoneSize != 0; }
//! Tests whether this calling convention specifies 'SpillZone'.
- inline bool hasSpillZone() const noexcept { return _spillZoneSize != 0; }
+ ASMJIT_INLINE_NODEBUG bool hasSpillZone() const noexcept { return _spillZoneSize != 0; }
//! Returns size of 'RedZone'.
- inline uint32_t redZoneSize() const noexcept { return _redZoneSize; }
+ ASMJIT_INLINE_NODEBUG uint32_t redZoneSize() const noexcept { return _redZoneSize; }
//! Returns size of 'SpillZone'.
- inline uint32_t spillZoneSize() const noexcept { return _spillZoneSize; }
+ ASMJIT_INLINE_NODEBUG uint32_t spillZoneSize() const noexcept { return _spillZoneSize; }
//! Sets size of 'RedZone'.
- inline void setRedZoneSize(uint32_t size) noexcept { _redZoneSize = uint8_t(size); }
+ ASMJIT_INLINE_NODEBUG void setRedZoneSize(uint32_t size) noexcept { _redZoneSize = uint8_t(size); }
//! Sets size of 'SpillZone'.
- inline void setSpillZoneSize(uint32_t size) noexcept { _spillZoneSize = uint8_t(size); }
+ ASMJIT_INLINE_NODEBUG void setSpillZoneSize(uint32_t size) noexcept { _spillZoneSize = uint8_t(size); }
//! Returns a natural stack alignment.
- inline uint32_t naturalStackAlignment() const noexcept { return _naturalStackAlignment; }
+ ASMJIT_INLINE_NODEBUG 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.
- inline void setNaturalStackAlignment(uint32_t value) noexcept { _naturalStackAlignment = uint8_t(value); }
+ ASMJIT_INLINE_NODEBUG 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(RegGroup group) const noexcept { return _saveRestoreRegSize[group]; }
+ ASMJIT_INLINE_NODEBUG 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(RegGroup group, uint32_t size) noexcept { _saveRestoreRegSize[group] = uint8_t(size); }
+ ASMJIT_INLINE_NODEBUG 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(RegGroup group) const noexcept { return _saveRestoreAlignment[group]; }
+ ASMJIT_INLINE_NODEBUG 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(RegGroup group, uint32_t alignment) noexcept { _saveRestoreAlignment[group] = uint8_t(alignment); }
+ ASMJIT_INLINE_NODEBUG void setSaveRestoreAlignment(RegGroup group, uint32_t alignment) noexcept { _saveRestoreAlignment[group] = uint8_t(alignment); }
//! Returns the order of passed registers of the given `group`.
inline const uint8_t* passedOrder(RegGroup group) const noexcept {
@@ -364,16 +360,21 @@ struct CallConv {
//! 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 a 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.
+//! It's typically used to describe function arguments in a C-API like form, which is then used to calculate a
+//! \ref FuncDetail instance, which then maps function signature into a platform and calling convention specific
+//! format.
+//!
+//! Function signature can be built either dynamically by using \ref addArg() and \ref addArgT() functionality,
+//! or dynamically by using a template-based \ref FuncSignature::build() function, which maps template types
+//! into a function signature.
struct FuncSignature {
//! \name Constants
//! \{
- enum : uint8_t {
- //! Doesn't have variable number of arguments (`...`).
- kNoVarArgs = 0xFFu
- };
+ //! Doesn't have variable number of arguments (`...`).
+ static constexpr uint8_t kNoVarArgs = 0xFFu;
//! \}
@@ -381,90 +382,87 @@ struct FuncSignature {
//! \{
//! Calling convention id.
- CallConvId _ccId;
+ CallConvId _ccId = CallConvId::kCDecl;
//! Count of arguments.
- uint8_t _argCount;
+ uint8_t _argCount = 0;
//! Index of a first VA or `kNoVarArgs`.
- uint8_t _vaIndex;
+ uint8_t _vaIndex = kNoVarArgs;
//! Return value TypeId.
- TypeId _ret;
- //! Function arguments TypeIds.
- const TypeId* _args;
+ TypeId _ret = TypeId::kVoid;
+ //! Reserved for future use.
+ uint8_t _reserved[4] {};
+ //! Function argument TypeIds.
+ TypeId _args[Globals::kMaxFuncArgs] {};
//! \}
- //! \name Initializtion & Reset
+ //! \name Construction & Destruction
//! \{
- //! Initializes the function signature.
- inline void init(CallConvId ccId, uint32_t vaIndex, TypeId ret, const TypeId* args, uint32_t argCount) noexcept {
- ASMJIT_ASSERT(argCount <= 0xFF);
+ //! Default constructed function signature, initialized to \ref CallConvId::kCDecl, having no return value and no arguments.
+ ASMJIT_FORCE_INLINE constexpr FuncSignature() = default;
- _ccId = ccId;
- _argCount = uint8_t(argCount);
- _vaIndex = uint8_t(vaIndex);
- _ret = ret;
- _args = args;
- }
+ //! Copy constructor, which is initialized to the same function signature as `other`.
+ ASMJIT_FORCE_INLINE constexpr FuncSignature(const FuncSignature& other) = default;
+
+ //! Initializes the function signature with calling convention id `ccId` and variable argument's index `vaIndex`.
+ ASMJIT_FORCE_INLINE constexpr FuncSignature(CallConvId ccId, uint32_t vaIndex = kNoVarArgs) noexcept
+ : _ccId(ccId),
+ _vaIndex(uint8_t(vaIndex)) {}
- inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
+ //! Initializes the function signature with calling convention id `ccId`, `vaIndex`, return value, and function arguments.
+ template<typename... Args>
+ ASMJIT_FORCE_INLINE constexpr FuncSignature(CallConvId ccId, uint32_t vaIndex, TypeId ret, Args&&...args) noexcept
+ : _ccId(ccId),
+ _argCount(uint8_t(sizeof...(args))),
+ _vaIndex(uint8_t(vaIndex)),
+ _ret(ret),
+ _args{std::forward<Args>(args)...} {}
+
+ //! Builds a function signature based on `RetValueAndArgs`. The first template argument is a function return type,
+ //! and function arguments follow.
+ //!
+ //! \note This function returns a new function signature, which can be passed to functions where it's required. It's
+ //! a convenience function that allows to build function signature statically based on types known at compile time,
+ //! which is common in JIT code generation.
+ template<typename... RetValueAndArgs>
+ static ASMJIT_INLINE_NODEBUG constexpr FuncSignature build(CallConvId ccId = CallConvId::kCDecl, uint32_t vaIndex = kNoVarArgs) noexcept {
+ return FuncSignature(ccId, vaIndex, (TypeId(TypeUtils::TypeIdOfT<RetValueAndArgs>::kTypeId))... );
+ }
//! \}
- //! \name Accessors
+ //! \name Overloaded Operators
//! \{
- //! Returns the calling convention.
- inline CallConvId callConvId() const noexcept { return _ccId; }
- //! Sets the calling convention to `ccId`;
- inline void setCallConvId(CallConvId ccId) noexcept { _ccId = ccId; }
+ //! Copy assignment - function signature can be copied by value.
+ ASMJIT_FORCE_INLINE FuncSignature& operator=(const FuncSignature& other) noexcept = default;
- //! Tests whether the function has variable number of arguments (...).
- inline bool hasVarArgs() const noexcept { return _vaIndex != kNoVarArgs; }
- //! Returns the variable arguments (...) index, `kNoVarArgs` if none.
- inline uint32_t vaIndex() const noexcept { return _vaIndex; }
- //! Sets the variable arguments (...) index to `index`.
- inline void setVaIndex(uint32_t index) noexcept { _vaIndex = uint8_t(index); }
- //! Resets the variable arguments index (making it a non-va function).
- inline void resetVaIndex() noexcept { _vaIndex = kNoVarArgs; }
+ //! Compares this function signature with `other` for equality..
+ ASMJIT_FORCE_INLINE bool operator==(const FuncSignature& other) const noexcept { return equals(other); }
+ //! Compares this function signature with `other` for inequality..
+ ASMJIT_FORCE_INLINE bool operator!=(const FuncSignature& other) const noexcept { return !equals(other); }
- //! Returns the number of function arguments.
- inline uint32_t argCount() const noexcept { return _argCount; }
+ //! \}
- inline bool hasRet() const noexcept { return _ret != TypeId::kVoid; }
- //! Returns the return value type.
- inline TypeId ret() const noexcept { return _ret; }
+ //! \name Initialization & Reset
+ //! \{
- //! Returns the type of the argument at index `i`.
- inline TypeId arg(uint32_t i) const noexcept {
- ASMJIT_ASSERT(i < _argCount);
- return _args[i];
- }
- //! Returns the array of function arguments' types.
- inline const TypeId* args() const noexcept { return _args; }
+ //! Resets this function signature to a default constructed state.
+ ASMJIT_INLINE_NODEBUG void reset() noexcept { *this = FuncSignature{}; }
//! \}
-};
-template<typename... RET_ARGS>
-class FuncSignatureT : public FuncSignature {
-public:
- 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));
- }
-};
-
-//! Function signature builder.
-class FuncSignatureBuilder : public FuncSignature {
-public:
- TypeId _builderArgList[Globals::kMaxFuncArgs];
-
- //! \name Initializtion & Reset
+ //! \name Equality & Comparison
//! \{
- inline FuncSignatureBuilder(CallConvId ccId = CallConvId::kHost, uint32_t vaIndex = kNoVarArgs) noexcept {
- init(ccId, vaIndex, TypeId::kVoid, _builderArgList, 0);
+ //! Compares this function signature with `other` for equality..
+ ASMJIT_INLINE_NODEBUG bool equals(const FuncSignature& other) const noexcept {
+ return _ccId == other._ccId &&
+ _argCount == other._argCount &&
+ _vaIndex == other._vaIndex &&
+ _ret == other._ret &&
+ memcmp(_args, other._args, sizeof(_args)) == 0;
}
//! \}
@@ -472,33 +470,85 @@ public:
//! \name Accessors
//! \{
+ //! Returns the calling convention.
+ ASMJIT_INLINE_NODEBUG CallConvId callConvId() const noexcept { return _ccId; }
+ //! Sets the calling convention to `ccId`;
+ ASMJIT_INLINE_NODEBUG void setCallConvId(CallConvId ccId) noexcept { _ccId = ccId; }
+
+ //! Tests whether the function signature has a return value.
+ ASMJIT_INLINE_NODEBUG bool hasRet() const noexcept { return _ret != TypeId::kVoid; }
+ //! Returns the type of the return value.
+ ASMJIT_INLINE_NODEBUG TypeId ret() const noexcept { return _ret; }
//! Sets the return type to `retType`.
- inline void setRet(TypeId retType) noexcept { _ret = retType; }
+ ASMJIT_INLINE_NODEBUG void setRet(TypeId retType) noexcept { _ret = retType; }
//! Sets the return type based on `T`.
template<typename T>
- inline void setRetT() noexcept { setRet(TypeId(TypeUtils::TypeIdOfT<T>::kTypeId)); }
+ ASMJIT_INLINE_NODEBUG void setRetT() noexcept { setRet(TypeId(TypeUtils::TypeIdOfT<T>::kTypeId)); }
+
+
+ //! Returns the array of function arguments' types.
+ ASMJIT_INLINE_NODEBUG const TypeId* args() const noexcept { return _args; }
+ //! Returns the number of function arguments.
+ ASMJIT_INLINE_NODEBUG uint32_t argCount() const noexcept { return _argCount; }
+
+ //! Returns the type of the argument at index `i`.
+ inline TypeId arg(uint32_t i) const noexcept {
+ ASMJIT_ASSERT(i < _argCount);
+ return _args[i];
+ }
//! Sets the argument at index `index` to `argType`.
inline void setArg(uint32_t index, TypeId argType) noexcept {
ASMJIT_ASSERT(index < _argCount);
- _builderArgList[index] = argType;
+ _args[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, TypeId(TypeUtils::TypeIdOfT<T>::kTypeId)); }
+ //! Tests whether an argument can be added to the signature, use before calling \ref addArg() and \ref addArgT().
+ //!
+ //! \note If you know that you are not adding more arguments than \ref Globals::kMaxFuncArgs then it's not necessary
+ //! to use this function. However, if you are adding arguments based on user input, for example, then either check
+ //! the number of arguments before using function signature or use \ref canAddArg() before actually adding them to
+ //! the function signature.
+ inline bool canAddArg() const noexcept { return _argCount < Globals::kMaxFuncArgs; }
+
//! Appends an argument of `type` to the function prototype.
inline void addArg(TypeId type) noexcept {
ASMJIT_ASSERT(_argCount < Globals::kMaxFuncArgs);
- _builderArgList[_argCount++] = type;
+ _args[_argCount++] = type;
}
+
//! Appends an argument of type based on `T` to the function prototype.
template<typename T>
inline void addArgT() noexcept { addArg(TypeId(TypeUtils::TypeIdOfT<T>::kTypeId)); }
+ //! Tests whether the function has variable number of arguments (...).
+ ASMJIT_INLINE_NODEBUG bool hasVarArgs() const noexcept { return _vaIndex != kNoVarArgs; }
+ //! Returns the variable arguments (...) index, `kNoVarArgs` if none.
+ ASMJIT_INLINE_NODEBUG uint32_t vaIndex() const noexcept { return _vaIndex; }
+ //! Sets the variable arguments (...) index to `index`.
+ ASMJIT_INLINE_NODEBUG void setVaIndex(uint32_t index) noexcept { _vaIndex = uint8_t(index); }
+ //! Resets the variable arguments index (making it a non-va function).
+ ASMJIT_INLINE_NODEBUG void resetVaIndex() noexcept { _vaIndex = kNoVarArgs; }
+
//! \}
};
+#if !defined(ASMJIT_NO_DEPRECATED)
+template<typename... RetValueAndArgs>
+class FuncSignatureT : public FuncSignature {
+public:
+ ASMJIT_DEPRECATED("Use FuncSignature::build<RetValueAndArgs>() instead")
+ ASMJIT_INLINE_NODEBUG constexpr FuncSignatureT(CallConvId ccId = CallConvId::kCDecl, uint32_t vaIndex = kNoVarArgs) noexcept
+ : FuncSignature(ccId, vaIndex, (TypeId(TypeUtils::TypeIdOfT<RetValueAndArgs>::kTypeId))... ) {}
+};
+
+ASMJIT_DEPRECATED("Use FuncSignature instead of FuncSignatureBuilder")
+typedef FuncSignature FuncSignatureBuilder;
+#endif // !ASMJIT_NO_DEPRECATED
+
//! Argument or return value (or its part) as defined by `FuncSignature`, but with register or stack address
//! (and other metadata) assigned.
struct FuncValue {
@@ -533,43 +583,47 @@ struct FuncValue {
//! \}
- //! \name Initializtion & Reset
+ //! \name Initialization & 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(TypeId typeId) noexcept {
+ //! Initializes this `FuncValue` only to the `typeId` provided - the rest of the values will be cleared.
+ ASMJIT_INLINE_NODEBUG void initTypeId(TypeId typeId) noexcept {
_data = uint32_t(typeId) << kTypeIdShift;
}
- inline void initReg(RegType regType, uint32_t regId, TypeId typeId, uint32_t flags = 0) noexcept {
+ //! Initializes this `FuncValue` to a register of `regType`, `regId`, and assigns its `typeId` and `flags`.
+ ASMJIT_INLINE_NODEBUG 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, TypeId typeId) noexcept {
+ //! Initializes this `FuncValue` to a stack at the given `offset` and assigns its `typeId`.
+ ASMJIT_INLINE_NODEBUG 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.
- inline void reset() noexcept { _data = 0; }
+ ASMJIT_INLINE_NODEBUG void reset() noexcept { _data = 0; }
//! \}
//! \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.
+ //! should first init the type-id by calling `initTypeId` and then continue building either register or stack.
//!
//! \{
+ //! Assigns a register of `regType` and `regId`.
inline void assignRegData(RegType regType, uint32_t regId) noexcept {
ASMJIT_ASSERT((_data & (kRegTypeMask | kRegIdMask)) == 0);
_data |= (uint32_t(regType) << kRegTypeShift) | (regId << kRegIdShift) | kFlagIsReg;
}
+ //! Assigns a stack location at `offset`.
inline void assignStackOffset(int32_t offset) noexcept {
ASMJIT_ASSERT((_data & kStackOffsetMask) == 0);
_data |= (uint32_t(offset) << kStackOffsetShift) | kFlagIsStack;
@@ -581,52 +635,54 @@ struct FuncValue {
//! \{
//! Returns true if the value is initialized (explicit bool cast).
- inline explicit operator bool() const noexcept { return _data != 0; }
+ ASMJIT_INLINE_NODEBUG explicit operator bool() const noexcept { return _data != 0; }
- inline void _replaceValue(uint32_t mask, uint32_t value) noexcept { _data = (_data & ~mask) | value; }
+ //! \cond INTERNAL
+ ASMJIT_INLINE_NODEBUG void _replaceValue(uint32_t mask, uint32_t value) noexcept { _data = (_data & ~mask) | value; }
+ //! \endcond
//! Tests whether the `FuncValue` has a flag `flag` set.
- inline bool hasFlag(uint32_t flag) const noexcept { return Support::test(_data, flag); }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG void addFlags(uint32_t flags) noexcept { _data |= flags; }
//! Clears `flags` of `FuncValue`.
- inline void clearFlags(uint32_t flags) noexcept { _data &= ~flags; }
+ ASMJIT_INLINE_NODEBUG void clearFlags(uint32_t flags) noexcept { _data &= ~flags; }
//! Tests whether the value is initialized (i.e. contains a valid data).
- inline bool isInitialized() const noexcept { return _data != 0; }
+ ASMJIT_INLINE_NODEBUG bool isInitialized() const noexcept { return _data != 0; }
//! Tests whether the argument is passed by register.
- inline bool isReg() const noexcept { return hasFlag(kFlagIsReg); }
+ ASMJIT_INLINE_NODEBUG bool isReg() const noexcept { return hasFlag(kFlagIsReg); }
//! Tests whether the argument is passed by stack.
- inline bool isStack() const noexcept { return hasFlag(kFlagIsStack); }
+ ASMJIT_INLINE_NODEBUG bool isStack() const noexcept { return hasFlag(kFlagIsStack); }
//! Tests whether the argument is passed by register.
- inline bool isAssigned() const noexcept { return hasFlag(kFlagIsReg | kFlagIsStack); }
+ ASMJIT_INLINE_NODEBUG bool isAssigned() const noexcept { return hasFlag(kFlagIsReg | kFlagIsStack); }
//! Tests whether the argument is passed through a pointer (used by WIN64 to pass XMM|YMM|ZMM).
- inline bool isIndirect() const noexcept { return hasFlag(kFlagIsIndirect); }
+ ASMJIT_INLINE_NODEBUG bool isIndirect() const noexcept { return hasFlag(kFlagIsIndirect); }
//! Tests whether the argument was already processed (used internally).
- inline bool isDone() const noexcept { return hasFlag(kFlagIsDone); }
+ ASMJIT_INLINE_NODEBUG bool isDone() const noexcept { return hasFlag(kFlagIsDone); }
//! Returns a register type of the register used to pass function argument or return value.
- inline RegType regType() const noexcept { return RegType((_data & kRegTypeMask) >> kRegTypeShift); }
+ ASMJIT_INLINE_NODEBUG 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(RegType regType) noexcept { _replaceValue(kRegTypeMask, uint32_t(regType) << kRegTypeShift); }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG uint32_t regId() const noexcept { return (_data & kRegIdMask) >> kRegIdShift; }
//! Sets a physical id of the register used to pass function argument or return value.
- inline void setRegId(uint32_t regId) noexcept { _replaceValue(kRegIdMask, regId << kRegIdShift); }
+ ASMJIT_INLINE_NODEBUG void setRegId(uint32_t regId) noexcept { _replaceValue(kRegIdMask, regId << kRegIdShift); }
//! Returns a stack offset of this argument.
- inline int32_t stackOffset() const noexcept { return int32_t(_data & kStackOffsetMask) >> kStackOffsetShift; }
+ ASMJIT_INLINE_NODEBUG int32_t stackOffset() const noexcept { return int32_t(_data & kStackOffsetMask) >> kStackOffsetShift; }
//! Sets a stack offset of this argument.
- inline void setStackOffset(int32_t offset) noexcept { _replaceValue(kStackOffsetMask, uint32_t(offset) << kStackOffsetShift); }
+ ASMJIT_INLINE_NODEBUG void setStackOffset(int32_t offset) noexcept { _replaceValue(kStackOffsetMask, uint32_t(offset) << kStackOffsetShift); }
//! Tests whether the argument or return value has associated `TypeId`.
- inline bool hasTypeId() const noexcept { return Support::test(_data, kTypeIdMask); }
+ ASMJIT_INLINE_NODEBUG bool hasTypeId() const noexcept { return Support::test(_data, kTypeIdMask); }
//! Returns a TypeId of this argument or return value.
- inline TypeId typeId() const noexcept { return TypeId((_data & kTypeIdMask) >> kTypeIdShift); }
+ ASMJIT_INLINE_NODEBUG TypeId typeId() const noexcept { return TypeId((_data & kTypeIdMask) >> kTypeIdShift); }
//! Sets a TypeId of this argument or return value.
- inline void setTypeId(TypeId typeId) noexcept { _replaceValue(kTypeIdMask, uint32_t(typeId) << kTypeIdShift); }
+ ASMJIT_INLINE_NODEBUG void setTypeId(TypeId typeId) noexcept { _replaceValue(kTypeIdMask, uint32_t(typeId) << kTypeIdShift); }
//! \}
};
@@ -665,40 +721,52 @@ public:
return n;
}
- inline FuncValue* values() noexcept { return _values; }
- inline const FuncValue* values() const noexcept { return _values; }
+ //! Returns values in this value in the pack.
+ //!
+ //! \note The returned array has exactly \ref Globals::kMaxValuePack elements.
+ ASMJIT_INLINE_NODEBUG FuncValue* values() noexcept { return _values; }
+ //! \overload
+ ASMJIT_INLINE_NODEBUG const FuncValue* values() const noexcept { return _values; }
+ //! Resets a value at the given `index` in the pack, which makes it unassigned.
inline void resetValue(size_t index) noexcept {
ASMJIT_ASSERT(index < Globals::kMaxValuePack);
_values[index].reset();
}
+ //! Tests whether the value at the given `index` in the pack is assigned.
inline bool hasValue(size_t index) noexcept {
ASMJIT_ASSERT(index < Globals::kMaxValuePack);
return _values[index].isInitialized();
}
+ //! Assigns a register at the given `index` to `reg` and an optional `typeId`.
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);
}
+ //! Assigns a register at the given `index` to `regType`, `regId`, and an optional `typeId`.
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);
}
+ //! Assigns a stack location at the given `index` to `offset` and an optional `typeId`.
inline void assignStack(size_t index, int32_t offset, TypeId typeId = TypeId::kVoid) noexcept {
ASMJIT_ASSERT(index < Globals::kMaxValuePack);
_values[index].initStack(offset, typeId);
}
+ //! Accesses the value in the pack at the given `index`.
+ //!
+ //! \note The maximum index value is `Globals::kMaxValuePack - 1`.
inline FuncValue& operator[](size_t index) {
ASMJIT_ASSERT(index < Globals::kMaxValuePack);
return _values[index];
}
-
+ //! \overload
inline const FuncValue& operator[](size_t index) const {
ASMJIT_ASSERT(index < Globals::kMaxValuePack);
return _values[index];
@@ -721,6 +789,11 @@ enum class FuncAttributes : uint32_t {
kHasFuncCalls = 0x00000020u,
//! Function has aligned save/restore of vector registers.
kAlignedVecSR = 0x00000040u,
+ //! Function must begin with an instruction that marks a start of a branch or function.
+ //!
+ //! * `ENDBR32/ENDBR64` instruction is inserted at the beginning of the function (X86, X86_64).
+ //! * `BTI` instruction is inserted at the beginning of the function (AArch64)
+ kIndirectBranchProtection = 0x00000080u,
//! FuncFrame is finalized and can be used by prolog/epilog inserter (PEI).
kIsFinalized = 0x00000800u,
@@ -757,10 +830,8 @@ public:
//! \name Constants
//! \{
- enum : uint8_t {
- //! Doesn't have variable number of arguments (`...`).
- kNoVarArgs = 0xFFu
- };
+ //! Function doesn't have a variable number of arguments (`...`).
+ static constexpr uint8_t kNoVarArgs = 0xFFu;
//! \}
@@ -768,33 +839,53 @@ public:
//! \{
//! Calling convention.
- CallConv _callConv;
+ CallConv _callConv {};
//! Number of function arguments.
- uint8_t _argCount;
+ uint8_t _argCount = 0;
//! Variable arguments index of `kNoVarArgs`.
- uint8_t _vaIndex;
+ uint8_t _vaIndex = 0;
//! Reserved for future use.
- uint16_t _reserved;
+ uint16_t _reserved = 0;
//! Registers that contain arguments.
- Support::Array<RegMask, Globals::kNumVirtGroups> _usedRegs;
+ Support::Array<RegMask, Globals::kNumVirtGroups> _usedRegs {};
//! Size of arguments passed by stack.
- uint32_t _argStackSize;
+ uint32_t _argStackSize = 0;
//! Function return value(s).
- FuncValuePack _rets;
+ FuncValuePack _rets {};
//! Function arguments.
- FuncValuePack _args[Globals::kMaxFuncArgs];
+ FuncValuePack _args[Globals::kMaxFuncArgs] {};
//! \}
//! \name Construction & Destruction
//! \{
- inline FuncDetail() noexcept { reset(); }
- inline FuncDetail(const FuncDetail& other) noexcept = default;
+ //! Creates a default constructed \ref FuncDetail.
+ ASMJIT_INLINE_NODEBUG FuncDetail() noexcept {}
+
+ //! Copy constructor.
+ //!
+ //! Function details are copyable.
+ ASMJIT_INLINE_NODEBUG FuncDetail(const FuncDetail& other) noexcept = default;
//! Initializes this `FuncDetail` to the given signature.
ASMJIT_API Error init(const FuncSignature& signature, const Environment& environment) noexcept;
- inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
+
+ //! \}
+
+ //! \name Overloaded Operators
+ //! \{
+
+ //! Assignment operator, copies `other` to this \ref FuncDetail.
+ ASMJIT_INLINE_NODEBUG FuncDetail& operator=(const FuncDetail& other) noexcept = default;
+
+ //! \}
+
+ //! \name Reset
+ //! \{
+
+ //! Resets the function detail to its default constructed state.
+ ASMJIT_INLINE_NODEBUG void reset() noexcept { *this = FuncDetail{}; }
//! \}
@@ -802,32 +893,32 @@ public:
//! \{
//! Returns the function's calling convention, see `CallConv`.
- inline const CallConv& callConv() const noexcept { return _callConv; }
+ ASMJIT_INLINE_NODEBUG const CallConv& callConv() const noexcept { return _callConv; }
//! Returns the associated calling convention flags, see `CallConv::Flags`.
- inline CallConvFlags flags() const noexcept { return _callConv.flags(); }
+ ASMJIT_INLINE_NODEBUG CallConvFlags flags() const noexcept { return _callConv.flags(); }
//! Checks whether a CallConv `flag` is set, see `CallConv::Flags`.
- inline bool hasFlag(CallConvFlags ccFlag) const noexcept { return _callConv.hasFlag(ccFlag); }
+ ASMJIT_INLINE_NODEBUG 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]); }
+ ASMJIT_INLINE_NODEBUG bool hasRet() const noexcept { return bool(_rets[0]); }
//! Returns the number of function arguments.
- inline uint32_t argCount() const noexcept { return _argCount; }
+ ASMJIT_INLINE_NODEBUG uint32_t argCount() const noexcept { return _argCount; }
//! Returns function return values.
- inline FuncValuePack& retPack() noexcept { return _rets; }
+ ASMJIT_INLINE_NODEBUG FuncValuePack& retPack() noexcept { return _rets; }
//! Returns function return values.
- inline const FuncValuePack& retPack() const noexcept { return _rets; }
+ ASMJIT_INLINE_NODEBUG const FuncValuePack& retPack() const noexcept { return _rets; }
//! Returns a function return value associated with the given `valueIndex`.
- inline FuncValue& ret(size_t valueIndex = 0) noexcept { return _rets[valueIndex]; }
+ ASMJIT_INLINE_NODEBUG FuncValue& ret(size_t valueIndex = 0) noexcept { return _rets[valueIndex]; }
//! Returns a function return value associated with the given `valueIndex` (const).
- inline const FuncValue& ret(size_t valueIndex = 0) const noexcept { return _rets[valueIndex]; }
+ ASMJIT_INLINE_NODEBUG const FuncValue& ret(size_t valueIndex = 0) const noexcept { return _rets[valueIndex]; }
//! Returns function argument packs array.
- inline FuncValuePack* argPacks() noexcept { return _args; }
+ ASMJIT_INLINE_NODEBUG FuncValuePack* argPacks() noexcept { return _args; }
//! Returns function argument packs array (const).
- inline const FuncValuePack* argPacks() const noexcept { return _args; }
+ ASMJIT_INLINE_NODEBUG const FuncValuePack* argPacks() const noexcept { return _args; }
//! Returns function argument pack at the given `argIndex`.
inline FuncValuePack& argPack(size_t argIndex) noexcept {
@@ -862,26 +953,26 @@ public:
}
//! Tests whether the function has variable arguments.
- inline bool hasVarArgs() const noexcept { return _vaIndex != kNoVarArgs; }
+ ASMJIT_INLINE_NODEBUG bool hasVarArgs() const noexcept { return _vaIndex != kNoVarArgs; }
//! Returns an index of a first variable argument.
- inline uint32_t vaIndex() const noexcept { return _vaIndex; }
+ ASMJIT_INLINE_NODEBUG uint32_t vaIndex() const noexcept { return _vaIndex; }
//! Tests whether the function passes one or more argument by stack.
- inline bool hasStackArgs() const noexcept { return _argStackSize != 0; }
+ ASMJIT_INLINE_NODEBUG bool hasStackArgs() const noexcept { return _argStackSize != 0; }
//! Returns stack size needed for function arguments passed on the stack.
- inline uint32_t argStackSize() const noexcept { return _argStackSize; }
+ ASMJIT_INLINE_NODEBUG uint32_t argStackSize() const noexcept { return _argStackSize; }
//! Returns red zone size.
- inline uint32_t redZoneSize() const noexcept { return _callConv.redZoneSize(); }
+ ASMJIT_INLINE_NODEBUG uint32_t redZoneSize() const noexcept { return _callConv.redZoneSize(); }
//! Returns spill zone size.
- inline uint32_t spillZoneSize() const noexcept { return _callConv.spillZoneSize(); }
+ ASMJIT_INLINE_NODEBUG uint32_t spillZoneSize() const noexcept { return _callConv.spillZoneSize(); }
//! Returns natural stack alignment.
- inline uint32_t naturalStackAlignment() const noexcept { return _callConv.naturalStackAlignment(); }
+ ASMJIT_INLINE_NODEBUG uint32_t naturalStackAlignment() const noexcept { return _callConv.naturalStackAlignment(); }
//! Returns a mask of all passed registers of the given register `group`.
- inline RegMask passedRegs(RegGroup group) const noexcept { return _callConv.passedRegs(group); }
+ ASMJIT_INLINE_NODEBUG RegMask passedRegs(RegGroup group) const noexcept { return _callConv.passedRegs(group); }
//! Returns a mask of all preserved registers of the given register `group`.
- inline RegMask preservedRegs(RegGroup group) const noexcept { return _callConv.preservedRegs(group); }
+ ASMJIT_INLINE_NODEBUG RegMask preservedRegs(RegGroup group) const noexcept { return _callConv.preservedRegs(group); }
//! Returns a mask of all used registers of the given register `group`.
inline RegMask usedRegs(RegGroup group) const noexcept {
@@ -901,7 +992,7 @@ public:
//! 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
+//! insert a proper and ABI conforming prolog and epilog. Function frame calculation is based on `CallConv` and
//! other function attributes.
//!
//! SSE vs AVX vs AVX-512
@@ -954,87 +1045,98 @@ public:
//! \{
//! Function attributes.
- FuncAttributes _attributes;
+ FuncAttributes _attributes {};
//! Target architecture.
- Arch _arch;
+ Arch _arch {};
//! SP register ID (to access call stack and local stack).
- uint8_t _spRegId;
+ uint8_t _spRegId = uint8_t(BaseReg::kIdBad);
//! SA register ID (to access stack arguments).
- uint8_t _saRegId;
+ uint8_t _saRegId = uint8_t(BaseReg::kIdBad);
//! Red zone size (copied from CallConv).
- uint8_t _redZoneSize;
+ uint8_t _redZoneSize = 0;
//! Spill zone size (copied from CallConv).
- uint8_t _spillZoneSize;
+ uint8_t _spillZoneSize = 0;
//! Natural stack alignment (copied from CallConv).
- uint8_t _naturalStackAlignment;
+ uint8_t _naturalStackAlignment = 0;
//! Minimum stack alignment to turn on dynamic alignment.
- uint8_t _minDynamicAlignment;
+ uint8_t _minDynamicAlignment = 0;
//! Call stack alignment.
- uint8_t _callStackAlignment;
+ uint8_t _callStackAlignment = 0;
//! Local stack alignment.
- uint8_t _localStackAlignment;
+ uint8_t _localStackAlignment = 0;
//! Final stack alignment.
- uint8_t _finalStackAlignment;
+ uint8_t _finalStackAlignment = 0;
//! Adjustment of the stack before returning (X86-STDCALL).
- uint16_t _calleeStackCleanup;
+ uint16_t _calleeStackCleanup = 0;
//! Call stack size.
- uint32_t _callStackSize;
+ uint32_t _callStackSize = 0;
//! Local stack size.
- uint32_t _localStackSize;
+ uint32_t _localStackSize = 0;
//! Final stack size (sum of call stack and local stack).
- uint32_t _finalStackSize;
+ uint32_t _finalStackSize = 0;
//! Local stack offset (non-zero only if call stack is used).
- uint32_t _localStackOffset;
+ uint32_t _localStackOffset = 0;
//! Offset relative to SP that contains previous SP (before alignment).
- uint32_t _daOffset;
+ uint32_t _daOffset = 0;
//! Offset of the first stack argument relative to SP.
- uint32_t _saOffsetFromSP;
+ uint32_t _saOffsetFromSP = 0;
//! Offset of the first stack argument relative to SA (_saRegId or FP).
- uint32_t _saOffsetFromSA;
+ uint32_t _saOffsetFromSA = 0;
//! Local stack adjustment in prolog/epilog.
- uint32_t _stackAdjustment;
+ uint32_t _stackAdjustment = 0;
//! Registers that are dirty.
- Support::Array<RegMask, Globals::kNumVirtGroups> _dirtyRegs;
+ Support::Array<RegMask, Globals::kNumVirtGroups> _dirtyRegs {};
//! Registers that must be preserved (copied from CallConv).
- Support::Array<RegMask, Globals::kNumVirtGroups> _preservedRegs;
+ Support::Array<RegMask, Globals::kNumVirtGroups> _preservedRegs {};
//! Size to save/restore per register group.
- Support::Array<uint8_t, Globals::kNumVirtGroups> _saveRestoreRegSize;
+ Support::Array<uint8_t, Globals::kNumVirtGroups> _saveRestoreRegSize {};
//! Alignment of save/restore area per register group.
- Support::Array<uint8_t, Globals::kNumVirtGroups> _saveRestoreAlignment;
+ Support::Array<uint8_t, Globals::kNumVirtGroups> _saveRestoreAlignment {};
//! Stack size required to save registers with push/pop.
- uint16_t _pushPopSaveSize;
+ uint16_t _pushPopSaveSize = 0;
//! Stack size required to save extra registers that cannot use push/pop.
- uint16_t _extraRegSaveSize;
+ uint16_t _extraRegSaveSize = 0;
//! Offset where registers saved/restored via push/pop are stored
- uint32_t _pushPopSaveOffset;
- //! Offset where extra ragisters that cannot use push/pop are stored.
- uint32_t _extraRegSaveOffset;
+ uint32_t _pushPopSaveOffset = 0;
+ //! Offset where extra registers that cannot use push/pop are stored.
+ uint32_t _extraRegSaveOffset = 0;
//! \}
//! \name Construction & Destruction
//! \{
- inline FuncFrame() noexcept { reset(); }
- inline FuncFrame(const FuncFrame& other) noexcept = default;
+ //! Creates a default constructed function frame, which has initialized all members to their default values.
+ ASMJIT_INLINE_NODEBUG FuncFrame() noexcept = default;
+ //! Creates a copy of `other` function frame.
+ ASMJIT_INLINE_NODEBUG FuncFrame(const FuncFrame& other) noexcept = default;
+ //! \}
+
+ //! \name Initialization & Reset
+ //! \{
+
+ //! Initializes the function frame based on `func` detail.
ASMJIT_API Error init(const FuncDetail& func) noexcept;
+ //! Resets the function frame into its default constructed state.
+ ASMJIT_INLINE_NODEBUG void reset() noexcept { *this = FuncFrame{}; }
- inline void reset() noexcept {
- memset(this, 0, sizeof(FuncFrame));
- _spRegId = BaseReg::kIdBad;
- _saRegId = BaseReg::kIdBad;
- _daOffset = kTagInvalidOffset;
- }
+ //! \}
+
+ //! \name Overloaded Operators
+ //! \{
+
+ //! Copy assignment - function frame is copy assignable.
+ ASMJIT_INLINE_NODEBUG FuncFrame& operator=(const FuncFrame& other) noexcept = default;
//! \}
@@ -1042,100 +1144,116 @@ public:
//! \{
//! Returns the target architecture of the function frame.
- inline Arch arch() const noexcept { return _arch; }
+ ASMJIT_INLINE_NODEBUG Arch arch() const noexcept { return _arch; }
//! Returns function frame attributes, see `Attributes`.
- inline FuncAttributes attributes() const noexcept { return _attributes; }
+ ASMJIT_INLINE_NODEBUG FuncAttributes attributes() const noexcept { return _attributes; }
//! Checks whether the FuncFame contains an attribute `attr`.
- inline bool hasAttribute(FuncAttributes attr) const noexcept { return Support::test(_attributes, attr); }
+ ASMJIT_INLINE_NODEBUG bool hasAttribute(FuncAttributes attr) const noexcept { return Support::test(_attributes, attr); }
//! Adds attributes `attrs` to the FuncFrame.
- inline void addAttributes(FuncAttributes attrs) noexcept { _attributes |= attrs; }
+ ASMJIT_INLINE_NODEBUG void addAttributes(FuncAttributes attrs) noexcept { _attributes |= attrs; }
//! Clears attributes `attrs` from the FrameFrame.
- inline void clearAttributes(FuncAttributes attrs) noexcept { _attributes &= ~attrs; }
+ ASMJIT_INLINE_NODEBUG void clearAttributes(FuncAttributes attrs) noexcept { _attributes &= ~attrs; }
//! Tests whether the function has variable number of arguments.
- inline bool hasVarArgs() const noexcept { return hasAttribute(FuncAttributes::kHasVarArgs); }
+ ASMJIT_INLINE_NODEBUG bool hasVarArgs() const noexcept { return hasAttribute(FuncAttributes::kHasVarArgs); }
//! Sets the variable arguments flag.
- inline void setVarArgs() noexcept { addAttributes(FuncAttributes::kHasVarArgs); }
+ ASMJIT_INLINE_NODEBUG void setVarArgs() noexcept { addAttributes(FuncAttributes::kHasVarArgs); }
//! Resets variable arguments flag.
- inline void resetVarArgs() noexcept { clearAttributes(FuncAttributes::kHasVarArgs); }
+ ASMJIT_INLINE_NODEBUG void resetVarArgs() noexcept { clearAttributes(FuncAttributes::kHasVarArgs); }
//! Tests whether the function preserves frame pointer (EBP|ESP on X86).
- inline bool hasPreservedFP() const noexcept { return hasAttribute(FuncAttributes::kHasPreservedFP); }
+ ASMJIT_INLINE_NODEBUG bool hasPreservedFP() const noexcept { return hasAttribute(FuncAttributes::kHasPreservedFP); }
//! Enables preserved frame pointer.
- inline void setPreservedFP() noexcept { addAttributes(FuncAttributes::kHasPreservedFP); }
+ ASMJIT_INLINE_NODEBUG void setPreservedFP() noexcept { addAttributes(FuncAttributes::kHasPreservedFP); }
//! Disables preserved frame pointer.
- inline void resetPreservedFP() noexcept { clearAttributes(FuncAttributes::kHasPreservedFP); }
+ ASMJIT_INLINE_NODEBUG void resetPreservedFP() noexcept { clearAttributes(FuncAttributes::kHasPreservedFP); }
//! Tests whether the function calls other functions.
- inline bool hasFuncCalls() const noexcept { return hasAttribute(FuncAttributes::kHasFuncCalls); }
- //! Sets `kFlagHasCalls` to true.
- inline void setFuncCalls() noexcept { addAttributes(FuncAttributes::kHasFuncCalls); }
- //! Sets `kFlagHasCalls` to false.
- inline void resetFuncCalls() noexcept { clearAttributes(FuncAttributes::kHasFuncCalls); }
+ ASMJIT_INLINE_NODEBUG bool hasFuncCalls() const noexcept { return hasAttribute(FuncAttributes::kHasFuncCalls); }
+ //! Sets `FuncAttributes::kHasFuncCalls` to true.
+ ASMJIT_INLINE_NODEBUG void setFuncCalls() noexcept { addAttributes(FuncAttributes::kHasFuncCalls); }
+ //! Sets `FuncAttributes::kHasFuncCalls` to false.
+ ASMJIT_INLINE_NODEBUG void resetFuncCalls() noexcept { clearAttributes(FuncAttributes::kHasFuncCalls); }
+
+ //! Tests whether the function uses indirect branch protection, see \ref FuncAttributes::kIndirectBranchProtection.
+ ASMJIT_INLINE_NODEBUG bool hasIndirectBranchProtection() const noexcept { return hasAttribute(FuncAttributes::kIndirectBranchProtection); }
+ //! Enabled indirect branch protection (sets `FuncAttributes::kIndirectBranchProtection` attribute to true).
+ ASMJIT_INLINE_NODEBUG void setIndirectBranchProtection() noexcept { addAttributes(FuncAttributes::kIndirectBranchProtection); }
+ //! Disables indirect branch protection (sets `FuncAttributes::kIndirectBranchProtection` attribute to false).
+ ASMJIT_INLINE_NODEBUG void resetIndirectBranchProtection() noexcept { clearAttributes(FuncAttributes::kIndirectBranchProtection); }
//! Tests whether the function has AVX enabled.
- inline bool isAvxEnabled() const noexcept { return hasAttribute(FuncAttributes::kX86_AVXEnabled); }
+ ASMJIT_INLINE_NODEBUG bool isAvxEnabled() const noexcept { return hasAttribute(FuncAttributes::kX86_AVXEnabled); }
//! Enables AVX use.
- inline void setAvxEnabled() noexcept { addAttributes(FuncAttributes::kX86_AVXEnabled); }
+ ASMJIT_INLINE_NODEBUG void setAvxEnabled() noexcept { addAttributes(FuncAttributes::kX86_AVXEnabled); }
//! Disables AVX use.
- inline void resetAvxEnabled() noexcept { clearAttributes(FuncAttributes::kX86_AVXEnabled); }
+ ASMJIT_INLINE_NODEBUG void resetAvxEnabled() noexcept { clearAttributes(FuncAttributes::kX86_AVXEnabled); }
//! Tests whether the function has AVX-512 enabled.
- inline bool isAvx512Enabled() const noexcept { return hasAttribute(FuncAttributes::kX86_AVX512Enabled); }
+ ASMJIT_INLINE_NODEBUG bool isAvx512Enabled() const noexcept { return hasAttribute(FuncAttributes::kX86_AVX512Enabled); }
//! Enables AVX-512 use.
- inline void setAvx512Enabled() noexcept { addAttributes(FuncAttributes::kX86_AVX512Enabled); }
+ ASMJIT_INLINE_NODEBUG void setAvx512Enabled() noexcept { addAttributes(FuncAttributes::kX86_AVX512Enabled); }
//! Disables AVX-512 use.
- inline void resetAvx512Enabled() noexcept { clearAttributes(FuncAttributes::kX86_AVX512Enabled); }
+ ASMJIT_INLINE_NODEBUG 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(FuncAttributes::kX86_MMXCleanup); }
+ ASMJIT_INLINE_NODEBUG bool hasMmxCleanup() const noexcept { return hasAttribute(FuncAttributes::kX86_MMXCleanup); }
//! Enables MMX cleanup.
- inline void setMmxCleanup() noexcept { addAttributes(FuncAttributes::kX86_MMXCleanup); }
+ ASMJIT_INLINE_NODEBUG void setMmxCleanup() noexcept { addAttributes(FuncAttributes::kX86_MMXCleanup); }
//! Disables MMX cleanup.
- inline void resetMmxCleanup() noexcept { clearAttributes(FuncAttributes::kX86_MMXCleanup); }
+ ASMJIT_INLINE_NODEBUG 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(FuncAttributes::kX86_AVXCleanup); }
+ ASMJIT_INLINE_NODEBUG bool hasAvxCleanup() const noexcept { return hasAttribute(FuncAttributes::kX86_AVXCleanup); }
//! Enables AVX cleanup.
- inline void setAvxCleanup() noexcept { addAttributes(FuncAttributes::kX86_AVXCleanup); }
+ ASMJIT_INLINE_NODEBUG void setAvxCleanup() noexcept { addAttributes(FuncAttributes::kX86_AVXCleanup); }
//! Disables AVX cleanup.
- inline void resetAvxCleanup() noexcept { clearAttributes(FuncAttributes::kX86_AVXCleanup); }
+ ASMJIT_INLINE_NODEBUG void resetAvxCleanup() noexcept { clearAttributes(FuncAttributes::kX86_AVXCleanup); }
//! Tests whether the function uses call stack.
- inline bool hasCallStack() const noexcept { return _callStackSize != 0; }
+ ASMJIT_INLINE_NODEBUG bool hasCallStack() const noexcept { return _callStackSize != 0; }
//! Tests whether the function uses local stack.
- inline bool hasLocalStack() const noexcept { return _localStackSize != 0; }
+ ASMJIT_INLINE_NODEBUG 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(FuncAttributes::kAlignedVecSR); }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG bool hasDynamicAlignment() const noexcept { return _finalStackAlignment >= _minDynamicAlignment; }
//! Tests whether the calling convention specifies 'RedZone'.
- inline bool hasRedZone() const noexcept { return _redZoneSize != 0; }
+ ASMJIT_INLINE_NODEBUG bool hasRedZone() const noexcept { return _redZoneSize != 0; }
//! Tests whether the calling convention specifies 'SpillZone'.
- inline bool hasSpillZone() const noexcept { return _spillZoneSize != 0; }
+ ASMJIT_INLINE_NODEBUG bool hasSpillZone() const noexcept { return _spillZoneSize != 0; }
//! Returns the size of 'RedZone'.
- inline uint32_t redZoneSize() const noexcept { return _redZoneSize; }
+ ASMJIT_INLINE_NODEBUG uint32_t redZoneSize() const noexcept { return _redZoneSize; }
//! Returns the size of 'SpillZone'.
- inline uint32_t spillZoneSize() const noexcept { return _spillZoneSize; }
+ ASMJIT_INLINE_NODEBUG uint32_t spillZoneSize() const noexcept { return _spillZoneSize; }
+
+ //! Resets the size of red zone, which would disable it entirely.
+ //!
+ //! \note Red zone is currently only used by an AMD64 SystemV calling convention, which expects 128
+ //! bytes of stack to be accessible below stack pointer. These bytes are then accessible within the
+ //! function and Compiler can use this space as a spill area. However, sometimes it's better to
+ //! disallow the use of red zone in case that a user wants to use this stack for a custom purpose.
+ ASMJIT_INLINE_NODEBUG void resetRedZone() noexcept { _redZoneSize = 0; }
+
//! Returns natural stack alignment (guaranteed stack alignment upon entry).
- inline uint32_t naturalStackAlignment() const noexcept { return _naturalStackAlignment; }
+ ASMJIT_INLINE_NODEBUG uint32_t naturalStackAlignment() const noexcept { return _naturalStackAlignment; }
//! Returns natural stack alignment (guaranteed stack alignment upon entry).
- inline uint32_t minDynamicAlignment() const noexcept { return _minDynamicAlignment; }
+ ASMJIT_INLINE_NODEBUG uint32_t minDynamicAlignment() const noexcept { return _minDynamicAlignment; }
//! Tests whether the callee must adjust SP before returning (X86-STDCALL only)
- inline bool hasCalleeStackCleanup() const noexcept { return _calleeStackCleanup != 0; }
+ ASMJIT_INLINE_NODEBUG bool hasCalleeStackCleanup() const noexcept { return _calleeStackCleanup != 0; }
//! Returns home many bytes of the stack the callee must adjust before returning (X86-STDCALL only)
- inline uint32_t calleeStackCleanup() const noexcept { return _calleeStackCleanup; }
+ ASMJIT_INLINE_NODEBUG uint32_t calleeStackCleanup() const noexcept { return _calleeStackCleanup; }
//! Returns call stack alignment.
- inline uint32_t callStackAlignment() const noexcept { return _callStackAlignment; }
+ ASMJIT_INLINE_NODEBUG uint32_t callStackAlignment() const noexcept { return _callStackAlignment; }
//! Returns local stack alignment.
- inline uint32_t localStackAlignment() const noexcept { return _localStackAlignment; }
+ ASMJIT_INLINE_NODEBUG uint32_t localStackAlignment() const noexcept { return _localStackAlignment; }
//! Returns final stack alignment (the maximum value of call, local, and natural stack alignments).
- inline uint32_t finalStackAlignment() const noexcept { return _finalStackAlignment; }
+ ASMJIT_INLINE_NODEBUG uint32_t finalStackAlignment() const noexcept { return _finalStackAlignment; }
//! Sets call stack alignment.
//!
@@ -1170,38 +1288,38 @@ public:
}
//! Returns call stack size.
- inline uint32_t callStackSize() const noexcept { return _callStackSize; }
+ ASMJIT_INLINE_NODEBUG uint32_t callStackSize() const noexcept { return _callStackSize; }
//! Returns local stack size.
- inline uint32_t localStackSize() const noexcept { return _localStackSize; }
+ ASMJIT_INLINE_NODEBUG uint32_t localStackSize() const noexcept { return _localStackSize; }
//! Sets call stack size.
- inline void setCallStackSize(uint32_t size) noexcept { _callStackSize = size; }
+ ASMJIT_INLINE_NODEBUG void setCallStackSize(uint32_t size) noexcept { _callStackSize = size; }
//! Sets local stack size.
- inline void setLocalStackSize(uint32_t size) noexcept { _localStackSize = size; }
+ ASMJIT_INLINE_NODEBUG void setLocalStackSize(uint32_t size) noexcept { _localStackSize = size; }
//! Combines call stack size with `size`, updating it to the greater value.
- inline void updateCallStackSize(uint32_t size) noexcept { _callStackSize = Support::max(_callStackSize, size); }
+ ASMJIT_INLINE_NODEBUG void updateCallStackSize(uint32_t size) noexcept { _callStackSize = Support::max(_callStackSize, size); }
//! Combines local stack size with `size`, updating it to the greater value.
- inline void updateLocalStackSize(uint32_t size) noexcept { _localStackSize = Support::max(_localStackSize, size); }
+ ASMJIT_INLINE_NODEBUG void updateLocalStackSize(uint32_t size) noexcept { _localStackSize = Support::max(_localStackSize, size); }
//! Returns final stack size (only valid after the FuncFrame is finalized).
- inline uint32_t finalStackSize() const noexcept { return _finalStackSize; }
+ ASMJIT_INLINE_NODEBUG uint32_t finalStackSize() const noexcept { return _finalStackSize; }
//! Returns an offset to access the local stack (non-zero only if call stack is used).
- inline uint32_t localStackOffset() const noexcept { return _localStackOffset; }
+ ASMJIT_INLINE_NODEBUG uint32_t localStackOffset() const noexcept { return _localStackOffset; }
//! Tests whether the function prolog/epilog requires a memory slot for storing unaligned SP.
- inline bool hasDAOffset() const noexcept { return _daOffset != kTagInvalidOffset; }
+ ASMJIT_INLINE_NODEBUG bool hasDAOffset() const noexcept { return _daOffset != kTagInvalidOffset; }
//! Returns a memory offset used to store DA (dynamic alignment) slot (relative to SP).
- inline uint32_t daOffset() const noexcept { return _daOffset; }
+ ASMJIT_INLINE_NODEBUG uint32_t daOffset() const noexcept { return _daOffset; }
- inline uint32_t saOffset(uint32_t regId) const noexcept {
+ ASMJIT_INLINE_NODEBUG uint32_t saOffset(uint32_t regId) const noexcept {
return regId == _spRegId ? saOffsetFromSP()
: saOffsetFromSA();
}
- inline uint32_t saOffsetFromSP() const noexcept { return _saOffsetFromSP; }
- inline uint32_t saOffsetFromSA() const noexcept { return _saOffsetFromSA; }
+ ASMJIT_INLINE_NODEBUG uint32_t saOffsetFromSP() const noexcept { return _saOffsetFromSP; }
+ ASMJIT_INLINE_NODEBUG 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
@@ -1239,11 +1357,16 @@ public:
addDirtyRegs(std::forward<Args>(args)...);
}
- inline void setAllDirty() noexcept {
+ //! A helper function to set all registers from all register groups dirty.
+ //!
+ //! \note This should not be used in general as it's the most pessimistic case. However, it can be used for testing
+ //! or in cases in which all registers are considered clobbered.
+ ASMJIT_INLINE_NODEBUG void setAllDirty() noexcept {
for (size_t i = 0; i < ASMJIT_ARRAY_SIZE(_dirtyRegs); i++)
_dirtyRegs[i] = 0xFFFFFFFFu;
}
+ //! A helper function to set all registers from the given register `group` dirty.
inline void setAllDirty(RegGroup group) noexcept {
ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
_dirtyRegs[group] = 0xFFFFFFFFu;
@@ -1260,12 +1383,13 @@ public:
//! 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.
+ //! preserved registers it they are saved and restored in function's prolog and epilog, respectively.
inline RegMask preservedRegs(RegGroup group) const noexcept {
ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
return _preservedRegs[group];
}
+ //! Returns the size of a save-restore are for the required register `group`.
inline uint32_t saveRestoreRegSize(RegGroup group) const noexcept {
ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
return _saveRestoreRegSize[group];
@@ -1276,35 +1400,35 @@ public:
return _saveRestoreAlignment[group];
}
- inline bool hasSARegId() const noexcept { return _saRegId != BaseReg::kIdBad; }
- inline uint32_t saRegId() const noexcept { return _saRegId; }
- inline void setSARegId(uint32_t regId) { _saRegId = uint8_t(regId); }
- inline void resetSARegId() { setSARegId(BaseReg::kIdBad); }
+ ASMJIT_INLINE_NODEBUG bool hasSARegId() const noexcept { return _saRegId != BaseReg::kIdBad; }
+ ASMJIT_INLINE_NODEBUG uint32_t saRegId() const noexcept { return _saRegId; }
+ ASMJIT_INLINE_NODEBUG void setSARegId(uint32_t regId) { _saRegId = uint8_t(regId); }
+ ASMJIT_INLINE_NODEBUG void resetSARegId() { setSARegId(BaseReg::kIdBad); }
//! Returns stack size required to save/restore registers via push/pop.
- inline uint32_t pushPopSaveSize() const noexcept { return _pushPopSaveSize; }
+ ASMJIT_INLINE_NODEBUG uint32_t pushPopSaveSize() const noexcept { return _pushPopSaveSize; }
//! Returns an offset to the stack where registers are saved via push/pop.
- inline uint32_t pushPopSaveOffset() const noexcept { return _pushPopSaveOffset; }
+ ASMJIT_INLINE_NODEBUG uint32_t pushPopSaveOffset() const noexcept { return _pushPopSaveOffset; }
//! 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).
- inline uint32_t extraRegSaveSize() const noexcept { return _extraRegSaveSize; }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG uint32_t extraRegSaveOffset() const noexcept { return _extraRegSaveOffset; }
//! Tests whether the functions contains stack adjustment.
- inline bool hasStackAdjustment() const noexcept { return _stackAdjustment != 0; }
+ ASMJIT_INLINE_NODEBUG 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.
- inline uint32_t stackAdjustment() const noexcept { return _stackAdjustment; }
+ ASMJIT_INLINE_NODEBUG uint32_t stackAdjustment() const noexcept { return _stackAdjustment; }
//! \}
- //! \name Finaliztion
+ //! \name Finalization
//! \{
ASMJIT_API Error finalize() noexcept;
@@ -1320,25 +1444,27 @@ public:
//! \{
//! Function detail.
- const FuncDetail* _funcDetail;
+ const FuncDetail* _funcDetail {};
//! Register that can be used to access arguments passed by stack.
- uint8_t _saRegId;
+ uint8_t _saRegId = uint8_t(BaseReg::kIdBad);
//! Reserved for future use.
- uint8_t _reserved[3];
+ uint8_t _reserved[3] {};
//! Mapping of each function argument.
- FuncValuePack _argPacks[Globals::kMaxFuncArgs];
+ FuncValuePack _argPacks[Globals::kMaxFuncArgs] {};
//! \}
//! \name Construction & Destruction
//! \{
- inline explicit FuncArgsAssignment(const FuncDetail* fd = nullptr) noexcept { reset(fd); }
+ //! Creates either a default initialized `FuncArgsAssignment` or to assignment that links to `fd`, if non-null.
+ ASMJIT_INLINE_NODEBUG explicit FuncArgsAssignment(const FuncDetail* fd = nullptr) noexcept { reset(fd); }
- inline FuncArgsAssignment(const FuncArgsAssignment& other) noexcept {
- memcpy(this, &other, sizeof(*this));
- }
+ //! Copy constructor.
+ ASMJIT_INLINE_NODEBUG FuncArgsAssignment(const FuncArgsAssignment& other) noexcept = default;
+ //! Resets this `FuncArgsAssignment` to either default constructed state or to assignment that links to `fd`,
+ //! if non-null.
inline void reset(const FuncDetail* fd = nullptr) noexcept {
_funcDetail = fd;
_saRegId = uint8_t(BaseReg::kIdBad);
@@ -1348,58 +1474,80 @@ public:
//! \}
+ //! \name Overloaded Operators
+ //! \{
+
+ //! Copy assignment.
+ ASMJIT_INLINE_NODEBUG FuncArgsAssignment& operator=(const FuncArgsAssignment& other) noexcept = default;
+
+ //! \}
+
//! \name Accessors
//! \{
- inline const FuncDetail* funcDetail() const noexcept { return _funcDetail; }
- inline void setFuncDetail(const FuncDetail* fd) noexcept { _funcDetail = fd; }
+ //! Returns the associated \ref FuncDetail of this `FuncArgsAssignment`.
+ ASMJIT_INLINE_NODEBUG const FuncDetail* funcDetail() const noexcept { return _funcDetail; }
+ //! Associates \ref FuncDetails with this `FuncArgsAssignment`.
+ ASMJIT_INLINE_NODEBUG void setFuncDetail(const FuncDetail* fd) noexcept { _funcDetail = fd; }
- inline bool hasSARegId() const noexcept { return _saRegId != BaseReg::kIdBad; }
- inline uint32_t saRegId() const noexcept { return _saRegId; }
- inline void setSARegId(uint32_t regId) { _saRegId = uint8_t(regId); }
- inline void resetSARegId() { _saRegId = uint8_t(BaseReg::kIdBad); }
+ ASMJIT_INLINE_NODEBUG bool hasSARegId() const noexcept { return _saRegId != BaseReg::kIdBad; }
+ ASMJIT_INLINE_NODEBUG uint32_t saRegId() const noexcept { return _saRegId; }
+ ASMJIT_INLINE_NODEBUG void setSARegId(uint32_t regId) { _saRegId = uint8_t(regId); }
+ ASMJIT_INLINE_NODEBUG void resetSARegId() { _saRegId = uint8_t(BaseReg::kIdBad); }
+ //! Returns assigned argument at `argIndex` and `valueIndex`.
+ //!
+ //! \note `argIndex` refers to he function argument and `valueIndex` refers to a value pack (in case multiple
+ //! values are passed as a single argument).
inline FuncValue& arg(size_t argIndex, size_t valueIndex) noexcept {
ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks));
return _argPacks[argIndex][valueIndex];
}
+ //! \overload
inline const FuncValue& arg(size_t argIndex, size_t valueIndex) const noexcept {
ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks));
return _argPacks[argIndex][valueIndex];
}
+ //! Tests whether argument at `argIndex` and `valueIndex` has been assigned.
inline bool isAssigned(size_t argIndex, size_t valueIndex) const noexcept {
ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks));
return _argPacks[argIndex][valueIndex].isAssigned();
}
+ //! Assigns register at `argIndex` and value index of 0 to `reg` and an optional `typeId`.
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);
}
+ //! Assigns register at `argIndex` and value index of 0 to `regType`, `regId`, and an optional `typeId`.
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);
}
+ //! Assigns stack at `argIndex` and value index of 0 to `offset` and an optional `typeId`.
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);
}
+ //! Assigns register at `argIndex` and `valueIndex` to `reg` and an optional `typeId`.
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);
}
+ //! Assigns register at `argIndex` and `valueIndex` to `regType`, `regId`, and an optional `typeId`.
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);
}
+ //! Assigns stack at `argIndex` and `valueIndex` to `offset` and an optional `typeId`.
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);
@@ -1418,6 +1566,9 @@ public:
_assignAllInternal(argIndex + 1, std::forward<Args>(args)...);
}
+ //! Assigns all argument at once.
+ //!
+ //! \note This function can be only used if the arguments don't contain value packs (multiple values per argument).
template<typename... Args>
inline void assignAll(Args&&... args) noexcept {
_assignAllInternal(0, std::forward<Args>(args)...);
@@ -1430,8 +1581,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 This function must be called in order to use `BaseEmitter::emitArgsAssignment()`, otherwise the \ref 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;
//! \}
@@ -1442,4 +1593,3 @@ public:
ASMJIT_END_NAMESPACE
#endif // ASMJIT_CORE_FUNC_H_INCLUDED
-
diff --git a/3rdparty/asmjit/src/asmjit/core/funcargscontext.cpp b/3rdparty/asmjit/src/asmjit/core/funcargscontext.cpp
index 1db50a7082a..a6580874089 100644
--- a/3rdparty/asmjit/src/asmjit/core/funcargscontext.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/funcargscontext.cpp
@@ -102,9 +102,23 @@ ASMJIT_FAVOR_SIZE Error FuncArgsContext::initWorkData(const FuncFrame& frame, co
ASMJIT_ASSERT(dstWd != nullptr);
dstWd->assign(varId, srcId);
- // The best case, register is allocated where it is expected to be.
- if (dstId == srcId)
- var.markDone();
+ // The best case, register is allocated where it is expected to be. However, we should
+ // not mark this as done if both registers are GP and sign or zero extension is required.
+ if (dstId == srcId) {
+ if (dstGroup != RegGroup::kGp) {
+ var.markDone();
+ }
+ else {
+ TypeId dt = dst.typeId();
+ TypeId st = src.typeId();
+
+ uint32_t dstSize = TypeUtils::sizeOf(dt);
+ uint32_t srcSize = TypeUtils::sizeOf(st);
+
+ if (dt == TypeId::kVoid || st == TypeId::kVoid || dstSize <= srcSize)
+ var.markDone();
+ }
+ }
}
else {
if (ASMJIT_UNLIKELY(srcGroup > RegGroup::kMaxVirt))
diff --git a/3rdparty/asmjit/src/asmjit/core/funcargscontext_p.h b/3rdparty/asmjit/src/asmjit/core/funcargscontext_p.h
index 72ee10585a4..a8ad6b47dcd 100644
--- a/3rdparty/asmjit/src/asmjit/core/funcargscontext_p.h
+++ b/3rdparty/asmjit/src/asmjit/core/funcargscontext_p.h
@@ -176,14 +176,14 @@ public:
FuncArgsContext() noexcept;
- inline const ArchTraits& archTraits() const noexcept { return *_archTraits; }
- inline Arch arch() const noexcept { return _arch; }
+ ASMJIT_INLINE_NODEBUG const ArchTraits& archTraits() const noexcept { return *_archTraits; }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG uint32_t varCount() const noexcept { return _varCount; }
+ ASMJIT_INLINE_NODEBUG size_t indexOf(const Var* var) const noexcept { return (size_t)(var - _vars); }
- inline Var& var(size_t varId) noexcept { return _vars[varId]; }
- inline const Var& var(size_t varId) const noexcept { return _vars[varId]; }
+ ASMJIT_INLINE_NODEBUG Var& var(size_t varId) noexcept { return _vars[varId]; }
+ ASMJIT_INLINE_NODEBUG const Var& var(size_t varId) const noexcept { return _vars[varId]; }
Error initWorkData(const FuncFrame& frame, const FuncArgsAssignment& args, const RAConstraints* constraints) noexcept;
Error markScratchRegs(FuncFrame& frame) noexcept;
diff --git a/3rdparty/asmjit/src/asmjit/core/globals.cpp b/3rdparty/asmjit/src/asmjit/core/globals.cpp
index 2bbd0c0577d..4a98431b6d5 100644
--- a/3rdparty/asmjit/src/asmjit/core/globals.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/globals.cpp
@@ -86,6 +86,8 @@ ASMJIT_FAVOR_SIZE const char* DebugUtils::errorAsString(Error err) noexcept {
"ExpressionLabelNotBound\0"
"ExpressionOverflow\0"
"FailedToOpenAnonymousMemory\0"
+ "FailedToOpenFile\0"
+ "ProtectionFailure\0"
"<Unknown>\0";
static const uint16_t sErrorIndex[] = {
@@ -93,7 +95,7 @@ ASMJIT_FAVOR_SIZE const char* DebugUtils::errorAsString(Error err) noexcept {
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
+ 1073, 1088, 1104, 1119, 1134, 1164, 1188, 1207, 1235, 1252, 1270
};
// @EnumStringEnd@
diff --git a/3rdparty/asmjit/src/asmjit/core/globals.h b/3rdparty/asmjit/src/asmjit/core/globals.h
index f2d3c6e63df..db921cfc6e1 100644
--- a/3rdparty/asmjit/src/asmjit/core/globals.h
+++ b/3rdparty/asmjit/src/asmjit/core/globals.h
@@ -14,9 +14,14 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_utilities
//! \{
namespace Support {
- //! Cast designed to cast between function and void* pointers.
- template<typename Dst, typename Src>
- static inline Dst ptr_cast_impl(Src p) noexcept { return (Dst)p; }
+
+//! Cast designed to cast between function and void* pointers.
+template<typename Dst, typename Src>
+static inline Dst ptr_cast_impl(Src p) noexcept { return (Dst)p; }
+
+//! Helper to implement placement new/delete without relying on `<new>` header.
+struct PlacementNew { void* ptr; };
+
} // {Support}
#if defined(ASMJIT_NO_STDCXX)
@@ -25,17 +30,15 @@ namespace Support {
ASMJIT_FORCE_INLINE void operatorDelete(void* p) noexcept { if (p) free(p); }
} // {Support}
-#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 {}
+#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* ptr) noexcept { Support::operatorDelete(ptr); } \
+ \
+ ASMJIT_FORCE_INLINE void* operator new(size_t, void* ptr) noexcept { return ptr; } \
+ ASMJIT_FORCE_INLINE void operator delete(void*, void*) noexcept {} \
+ \
+ ASMJIT_FORCE_INLINE void* operator new(size_t, Support::PlacementNew ptr) noexcept { return ptr.ptr; } \
+ ASMJIT_FORCE_INLINE void operator delete(void*, Support::PlacementNew) noexcept {}
#else
#define ASMJIT_BASE_CLASS(TYPE)
#endif
@@ -93,10 +96,9 @@ static constexpr uint32_t kMaxTreeHeight = (ASMJIT_ARCH_BITS == 32 ? 30 : 61) +
static constexpr uint32_t kMaxOpCount = 6;
//! Maximum arguments of a function supported by the Compiler / Function API.
-static constexpr uint32_t kMaxFuncArgs = 16;
+static constexpr uint32_t kMaxFuncArgs = 32;
-//! The number of values that can be assigned to a single function argument or
-//! return value.
+//! The number of values that can be assigned to a single function argument or return value.
static constexpr uint32_t kMaxValuePack = 4;
//! Maximum number of physical registers AsmJit can use per register group.
@@ -129,16 +131,20 @@ static constexpr uint32_t kNumVirtGroups = 4;
struct Init_ {};
struct NoInit_ {};
+//! A decorator used to initialize.
static const constexpr Init_ Init {};
+//! A decorator used to not initialize.
static const constexpr NoInit_ NoInit {};
} // {Globals}
+//! Casts a `void*` pointer `func` to a function pointer `Func`.
template<typename Func>
-static inline Func ptr_as_func(void* func) noexcept { return Support::ptr_cast_impl<Func, void*>(func); }
+static ASMJIT_INLINE_NODEBUG Func ptr_as_func(void* func) noexcept { return Support::ptr_cast_impl<Func, void*>(func); }
+//! Casts a function pointer `func` to a void pointer `void*`.
template<typename Func>
-static inline void* func_as_ptr(Func func) noexcept { return Support::ptr_cast_impl<void*, Func>(func); }
+static ASMJIT_INLINE_NODEBUG void* func_as_ptr(Func func) noexcept { return Support::ptr_cast_impl<void*, Func>(func); }
//! \}
@@ -175,7 +181,10 @@ enum ErrorCode : uint32_t {
//! The object is already initialized.
kErrorAlreadyInitialized,
- //! Built-in feature was disabled at compile time and it's not available.
+ //! Either a built-in feature was disabled at compile time and it's not available or the feature is not
+ //! available on the target platform.
+ //!
+ //! For example trying to allocate large pages on unsupported platform would return this error.
kErrorFeatureNotEnabled,
//! Too many handles (Windows) or file descriptors (Unix/Posix).
@@ -320,6 +329,15 @@ enum ErrorCode : uint32_t {
//! Failed to open anonymous memory handle or file descriptor.
kErrorFailedToOpenAnonymousMemory,
+ //! Failed to open a file.
+ //!
+ //! \note This is a generic error that is used by internal filesystem API.
+ kErrorFailedToOpenFile,
+
+ //! Protection failure can be returned from a virtual memory allocator or when trying to change memory access
+ //! permissions.
+ kErrorProtectionFailure,
+
// @EnumValuesEnd@
//! Count of AsmJit error codes.
@@ -332,7 +350,7 @@ namespace DebugUtils {
//! \cond INTERNAL
//! Used to silence warnings about unused arguments or variables.
template<typename... Args>
-static inline void unused(Args&&...) noexcept {}
+static ASMJIT_INLINE_NODEBUG void unused(Args&&...) noexcept {}
//! \endcond
//! Returns the error `err` passed.
@@ -390,4 +408,14 @@ ASMJIT_API void ASMJIT_NORETURN assertionFailed(const char* file, int line, cons
ASMJIT_END_NAMESPACE
+//! Implementation of a placement new so we don't have to depend on `<new>`.
+ASMJIT_INLINE_NODEBUG void* operator new(size_t, const asmjit::Support::PlacementNew& p) noexcept {
+#if defined(_MSC_VER) && !defined(__clang__)
+ __assume(p.ptr != nullptr); // Otherwise MSVC would emit a nullptr check.
+#endif
+ return p.ptr;
+}
+
+ASMJIT_INLINE_NODEBUG void operator delete(void*, const asmjit::Support::PlacementNew&) noexcept {}
+
#endif // ASMJIT_CORE_GLOBALS_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/core/inst.cpp b/3rdparty/asmjit/src/asmjit/core/inst.cpp
index 8f29d8b7585..ade4ae001f2 100644
--- a/3rdparty/asmjit/src/asmjit/core/inst.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/inst.cpp
@@ -24,12 +24,12 @@ ASMJIT_BEGIN_NAMESPACE
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);
+ return x86::InstInternal::instIdToString(instId, output);
#endif
#if !defined(ASMJIT_NO_AARCH64)
if (Environment::isFamilyAArch64(arch))
- return a64::InstInternal::instIdToString(arch, instId, output);
+ return a64::InstInternal::instIdToString(instId, output);
#endif
return DebugUtils::errored(kErrorInvalidArch);
@@ -38,12 +38,12 @@ Error InstAPI::instIdToString(Arch arch, InstId instId, String& output) 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);
+ return x86::InstInternal::stringToInstId(s, len);
#endif
#if !defined(ASMJIT_NO_AARCH64)
if (Environment::isFamilyAArch64(arch))
- return a64::InstInternal::stringToInstId(arch, s, len);
+ return a64::InstInternal::stringToInstId(s, len);
#endif
return 0;
@@ -56,13 +56,17 @@ InstId InstAPI::stringToInstId(Arch arch, const char* s, size_t len) noexcept {
#ifndef ASMJIT_NO_VALIDATION
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);
+ if (Environment::isFamilyX86(arch)) {
+ if (arch == Arch::kX86)
+ return x86::InstInternal::validateX86(inst, operands, opCount, validationFlags);
+ else
+ return x86::InstInternal::validateX64(inst, operands, opCount, validationFlags);
+ }
#endif
#if !defined(ASMJIT_NO_AARCH64)
if (Environment::isFamilyAArch64(arch))
- return a64::InstInternal::validate(arch, inst, operands, opCount, validationFlags);
+ return a64::InstInternal::validate(inst, operands, opCount, validationFlags);
#endif
return DebugUtils::errored(kErrorInvalidArch);
@@ -84,7 +88,7 @@ Error InstAPI::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_* oper
#if !defined(ASMJIT_NO_AARCH64)
if (Environment::isFamilyAArch64(arch))
- return a64::InstInternal::queryRWInfo(arch, inst, operands, opCount, out);
+ return a64::InstInternal::queryRWInfo(inst, operands, opCount, out);
#endif
return DebugUtils::errored(kErrorInvalidArch);
@@ -103,7 +107,7 @@ Error InstAPI::queryFeatures(Arch arch, const BaseInst& inst, const Operand_* op
#if !defined(ASMJIT_NO_AARCH64)
if (Environment::isFamilyAArch64(arch))
- return a64::InstInternal::queryFeatures(arch, inst, operands, opCount, out);
+ return a64::InstInternal::queryFeatures(inst, operands, opCount, out);
#endif
return DebugUtils::errored(kErrorInvalidArch);
diff --git a/3rdparty/asmjit/src/asmjit/core/inst.h b/3rdparty/asmjit/src/asmjit/core/inst.h
index 643678971a7..a653fe8e4cc 100644
--- a/3rdparty/asmjit/src/asmjit/core/inst.h
+++ b/3rdparty/asmjit/src/asmjit/core/inst.h
@@ -20,7 +20,7 @@ ASMJIT_BEGIN_NAMESPACE
//!
//! Each architecture has a set of valid instructions indexed from 0. Instruction with 0 id is, however, a special
//! instruction that describes a "no instruction" or "invalid instruction". Different architectures can assign a.
-//! different instruction to the same id, each architecture typicall has its own instructions indexed from 1.
+//! different instruction to the same id, each architecture typically has its own instructions indexed from 1.
//!
//! Instruction identifiers listed by architecture:
//!
@@ -189,7 +189,7 @@ enum class InstControlFlow : uint32_t {
//! 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
+//! Provides hints to the instruction 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 {
@@ -231,17 +231,17 @@ public:
//!
//! 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
+ ASMJIT_INLINE_NODEBUG explicit BaseInst(InstId instId = 0, InstOptions options = InstOptions::kNone) noexcept
: _id(instId),
_options(options),
_extraReg() {}
- inline BaseInst(InstId instId, InstOptions options, const RegOnly& extraReg) noexcept
+ ASMJIT_INLINE_NODEBUG BaseInst(InstId instId, InstOptions options, const RegOnly& extraReg) noexcept
: _id(instId),
_options(options),
_extraReg(extraReg) {}
- inline BaseInst(InstId instId, InstOptions options, const BaseReg& extraReg) noexcept
+ ASMJIT_INLINE_NODEBUG BaseInst(InstId instId, InstOptions options, const BaseReg& extraReg) noexcept
: _id(instId),
_options(options),
_extraReg { extraReg.signature(), extraReg.id() } {}
@@ -252,22 +252,22 @@ public:
//! \{
//! Returns the instruction id with modifiers.
- inline InstId id() const noexcept { return _id; }
+ ASMJIT_INLINE_NODEBUG InstId id() const noexcept { return _id; }
//! Sets the instruction id and modiiers from `id`.
- inline void setId(InstId id) noexcept { _id = id; }
+ ASMJIT_INLINE_NODEBUG void setId(InstId id) noexcept { _id = id; }
//! Resets the instruction id and modifiers to zero, see \ref kIdNone.
- inline void resetId() noexcept { _id = 0; }
+ ASMJIT_INLINE_NODEBUG void resetId() noexcept { _id = 0; }
//! Returns a real instruction id that doesn't contain any modifiers.
- inline InstId realId() const noexcept { return _id & uint32_t(InstIdParts::kRealId); }
+ ASMJIT_INLINE_NODEBUG InstId realId() const noexcept { return _id & uint32_t(InstIdParts::kRealId); }
template<InstIdParts kPart>
- inline uint32_t getInstIdPart() const noexcept {
+ ASMJIT_INLINE_NODEBUG uint32_t getInstIdPart() const noexcept {
return (uint32_t(_id) & uint32_t(kPart)) >> Support::ConstCTZ<uint32_t(kPart)>::value;
}
template<InstIdParts kPart>
- inline void setInstIdPart(uint32_t value) noexcept {
+ ASMJIT_INLINE_NODEBUG void setInstIdPart(uint32_t value) noexcept {
_id = (_id & ~uint32_t(kPart)) | (value << Support::ConstCTZ<uint32_t(kPart)>::value);
}
@@ -276,47 +276,61 @@ public:
//! \name Instruction Options
//! \{
- 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; }
+ ASMJIT_INLINE_NODEBUG InstOptions options() const noexcept { return _options; }
+ ASMJIT_INLINE_NODEBUG bool hasOption(InstOptions option) const noexcept { return Support::test(_options, option); }
+ ASMJIT_INLINE_NODEBUG void setOptions(InstOptions options) noexcept { _options = options; }
+ ASMJIT_INLINE_NODEBUG void addOptions(InstOptions options) noexcept { _options |= options; }
+ ASMJIT_INLINE_NODEBUG void clearOptions(InstOptions options) noexcept { _options &= ~options; }
+ ASMJIT_INLINE_NODEBUG void resetOptions() noexcept { _options = InstOptions::kNone; }
//! \}
//! \name Extra Register
//! \{
- inline bool hasExtraReg() const noexcept { return _extraReg.isReg(); }
- inline RegOnly& extraReg() noexcept { return _extraReg; }
- inline const RegOnly& extraReg() const noexcept { return _extraReg; }
- inline void setExtraReg(const BaseReg& reg) noexcept { _extraReg.init(reg); }
- inline void setExtraReg(const RegOnly& reg) noexcept { _extraReg.init(reg); }
- inline void resetExtraReg() noexcept { _extraReg.reset(); }
+ ASMJIT_INLINE_NODEBUG bool hasExtraReg() const noexcept { return _extraReg.isReg(); }
+ ASMJIT_INLINE_NODEBUG RegOnly& extraReg() noexcept { return _extraReg; }
+ ASMJIT_INLINE_NODEBUG const RegOnly& extraReg() const noexcept { return _extraReg; }
+ ASMJIT_INLINE_NODEBUG void setExtraReg(const BaseReg& reg) noexcept { _extraReg.init(reg); }
+ ASMJIT_INLINE_NODEBUG void setExtraReg(const RegOnly& reg) noexcept { _extraReg.init(reg); }
+ ASMJIT_INLINE_NODEBUG void resetExtraReg() noexcept { _extraReg.reset(); }
//! \}
//! \name ARM Specific
//! \{
- inline arm::CondCode armCondCode() const noexcept { return (arm::CondCode)getInstIdPart<InstIdParts::kARM_Cond>(); }
- inline void setArmCondCode(arm::CondCode cc) noexcept { setInstIdPart<InstIdParts::kARM_Cond>(uint32_t(cc)); }
+ ASMJIT_INLINE_NODEBUG arm::CondCode armCondCode() const noexcept { return (arm::CondCode)getInstIdPart<InstIdParts::kARM_Cond>(); }
+ ASMJIT_INLINE_NODEBUG void setArmCondCode(arm::CondCode cc) noexcept { setInstIdPart<InstIdParts::kARM_Cond>(uint32_t(cc)); }
+
+ ASMJIT_INLINE_NODEBUG a32::DataType armDt() const noexcept { return (a32::DataType)getInstIdPart<InstIdParts::kA32_DT>(); }
+ ASMJIT_INLINE_NODEBUG a32::DataType armDt2() const noexcept { return (a32::DataType)getInstIdPart<InstIdParts::kA32_DT2>(); }
//! \}
//! \name Statics
//! \{
- static inline constexpr InstId composeARMInstId(uint32_t id, arm::CondCode cc) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr InstId composeARMInstId(uint32_t id, arm::CondCode cc) noexcept {
return id | (uint32_t(cc) << Support::ConstCTZ<uint32_t(InstIdParts::kARM_Cond)>::value);
}
- static inline constexpr InstId extractRealId(uint32_t id) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr InstId composeARMInstId(uint32_t id, a32::DataType dt, arm::CondCode cc = arm::CondCode::kAL) noexcept {
+ return id | (uint32_t(dt) << Support::ConstCTZ<uint32_t(InstIdParts::kA32_DT)>::value)
+ | (uint32_t(cc) << Support::ConstCTZ<uint32_t(InstIdParts::kARM_Cond)>::value);
+ }
+
+ static ASMJIT_INLINE_NODEBUG constexpr InstId composeARMInstId(uint32_t id, a32::DataType dt, a32::DataType dt2, arm::CondCode cc = arm::CondCode::kAL) noexcept {
+ return id | (uint32_t(dt) << Support::ConstCTZ<uint32_t(InstIdParts::kA32_DT)>::value)
+ | (uint32_t(dt2) << Support::ConstCTZ<uint32_t(InstIdParts::kA32_DT2)>::value)
+ | (uint32_t(cc) << Support::ConstCTZ<uint32_t(InstIdParts::kARM_Cond)>::value);
+ }
+
+ static ASMJIT_INLINE_NODEBUG constexpr InstId extractRealId(uint32_t id) noexcept {
return id & uint32_t(InstIdParts::kRealId);
}
- static inline constexpr arm::CondCode extractARMCondCode(uint32_t id) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr arm::CondCode extractARMCondCode(uint32_t id) noexcept {
return (arm::CondCode)((uint32_t(id) & uint32_t(InstIdParts::kARM_Cond)) >> Support::ConstCTZ<uint32_t(InstIdParts::kARM_Cond)>::value);
}
@@ -333,16 +347,16 @@ enum class CpuRWFlags : uint32_t {
// Common RW Flags (0x000000FF)
// ----------------------------
- //! Carry flag.
- kCF = 0x00000001u,
//! Signed overflow flag.
- kOF = 0x00000002u,
- //! Sign flag (negative/sign, if set).
- kSF = 0x00000004u,
+ kOF = 0x00000001u,
+ //! Carry flag.
+ kCF = 0x00000002u,
//! Zero and/or equality flag (1 if zero/equal).
- kZF = 0x00000008u,
+ kZF = 0x00000004u,
+ //! Sign flag (negative/sign, if set).
+ kSF = 0x00000008u,
- // X86 Specific RW Flags (0xFFFFFF00)
+ // X86 Specific RW Flags
// ----------------------------------
//! Carry flag (X86, X86_64).
@@ -373,12 +387,22 @@ enum class CpuRWFlags : uint32_t {
//! FPU C2 status flag (X86, X86_64).
kX86_C2 = 0x00040000u,
//! FPU C3 status flag (X86, X86_64).
- kX86_C3 = 0x00080000u
+ kX86_C3 = 0x00080000u,
+
+ // ARM Specific RW Flags
+ // ----------------------------------
+
+ kARM_V = kOF,
+ kARM_C = kCF,
+ kARM_Z = kZF,
+ kARM_N = kSF,
+ kARM_Q = 0x00000100u,
+ kARM_GE = 0x00000200u
};
ASMJIT_DEFINE_ENUM_FLAGS(CpuRWFlags)
//! Operand read/write flags describe how the operand is accessed and some additional features.
-enum class OpRWFlags {
+enum class OpRWFlags : uint32_t {
//! No flags.
kNone = 0,
@@ -406,6 +430,9 @@ enum class OpRWFlags {
//! The `extendByteMask()` represents a zero extension.
kZExt = 0x00000010u,
+ //! The register must have assigned a unique physical ID, which cannot be assigned to any other register.
+ kUnique = 0x00000080u,
+
//! Register operand must use \ref OpRWInfo::physId().
kRegPhysId = 0x00000100u,
//! Base register of a memory operand must use \ref OpRWInfo::physId().
@@ -474,7 +501,7 @@ struct OpRWInfo {
//! \{
//! Resets this operand information to all zeros.
- inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
+ ASMJIT_INLINE_NODEBUG void reset() noexcept { *this = OpRWInfo{}; }
//! Resets this operand info (resets all members) and set common information
//! to the given `opFlags`, `regSize`, and possibly `physId`.
@@ -485,13 +512,14 @@ struct OpRWInfo {
_consecutiveLeadCount = 0;
_resetReserved();
- uint64_t mask = Support::lsbMask<uint64_t>(regSize);
+ uint64_t mask = Support::lsbMask<uint64_t>(Support::min<uint32_t>(regSize, 64));
+
_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 {
+ ASMJIT_INLINE_NODEBUG void _resetReserved() noexcept {
_reserved[0] = 0;
}
@@ -501,36 +529,40 @@ struct OpRWInfo {
//! \{
//! Returns operand flags.
- inline OpRWFlags opFlags() const noexcept { return _opFlags; }
+ ASMJIT_INLINE_NODEBUG OpRWFlags opFlags() const noexcept { return _opFlags; }
//! Tests whether operand flags contain the given `flag`.
- inline bool hasOpFlag(OpRWFlags flag) const noexcept { return Support::test(_opFlags, flag); }
+ ASMJIT_INLINE_NODEBUG bool hasOpFlag(OpRWFlags flag) const noexcept { return Support::test(_opFlags, flag); }
//! Adds the given `flags` to operand flags.
- inline void addOpFlags(OpRWFlags flags) noexcept { _opFlags |= flags; }
+ ASMJIT_INLINE_NODEBUG void addOpFlags(OpRWFlags flags) noexcept { _opFlags |= flags; }
//! Removes the given `flags` from operand flags.
- inline void clearOpFlags(OpRWFlags flags) noexcept { _opFlags &= ~flags; }
+ ASMJIT_INLINE_NODEBUG void clearOpFlags(OpRWFlags flags) noexcept { _opFlags &= ~flags; }
//! Tests whether this operand is read from.
- inline bool isRead() const noexcept { return hasOpFlag(OpRWFlags::kRead); }
+ ASMJIT_INLINE_NODEBUG bool isRead() const noexcept { return hasOpFlag(OpRWFlags::kRead); }
//! Tests whether this operand is written to.
- inline bool isWrite() const noexcept { return hasOpFlag(OpRWFlags::kWrite); }
+ ASMJIT_INLINE_NODEBUG bool isWrite() const noexcept { return hasOpFlag(OpRWFlags::kWrite); }
//! Tests whether this operand is both read and write.
- inline bool isReadWrite() const noexcept { return (_opFlags & OpRWFlags::kRW) == OpRWFlags::kRW; }
+ ASMJIT_INLINE_NODEBUG bool isReadWrite() const noexcept { return (_opFlags & OpRWFlags::kRW) == OpRWFlags::kRW; }
//! Tests whether this operand is read only.
- inline bool isReadOnly() const noexcept { return (_opFlags & OpRWFlags::kRW) == OpRWFlags::kRead; }
+ ASMJIT_INLINE_NODEBUG bool isReadOnly() const noexcept { return (_opFlags & OpRWFlags::kRW) == OpRWFlags::kRead; }
//! Tests whether this operand is write only.
- inline bool isWriteOnly() const noexcept { return (_opFlags & OpRWFlags::kRW) == OpRWFlags::kWrite; }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG 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(OpRWFlags::kRegMem); }
+ ASMJIT_INLINE_NODEBUG bool isRm() const noexcept { return hasOpFlag(OpRWFlags::kRegMem); }
//! Tests whether the operand will be zero extended.
- inline bool isZExt() const noexcept { return hasOpFlag(OpRWFlags::kZExt); }
+ ASMJIT_INLINE_NODEBUG bool isZExt() const noexcept { return hasOpFlag(OpRWFlags::kZExt); }
+
+ //! Tests whether the operand must have allocated a unique physical id that cannot be shared with other register
+ //! operands.
+ ASMJIT_INLINE_NODEBUG bool isUnique() const noexcept { return hasOpFlag(OpRWFlags::kUnique); }
//! \}
@@ -539,38 +571,38 @@ struct OpRWInfo {
//! 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); }
+ ASMJIT_INLINE_NODEBUG bool isMemFake() const noexcept { return hasOpFlag(OpRWFlags::kMemFake); }
//! Tests whether the instruction's memory BASE register is used.
- inline bool isMemBaseUsed() const noexcept { return hasOpFlag(OpRWFlags::kMemBaseRW); }
+ ASMJIT_INLINE_NODEBUG bool isMemBaseUsed() const noexcept { return hasOpFlag(OpRWFlags::kMemBaseRW); }
//! Tests whether the instruction reads from its BASE registers.
- inline bool isMemBaseRead() const noexcept { return hasOpFlag(OpRWFlags::kMemBaseRead); }
+ ASMJIT_INLINE_NODEBUG bool isMemBaseRead() const noexcept { return hasOpFlag(OpRWFlags::kMemBaseRead); }
//! Tests whether the instruction writes to its BASE registers.
- inline bool isMemBaseWrite() const noexcept { return hasOpFlag(OpRWFlags::kMemBaseWrite); }
+ ASMJIT_INLINE_NODEBUG 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 & OpRWFlags::kMemBaseRW) == OpRWFlags::kMemBaseRW; }
+ ASMJIT_INLINE_NODEBUG 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 & OpRWFlags::kMemBaseRW) == OpRWFlags::kMemBaseRead; }
+ ASMJIT_INLINE_NODEBUG 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 & OpRWFlags::kMemBaseRW) == OpRWFlags::kMemBaseWrite; }
+ ASMJIT_INLINE_NODEBUG 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(OpRWFlags::kMemBasePreModify); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG bool isMemBasePostModify() const noexcept { return hasOpFlag(OpRWFlags::kMemBasePostModify); }
//! Tests whether the instruction's memory INDEX register is used.
- inline bool isMemIndexUsed() const noexcept { return hasOpFlag(OpRWFlags::kMemIndexRW); }
+ ASMJIT_INLINE_NODEBUG bool isMemIndexUsed() const noexcept { return hasOpFlag(OpRWFlags::kMemIndexRW); }
//! Tests whether the instruction reads the INDEX registers.
- inline bool isMemIndexRead() const noexcept { return hasOpFlag(OpRWFlags::kMemIndexRead); }
+ ASMJIT_INLINE_NODEBUG bool isMemIndexRead() const noexcept { return hasOpFlag(OpRWFlags::kMemIndexRead); }
//! Tests whether the instruction writes to its INDEX registers.
- inline bool isMemIndexWrite() const noexcept { return hasOpFlag(OpRWFlags::kMemIndexWrite); }
+ ASMJIT_INLINE_NODEBUG 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 & OpRWFlags::kMemIndexRW) == OpRWFlags::kMemIndexRW; }
+ ASMJIT_INLINE_NODEBUG 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 & OpRWFlags::kMemIndexRW) == OpRWFlags::kMemIndexRead; }
+ ASMJIT_INLINE_NODEBUG 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 & OpRWFlags::kMemIndexRW) == OpRWFlags::kMemIndexWrite; }
+ ASMJIT_INLINE_NODEBUG bool isMemIndexWriteOnly() const noexcept { return (_opFlags & OpRWFlags::kMemIndexRW) == OpRWFlags::kMemIndexWrite; }
//! \}
@@ -580,11 +612,11 @@ struct OpRWInfo {
//! Returns a physical id of the register that is fixed for this operand.
//!
//! Returns \ref BaseReg::kIdBad if any register can be used.
- inline uint32_t physId() const noexcept { return _physId; }
+ ASMJIT_INLINE_NODEBUG uint32_t physId() const noexcept { return _physId; }
//! Tests whether \ref physId() would return a valid physical register id.
- inline bool hasPhysId() const noexcept { return _physId != BaseReg::kIdBad; }
+ ASMJIT_INLINE_NODEBUG bool hasPhysId() const noexcept { return _physId != BaseReg::kIdBad; }
//! Sets physical register id, which would be fixed for this operand.
- inline void setPhysId(uint32_t physId) noexcept { _physId = uint8_t(physId); }
+ ASMJIT_INLINE_NODEBUG void setPhysId(uint32_t physId) noexcept { _physId = uint8_t(physId); }
//! \}
@@ -592,9 +624,9 @@ struct OpRWInfo {
//! \{
//! Returns Reg/Mem size of the operand.
- inline uint32_t rmSize() const noexcept { return _rmSize; }
+ ASMJIT_INLINE_NODEBUG uint32_t rmSize() const noexcept { return _rmSize; }
//! Sets Reg/Mem size of the operand.
- inline void setRmSize(uint32_t rmSize) noexcept { _rmSize = uint8_t(rmSize); }
+ ASMJIT_INLINE_NODEBUG void setRmSize(uint32_t rmSize) noexcept { _rmSize = uint8_t(rmSize); }
//! \}
@@ -602,18 +634,18 @@ struct OpRWInfo {
//! \{
//! Returns read mask.
- inline uint64_t readByteMask() const noexcept { return _readByteMask; }
+ ASMJIT_INLINE_NODEBUG uint64_t readByteMask() const noexcept { return _readByteMask; }
//! Returns write mask.
- inline uint64_t writeByteMask() const noexcept { return _writeByteMask; }
+ ASMJIT_INLINE_NODEBUG uint64_t writeByteMask() const noexcept { return _writeByteMask; }
//! Returns extend mask.
- inline uint64_t extendByteMask() const noexcept { return _extendByteMask; }
+ ASMJIT_INLINE_NODEBUG uint64_t extendByteMask() const noexcept { return _extendByteMask; }
//! Sets read mask.
- inline void setReadByteMask(uint64_t mask) noexcept { _readByteMask = mask; }
+ ASMJIT_INLINE_NODEBUG void setReadByteMask(uint64_t mask) noexcept { _readByteMask = mask; }
//! Sets write mask.
- inline void setWriteByteMask(uint64_t mask) noexcept { _writeByteMask = mask; }
- //! Sets externd mask.
- inline void setExtendByteMask(uint64_t mask) noexcept { _extendByteMask = mask; }
+ ASMJIT_INLINE_NODEBUG void setWriteByteMask(uint64_t mask) noexcept { _writeByteMask = mask; }
+ //! Sets extend mask.
+ ASMJIT_INLINE_NODEBUG void setExtendByteMask(uint64_t mask) noexcept { _extendByteMask = mask; }
//! \}
};
@@ -647,7 +679,7 @@ struct InstRWInfo {
uint8_t _rmFeature;
//! Reserved for future use.
uint8_t _reserved[18];
- //! Read/Write onfo of extra register (rep{} or kz{}).
+ //! Read/Write info of extra register (rep{} or kz{}).
OpRWInfo _extraReg;
//! Read/Write info of instruction operands.
OpRWInfo _operands[Globals::kMaxOpCount];
@@ -658,7 +690,7 @@ struct InstRWInfo {
//! \{
//! Resets this RW information to all zeros.
- inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
+ ASMJIT_INLINE_NODEBUG void reset() noexcept { *this = InstRWInfo{}; }
//! \}
@@ -666,13 +698,13 @@ struct InstRWInfo {
//! \{
//! Returns flags associated with the instruction, see \ref InstRWFlags.
- inline InstRWFlags instFlags() const noexcept { return _instFlags; }
+ ASMJIT_INLINE_NODEBUG InstRWFlags instFlags() const noexcept { return _instFlags; }
//! Tests whether the instruction flags contain `flag`.
- inline bool hasInstFlag(InstRWFlags flag) const noexcept { return Support::test(_instFlags, flag); }
+ ASMJIT_INLINE_NODEBUG bool hasInstFlag(InstRWFlags flag) const noexcept { return Support::test(_instFlags, flag); }
//! Tests whether the instruction flags contain \ref InstRWFlags::kMovOp.
- inline bool isMovOp() const noexcept { return hasInstFlag(InstRWFlags::kMovOp); }
+ ASMJIT_INLINE_NODEBUG bool isMovOp() const noexcept { return hasInstFlag(InstRWFlags::kMovOp); }
//! \}
@@ -680,9 +712,9 @@ struct InstRWInfo {
//! \{
//! Returns a mask of CPU flags read.
- inline CpuRWFlags readFlags() const noexcept { return _readFlags; }
+ ASMJIT_INLINE_NODEBUG CpuRWFlags readFlags() const noexcept { return _readFlags; }
//! Returns a mask of CPU flags written.
- inline CpuRWFlags writeFlags() const noexcept { return _writeFlags; }
+ ASMJIT_INLINE_NODEBUG CpuRWFlags writeFlags() const noexcept { return _writeFlags; }
//! \}
@@ -699,7 +731,7 @@ struct InstRWInfo {
//! 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; }
+ ASMJIT_INLINE_NODEBUG uint32_t rmFeature() const noexcept { return _rmFeature; }
//! \}
@@ -707,10 +739,10 @@ struct InstRWInfo {
//! \{
//! Returns RW information of extra register operand (extraReg).
- inline const OpRWInfo& extraReg() const noexcept { return _extraReg; }
+ ASMJIT_INLINE_NODEBUG const OpRWInfo& extraReg() const noexcept { return _extraReg; }
//! Returns RW information of all instruction's operands.
- inline const OpRWInfo* operands() const noexcept { return _operands; }
+ ASMJIT_INLINE_NODEBUG const OpRWInfo* operands() const noexcept { return _operands; }
//! Returns RW information of the operand at the given `index`.
inline const OpRWInfo& operand(size_t index) const noexcept {
@@ -719,7 +751,7 @@ struct InstRWInfo {
}
//! Returns the number of operands this instruction has.
- inline uint32_t opCount() const noexcept { return _opCount; }
+ ASMJIT_INLINE_NODEBUG uint32_t opCount() const noexcept { return _opCount; }
//! \}
};
diff --git a/3rdparty/asmjit/src/asmjit/core/instdb.cpp b/3rdparty/asmjit/src/asmjit/core/instdb.cpp
new file mode 100644
index 00000000000..cde369f6a18
--- /dev/null
+++ b/3rdparty/asmjit/src/asmjit/core/instdb.cpp
@@ -0,0 +1,101 @@
+// 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
+
+#include "../core/api-build_p.h"
+#include "../core/instdb_p.h"
+
+ASMJIT_BEGIN_NAMESPACE
+
+namespace InstNameUtils {
+
+static constexpr uint32_t kBufferSize = 32;
+
+static ASMJIT_FORCE_INLINE char decode5BitChar(uint32_t c) noexcept {
+ uint32_t base = c <= 26 ? uint32_t('a') - 1u : uint32_t('0') - 27u;
+ return char(base + c);
+}
+
+static ASMJIT_FORCE_INLINE size_t decodeToBuffer(char nameOut[kBufferSize], uint32_t nameValue, const char* stringTable) noexcept {
+ size_t i;
+
+ if (nameValue & 0x80000000u) {
+ // Small string of 5-bit characters.
+ for (i = 0; i < 6; i++, nameValue >>= 5) {
+ uint32_t c = nameValue & 0x1F;
+ if (c == 0)
+ break;
+ nameOut[i] = decode5BitChar(c);
+ }
+ return i;
+ }
+ else {
+ size_t prefixBase = nameValue & 0xFFFu;
+ size_t prefixSize = (nameValue >> 12) & 0xFu;
+
+ size_t suffixBase = (nameValue >> 16) & 0xFFFu;
+ size_t suffixSize = (nameValue >> 28) & 0x7u;
+
+ for (i = 0; i < prefixSize; i++)
+ nameOut[i] = stringTable[prefixBase + i];
+
+ char* suffixOut = nameOut + prefixSize;
+ for (i = 0; i < suffixSize; i++)
+ suffixOut[i] = stringTable[suffixBase + i];
+
+ return prefixSize + suffixSize;
+ }
+}
+
+Error decode(String& output, uint32_t nameValue, const char* stringTable) noexcept {
+ char nameData[kBufferSize];
+ size_t nameSize = decodeToBuffer(nameData, nameValue, stringTable);
+
+ return output.append(nameData, nameSize);
+}
+
+InstId find(const char* s, size_t len, const InstNameIndex& nameIndex, const uint32_t* nameTable, const char* stringTable) noexcept {
+ if (ASMJIT_UNLIKELY(!s))
+ return BaseInst::kIdNone;
+
+ if (len == SIZE_MAX)
+ len = strlen(s);
+
+ if (ASMJIT_UNLIKELY(len == 0 || len > nameIndex.maxNameLength))
+ return BaseInst::kIdNone;
+
+ uint32_t prefix = uint32_t(s[0]) - 'a';
+ if (ASMJIT_UNLIKELY(prefix > 'z' - 'a'))
+ return BaseInst::kIdNone;
+
+ size_t base = nameIndex.data[prefix].start;
+ size_t end = nameIndex.data[prefix].end;
+
+ if (ASMJIT_UNLIKELY(!base))
+ return BaseInst::kIdNone;
+
+ char nameData[kBufferSize];
+ for (size_t lim = end - base; lim != 0; lim >>= 1) {
+ size_t instId = base + (lim >> 1);
+ size_t nameSize = decodeToBuffer(nameData, nameTable[instId], stringTable);
+
+ int result = Support::compareStringViews(s, len, nameData, nameSize);
+ if (result < 0)
+ continue;
+
+ if (result > 0) {
+ base = instId + 1;
+ lim--;
+ continue;
+ }
+
+ return InstId(instId);
+ }
+
+ return BaseInst::kIdNone;
+}
+
+} // {InstNameUtils}
+
+ASMJIT_END_NAMESPACE
diff --git a/3rdparty/asmjit/src/asmjit/core/instdb_p.h b/3rdparty/asmjit/src/asmjit/core/instdb_p.h
new file mode 100644
index 00000000000..b5afb72cb36
--- /dev/null
+++ b/3rdparty/asmjit/src/asmjit/core/instdb_p.h
@@ -0,0 +1,40 @@
+// 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_INSTDB_P_H_INCLUDED
+#define ASMJIT_CORE_INSTDB_P_H_INCLUDED
+
+#include "../core/inst.h"
+#include "../core/string.h"
+
+ASMJIT_BEGIN_NAMESPACE
+
+//! \cond INTERNAL
+//! \addtogroup asmjit_instruction_db
+//! \{
+
+struct InstNameIndex {
+ struct Span {
+ uint16_t start;
+ uint16_t end;
+ };
+
+ Span data[26];
+ uint16_t maxNameLength;
+};
+
+namespace InstNameUtils {
+
+Error decode(String& output, uint32_t nameValue, const char* stringTable) noexcept;
+InstId find(const char* s, size_t len, const InstNameIndex& nameIndex, const uint32_t* nameTable, const char* stringTable) noexcept;
+
+} // {InstNameUtils}
+
+//! \}
+//! \endcond
+
+ASMJIT_END_NAMESPACE
+
+#endif // ASMJIT_CORE_INSTDB_P_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/core/jitallocator.cpp b/3rdparty/asmjit/src/asmjit/core/jitallocator.cpp
index 19fbe4b2338..44e864105fe 100644
--- a/3rdparty/asmjit/src/asmjit/core/jitallocator.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/jitallocator.cpp
@@ -31,18 +31,19 @@ static constexpr uint32_t kJitAllocatorMultiPoolCount = 3;
static constexpr uint32_t kJitAllocatorBaseGranularity = 64;
//! Maximum block size (32MB).
-static constexpr uint32_t kJitAllocatorMaxBlockSize = 1024 * 1024 * 32;
+static constexpr uint32_t kJitAllocatorMaxBlockSize = 1024 * 1024 * 64;
// JitAllocator - Fill Pattern
// ===========================
static inline uint32_t JitAllocator_defaultFillPattern() noexcept {
+#if ASMJIT_ARCH_X86
// X86 and X86_64 - 4x 'int3' instruction.
- if (ASMJIT_ARCH_X86)
- return 0xCCCCCCCCu;
-
+ return 0xCCCCCCCCu;
+#else
// Unknown...
return 0u;
+#endif
}
// JitAllocator - BitVectorRangeIterator
@@ -146,42 +147,38 @@ public:
//! Double linked list of blocks.
ZoneList<JitAllocatorBlock> blocks;
//! Where to start looking first.
- JitAllocatorBlock* cursor;
+ JitAllocatorBlock* cursor = nullptr;
//! Count of blocks.
- uint32_t blockCount;
+ uint32_t blockCount = 0;
//! Allocation granularity.
- uint16_t granularity;
+ uint16_t granularity = 0;
//! Log2(granularity).
- uint8_t granularityLog2;
+ uint8_t granularityLog2 = 0;
//! Count of empty blocks (either 0 or 1 as we won't keep more blocks empty).
- uint8_t emptyBlockCount;
+ uint8_t emptyBlockCount = 0;
//! Number of bits reserved across all blocks.
- size_t totalAreaSize;
+ size_t totalAreaSize[2] {};
//! Number of bits used across all blocks.
- size_t totalAreaUsed;
+ size_t totalAreaUsed[2] {};
//! Overhead of all blocks (in bytes).
- size_t totalOverheadBytes;
+ size_t totalOverheadBytes = 0;
inline JitAllocatorPool(uint32_t granularity) noexcept
: blocks(),
- cursor(nullptr),
- blockCount(0),
granularity(uint16_t(granularity)),
- granularityLog2(uint8_t(Support::ctz(granularity))),
- emptyBlockCount(0),
- totalAreaSize(0),
- totalAreaUsed(0),
- totalOverheadBytes(0) {}
+ granularityLog2(uint8_t(Support::ctz(granularity))) {}
inline void reset() noexcept {
blocks.reset();
cursor = nullptr;
- blockCount = 0;
- totalAreaSize = 0;
- totalAreaUsed = 0;
- totalOverheadBytes = 0;
+ blockCount = 0u;
+ totalAreaSize[0] = 0u;
+ totalAreaSize[1] = 0u;
+ totalAreaUsed[0] = 0u;
+ totalAreaUsed[1] = 0u;
+ totalOverheadBytes = 0u;
}
inline size_t byteSizeFromAreaSize(uint32_t areaSize) const noexcept { return size_t(areaSize) * granularity; }
@@ -202,39 +199,47 @@ public:
ASMJIT_NONCOPYABLE(JitAllocatorBlock)
enum Flags : uint32_t {
+ //! Block has initial padding, see \ref JitAllocatorOptions::kDisableInitialPadding.
+ kFlagInitialPadding = 0x00000001u,
//! Block is empty.
- kFlagEmpty = 0x00000001u,
+ kFlagEmpty = 0x00000002u,
//! Block is dirty (largestUnusedArea, searchStart, searchEnd).
- kFlagDirty = 0x00000002u,
- //! Block is dual-mapped.
- kFlagDualMapped = 0x00000004u
+ kFlagDirty = 0x00000004u,
+ //! Block represents memory that is using large pages.
+ kFlagLargePages = 0x00000008u,
+ //! Block represents memory that is dual-mapped.
+ kFlagDualMapped = 0x00000010u
};
+ static_assert(kFlagInitialPadding == 1, "JitAllocatorBlock::kFlagInitialPadding must be equal to 1");
+
+ static inline uint32_t initialAreaStartByFlags(uint32_t flags) noexcept { return flags & kFlagInitialPadding; }
+
//! Link to the pool that owns this block.
- JitAllocatorPool* _pool;
+ JitAllocatorPool* _pool {};
//! Virtual memory mapping - either single mapping (both pointers equal) or
//! dual mapping, where one pointer is Read+Execute and the second Read+Write.
- VirtMem::DualMapping _mapping;
+ VirtMem::DualMapping _mapping {};
//! Virtual memory size (block size) [bytes].
- size_t _blockSize;
+ size_t _blockSize = 0;
//! Block flags.
- uint32_t _flags;
+ uint32_t _flags = 0;
//! Size of the whole block area (bit-vector size).
- uint32_t _areaSize;
+ uint32_t _areaSize = 0;
//! Used area (number of bits in bit-vector used).
- uint32_t _areaUsed;
+ uint32_t _areaUsed = 0;
//! The largest unused continuous area in the bit-vector (or `areaSize` to initiate rescan).
- uint32_t _largestUnusedArea;
+ uint32_t _largestUnusedArea = 0;
//! Start of a search range (for unused bits).
- uint32_t _searchStart;
+ uint32_t _searchStart = 0;
//! End of a search range (for unused bits).
- uint32_t _searchEnd;
+ uint32_t _searchEnd = 0;
//! Used bit-vector (0 = unused, 1 = used).
- Support::BitWord* _usedBitVector;
+ Support::BitWord* _usedBitVector {};
//! Stop bit-vector (0 = don't care, 1 = stop).
- Support::BitWord* _stopBitVector;
+ Support::BitWord* _stopBitVector {};
inline JitAllocatorBlock(
JitAllocatorPool* pool,
@@ -250,12 +255,15 @@ public:
_blockSize(blockSize),
_flags(blockFlags),
_areaSize(areaSize),
- _areaUsed(0),
- _largestUnusedArea(areaSize),
- _searchStart(0),
- _searchEnd(areaSize),
+ _areaUsed(0), // Will be initialized by clearBlock().
+ _largestUnusedArea(0), // Will be initialized by clearBlock().
+ _searchStart(0), // Will be initialized by clearBlock().
+ _searchEnd(0), // Will be initialized by clearBlock().
_usedBitVector(usedBitVector),
- _stopBitVector(stopBitVector) {}
+ _stopBitVector(stopBitVector) {
+
+ clearBlock();
+ }
inline JitAllocatorPool* pool() const noexcept { return _pool; }
@@ -266,9 +274,15 @@ public:
inline void addFlags(uint32_t f) noexcept { _flags |= f; }
inline void clearFlags(uint32_t f) noexcept { _flags &= ~f; }
+ inline bool empty() const noexcept { return hasFlag(kFlagEmpty); }
inline bool isDirty() const noexcept { return hasFlag(kFlagDirty); }
inline void makeDirty() noexcept { addFlags(kFlagDirty); }
+ inline bool hasLargePages() const noexcept { return hasFlag(kFlagLargePages); }
+ inline bool hasInitialPadding() const noexcept { return hasFlag(kFlagInitialPadding); }
+
+ inline uint32_t initialAreaStart() const noexcept { return initialAreaStartByFlags(_flags); }
+
inline size_t blockSize() const noexcept { return _blockSize; }
inline uint32_t areaSize() const noexcept { return _areaSize; }
@@ -278,7 +292,27 @@ public:
inline void decreaseUsedArea(uint32_t value) noexcept {
_areaUsed -= value;
- _pool->totalAreaUsed -= value;
+ _pool->totalAreaUsed[size_t(hasLargePages())] -= value;
+ }
+
+ inline void clearBlock() noexcept {
+ bool bit = hasInitialPadding();
+ size_t numBitWords = _pool->bitWordCountFromAreaSize(_areaSize);
+
+ memset(_usedBitVector, 0, numBitWords * sizeof(Support::BitWord));
+ memset(_stopBitVector, 0, numBitWords * sizeof(Support::BitWord));
+
+ Support::bitVectorSetBit(_usedBitVector, 0, bit);
+ Support::bitVectorSetBit(_stopBitVector, 0, bit);
+
+ uint32_t start = initialAreaStartByFlags(_flags);
+ _areaUsed = start;
+ _largestUnusedArea = _areaSize - start;
+ _searchStart = start;
+ _searchEnd = _areaSize;
+
+ addFlags(JitAllocatorBlock::kFlagEmpty);
+ clearFlags(JitAllocatorBlock::kFlagDirty);
}
inline void markAllocatedArea(uint32_t allocatedAreaStart, uint32_t allocatedAreaEnd) noexcept {
@@ -289,21 +323,24 @@ public:
Support::bitVectorSetBit(_stopBitVector, allocatedAreaEnd - 1, true);
// Update search region and statistics.
- _pool->totalAreaUsed += allocatedAreaSize;
+ _pool->totalAreaUsed[size_t(hasLargePages())] += allocatedAreaSize;
_areaUsed += allocatedAreaSize;
if (areaAvailable() == 0) {
_searchStart = _areaSize;
_searchEnd = 0;
_largestUnusedArea = 0;
- clearFlags(kFlagDirty);
+
+ clearFlags(kFlagDirty | kFlagEmpty);
}
else {
if (_searchStart == allocatedAreaStart)
_searchStart = allocatedAreaEnd;
if (_searchEnd == allocatedAreaEnd)
_searchEnd = allocatedAreaStart;
+
addFlags(kFlagDirty);
+ clearFlags(kFlagEmpty);
}
}
@@ -311,7 +348,7 @@ public:
uint32_t releasedAreaSize = releasedAreaEnd - releasedAreaStart;
// Update the search region and statistics.
- _pool->totalAreaUsed -= releasedAreaSize;
+ _pool->totalAreaUsed[size_t(hasLargePages())] -= releasedAreaSize;
_areaUsed -= releasedAreaSize;
_searchStart = Support::min(_searchStart, releasedAreaStart);
_searchEnd = Support::max(_searchEnd, releasedAreaEnd);
@@ -320,10 +357,10 @@ public:
Support::bitVectorClear(_usedBitVector, releasedAreaStart, releasedAreaSize);
Support::bitVectorSetBit(_stopBitVector, releasedAreaEnd - 1, false);
- if (areaUsed() == 0) {
- _searchStart = 0;
+ if (areaUsed() == initialAreaStart()) {
+ _searchStart = initialAreaStart();
_searchEnd = _areaSize;
- _largestUnusedArea = _areaSize;
+ _largestUnusedArea = _areaSize - initialAreaStart();
addFlags(kFlagEmpty);
clearFlags(kFlagDirty);
}
@@ -341,7 +378,7 @@ public:
ASMJIT_ASSERT(shrunkAreaSize != 0);
// Update the search region and statistics.
- _pool->totalAreaUsed -= shrunkAreaSize;
+ _pool->totalAreaUsed[size_t(hasLargePages())] -= shrunkAreaSize;
_areaUsed -= shrunkAreaSize;
_searchStart = Support::min(_searchStart, shrunkAreaStart);
_searchEnd = Support::max(_searchEnd, shrunkAreaEnd);
@@ -411,7 +448,7 @@ static inline JitAllocatorPrivateImpl* JitAllocatorImpl_new(const JitAllocator::
// Setup pool count to [1..3].
size_t poolCount = 1;
if (Support::test(options, JitAllocatorOptions::kUseMultiplePools))
- poolCount = kJitAllocatorMultiPoolCount;;
+ poolCount = kJitAllocatorMultiPoolCount;
// Setup block size [64kB..256MB].
if (blockSize < 64 * 1024 || blockSize > 256 * 1024 * 1024 || !Support::isPowerOf2(blockSize))
@@ -430,8 +467,17 @@ static inline JitAllocatorPrivateImpl* JitAllocatorImpl_new(const JitAllocator::
if (ASMJIT_UNLIKELY(!p))
return nullptr;
+ VirtMem::HardenedRuntimeInfo hardenedRtInfo = VirtMem::hardenedRuntimeInfo();
+ if (Support::test(hardenedRtInfo.flags, VirtMem::HardenedRuntimeFlags::kEnabled)) {
+ // If we are running within a hardened environment (mapping RWX is not allowed) then we have to use dual mapping
+ // or other runtime capabilities like Apple specific MAP_JIT. There is no point in not enabling these as otherwise
+ // the allocation would fail and JitAllocator would not be able to allocate memory.
+ if (!Support::test(hardenedRtInfo.flags, VirtMem::HardenedRuntimeFlags::kMapJit))
+ options |= JitAllocatorOptions::kUseDualMapping;
+ }
+
JitAllocatorPool* pools = reinterpret_cast<JitAllocatorPool*>((uint8_t*)p + sizeof(JitAllocatorPrivateImpl));
- JitAllocatorPrivateImpl* impl = new(p) JitAllocatorPrivateImpl(pools, poolCount);
+ JitAllocatorPrivateImpl* impl = new(Support::PlacementNew{p}) JitAllocatorPrivateImpl(pools, poolCount);
impl->options = options;
impl->blockSize = blockSize;
@@ -440,7 +486,7 @@ static inline JitAllocatorPrivateImpl* JitAllocatorImpl_new(const JitAllocator::
impl->pageSize = vmInfo.pageSize;
for (size_t poolId = 0; poolId < poolCount; poolId++)
- new(&pools[poolId]) JitAllocatorPool(granularity << poolId);
+ new(Support::PlacementNew{&pools[poolId]}) JitAllocatorPool(granularity << poolId);
return impl;
}
@@ -473,6 +519,14 @@ static inline size_t JitAllocatorImpl_calculateIdealBlockSize(JitAllocatorPrivat
JitAllocatorBlock* last = pool->blocks.last();
size_t blockSize = last ? last->blockSize() : size_t(impl->blockSize);
+ // We have to increase the allocationSize if we know that the block must provide padding.
+ if (!Support::test(impl->options, JitAllocatorOptions::kDisableInitialPadding)) {
+ size_t granularity = pool->granularity;
+ if (SIZE_MAX - allocationSize < granularity)
+ return 0; // Overflown
+ allocationSize += granularity;
+ }
+
if (blockSize < kJitAllocatorMaxBlockSize)
blockSize *= 2u;
@@ -485,64 +539,102 @@ static inline size_t JitAllocatorImpl_calculateIdealBlockSize(JitAllocatorPrivat
return blockSize;
}
-ASMJIT_FAVOR_SPEED static void JitAllocatorImpl_fillPattern(void* mem, uint32_t pattern, size_t sizeInBytes) noexcept {
- size_t n = sizeInBytes / 4u;
- uint32_t* p = static_cast<uint32_t*>(mem);
+ASMJIT_NOINLINE
+ASMJIT_FAVOR_SPEED static void JitAllocatorImpl_fillPattern(void* mem, uint32_t pattern, size_t byteSize) noexcept {
+ // NOTE: This is always used to fill a pattern in allocated / freed memory. The allocation has always
+ // a granularity that is greater than the pattern, however, when shrink() is used, we may end up having
+ // an unaligned start, so deal with it here and then copy aligned pattern in the loop.
+ if ((uintptr_t(mem) & 0x1u) && byteSize >= 1u) {
+ static_cast<uint8_t*>(mem)[0] = uint8_t(pattern & 0xFF);
+ mem = static_cast<uint8_t*>(mem) + 1;
+ byteSize--;
+ }
+
+ if ((uintptr_t(mem) & 0x2u) && byteSize >= 2u) {
+ static_cast<uint16_t*>(mem)[0] = uint16_t(pattern & 0xFFFF);
+ mem = static_cast<uint16_t*>(mem) + 1;
+ byteSize -= 2;
+ }
+
+ // Something would be seriously broken if we end up with aligned `mem`, but unaligned `byteSize`.
+ ASMJIT_ASSERT((byteSize & 0x3u) == 0u);
+
+ uint32_t* mem32 = static_cast<uint32_t*>(mem);
+ size_t n = byteSize / 4u;
for (size_t i = 0; i < n; i++)
- p[i] = pattern;
+ mem32[i] = pattern;
}
// Allocate a new `JitAllocatorBlock` for the given `blockSize`.
//
// NOTE: The block doesn't have `kFlagEmpty` flag set, because the new block
// is only allocated when it's actually needed, so it would be cleared anyway.
-static JitAllocatorBlock* JitAllocatorImpl_newBlock(JitAllocatorPrivateImpl* impl, JitAllocatorPool* pool, size_t blockSize) noexcept {
+static Error JitAllocatorImpl_newBlock(JitAllocatorPrivateImpl* impl, JitAllocatorBlock** dst, JitAllocatorPool* pool, size_t blockSize) noexcept {
using Support::BitWord;
using Support::kBitWordSizeInBits;
- uint32_t areaSize = uint32_t((blockSize + pool->granularity - 1) >> pool->granularityLog2);
- uint32_t numBitWords = (areaSize + kBitWordSizeInBits - 1u) / kBitWordSizeInBits;
+ uint32_t blockFlags = 0;
+ if (!Support::test(impl->options, JitAllocatorOptions::kDisableInitialPadding))
+ blockFlags |= JitAllocatorBlock::kFlagInitialPadding;
- JitAllocatorBlock* block = static_cast<JitAllocatorBlock*>(::malloc(sizeof(JitAllocatorBlock)));
- BitWord* bitWords = nullptr;
VirtMem::DualMapping virtMem {};
- Error err = kErrorOutOfMemory;
-
- if (block != nullptr)
- bitWords = static_cast<BitWord*>(::malloc(size_t(numBitWords) * 2 * sizeof(BitWord)));
+ VirtMem::MemoryFlags memFlags = VirtMem::MemoryFlags::kAccessRWX;
- uint32_t blockFlags = 0;
- if (bitWords != nullptr) {
- if (Support::test(impl->options, JitAllocatorOptions::kUseDualMapping)) {
- err = VirtMem::allocDualMapping(&virtMem, blockSize, VirtMem::MemoryFlags::kAccessRWX);
- blockFlags |= JitAllocatorBlock::kFlagDualMapped;
- }
- else {
- err = VirtMem::alloc(&virtMem.rx, blockSize, VirtMem::MemoryFlags::kAccessRWX);
- virtMem.rw = virtMem.rx;
- }
+ if (Support::test(impl->options, JitAllocatorOptions::kUseDualMapping)) {
+ ASMJIT_PROPAGATE(VirtMem::allocDualMapping(&virtMem, blockSize, memFlags));
+ blockFlags |= JitAllocatorBlock::kFlagDualMapped;
}
+ else {
+ bool allocateRegularPages = true;
+ if (Support::test(impl->options, JitAllocatorOptions::kUseLargePages)) {
+ size_t largePageSize = VirtMem::largePageSize();
+ bool tryLargePage = blockSize >= largePageSize || Support::test(impl->options, JitAllocatorOptions::kAlignBlockSizeToLargePage);
+
+ // Only proceed if we can actually allocate large pages.
+ if (largePageSize && tryLargePage) {
+ size_t largeBlockSize = Support::alignUp(blockSize, largePageSize);
+ Error err = VirtMem::alloc(&virtMem.rx, largeBlockSize, memFlags | VirtMem::MemoryFlags::kMMapLargePages);
+
+ // Fallback to regular pages if large page(s) allocation failed.
+ if (err == kErrorOk) {
+ allocateRegularPages = false;
+ blockSize = largeBlockSize;
+ blockFlags |= JitAllocatorBlock::kFlagLargePages;
+ }
+ }
+ }
- // Out of memory.
- if (ASMJIT_UNLIKELY(!block || !bitWords || err != kErrorOk)) {
- if (bitWords)
- ::free(bitWords);
+ // Called either if large pages were not requested or large page(s) allocation failed.
+ if (allocateRegularPages) {
+ ASMJIT_PROPAGATE(VirtMem::alloc(&virtMem.rx, blockSize, memFlags));
+ }
- if (block)
- ::free(block);
+ virtMem.rw = virtMem.rx;
+ }
- return nullptr;
+ uint32_t areaSize = uint32_t((blockSize + pool->granularity - 1) >> pool->granularityLog2);
+ uint32_t numBitWords = (areaSize + kBitWordSizeInBits - 1u) / kBitWordSizeInBits;
+ uint8_t* blockPtr = static_cast<uint8_t*>(::malloc(sizeof(JitAllocatorBlock) + size_t(numBitWords) * 2u * sizeof(BitWord)));
+
+ // Out of memory...
+ if (ASMJIT_UNLIKELY(blockPtr == nullptr)) {
+ if (Support::test(impl->options, JitAllocatorOptions::kUseDualMapping))
+ VirtMem::releaseDualMapping(&virtMem, blockSize);
+ else
+ VirtMem::release(virtMem.rx, blockSize);
+ return DebugUtils::errored(kErrorOutOfMemory);
}
- // Fill the memory if the secure mode is enabled.
+ // Fill the allocated virtual memory if secure mode is enabled.
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);
+ BitWord* bitWords = reinterpret_cast<BitWord*>(blockPtr + sizeof(JitAllocatorBlock));
+ *dst = new(Support::PlacementNew{blockPtr}) JitAllocatorBlock(pool, virtMem, blockSize, blockFlags, bitWords, bitWords + numBitWords, areaSize);
+ return kErrorOk;
}
static void JitAllocatorImpl_deleteBlock(JitAllocatorPrivateImpl* impl, JitAllocatorBlock* block) noexcept {
@@ -553,7 +645,6 @@ static void JitAllocatorImpl_deleteBlock(JitAllocatorPrivateImpl* impl, JitAlloc
else
VirtMem::release(block->rxPtr(), block->blockSize());
- ::free(block->_usedBitVector);
::free(block);
}
@@ -568,8 +659,10 @@ static void JitAllocatorImpl_insertBlock(JitAllocatorPrivateImpl* impl, JitAlloc
pool->blocks.append(block);
// Update statistics.
+ size_t statIndex = size_t(block->hasLargePages());
pool->blockCount++;
- pool->totalAreaSize += block->areaSize();
+ pool->totalAreaSize[statIndex] += block->areaSize();
+ pool->totalAreaUsed[statIndex] += block->areaUsed();
pool->totalOverheadBytes += sizeof(JitAllocatorBlock) + JitAllocatorImpl_bitVectorSizeToByteSize(block->areaSize()) * 2u;
}
@@ -584,8 +677,10 @@ static void JitAllocatorImpl_removeBlock(JitAllocatorPrivateImpl* impl, JitAlloc
pool->blocks.unlink(block);
// Update statistics.
+ size_t statIndex = size_t(block->hasLargePages());
pool->blockCount--;
- pool->totalAreaSize -= block->areaSize();
+ pool->totalAreaSize[statIndex] -= block->areaSize();
+ pool->totalAreaUsed[statIndex] -= block->areaUsed();
pool->totalOverheadBytes -= sizeof(JitAllocatorBlock) + JitAllocatorImpl_bitVectorSizeToByteSize(block->areaSize()) * 2u;
}
@@ -594,12 +689,10 @@ static void JitAllocatorImpl_wipeOutBlock(JitAllocatorPrivateImpl* impl, JitAllo
return;
JitAllocatorPool* pool = block->pool();
- uint32_t areaSize = block->areaSize();
- uint32_t granularity = pool->granularity;
- size_t numBitWords = pool->bitWordCountFromAreaSize(areaSize);
-
- VirtMem::protectJitMemory(VirtMem::ProtectJitAccess::kReadWrite);
if (Support::test(impl->options, JitAllocatorOptions::kFillUnusedMemory)) {
+ VirtMem::protectJitMemory(VirtMem::ProtectJitAccess::kReadWrite);
+
+ uint32_t granularity = pool->granularity;
uint8_t* rwPtr = block->rwPtr();
BitVectorRangeIterator<Support::BitWord, 0> it(block->_usedBitVector, pool->bitWordCountFromAreaSize(block->areaSize()));
@@ -613,18 +706,10 @@ static void JitAllocatorImpl_wipeOutBlock(JitAllocatorPrivateImpl* impl, JitAllo
JitAllocatorImpl_fillPattern(spanPtr, impl->fillPattern, spanSize);
VirtMem::flushInstructionCache(spanPtr, spanSize);
}
+ VirtMem::protectJitMemory(VirtMem::ProtectJitAccess::kReadExecute);
}
- 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));
-
- block->_areaUsed = 0;
- block->_largestUnusedArea = areaSize;
- block->_searchStart = 0;
- block->_searchEnd = areaSize;
- block->addFlags(JitAllocatorBlock::kFlagEmpty);
- block->clearFlags(JitAllocatorBlock::kFlagDirty);
+ block->clearBlock();
}
// JitAllocator - Construction & Destruction
@@ -659,26 +744,28 @@ void JitAllocator::reset(ResetPolicy resetPolicy) noexcept {
JitAllocatorPool& pool = impl->pools[poolId];
JitAllocatorBlock* block = pool.blocks.first();
- JitAllocatorBlock* blockToKeep = nullptr;
- if (resetPolicy != ResetPolicy::kHard && uint32_t(impl->options & JitAllocatorOptions::kImmediateRelease) == 0) {
- blockToKeep = block;
- block = block->next();
- }
+ pool.reset();
- while (block) {
- JitAllocatorBlock* next = block->next();
- JitAllocatorImpl_deleteBlock(impl, block);
- block = next;
- }
+ if (block) {
+ JitAllocatorBlock* blockToKeep = nullptr;
+ if (resetPolicy != ResetPolicy::kHard && uint32_t(impl->options & JitAllocatorOptions::kImmediateRelease) == 0) {
+ blockToKeep = block;
+ block = block->next();
+ }
- pool.reset();
+ while (block) {
+ JitAllocatorBlock* next = block->next();
+ JitAllocatorImpl_deleteBlock(impl, block);
+ block = next;
+ }
- if (blockToKeep) {
- blockToKeep->_listNodes[0] = nullptr;
- blockToKeep->_listNodes[1] = nullptr;
- JitAllocatorImpl_wipeOutBlock(impl, blockToKeep);
- JitAllocatorImpl_insertBlock(impl, blockToKeep);
- pool.emptyBlockCount = 1;
+ if (blockToKeep) {
+ blockToKeep->_listNodes[0] = nullptr;
+ blockToKeep->_listNodes[1] = nullptr;
+ JitAllocatorImpl_wipeOutBlock(impl, blockToKeep);
+ JitAllocatorImpl_insertBlock(impl, blockToKeep);
+ pool.emptyBlockCount = 1;
+ }
}
}
}
@@ -698,8 +785,8 @@ JitAllocator::Statistics JitAllocator::statistics() const noexcept {
for (size_t poolId = 0; poolId < poolCount; poolId++) {
const JitAllocatorPool& pool = impl->pools[poolId];
statistics._blockCount += size_t(pool.blockCount);
- statistics._reservedSize += size_t(pool.totalAreaSize) * pool.granularity;
- statistics._usedSize += size_t(pool.totalAreaUsed) * pool.granularity;
+ statistics._reservedSize += size_t(pool.totalAreaSize[0] + pool.totalAreaSize[1]) * pool.granularity;
+ statistics._usedSize += size_t(pool.totalAreaUsed[0] + pool.totalAreaUsed[1]) * pool.granularity;
statistics._overheadSize += size_t(pool.totalOverheadBytes);
}
@@ -712,16 +799,15 @@ JitAllocator::Statistics JitAllocator::statistics() const noexcept {
// JitAllocator - Alloc & Release
// ==============================
-Error JitAllocator::alloc(void** rxPtrOut, void** rwPtrOut, size_t size) noexcept {
+Error JitAllocator::alloc(Span& out, size_t size) noexcept {
+ out = Span{};
+
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();
- *rxPtrOut = nullptr;
- *rwPtrOut = nullptr;
-
// Align to the minimum granularity by default.
size = Support::alignUp<size_t>(size, impl->granularity);
if (ASMJIT_UNLIKELY(size == 0))
@@ -783,21 +869,18 @@ Error JitAllocator::alloc(void** rxPtrOut, void** rwPtrOut, size_t size) noexcep
} while (block != initial);
}
- // Allocate a new block if there is no region of a required width.
+ // Allocate a new block if there is no region of a required size.
if (areaIndex == kNoIndex) {
size_t blockSize = JitAllocatorImpl_calculateIdealBlockSize(impl, pool, size);
if (ASMJIT_UNLIKELY(!blockSize))
return DebugUtils::errored(kErrorOutOfMemory);
- block = JitAllocatorImpl_newBlock(impl, pool, blockSize);
- areaIndex = 0;
-
- if (ASMJIT_UNLIKELY(!block))
- return DebugUtils::errored(kErrorOutOfMemory);
+ ASMJIT_PROPAGATE(JitAllocatorImpl_newBlock(impl, &block, pool, blockSize));
+ areaIndex = block->initialAreaStart();
JitAllocatorImpl_insertBlock(impl, block);
- block->_searchStart = areaSize;
- block->_largestUnusedArea = block->areaSize() - areaSize;
+ block->_searchStart += areaSize;
+ block->_largestUnusedArea -= areaSize;
}
else if (block->hasFlag(JitAllocatorBlock::kFlagEmpty)) {
pool->emptyBlockCount--;
@@ -808,32 +891,35 @@ Error JitAllocator::alloc(void** rxPtrOut, void** rwPtrOut, size_t size) noexcep
impl->allocationCount++;
block->markAllocatedArea(areaIndex, areaIndex + areaSize);
- // Return a pointer to the allocated memory.
+ // Return a span referencing the allocated memory.
size_t offset = pool->byteSizeFromAreaSize(areaIndex);
ASMJIT_ASSERT(offset <= block->blockSize() - size);
- *rxPtrOut = block->rxPtr() + offset;
- *rwPtrOut = block->rwPtr() + offset;
+ out._rx = block->rxPtr() + offset;
+ out._rw = block->rwPtr() + offset;
+ out._size = size;
+ out._block = static_cast<void*>(block);
+
return kErrorOk;
}
-Error JitAllocator::release(void* rxPtr) noexcept {
+Error JitAllocator::release(void* rx) noexcept {
if (ASMJIT_UNLIKELY(_impl == &JitAllocatorImpl_none))
return DebugUtils::errored(kErrorNotInitialized);
- if (ASMJIT_UNLIKELY(!rxPtr))
+ if (ASMJIT_UNLIKELY(!rx))
return DebugUtils::errored(kErrorInvalidArgument);
JitAllocatorPrivateImpl* impl = static_cast<JitAllocatorPrivateImpl*>(_impl);
LockGuard guard(impl->lock);
- JitAllocatorBlock* block = impl->tree.get(static_cast<uint8_t*>(rxPtr));
+ JitAllocatorBlock* block = impl->tree.get(static_cast<uint8_t*>(rx));
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*)rxPtr - block->rxPtr());
+ size_t offset = (size_t)((uint8_t*)rx - block->rxPtr());
// The first bit representing the allocated area and its size.
uint32_t areaIndex = uint32_t(offset >> pool->granularityLog2);
@@ -853,7 +939,7 @@ Error JitAllocator::release(void* rxPtr) noexcept {
}
// Release the whole block if it became empty.
- if (block->areaUsed() == 0) {
+ if (block->empty()) {
if (pool->emptyBlockCount || Support::test(impl->options, JitAllocatorOptions::kImmediateRelease)) {
JitAllocatorImpl_removeBlock(impl, block);
JitAllocatorImpl_deleteBlock(impl, block);
@@ -866,49 +952,196 @@ Error JitAllocator::release(void* rxPtr) noexcept {
return kErrorOk;
}
-Error JitAllocator::shrink(void* rxPtr, size_t newSize) noexcept {
+static Error JitAllocatorImpl_shrink(JitAllocatorPrivateImpl* impl, JitAllocator::Span& span, size_t newSize, bool alreadyUnderWriteScope) noexcept {
+ JitAllocatorBlock* block = static_cast<JitAllocatorBlock*>(span._block);
+ if (ASMJIT_UNLIKELY(!block))
+ return DebugUtils::errored(kErrorInvalidArgument);
+
+ LockGuard guard(impl->lock);
+
+ // Offset relative to the start of the block.
+ JitAllocatorPool* pool = block->pool();
+ size_t offset = (size_t)((uint8_t*)span.rx() - block->rxPtr());
+
+ // The first bit representing the allocated area and its size.
+ uint32_t areaStart = uint32_t(offset >> pool->granularityLog2);
+
+ // Don't trust `span.size()` - if it has been already truncated we would be off...
+ bool isUsed = Support::bitVectorGetBit(block->_usedBitVector, areaStart);
+ if (ASMJIT_UNLIKELY(!isUsed))
+ return DebugUtils::errored(kErrorInvalidArgument);
+
+ uint32_t areaEnd = uint32_t(Support::bitVectorIndexOf(block->_stopBitVector, areaStart, true)) + 1;
+ uint32_t areaPrevSize = areaEnd - areaStart;
+ uint32_t spanPrevSize = areaPrevSize * pool->granularity;
+ uint32_t areaShrunkSize = pool->areaSizeFromByteSize(newSize);
+
+ if (ASMJIT_UNLIKELY(areaShrunkSize > areaPrevSize))
+ return DebugUtils::errored(kErrorInvalidArgument);
+
+ uint32_t areaDiff = areaPrevSize - areaShrunkSize;
+ if (areaDiff) {
+ block->markShrunkArea(areaStart + areaShrunkSize, areaEnd);
+ span._size = pool->byteSizeFromAreaSize(areaShrunkSize);
+ }
+
+ // Fill released memory if the secure mode is enabled.
+ if (newSize < spanPrevSize && Support::test(impl->options, JitAllocatorOptions::kFillUnusedMemory)) {
+ uint8_t* spanPtr = block->rwPtr() + (areaStart + areaShrunkSize) * pool->granularity;
+ size_t spanSize = areaDiff * pool->granularity;
+
+ if (!alreadyUnderWriteScope) {
+ VirtMem::ProtectJitReadWriteScope scope(spanPtr, spanSize, VirtMem::CachePolicy::kNeverFlush);
+ JitAllocatorImpl_fillPattern(spanPtr, impl->fillPattern, spanSize);
+ }
+ else {
+ JitAllocatorImpl_fillPattern(spanPtr, impl->fillPattern, spanSize);
+ }
+ }
+
+ return kErrorOk;
+}
+
+Error JitAllocator::shrink(Span& span, size_t newSize) noexcept {
if (ASMJIT_UNLIKELY(_impl == &JitAllocatorImpl_none))
return DebugUtils::errored(kErrorNotInitialized);
- if (ASMJIT_UNLIKELY(!rxPtr))
+ if (ASMJIT_UNLIKELY(!span.rx()))
return DebugUtils::errored(kErrorInvalidArgument);
- if (ASMJIT_UNLIKELY(newSize == 0))
- return release(rxPtr);
+ if (ASMJIT_UNLIKELY(newSize == 0)) {
+ Error err = release(span.rx());
+ span = Span{};
+ return err;
+ }
+
+ return JitAllocatorImpl_shrink(static_cast<JitAllocatorPrivateImpl*>(_impl), span, newSize, false);
+}
+
+Error JitAllocator::query(Span& out, void* rx) const noexcept {
+ out = Span{};
+
+ if (ASMJIT_UNLIKELY(_impl == &JitAllocatorImpl_none))
+ return DebugUtils::errored(kErrorNotInitialized);
JitAllocatorPrivateImpl* impl = static_cast<JitAllocatorPrivateImpl*>(_impl);
LockGuard guard(impl->lock);
- JitAllocatorBlock* block = impl->tree.get(static_cast<uint8_t*>(rxPtr));
+ JitAllocatorBlock* block = impl->tree.get(static_cast<uint8_t*>(rx));
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*)rxPtr - block->rxPtr());
+ size_t offset = (size_t)((uint8_t*)rx - block->rxPtr());
// The first bit representing the allocated area and its size.
uint32_t areaStart = uint32_t(offset >> pool->granularityLog2);
+
+ bool isUsed = Support::bitVectorGetBit(block->_usedBitVector, areaStart);
+ if (ASMJIT_UNLIKELY(!isUsed))
+ return DebugUtils::errored(kErrorInvalidArgument);
+
uint32_t areaEnd = uint32_t(Support::bitVectorIndexOf(block->_stopBitVector, areaStart, true)) + 1;
+ size_t byteOffset = pool->byteSizeFromAreaSize(areaStart);
+ size_t byteSize = pool->byteSizeFromAreaSize(areaEnd - areaStart);
- uint32_t areaPrevSize = areaEnd - areaStart;
- uint32_t areaShrunkSize = pool->areaSizeFromByteSize(newSize);
+ out._rx = static_cast<uint8_t*>(block->_mapping.rx) + byteOffset;
+ out._rw = static_cast<uint8_t*>(block->_mapping.rw) + byteOffset;
+ out._size = byteSize;
+ out._block = static_cast<void*>(block);
- if (ASMJIT_UNLIKELY(areaShrunkSize > areaPrevSize))
- return DebugUtils::errored(kErrorInvalidState);
+ return kErrorOk;
+}
- uint32_t areaDiff = areaPrevSize - areaShrunkSize;
- if (areaDiff) {
- block->markShrunkArea(areaStart + areaShrunkSize, areaEnd);
+// JitAllocator - Write
+// ====================
- // Fill released memory if the secure mode is enabled.
- if (Support::test(impl->options, JitAllocatorOptions::kFillUnusedMemory))
- JitAllocatorImpl_fillPattern(block->rwPtr() + (areaStart + areaShrunkSize) * pool->granularity, fillPattern(), areaDiff * pool->granularity);
+static ASMJIT_FORCE_INLINE VirtMem::CachePolicy JitAllocator_defaultPolicyForSpan(const JitAllocator::Span& span) noexcept {
+ if (Support::test(span.flags(), JitAllocator::Span::Flags::kInstructionCacheClean))
+ return VirtMem::CachePolicy::kNeverFlush;
+ else
+ return VirtMem::CachePolicy::kFlushAfterWrite;
+}
+
+Error JitAllocator::write(Span& span, size_t offset, const void* src, size_t size, VirtMem::CachePolicy policy) noexcept {
+ if (ASMJIT_UNLIKELY(span._block == nullptr || offset > span.size() || span.size() - offset < size))
+ return DebugUtils::errored(kErrorInvalidArgument);
+
+ if (ASMJIT_UNLIKELY(size == 0))
+ return kErrorOk;
+
+ if (policy == VirtMem::CachePolicy::kDefault)
+ policy = JitAllocator_defaultPolicyForSpan(span);
+
+ VirtMem::ProtectJitReadWriteScope writeScope(span.rx(), span.size(), policy);
+ memcpy(static_cast<uint8_t*>(span.rw()) + offset, src, size);
+ return kErrorOk;
+}
+
+Error JitAllocator::write(Span& span, WriteFunc writeFunc, void* userData, VirtMem::CachePolicy policy) noexcept {
+ if (ASMJIT_UNLIKELY(span._block == nullptr) || span.size() == 0)
+ return DebugUtils::errored(kErrorInvalidArgument);
+
+ size_t size = span.size();
+ if (ASMJIT_UNLIKELY(size == 0))
+ return kErrorOk;
+
+ if (policy == VirtMem::CachePolicy::kDefault)
+ policy = JitAllocator_defaultPolicyForSpan(span);
+
+ VirtMem::ProtectJitReadWriteScope writeScope(span.rx(), span.size(), policy);
+ ASMJIT_PROPAGATE(writeFunc(span, userData));
+
+ // Check whether span.truncate() has been called.
+ if (span.size() != size) {
+ // OK, this is a bit awkward... However, shrink wants the original span and newSize, so we have to swap.
+ std::swap(span._size, size);
+ return JitAllocatorImpl_shrink(static_cast<JitAllocatorPrivateImpl*>(_impl), span, size, true);
}
return kErrorOk;
}
+// JitAllocator - Write Scope
+// ==========================
+
+Error JitAllocator::beginWriteScope(WriteScopeData& scope, VirtMem::CachePolicy policy) noexcept {
+ scope._allocator = this;
+ scope._data[0] = size_t(policy);
+ return kErrorOk;
+}
+
+Error JitAllocator::endWriteScope(WriteScopeData& scope) noexcept {
+ if (ASMJIT_UNLIKELY(!scope._allocator))
+ return DebugUtils::errored(kErrorInvalidArgument);
+
+ return kErrorOk;
+}
+
+Error JitAllocator::flushWriteScope(WriteScopeData& scope) noexcept {
+ if (ASMJIT_UNLIKELY(!scope._allocator))
+ return DebugUtils::errored(kErrorInvalidArgument);
+
+ return kErrorOk;
+}
+
+Error JitAllocator::scopedWrite(WriteScopeData& scope, Span& span, size_t offset, const void* src, size_t size) noexcept {
+ if (ASMJIT_UNLIKELY(!scope._allocator))
+ return DebugUtils::errored(kErrorInvalidArgument);
+
+ VirtMem::CachePolicy policy = VirtMem::CachePolicy(scope._data[0]);
+ return scope._allocator->write(span, offset, src, size, policy);
+}
+
+Error JitAllocator::scopedWrite(WriteScopeData& scope, Span& span, WriteFunc writeFunc, void* userData) noexcept {
+ if (ASMJIT_UNLIKELY(!scope._allocator))
+ return DebugUtils::errored(kErrorInvalidArgument);
+
+ VirtMem::CachePolicy policy = VirtMem::CachePolicy(scope._data[0]);
+ return scope._allocator->write(span, writeFunc, userData, policy);
+}
+
// JitAllocator - Tests
// ====================
@@ -963,6 +1196,34 @@ public:
uint64_t _state[2];
};
+namespace JitAllocatorUtils {
+ static void fillPattern64(void* p_, uint64_t pattern, size_t sizeInBytes) noexcept {
+ uint64_t* p = static_cast<uint64_t*>(p_);
+ size_t n = sizeInBytes / 8u;
+
+ for (size_t i = 0; i < n; i++)
+ p[i] = pattern;
+ }
+
+ static bool verifyPattern64(const void* p_, uint64_t pattern, size_t sizeInBytes) noexcept {
+ const uint64_t* p = static_cast<const uint64_t*>(p_);
+ size_t n = sizeInBytes / 8u;
+
+ for (size_t i = 0; i < n; i++) {
+ if (p[i] != pattern) {
+ INFO("Pattern verification failed at 0x%p [%zu * 8]: value(0x%016llX) != expected(0x%016llX)",
+ p,
+ i,
+ (unsigned long long)p[i],
+ (unsigned long long)pattern);
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
+
// Helper class to verify that JitAllocator doesn't return addresses that overlap.
class JitAllocatorWrapper {
public:
@@ -980,9 +1241,19 @@ public:
class Record : public ZoneTreeNodeT<Record>,
public Range {
public:
- inline Record(uint8_t* addr, size_t size)
+ //! Read/write address, in case this is a dual mapping.
+ void* _rw;
+ //! Describes a pattern used to fill the allocated memory.
+ uint64_t pattern;
+
+ inline Record(void* rx, void* rw, size_t size, uint64_t pattern)
: ZoneTreeNodeT<Record>(),
- Range(addr, size) {}
+ Range(static_cast<uint8_t*>(rx), size),
+ _rw(rw),
+ pattern(pattern) {}
+
+ inline void* rx() const noexcept { return addr; }
+ inline void* rw() const noexcept { return _rw; }
inline bool operator<(const Record& other) const noexcept { return addr < other.addr; }
inline bool operator>(const Record& other) const noexcept { return addr > other.addr; }
@@ -995,65 +1266,82 @@ public:
ZoneAllocator _heap;
ZoneTree<Record> _records;
JitAllocator _allocator;
+ Random _rng;
explicit JitAllocatorWrapper(const JitAllocator::CreateParams* params) noexcept
: _zone(1024 * 1024),
_heap(&_zone),
- _allocator(params) {}
+ _allocator(params),
+ _rng(0x123456789u) {}
- void _insert(void* p_, size_t size) noexcept {
- uint8_t* p = static_cast<uint8_t*>(p_);
+ void _insert(void* pRX, void* pRW, size_t size) noexcept {
+ uint8_t* p = static_cast<uint8_t*>(pRX);
uint8_t* pEnd = p + size - 1;
Record* record;
record = _records.get(p);
- if (record)
- EXPECT(record == nullptr, "Address [%p:%p] collides with a newly allocated [%p:%p]\n", record->addr, record->addr + record->size, p, p + size);
+ EXPECT_NULL(record)
+ .message("Address [%p:%p] collides with a newly allocated [%p:%p]\n", record->addr, record->addr + record->size, p, p + size);
record = _records.get(pEnd);
- if (record)
- EXPECT(record == nullptr, "Address [%p:%p] collides with a newly allocated [%p:%p]\n", record->addr, record->addr + record->size, p, p + size);
+ EXPECT_NULL(record)
+ .message("Address [%p:%p] collides with a newly allocated [%p:%p]\n", record->addr, record->addr + record->size, p, p + size);
+
+ uint64_t pattern = _rng.nextUInt64();
+ record = _heap.newT<Record>(pRX, pRW, size, pattern);
+ EXPECT_NOT_NULL(record);
+
+ {
+ VirtMem::ProtectJitReadWriteScope scope(pRW, size);
+ JitAllocatorUtils::fillPattern64(pRW, pattern, size);
+ }
- record = _heap.newT<Record>(p, size);
- EXPECT(record != nullptr, "Out of memory, cannot allocate 'Record'");
+ VirtMem::flushInstructionCache(pRX, size);
+ EXPECT_TRUE(JitAllocatorUtils::verifyPattern64(pRX, pattern, size));
_records.insert(record);
}
void _remove(void* p) noexcept {
Record* record = _records.get(static_cast<uint8_t*>(p));
- EXPECT(record != nullptr, "Address [%p] doesn't exist\n", p);
+ EXPECT_NOT_NULL(record);
+
+ EXPECT_TRUE(JitAllocatorUtils::verifyPattern64(record->rx(), record->pattern, record->size));
+ EXPECT_TRUE(JitAllocatorUtils::verifyPattern64(record->rw(), record->pattern, record->size));
_records.remove(record);
_heap.release(record, sizeof(Record));
}
void* alloc(size_t size) noexcept {
- void* rxPtr;
- void* rwPtr;
-
- Error err = _allocator.alloc(&rxPtr, &rwPtr, size);
- EXPECT(err == kErrorOk, "JitAllocator failed to allocate %zu bytes\n", size);
+ JitAllocator::Span span;
+ Error err = _allocator.alloc(span, size);
+ EXPECT_EQ(err, kErrorOk)
+ .message("JitAllocator failed to allocate %zu bytes\n", size);
- _insert(rxPtr, size);
- return rxPtr;
+ _insert(span.rx(), span.rw(), size);
+ return span.rx();
}
void release(void* p) noexcept {
_remove(p);
- EXPECT(_allocator.release(p) == kErrorOk, "JitAllocator failed to release '%p'\n", p);
+ EXPECT_EQ(_allocator.release(p), kErrorOk)
+ .message("JitAllocator failed to release '%p'\n", p);
}
void shrink(void* p, size_t newSize) noexcept {
Record* record = _records.get(static_cast<uint8_t*>(p));
- EXPECT(record != nullptr, "Address [%p] doesn't exist\n", p);
+ EXPECT_NOT_NULL(record);
if (!newSize)
return release(p);
- Error err = _allocator.shrink(p, newSize);
- EXPECT(err == kErrorOk, "JitAllocator failed to shrink %p to %zu bytes\n", p, newSize);
+ JitAllocator::Span span;
+ EXPECT_EQ(_allocator.query(span, p), kErrorOk);
+ Error err = _allocator.shrink(span, newSize);
+ EXPECT_EQ(err, kErrorOk)
+ .message("JitAllocator failed to shrink %p to %zu bytes\n", p, newSize);
record->size = newSize;
}
@@ -1095,13 +1383,19 @@ 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_EQ(in[j], out[j])
+ .message("Invalid pattern detected at [%zu] (%llX != %llX)", j, (unsigned long long)in[j], (unsigned long long)out[j]);
}
}
}
-UNIT(jit_allocator) {
- size_t kCount = BrokenAPI::hasArg("--quick") ? 1000 : 100000;
+static void test_jit_allocator_reset_empty() noexcept {
+ JitAllocator allocator;
+ allocator.reset(ResetPolicy::kSoft);
+}
+
+static void test_jit_allocator_alloc_release() noexcept {
+ size_t kCount = BrokenAPI::hasArg("--quick") ? 20000 : 100000;
struct TestParams {
const char* name;
@@ -1110,15 +1404,23 @@ UNIT(jit_allocator) {
uint32_t granularity;
};
- static TestParams testParams[] = {
- { "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 }
+ using Opt = JitAllocatorOptions;
+
+ VirtMem::HardenedRuntimeInfo hri = VirtMem::hardenedRuntimeInfo();
+
+ TestParams testParams[] = {
+ { "Default" , Opt::kNone, 0, 0 },
+ { "16MB blocks" , Opt::kNone, 16 * 1024 * 1024, 0 },
+ { "256B granularity" , Opt::kNone, 0, 256 },
+ { "kUseMultiplePools" , Opt::kUseMultiplePools, 0, 0 },
+ { "kFillUnusedMemory" , Opt::kFillUnusedMemory, 0, 0 },
+ { "kImmediateRelease" , Opt::kImmediateRelease, 0, 0 },
+ { "kDisableInitialPadding" , Opt::kDisableInitialPadding, 0, 0 },
+ { "kUseLargePages" , Opt::kUseLargePages, 0, 0 },
+ { "kUseLargePages | kFillUnusedMemory" , Opt::kUseLargePages | Opt::kFillUnusedMemory, 0, 0 },
+ { "kUseLargePages | kAlignBlockSizeToLargePage", Opt::kUseLargePages | Opt::kAlignBlockSizeToLargePage, 0, 0 },
+ { "kUseDualMapping" , Opt::kUseDualMapping , 0, 0 },
+ { "kUseDualMapping | kFillUnusedMemory" , Opt::kUseDualMapping | Opt::kFillUnusedMemory, 0, 0 }
};
INFO("BitVectorRangeIterator<uint32_t>");
@@ -1134,6 +1436,12 @@ UNIT(jit_allocator) {
}
for (uint32_t testId = 0; testId < ASMJIT_ARRAY_SIZE(testParams); testId++) {
+ // Don't try to allocate dual-mapping if dual mapping is not possible - it would fail the test.
+ if (Support::test(testParams[testId].options, JitAllocatorOptions::kUseDualMapping) &&
+ !Support::test(hri.flags, VirtMem::HardenedRuntimeFlags::kDualMapping)) {
+ continue;
+ }
+
INFO("JitAllocator(%s)", testParams[testId].name);
JitAllocator::CreateParams params {};
@@ -1151,8 +1459,7 @@ UNIT(jit_allocator) {
INFO(" Memory alloc/release test - %d allocations", kCount);
void** ptrArray = (void**)::malloc(sizeof(void*) * size_t(kCount));
- EXPECT(ptrArray != nullptr,
- "Couldn't allocate '%u' bytes for pointer-array", unsigned(sizeof(void*) * size_t(kCount)));
+ EXPECT_NOT_NULL(ptrArray);
// Random blocks tests...
INFO(" Allocating random blocks...");
@@ -1235,8 +1542,30 @@ UNIT(jit_allocator) {
::free(ptrArray);
}
}
-#endif
+
+static void test_jit_allocator_query() noexcept {
+ JitAllocator allocator;
+ size_t allocatedSize = 100;
+
+ JitAllocator::Span allocatedSpan;
+ EXPECT_EQ(allocator.alloc(allocatedSpan, allocatedSize), kErrorOk);
+ EXPECT_NOT_NULL(allocatedSpan.rx());
+ EXPECT_GE(allocatedSpan.size(), allocatedSize);
+
+ JitAllocator::Span queriedSpan;
+ EXPECT_EQ(allocator.query(queriedSpan, allocatedSpan.rx()), kErrorOk);
+ EXPECT_EQ(allocatedSpan.rx(), queriedSpan.rx());
+ EXPECT_EQ(allocatedSpan.rw(), queriedSpan.rw());
+ EXPECT_EQ(allocatedSpan.size(), queriedSpan.size());
+}
+
+UNIT(jit_allocator) {
+ test_jit_allocator_reset_empty();
+ test_jit_allocator_alloc_release();
+ test_jit_allocator_query();
+}
+#endif // ASMJIT_TEST
ASMJIT_END_NAMESPACE
-#endif
+#endif // !ASMJIT_NO_JIT
diff --git a/3rdparty/asmjit/src/asmjit/core/jitallocator.h b/3rdparty/asmjit/src/asmjit/core/jitallocator.h
index e8fe69519ee..b694f8cd535 100644
--- a/3rdparty/asmjit/src/asmjit/core/jitallocator.h
+++ b/3rdparty/asmjit/src/asmjit/core/jitallocator.h
@@ -10,6 +10,7 @@
#ifndef ASMJIT_NO_JIT
#include "../core/globals.h"
+#include "../core/support.h"
#include "../core/virtmem.h"
ASMJIT_BEGIN_NAMESPACE
@@ -26,6 +27,10 @@ enum class JitAllocatorOptions : uint32_t {
//! 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.
+ //!
+ //! \remarks Dual mapping would be automatically turned on by \ref JitAllocator in case of hardened runtime that
+ //! enforces `W^X` policy, so specifying this flag is essentially forcing to use dual mapped pages even when RWX
+ //! pages can be allocated and dual mapping is not necessary.
kUseDualMapping = 0x00000001u,
//! Enables the use of multiple pools with increasing granularity instead of a single pool. This flag would enable
@@ -50,6 +55,40 @@ enum class JitAllocatorOptions : uint32_t {
//! or have all blocks fully occupied.
kImmediateRelease = 0x00000008u,
+ //! This flag enables placing functions (or allocating memory) at the very beginning of each memory mapped region.
+ //!
+ //! Initially, this was the default behavior. However, LLVM developers working on undefined behavior sanitizer
+ //! (UBSAN) decided that they want to store metadata before each function and to access such metadata before an
+ //! indirect function call. This means that the instrumented code always reads from `[fnPtr - 8]` to decode whether
+ //! the function has his metadata present. However, reading 8 bytes below a function means that if a function is
+ //! placed at the very beginning of a memory mapped region, it could try to read bytes that are inaccessible. And
+ //! since AsmJit can be compiled as a shared library and used by applications instrumented by UBSAN, it's not
+ //! possible to conditionally compile the support only when necessary.
+ //!
+ //! \remarks This flag controls a workaround to make it possible to use LLVM UBSAN with AsmJit's \ref JitAllocator.
+ //! There is no undefined behavior even when `kDisableInitialPadding` is used, however, that doesn't really matter
+ //! as LLVM's UBSAN introduces one, and according to LLVM developers it's a "trade-off". This flag is safe to use
+ //! when the code is not instrumented with LLVM's UBSAN.
+ kDisableInitialPadding = 0x00000010u,
+
+ //! Enables the use of large pages, if they are supported and the process can actually allocate them.
+ //!
+ //! \remarks This flag is a hint - if large pages can be allocated, JitAllocator would try to allocate them.
+ //! However, if the allocation fails, it will still try to fallback to use regular pages as \ref JitAllocator
+ //! is designed to minimize allocation failures, so a regular page is better than no page at all. Also, if a
+ //! block \ref JitAllocator wants to allocate is too small to consume a whole large page, regular page(s) will
+ //! be allocated as well.
+ kUseLargePages = 0x00000020u,
+
+ //! Forces \ref JitAllocator to always align block size to be at least as big as a large page, if large pages are
+ //! enabled. This option does nothing if large pages are disabled.
+ //!
+ //! \remarks If \ref kUseLargePages option is used, the allocator would prefer large pages only when allocating a
+ //! block that has a sufficient size. Usually the allocator first allocates smaller block and when more requests
+ //! come it will start increasing the block size of next allocations. This option makes it sure that even the first
+ //! allocation would be the same as a minimum large page when large pages are enabled and can be allocated.
+ kAlignBlockSizeToLargePage = 0x00000040u,
+
//! Use a custom fill pattern, must be combined with `kFlagFillUnusedMemory`.
kCustomFillPattern = 0x10000000u
};
@@ -75,6 +114,7 @@ class JitAllocator {
public:
ASMJIT_NONCOPYABLE(JitAllocator)
+ //! Visible \ref JitAllocator implementation data.
struct Impl {
//! Allocator options.
JitAllocatorOptions options;
@@ -86,9 +126,14 @@ public:
uint32_t fillPattern;
};
+ //! \name Members
+ //! \{
+
//! Allocator implementation (private).
Impl* _impl;
+ //! \}
+
//! \name Construction & Destruction
//! \{
@@ -129,7 +174,7 @@ public:
uint32_t fillPattern = 0;
// Reset the content of `CreateParams`.
- inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
+ ASMJIT_INLINE_NODEBUG void reset() noexcept { *this = CreateParams{}; }
};
//! Creates a `JitAllocator` instance.
@@ -137,7 +182,7 @@ public:
//! Destroys the `JitAllocator` instance and release all blocks held.
ASMJIT_API ~JitAllocator() noexcept;
- inline bool isInitialized() const noexcept { return _impl->blockSize == 0; }
+ ASMJIT_INLINE_NODEBUG bool isInitialized() const noexcept { return _impl->blockSize == 0; }
//! Free all allocated memory - makes all pointers returned by `alloc()` invalid.
//!
@@ -151,47 +196,315 @@ public:
//! \{
//! Returns allocator options, see `Flags`.
- inline JitAllocatorOptions options() const noexcept { return _impl->options; }
+ ASMJIT_INLINE_NODEBUG JitAllocatorOptions options() const noexcept { return _impl->options; }
//! Tests whether the allocator has the given `option` set.
- inline bool hasOption(JitAllocatorOptions option) const noexcept { return uint32_t(_impl->options & option) != 0; }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG uint32_t blockSize() const noexcept { return _impl->blockSize; }
//! Returns granularity of the allocator.
- inline uint32_t granularity() const noexcept { return _impl->granularity; }
+ ASMJIT_INLINE_NODEBUG uint32_t granularity() const noexcept { return _impl->granularity; }
//! Returns pattern that is used to fill unused memory if `kFlagUseFillPattern` is set.
- inline uint32_t fillPattern() const noexcept { return _impl->fillPattern; }
+ ASMJIT_INLINE_NODEBUG uint32_t fillPattern() const noexcept { return _impl->fillPattern; }
//! \}
//! \name Alloc & Release
//! \{
- //! Allocates a new memory block of the requested `size`.
+ //! A memory reference returned by \ref JitAllocator::alloc().
//!
- //! 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;
+ //! Span contains everything needed to actually write new code to the memory chunk it references.
+ class Span {
+ public:
+ //! \name Constants
+ //! \{
+
+ //! Span flags
+ enum class Flags : uint32_t {
+ //! No flags.
+ kNone = 0u,
+
+ //! The process has never executed the region of the span.
+ //!
+ //! If this flag is set on a \ref Span it would mean that the allocator can avoid flushing
+ //! instruction cache after a code has been written to it.
+ kInstructionCacheClean = 0x00000001u
+ };
+
+ //! \}
+
+ //! \name Members
+ //! \{
+
+ //! Address of memory that has Read and Execute permissions.
+ void* _rx = nullptr;
+
+ //! Address of memory that has Read and Write permissions.
+ void* _rw = nullptr;
+
+ //! Size of the span in bytes (rounded up to the allocation granularity).
+ size_t _size = 0;
+
+ //! Pointer that references a memory block maintained by \ref JitAllocator.
+ //!
+ //! This pointer is considered private and should never be used nor inspected outside of AsmJit.
+ void* _block = nullptr;
+
+ //! Span flags.
+ Flags _flags = Flags::kNone;
+
+ //! Reserved for future use.
+ uint32_t _reserved = 0;
+
+ //! \}
+
+ //! \name Accessors
+ //! \{
+
+ //! Returns a pointer having Read & Execute permissions (references executable memory).
+ //!
+ //! This pointer is never NULL if the allocation succeeded, it points to an executable memory.
+ ASMJIT_INLINE_NODEBUG void* rx() const noexcept { return _rx; }
+
+ //! Returns a pointer having Read & Write permissions (references writable memory).
+ //!
+ //! Depending on the type of the allocation strategy this could either be:
+ //!
+ //! - the same address as returned by `rx()` if the allocator uses RWX mapping (pages have all of Read, Write,
+ //! and Execute permissions) or MAP_JIT, which requires either \ref VirtMem::ProtectJitReadWriteScope or to
+ //! call \ref VirtMem::protectJitMemory() manually.
+ //! - a valid pointer, but not the same as `rx` - this would be valid if dual mapping is used.
+ //! - NULL pointer, in case that the allocation strategy doesn't use RWX, MAP_JIT, or dual mapping. In this
+ //! case only \ref JitAllocator can copy new code into the executable memory referenced by \ref Span.
+ //!
+ //! \note If `rw()` returns a non-null pointer it's important to use either VirtMem::protectJitMemory() or
+ //! \ref VirtMem::ProtectJitReadWriteScope to guard the write, because in case of `MAP_JIT` it would temporarily
+ //! switch the permissions of the pointer to RW (that's per thread permissions).
+ //!
+ //! If \ref VirtMem::ProtectJitReadWriteScope is not used it's important to clear the instruction cache via
+ //! \ref VirtMem::flushInstructionCache() after the write is done.
+ ASMJIT_INLINE_NODEBUG void* rw() const noexcept { return _rw; }
+
+ //! Returns size of this span, aligned to the allocator granularity.
+ ASMJIT_INLINE_NODEBUG size_t size() const noexcept { return _size; }
+
+ //! Returns span flags.
+ ASMJIT_INLINE_NODEBUG Flags flags() const noexcept { return _flags; }
+
+ //! Shrinks this span to `newSize`.
+ //!
+ //! \note This is the only function that is able to change the size of a span, and it's only use case is to
+ //! shrink the span size during \ref JitAllocator::write(). When the writer detects that the span size shrunk,
+ //! it will automatically shrink the memory used by the span, and propagate the new aligned size to the caller.
+ ASMJIT_INLINE_NODEBUG void shrink(size_t newSize) noexcept { _size = Support::min(_size, newSize); }
+
+ //! Returns whether \ref rw() returns a non-null pointer.
+ ASMJIT_INLINE_NODEBUG bool isDirectlyWritable() const noexcept { return _rw != nullptr; }
+
+ //! \}
+ };
+
+ //! Allocates a new memory span of the requested `size`.
+ ASMJIT_API Error alloc(Span& out, size_t size) noexcept;
//! Releases a memory block returned by `alloc()`.
//!
//! \remarks This function is thread-safe.
- ASMJIT_API Error release(void* rxPtr) noexcept;
+ ASMJIT_API Error release(void* rx) noexcept;
- //! Frees extra memory allocated with `rxPtr` by shrinking it to the given `newSize`.
+ //! Frees extra memory allocated with `rx` by shrinking it to the given `newSize`.
//!
//! \remarks This function is thread-safe.
- ASMJIT_API Error shrink(void* rxPtr, size_t newSize) noexcept;
+ ASMJIT_API Error shrink(Span& span, size_t newSize) noexcept;
- //! Queries information about an allocated memory block that contains the given `rxPtr`.
+ //! Queries information about an allocated memory block that contains the given `rx`, and writes it to `out`.
//!
- //! 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;
+ //! If the pointer is matched, the function returns `kErrorOk` and fills `out` with the corresponding span.
+ ASMJIT_API Error query(Span& out, void* rx) const noexcept;
+
+#if !defined(ASMJIT_NO_DEPRECATED)
+ //! Allocates a new memory block of the requested `size`.
+ ASMJIT_DEPRECATED("Use alloc(Span& out, size_t size) instead")
+ ASMJIT_FORCE_INLINE Error alloc(void** rxPtrOut, void** rwPtrOut, size_t size) noexcept {
+ Span span;
+ Error err = alloc(span, size);
+ *rwPtrOut = span.rw();
+ *rxPtrOut = span.rx();
+ return err;
+ }
+
+ ASMJIT_DEPRECATED("Use shrink(Span& span, size_t newSize) instead")
+ ASMJIT_FORCE_INLINE Error shrink(void* rxPtr, size_t newSize) noexcept {
+ Span span;
+ ASMJIT_PROPAGATE(query(span, rxPtr));
+ return (span.size() > newSize) ? shrink(span, newSize) : Error(kErrorOk);
+ }
+
+ ASMJIT_DEPRECATED("Use query(Span& out, void* rx) instead")
+ ASMJIT_FORCE_INLINE Error query(void* rxPtr, void** rxPtrOut, void** rwPtrOut, size_t* sizeOut) const noexcept {
+ Span span;
+ Error err = query(span, rxPtr);
+ *rxPtrOut = span.rx();
+ *rwPtrOut = span.rw();
+ *sizeOut = span.size();
+ return err;
+ }
+#endif
+
+ //! \}
+
+ //! \name Write Operations
+ //! \{
+
+ typedef Error (ASMJIT_CDECL* WriteFunc)(Span& span, void* userData) ASMJIT_NOEXCEPT_TYPE;
+
+ ASMJIT_API Error write(
+ Span& span,
+ size_t offset,
+ const void* src,
+ size_t size,
+ VirtMem::CachePolicy policy = VirtMem::CachePolicy::kDefault) noexcept;
+
+ ASMJIT_API Error write(
+ Span& span,
+ WriteFunc writeFunc,
+ void* userData,
+ VirtMem::CachePolicy policy = VirtMem::CachePolicy::kDefault) noexcept;
+
+ template<class Lambda>
+ ASMJIT_FORCE_INLINE Error write(
+ Span& span,
+ Lambda&& lambdaFunc,
+ VirtMem::CachePolicy policy = VirtMem::CachePolicy::kDefault) noexcept {
+
+ WriteFunc wrapperFunc = [](Span& span, void* userData) noexcept -> Error {
+ Lambda& lambdaFunc = *static_cast<Lambda*>(userData);
+ return lambdaFunc(span);
+ };
+ return write(span, wrapperFunc, (void*)(&lambdaFunc), policy);
+ }
+
+ //! \}
+
+ //! \name Write Operations with Scope
+ //! \{
+
+ //! \cond INTERNAL
+
+ //! Write scope data.
+ //!
+ //! This is mostly for internal purposes, please use \ref WriteScope instead.
+ struct WriteScopeData {
+ //! \name Members
+ //! \{
+
+ //! Link to the allocator.
+ JitAllocator* _allocator;
+ //! Cache policy passed to \ref JitAllocator::beginWriteScope().
+ VirtMem::CachePolicy _policy;
+ //! Internal flags used by the implementation.
+ uint32_t _flags;
+ //! Internal data used by the implementation.
+ size_t _data[64];
+
+ //! \}
+ };
+
+ //! Begins a write `scope`.
+ //!
+ //! This is mostly for internal purposes, please use \ref WriteScope constructor instead.
+ ASMJIT_API Error beginWriteScope(WriteScopeData& scope, VirtMem::CachePolicy policy = VirtMem::CachePolicy::kDefault) noexcept;
+
+ //! Ends a write `scope`.
+ //!
+ //! This is mostly for internal purposes, please use \ref WriteScope destructor instead.
+ ASMJIT_API Error endWriteScope(WriteScopeData& scope) noexcept;
+
+ //! Flushes accumulated changes in a write `scope`.
+ //!
+ //! This is mostly for internal purposes, please use \ref WriteScope destructor or \ref WriteScope::flush() instead.
+ ASMJIT_API Error flushWriteScope(WriteScopeData& scope) noexcept;
+
+ //! Alternative to `JitAllocator::write(span, offset, src, size)`, but under a write `scope`.
+ //!
+ //! This is mostly for internal purposes, please use \ref WriteScope::write() instead.
+ ASMJIT_API Error scopedWrite(WriteScopeData& scope, Span& span, size_t offset, const void* src, size_t size) noexcept;
+
+ //! Alternative to `JitAllocator::write(span, writeFunc, userData)`, but under a write `scope`.
+ //!
+ //! This is mostly for internal purposes, please use \ref WriteScope::write() instead.
+ ASMJIT_API Error scopedWrite(WriteScopeData& scope, Span& span, WriteFunc writeFunc, void* userData) noexcept;
+
+ //! Alternative to `JitAllocator::write(span, [lambda])`, but under a write `scope`.
+ //!
+ //! This is mostly for internal purposes, please use \ref WriteScope::write() instead.
+ template<class Lambda>
+ inline Error scopedWrite(WriteScopeData& scope, Span& span, Lambda&& lambdaFunc) noexcept {
+ WriteFunc wrapperFunc = [](Span& span, void* userData) noexcept -> Error {
+ Lambda& lambdaFunc = *static_cast<Lambda*>(userData);
+ return lambdaFunc(span);
+ };
+ return scopedWrite(scope, span, wrapperFunc, (void*)(&lambdaFunc));
+ }
+
+ //! \endcond
+
+ //! Write scope can be used to create a single scope that is optimized for writing multiple spans.
+ class WriteScope : public WriteScopeData {
+ public:
+ ASMJIT_NONCOPYABLE(WriteScope)
+
+ //! \name Construction & Destruction
+ //! \{
+
+ // Begins a write scope.
+ inline explicit WriteScope(JitAllocator* allocator, VirtMem::CachePolicy policy = VirtMem::CachePolicy::kDefault) noexcept {
+ allocator->beginWriteScope(*this, policy);
+ }
+
+ // Ends a write scope.
+ inline ~WriteScope() noexcept {
+ if (_allocator)
+ _allocator->endWriteScope(*this);
+ }
+
+ //! \}
+
+ //! \name Accessors
+ //! \{
+
+ ASMJIT_INLINE_NODEBUG JitAllocator* allocator() const noexcept { return _allocator; }
+ ASMJIT_INLINE_NODEBUG VirtMem::CachePolicy policy() const noexcept { return _policy; }
+
+ //! \}
+
+ //! \name Operations
+ //! \{
+
+ //! Similar to `JitAllocator::write(span, offset, src, size)`, but under a write scope.
+ ASMJIT_INLINE_NODEBUG Error write(Span& span, size_t offset, const void* src, size_t size) noexcept {
+ return _allocator->scopedWrite(*this, span, offset, src, size);
+ }
+
+ //! Similar to `JitAllocator::write(span, writeFunc, userData)`, but under a write scope.
+ ASMJIT_INLINE_NODEBUG Error write(Span& span, WriteFunc writeFunc, void* userData) noexcept {
+ return _allocator->scopedWrite(*this, span, writeFunc, userData);
+ }
+
+ //! Similar to `JitAllocator::write(span, <lambda>)`, but under a write scope.
+ template<class Lambda>
+ ASMJIT_INLINE_NODEBUG Error write(Span& span, Lambda&& lambdaFunc) noexcept {
+ return _allocator->scopedWrite(*this, span, lambdaFunc);
+ }
+
+ //! Flushes accumulated changes in this write scope.
+ ASMJIT_INLINE_NODEBUG Error flush() noexcept {
+ return _allocator->flushWriteScope(*this);
+ }
+
+ //! \}
+ };
//! \}
@@ -211,36 +524,32 @@ public:
//! Allocation overhead (in bytes) required to maintain all blocks.
size_t _overheadSize;
- inline void reset() noexcept {
- _blockCount = 0;
- _usedSize = 0;
- _reservedSize = 0;
- _overheadSize = 0;
- }
+ //! Resets the statistics to all zeros.
+ ASMJIT_INLINE_NODEBUG void reset() noexcept { *this = Statistics{}; }
//! Returns count of blocks managed by `JitAllocator` at the moment.
- inline size_t blockCount() const noexcept { return _blockCount; }
+ ASMJIT_INLINE_NODEBUG size_t blockCount() const noexcept { return _blockCount; }
//! Returns the number of active allocations.
- inline size_t allocationCount() const noexcept { return _allocationCount; }
+ ASMJIT_INLINE_NODEBUG size_t allocationCount() const noexcept { return _allocationCount; }
//! Returns how many bytes are currently used.
- inline size_t usedSize() const noexcept { return _usedSize; }
+ ASMJIT_INLINE_NODEBUG size_t usedSize() const noexcept { return _usedSize; }
//! Returns the number of bytes unused by the allocator at the moment.
- inline size_t unusedSize() const noexcept { return _reservedSize - _usedSize; }
- //! Returns the total number of bytes bytes reserved by the allocator (sum of sizes of all blocks).
- inline size_t reservedSize() const noexcept { return _reservedSize; }
+ ASMJIT_INLINE_NODEBUG size_t unusedSize() const noexcept { return _reservedSize - _usedSize; }
+ //! Returns the total number of bytes reserved by the allocator (sum of sizes of all blocks).
+ ASMJIT_INLINE_NODEBUG size_t reservedSize() const noexcept { return _reservedSize; }
//! Returns the number of bytes the allocator needs to manage the allocated memory.
- inline size_t overheadSize() const noexcept { return _overheadSize; }
+ ASMJIT_INLINE_NODEBUG size_t overheadSize() const noexcept { return _overheadSize; }
- inline double usedSizeAsPercent() const noexcept {
+ ASMJIT_INLINE_NODEBUG double usedSizeAsPercent() const noexcept {
return (double(usedSize()) / (double(reservedSize()) + 1e-16)) * 100.0;
}
- inline double unusedSizeAsPercent() const noexcept {
+ ASMJIT_INLINE_NODEBUG double unusedSizeAsPercent() const noexcept {
return (double(unusedSize()) / (double(reservedSize()) + 1e-16)) * 100.0;
}
- inline double overheadSizeAsPercent() const noexcept {
+ ASMJIT_INLINE_NODEBUG double overheadSizeAsPercent() const noexcept {
return (double(overheadSize()) / (double(reservedSize()) + 1e-16)) * 100.0;
}
};
diff --git a/3rdparty/asmjit/src/asmjit/core/jitruntime.cpp b/3rdparty/asmjit/src/asmjit/core/jitruntime.cpp
index 491c2040fbe..0cc026987a2 100644
--- a/3rdparty/asmjit/src/asmjit/core/jitruntime.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/jitruntime.cpp
@@ -15,6 +15,7 @@ JitRuntime::JitRuntime(const JitAllocator::CreateParams* params) noexcept
: _allocator(params) {
_environment = Environment::host();
_environment.setObjectFormat(ObjectFormat::kJIT);
+ _cpuFeatures = CpuInfo::host().features();
}
JitRuntime::~JitRuntime() noexcept {}
@@ -29,45 +30,43 @@ Error JitRuntime::_add(void** dst, CodeHolder* code) noexcept {
if (ASMJIT_UNLIKELY(estimatedCodeSize == 0))
return DebugUtils::errored(kErrorNoCodeGenerated);
- uint8_t* rx;
- uint8_t* rw;
- ASMJIT_PROPAGATE(_allocator.alloc((void**)&rx, (void**)&rw, estimatedCodeSize));
+ JitAllocator::Span span;
+ ASMJIT_PROPAGATE(_allocator.alloc(span, estimatedCodeSize));
// Relocate the code.
- Error err = code->relocateToBase(uintptr_t((void*)rx));
+ Error err = code->relocateToBase(uintptr_t(span.rx()));
if (ASMJIT_UNLIKELY(err)) {
- _allocator.release(rx);
+ _allocator.release(span.rx());
return err;
}
// Recalculate the final code size and shrink the memory we allocated for it
// in case that some relocations didn't require records in an address table.
size_t codeSize = code->codeSize();
- if (codeSize < estimatedCodeSize)
- _allocator.shrink(rx, codeSize);
+ ASMJIT_ASSERT(codeSize <= estimatedCodeSize);
- if (codeSize < estimatedCodeSize)
- _allocator.shrink(rx, codeSize);
-
- {
- VirtMem::ProtectJitReadWriteScope rwScope(rx, codeSize);
+ _allocator.write(span, [&](JitAllocator::Span& span) noexcept -> Error {
+ uint8_t* rw = static_cast<uint8_t*>(span.rw());
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());
- ASMJIT_ASSERT(offset + bufferSize <= codeSize);
+ ASMJIT_ASSERT(offset + bufferSize <= span.size());
memcpy(rw + offset, section->data(), bufferSize);
if (virtualSize > bufferSize) {
- ASMJIT_ASSERT(offset + virtualSize <= codeSize);
+ ASMJIT_ASSERT(offset + virtualSize <= span.size());
memset(rw + offset + bufferSize, 0, virtualSize - bufferSize);
}
}
- }
- *dst = rx;
+ span.shrink(codeSize);
+ return kErrorOk;
+ });
+
+ *dst = span.rx();
return kErrorOk;
}
diff --git a/3rdparty/asmjit/src/asmjit/core/jitruntime.h b/3rdparty/asmjit/src/asmjit/core/jitruntime.h
index 6f35e21277a..717a6b58d6b 100644
--- a/3rdparty/asmjit/src/asmjit/core/jitruntime.h
+++ b/3rdparty/asmjit/src/asmjit/core/jitruntime.h
@@ -20,8 +20,10 @@ class CodeHolder;
//! \addtogroup asmjit_virtual_memory
//! \{
-//! JIT execution runtime is a special `Target` that is designed to store and
-//! execute the generated code.
+//! JIT execution runtime is a special `Target` that is designed to store and execute a generated code.
+//!
+//! JIT runtime is the easiest way of using AsmJit as it abstracts allocation and deallocation of virtual memory
+//! where executable code can be placed and from which it can be executed as well.
class ASMJIT_VIRTAPI JitRuntime : public Target {
public:
ASMJIT_NONCOPYABLE(JitRuntime)
@@ -35,9 +37,19 @@ public:
//! Creates a `JitRuntime` instance.
ASMJIT_API explicit JitRuntime(const JitAllocator::CreateParams* params = nullptr) noexcept;
//! Destroys the `JitRuntime` instance.
- ASMJIT_API virtual ~JitRuntime() noexcept;
+ ASMJIT_API ~JitRuntime() noexcept override;
- inline void reset(ResetPolicy resetPolicy = ResetPolicy::kSoft) noexcept {
+ //! \}
+
+ //! \name Accessors
+ //! \{
+
+ //! Resets the \ref JitRuntime, freeing everything that was allocated by it.
+ //!
+ //! Depending on `resetPolicy` the currently held memory can be either freed entirely when ResetPolicy::kHard is used,
+ //! or the allocator can keep some of it for next allocations when ResetPolicy::kSoft is used, which is the default
+ //! behavior.
+ ASMJIT_INLINE_NODEBUG void reset(ResetPolicy resetPolicy = ResetPolicy::kSoft) noexcept {
_allocator.reset(resetPolicy);
}
@@ -47,7 +59,7 @@ public:
//! \{
//! Returns the associated `JitAllocator`.
- inline JitAllocator* allocator() const noexcept { return const_cast<JitAllocator*>(&_allocator); }
+ ASMJIT_INLINE_NODEBUG JitAllocator* allocator() const noexcept { return const_cast<JitAllocator*>(&_allocator); }
//! \}
@@ -62,13 +74,13 @@ public:
//! 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 {
+ ASMJIT_INLINE_NODEBUG Error add(Func* dst, CodeHolder* code) noexcept {
return _add(Support::ptr_cast_impl<void**, Func*>(dst), code);
}
//! Releases `p` which was obtained by calling `add()`.
template<typename Func>
- inline Error release(Func p) noexcept {
+ ASMJIT_INLINE_NODEBUG Error release(Func p) noexcept {
return _release(Support::ptr_cast_impl<void*, Func>(p));
}
diff --git a/3rdparty/asmjit/src/asmjit/core/logger.cpp b/3rdparty/asmjit/src/asmjit/core/logger.cpp
index 4567b3c9389..9bc14bae5fd 100644
--- a/3rdparty/asmjit/src/asmjit/core/logger.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/logger.cpp
@@ -19,6 +19,14 @@ Logger::Logger() noexcept
: _options() {}
Logger::~Logger() noexcept {}
+// [[pure virtual]]
+Error Logger::_log(const char* data, size_t size) noexcept {
+ DebugUtils::unused(data, size);
+
+ // Do not error in this case - the logger would just sink to /dev/null.
+ return kErrorOk;
+}
+
Error Logger::logf(const char* fmt, ...) noexcept {
Error err;
va_list ap;
diff --git a/3rdparty/asmjit/src/asmjit/core/logger.h b/3rdparty/asmjit/src/asmjit/core/logger.h
index d416a50d84d..54c169f52fe 100644
--- a/3rdparty/asmjit/src/asmjit/core/logger.h
+++ b/3rdparty/asmjit/src/asmjit/core/logger.h
@@ -47,38 +47,38 @@ public:
//! \{
//! Returns \ref FormatOptions of this logger.
- inline FormatOptions& options() noexcept { return _options; }
+ ASMJIT_INLINE_NODEBUG FormatOptions& options() noexcept { return _options; }
//! \overload
- inline const FormatOptions& options() const noexcept { return _options; }
+ ASMJIT_INLINE_NODEBUG const FormatOptions& options() const noexcept { return _options; }
//! Sets formatting options of this Logger to `options`.
- inline void setOptions(const FormatOptions& options) noexcept { _options = options; }
+ ASMJIT_INLINE_NODEBUG void setOptions(const FormatOptions& options) noexcept { _options = options; }
//! Resets formatting options of this Logger to defaults.
- inline void resetOptions() noexcept { _options.reset(); }
+ ASMJIT_INLINE_NODEBUG void resetOptions() noexcept { _options.reset(); }
//! Returns formatting flags.
- inline FormatFlags flags() const noexcept { return _options.flags(); }
+ ASMJIT_INLINE_NODEBUG FormatFlags flags() const noexcept { return _options.flags(); }
//! Tests whether the logger has the given `flag` enabled.
- inline bool hasFlag(FormatFlags flag) const noexcept { return _options.hasFlag(flag); }
+ ASMJIT_INLINE_NODEBUG bool hasFlag(FormatFlags flag) const noexcept { return _options.hasFlag(flag); }
//! Sets formatting flags to `flags`.
- inline void setFlags(FormatFlags flags) noexcept { _options.setFlags(flags); }
+ ASMJIT_INLINE_NODEBUG void setFlags(FormatFlags flags) noexcept { _options.setFlags(flags); }
//! Enables the given formatting `flags`.
- inline void addFlags(FormatFlags flags) noexcept { _options.addFlags(flags); }
+ ASMJIT_INLINE_NODEBUG void addFlags(FormatFlags flags) noexcept { _options.addFlags(flags); }
//! Disables the given formatting `flags`.
- inline void clearFlags(FormatFlags flags) noexcept { _options.clearFlags(flags); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG void resetPadding(FormatPaddingGroup type) noexcept { _options.resetPadding(type); }
//! \}
@@ -90,12 +90,12 @@ public:
//! 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;
+ ASMJIT_API virtual Error _log(const char* data, size_t size) noexcept;
//! Logs string `str`, which is either null terminated or having size `size`.
- inline Error log(const char* data, size_t size = SIZE_MAX) noexcept { return _log(data, size); }
+ ASMJIT_INLINE_NODEBUG Error log(const char* data, size_t size = SIZE_MAX) noexcept { return _log(data, size); }
//! Logs content of a string `str`.
- inline Error log(const String& str) noexcept { return _log(str.data(), str.size()); }
+ ASMJIT_INLINE_NODEBUG 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().
ASMJIT_API Error logf(const char* fmt, ...) noexcept;
@@ -119,7 +119,7 @@ public:
//! Creates a new `FileLogger` that logs to `FILE*`.
ASMJIT_API FileLogger(FILE* file = nullptr) noexcept;
//! Destroys the `FileLogger`.
- ASMJIT_API virtual ~FileLogger() noexcept;
+ ASMJIT_API ~FileLogger() noexcept override;
//! \}
@@ -127,14 +127,14 @@ public:
//! \{
//! Returns the logging output stream or null if the logger has no output stream.
- inline FILE* file() const noexcept { return _file; }
+ ASMJIT_INLINE_NODEBUG 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.
- inline void setFile(FILE* file) noexcept { _file = file; }
+ ASMJIT_INLINE_NODEBUG void setFile(FILE* file) noexcept { _file = file; }
//! \}
@@ -155,7 +155,7 @@ public:
//! Create new `StringLogger`.
ASMJIT_API StringLogger() noexcept;
//! Destroys the `StringLogger`.
- ASMJIT_API virtual ~StringLogger() noexcept;
+ ASMJIT_API ~StringLogger() noexcept override;
//! \}
@@ -165,16 +165,16 @@ public:
//! Returns the content of the logger as \ref String.
//!
//! It can be moved, if desired.
- inline String& content() noexcept { return _content; }
+ ASMJIT_INLINE_NODEBUG String& content() noexcept { return _content; }
//! \overload
- inline const String& content() const noexcept { return _content; }
+ ASMJIT_INLINE_NODEBUG const String& content() const noexcept { return _content; }
//! Returns aggregated logger data as `char*` pointer.
//!
//! The pointer is owned by `StringLogger`, it can't be modified or freed.
- inline const char* data() const noexcept { return _content.data(); }
+ ASMJIT_INLINE_NODEBUG const char* data() const noexcept { return _content.data(); }
//! Returns size of the data returned by `data()`.
- inline size_t dataSize() const noexcept { return _content.size(); }
+ ASMJIT_INLINE_NODEBUG size_t dataSize() const noexcept { return _content.size(); }
//! \}
@@ -182,7 +182,7 @@ public:
//! \{
//! Clears the accumulated logger data.
- inline void clear() noexcept { _content.clear(); }
+ ASMJIT_INLINE_NODEBUG void clear() noexcept { _content.clear(); }
//! \}
diff --git a/3rdparty/asmjit/src/asmjit/core/operand.cpp b/3rdparty/asmjit/src/asmjit/core/operand.cpp
index ee026817f8e..b78dc54678a 100644
--- a/3rdparty/asmjit/src/asmjit/core/operand.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/operand.cpp
@@ -19,36 +19,36 @@ enum class StrongEnumForImmTests : uint32_t {
UNIT(operand) {
INFO("Checking operand sizes");
- EXPECT(sizeof(Operand) == 16);
- EXPECT(sizeof(BaseReg) == 16);
- EXPECT(sizeof(BaseMem) == 16);
- EXPECT(sizeof(Imm) == 16);
- EXPECT(sizeof(Label) == 16);
+ EXPECT_EQ(sizeof(Operand), 16u);
+ EXPECT_EQ(sizeof(BaseReg), 16u);
+ EXPECT_EQ(sizeof(BaseMem), 16u);
+ EXPECT_EQ(sizeof(Imm), 16u);
+ EXPECT_EQ(sizeof(Label), 16u);
INFO("Checking basic functionality of Operand");
Operand a, b;
Operand dummy;
- EXPECT(a.isNone() == true);
- EXPECT(a.isReg() == false);
- EXPECT(a.isMem() == false);
- EXPECT(a.isImm() == false);
- EXPECT(a.isLabel() == false);
- EXPECT(a == b);
- EXPECT(a._data[0] == 0);
- EXPECT(a._data[1] == 0);
+ EXPECT_TRUE(a.isNone());
+ EXPECT_FALSE(a.isReg());
+ EXPECT_FALSE(a.isMem());
+ EXPECT_FALSE(a.isImm());
+ EXPECT_FALSE(a.isLabel());
+ EXPECT_EQ(a, b);
+ EXPECT_EQ(a._data[0], 0u);
+ EXPECT_EQ(a._data[1], 0u);
INFO("Checking basic functionality of Label");
Label label;
- EXPECT(label.isValid() == false);
- EXPECT(label.id() == Globals::kInvalidId);
+ EXPECT_FALSE(label.isValid());
+ EXPECT_EQ(label.id(), Globals::kInvalidId);
INFO("Checking basic functionality of BaseReg");
- EXPECT(BaseReg().isReg() == true);
- EXPECT(BaseReg().isValid() == false);
- EXPECT(BaseReg()._data[0] == 0);
- EXPECT(BaseReg()._data[1] == 0);
- EXPECT(dummy.as<BaseReg>().isValid() == false);
+ EXPECT_TRUE(BaseReg().isReg());
+ EXPECT_FALSE(BaseReg().isValid());
+ EXPECT_EQ(BaseReg()._data[0], 0u);
+ EXPECT_EQ(BaseReg()._data[1], 0u);
+ EXPECT_FALSE(dummy.as<BaseReg>().isValid());
// Create some register (not specific to any architecture).
OperandSignature rSig = OperandSignature::fromOpType(OperandType::kReg) |
@@ -57,75 +57,75 @@ UNIT(operand) {
OperandSignature::fromSize(8);
BaseReg r1(rSig, 5);
- EXPECT(r1.isValid() == true);
- EXPECT(r1.isReg() == true);
- EXPECT(r1.isReg(RegType::kVec128) == true);
- EXPECT(r1.isPhysReg() == true);
- EXPECT(r1.isVirtReg() == false);
- EXPECT(r1.signature() == rSig);
- EXPECT(r1.type() == RegType::kVec128);
- EXPECT(r1.group() == RegGroup::kVec);
- EXPECT(r1.size() == 8);
- EXPECT(r1.id() == 5);
- EXPECT(r1.isReg(RegType::kVec128, 5) == true); // RegType and Id.
- EXPECT(r1._data[0] == 0);
- EXPECT(r1._data[1] == 0);
+ EXPECT_TRUE(r1.isValid());
+ EXPECT_TRUE(r1.isReg());
+ EXPECT_TRUE(r1.isReg(RegType::kVec128));
+ EXPECT_TRUE(r1.isPhysReg());
+ EXPECT_FALSE(r1.isVirtReg());
+ EXPECT_EQ(r1.signature(), rSig);
+ EXPECT_EQ(r1.type(), RegType::kVec128);
+ EXPECT_EQ(r1.group(), RegGroup::kVec);
+ EXPECT_EQ(r1.size(), 8u);
+ EXPECT_EQ(r1.id(), 5u);
+ EXPECT_TRUE(r1.isReg(RegType::kVec128, 5)); // RegType and Id.
+ EXPECT_EQ(r1._data[0], 0u);
+ EXPECT_EQ(r1._data[1], 0u);
// The same type of register having different id.
BaseReg r2(r1, 6);
- EXPECT(r2.isValid() == true);
- EXPECT(r2.isReg() == true);
- EXPECT(r2.isReg(RegType::kVec128) == true);
- EXPECT(r2.isPhysReg() == true);
- EXPECT(r2.isVirtReg() == false);
- EXPECT(r2.signature() == rSig);
- EXPECT(r2.type() == r1.type());
- EXPECT(r2.group() == r1.group());
- EXPECT(r2.size() == r1.size());
- EXPECT(r2.id() == 6);
- EXPECT(r2.isReg(RegType::kVec128, 6) == true);
+ EXPECT_TRUE(r2.isValid());
+ EXPECT_TRUE(r2.isReg());
+ EXPECT_TRUE(r2.isReg(RegType::kVec128));
+ EXPECT_TRUE(r2.isPhysReg());
+ EXPECT_FALSE(r2.isVirtReg());
+ EXPECT_EQ(r2.signature(), rSig);
+ EXPECT_EQ(r2.type(), r1.type());
+ EXPECT_EQ(r2.group(), r1.group());
+ EXPECT_EQ(r2.size(), r1.size());
+ EXPECT_EQ(r2.id(), 6u);
+ EXPECT_TRUE(r2.isReg(RegType::kVec128, 6));
r1.reset();
- EXPECT(!r1.isReg());
- EXPECT(!r1.isValid());
+ EXPECT_FALSE(r1.isReg());
+ EXPECT_FALSE(r1.isValid());
INFO("Checking basic functionality of BaseMem");
BaseMem m;
- EXPECT(m.isMem());
- EXPECT(m == BaseMem());
- EXPECT(m.hasBase() == false);
- EXPECT(m.hasIndex() == false);
- EXPECT(m.hasOffset() == false);
- EXPECT(m.isOffset64Bit() == true);
- EXPECT(m.offset() == 0);
+ EXPECT_TRUE(m.isMem());
+ EXPECT_EQ(m, BaseMem());
+ EXPECT_FALSE(m.hasBase());
+ EXPECT_FALSE(m.hasIndex());
+ EXPECT_FALSE(m.hasOffset());
+ EXPECT_TRUE(m.isOffset64Bit());
+ EXPECT_EQ(m.offset(), 0);
m.setOffset(-1);
- EXPECT(m.offsetLo32() == -1);
- EXPECT(m.offset() == -1);
+ EXPECT_EQ(m.offsetLo32(), -1);
+ EXPECT_EQ(m.offset(), -1);
int64_t x = int64_t(0xFF00FF0000000001u);
int32_t xHi = int32_t(0xFF00FF00u);
m.setOffset(x);
- EXPECT(m.offset() == x);
- EXPECT(m.offsetLo32() == 1);
- EXPECT(m.offsetHi32() == xHi);
+ EXPECT_EQ(m.offset(), x);
+ EXPECT_EQ(m.offsetLo32(), 1);
+ EXPECT_EQ(m.offsetHi32(), xHi);
INFO("Checking basic functionality of Imm");
Imm immValue(-42);
- 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));
+ EXPECT_EQ(immValue.type(), ImmType::kInt);
+ EXPECT_EQ(Imm(-1).value(), -1);
+ EXPECT_EQ(imm(-1).value(), -1);
+ EXPECT_EQ(immValue.value(), -42);
+ EXPECT_EQ(imm(0xFFFFFFFF).value(), int64_t(0xFFFFFFFF));
Imm immDouble(0.4);
- EXPECT(immDouble.type() == ImmType::kDouble);
- EXPECT(immDouble.valueAs<double>() == 0.4);
- EXPECT(immDouble == imm(0.4));
+ EXPECT_EQ(immDouble.type(), ImmType::kDouble);
+ EXPECT_EQ(immDouble.valueAs<double>(), 0.4);
+ EXPECT_EQ(immDouble, imm(0.4));
- EXPECT(Imm(StrongEnumForImmTests::kValue0).value() == 0);
- EXPECT(Imm(StrongEnumForImmTests::kValue0xFFFFFFFF).value() == 0xFFFFFFFFu);
+ EXPECT_EQ(Imm(StrongEnumForImmTests::kValue0).value(), 0);
+ EXPECT_EQ(Imm(StrongEnumForImmTests::kValue0xFFFFFFFF).value(), 0xFFFFFFFFu);
}
#endif
diff --git a/3rdparty/asmjit/src/asmjit/core/operand.h b/3rdparty/asmjit/src/asmjit/core/operand.h
index 2f81a217f1b..3626779316d 100644
--- a/3rdparty/asmjit/src/asmjit/core/operand.h
+++ b/3rdparty/asmjit/src/asmjit/core/operand.h
@@ -23,13 +23,15 @@ enum class OperandType : uint32_t {
kReg = 1,
//! Operand is a memory.
kMem = 2,
+ //! Operand is a register-list.
+ kRegList = 3,
//! Operand is an immediate value.
- kImm = 3,
+ kImm = 4,
//! Operand is a label.
- kLabel = 4,
+ kLabel = 5,
//! Maximum value of `OperandType`.
- kMaxValue = kLabel
+ kMaxValue = kRegList
};
static_assert(uint32_t(OperandType::kMem) == uint32_t(OperandType::kReg) + 1,
@@ -47,7 +49,7 @@ enum class RegType : uint8_t {
//! No register - unused, invalid, multiple meanings.
kNone = 0,
- //! This is not a register type. This value is reserved for a \ref Label that used in \ref BaseMem as a base.
+ //! This is not a register type. This value is reserved for a \ref Label that's used in \ref BaseMem as a base.
//!
//! 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
@@ -55,7 +57,7 @@ enum class RegType : uint8_t {
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.
+ //! actually exposes it as a separate register type, which most modern architectures do.
kPC = 2,
//! 8-bit low general purpose register (X86).
@@ -64,21 +66,21 @@ enum class RegType : uint8_t {
kGp8Hi = 4,
//! 16-bit general purpose register (X86).
kGp16 = 5,
- //! 32-bit general purpose register (X86|ARM).
+ //! 32-bit general purpose register (X86|AArch32|AArch64).
kGp32 = 6,
- //! 64-bit general purpose register (X86|ARM).
+ //! 64-bit general purpose register (X86|AArch64).
kGp64 = 7,
- //! 8-bit view of a vector register (ARM).
+ //! 8-bit view of a vector register (AArch64).
kVec8 = 8,
- //! 16-bit view of a vector register (ARM).
+ //! 16-bit view of a vector register (AArch64).
kVec16 = 9,
- //! 32-bit view of a vector register (ARM).
+ //! 32-bit view of a vector register (AArch32|AArch64).
kVec32 = 10,
- //! 64-bit view of a vector register (ARM).
+ //! 64-bit view of a vector register (AArch32|AArch64).
//!
//! \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).
+ //! 128-bit view of a vector register (X86|AArch32|AArch64).
kVec128 = 12,
//! 256-bit view of a vector register (X86).
kVec256 = 13,
@@ -98,9 +100,6 @@ enum class RegType : uint8_t {
// X86 Specific Register Types
// ---------------------------
- // 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, ...).
@@ -137,7 +136,7 @@ enum class RegType : uint8_t {
kX86_Tmm = kExtra + 6,
// ARM Specific Register Types
- // ===========================
+ // ---------------------------
//! Program pointer (PC) register (AArch64).
kARM_PC = kPC,
@@ -153,7 +152,9 @@ enum class RegType : uint8_t {
kARM_VecS = kVec32,
//! 64-bit view of VFP/ASIMD register (D).
kARM_VecD = kVec64,
- //! 128-bit view of VFP/ASIMD register (Q|V).
+ //! 128-bit view of VFP/ASIMD register (Q).
+ kARM_VecQ = kVec128,
+ //! 128-bit view of VFP/ASIMD register (V).
kARM_VecV = kVec128,
//! Maximum value of `RegType`.
@@ -172,8 +173,8 @@ enum class RegGroup : uint8_t {
//! 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,
+ //! Mask register group compatible with all backends that can use masking.
+ kMask = 2,
//! Extra virtual group #3 that can be used by Compiler for register allocation.
kExtraVirt3 = 3,
@@ -186,8 +187,8 @@ enum class RegGroup : uint8_t {
// X86 Specific Register Groups
// ----------------------------
- //! K register group (KReg) - maps to \ref RegGroup::kExtraVirt2 (X86, X86_64).
- kX86_K = kExtraVirt2,
+ //! K register group (KReg) - maps to \ref RegGroup::kMask (X86, X86_64).
+ kX86_K = kMask,
//! MMX register group (MM) - maps to \ref RegGroup::kExtraVirt3 (X86, X86_64).
kX86_MM = kExtraVirt3,
@@ -294,147 +295,150 @@ struct OperandSignature {
//!
//! \{
- inline constexpr bool operator!() const noexcept { return _bits != 0; }
- inline constexpr explicit operator bool() const noexcept { return _bits != 0; }
+ ASMJIT_INLINE_NODEBUG constexpr bool operator!() const noexcept { return _bits == 0; }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG OperandSignature& operator|=(uint32_t x) noexcept { _bits |= x; return *this; }
+ ASMJIT_INLINE_NODEBUG OperandSignature& operator&=(uint32_t x) noexcept { _bits &= x; return *this; }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG OperandSignature& operator|=(const OperandSignature& other) noexcept { return operator|=(other._bits); }
+ ASMJIT_INLINE_NODEBUG OperandSignature& operator&=(const OperandSignature& other) noexcept { return operator&=(other._bits); }
+ ASMJIT_INLINE_NODEBUG OperandSignature& operator^=(const OperandSignature& other) noexcept { return operator^=(other._bits); }
- inline constexpr OperandSignature operator~() const noexcept { return OperandSignature{~_bits}; }
+ ASMJIT_INLINE_NODEBUG 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}; }
+ ASMJIT_INLINE_NODEBUG constexpr OperandSignature operator|(uint32_t x) const noexcept { return OperandSignature{_bits | x}; }
+ ASMJIT_INLINE_NODEBUG constexpr OperandSignature operator&(uint32_t x) const noexcept { return OperandSignature{_bits & x}; }
+ ASMJIT_INLINE_NODEBUG 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}; }
+ ASMJIT_INLINE_NODEBUG constexpr OperandSignature operator|(const OperandSignature& other) const noexcept { return OperandSignature{_bits | other._bits}; }
+ ASMJIT_INLINE_NODEBUG constexpr OperandSignature operator&(const OperandSignature& other) const noexcept { return OperandSignature{_bits & other._bits}; }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG constexpr bool operator==(uint32_t x) const noexcept { return _bits == x; }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG constexpr bool operator==(const OperandSignature& other) const noexcept { return _bits == other._bits; }
+ ASMJIT_INLINE_NODEBUG constexpr bool operator!=(const OperandSignature& other) const noexcept { return _bits != other._bits; }
//! \}
//! \name Accessors
//! \{
- inline void reset() noexcept { _bits = 0; }
+ ASMJIT_INLINE_NODEBUG void reset() noexcept { _bits = 0; }
- inline constexpr uint32_t bits() const noexcept { return _bits; }
- inline void setBits(uint32_t bits) noexcept { _bits = bits; }
+ ASMJIT_INLINE_NODEBUG constexpr uint32_t bits() const noexcept { return _bits; }
+ ASMJIT_INLINE_NODEBUG 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 {
+ template<uint32_t kFieldMask>
+ ASMJIT_INLINE_NODEBUG 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>
+ ASMJIT_INLINE_NODEBUG constexpr bool hasField(uint32_t value) const noexcept {
+ return (_bits & kFieldMask) != value << Support::ConstCTZ<kFieldMask>::value;
}
- 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>
+ ASMJIT_INLINE_NODEBUG constexpr uint32_t getField() const noexcept {
+ return (_bits >> Support::ConstCTZ<kFieldMask>::value) & (kFieldMask >> Support::ConstCTZ<kFieldMask>::value);
}
- 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);
+ template<uint32_t kFieldMask>
+ ASMJIT_INLINE_NODEBUG void setField(uint32_t value) noexcept {
+ ASMJIT_ASSERT(((value << Support::ConstCTZ<kFieldMask>::value) & ~kFieldMask) == 0);
+ _bits = (_bits & ~kFieldMask) | (value << Support::ConstCTZ<kFieldMask>::value);
}
- inline constexpr OperandSignature subset(uint32_t mask) const noexcept { return OperandSignature{_bits & mask}; }
+ ASMJIT_INLINE_NODEBUG constexpr OperandSignature subset(uint32_t mask) const noexcept { return OperandSignature{_bits & mask}; }
+
+ template<uint32_t kFieldMask, uint32_t kFieldShift = Support::ConstCTZ<kFieldMask>::value>
+ ASMJIT_INLINE_NODEBUG constexpr OperandSignature replacedValue(uint32_t value) const noexcept { return OperandSignature{(_bits & ~kFieldMask) | (value << kFieldShift)}; }
template<uint32_t kFieldMask>
- inline constexpr bool matchesSignature(const OperandSignature& signature) const noexcept {
+ ASMJIT_INLINE_NODEBUG 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 {
+ ASMJIT_INLINE_NODEBUG 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 {
+ ASMJIT_INLINE_NODEBUG constexpr bool matchesFields(const OperandSignature& fields) const noexcept {
return (_bits & kFieldMask) == fields._bits;
}
- inline constexpr bool isValid() const noexcept { return _bits != 0; }
+ ASMJIT_INLINE_NODEBUG constexpr bool isValid() const noexcept { return _bits != 0; }
- inline constexpr OperandType opType() const noexcept { return (OperandType)getField<kOpTypeMask>(); }
+ ASMJIT_INLINE_NODEBUG 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>(); }
+ ASMJIT_INLINE_NODEBUG constexpr RegType regType() const noexcept { return (RegType)getField<kRegTypeMask>(); }
+ ASMJIT_INLINE_NODEBUG 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>(); }
+ ASMJIT_INLINE_NODEBUG constexpr RegType memBaseType() const noexcept { return (RegType)getField<kMemBaseTypeMask>(); }
+ ASMJIT_INLINE_NODEBUG 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>(); }
+ ASMJIT_INLINE_NODEBUG constexpr uint32_t predicate() const noexcept { return getField<kPredicateMask>(); }
+ ASMJIT_INLINE_NODEBUG 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)); }
+ ASMJIT_INLINE_NODEBUG void setOpType(OperandType opType) noexcept { setField<kOpTypeMask>(uint32_t(opType)); }
+ ASMJIT_INLINE_NODEBUG void setRegType(RegType regType) noexcept { setField<kRegTypeMask>(uint32_t(regType)); }
+ ASMJIT_INLINE_NODEBUG 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)); }
+ ASMJIT_INLINE_NODEBUG void setMemBaseType(RegType baseType) noexcept { setField<kMemBaseTypeMask>(uint32_t(baseType)); }
+ ASMJIT_INLINE_NODEBUG void setMemIndexType(RegType 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); }
+ ASMJIT_INLINE_NODEBUG void setPredicate(uint32_t predicate) noexcept { setField<kPredicateMask>(predicate); }
+ ASMJIT_INLINE_NODEBUG void setSize(uint32_t size) noexcept { setField<kSizeMask>(size); }
//! \}
//! \name Static Constructors
//! \{
- static inline constexpr OperandSignature fromBits(uint32_t bits) noexcept {
+ static ASMJIT_INLINE_NODEBUG 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 {
+ static ASMJIT_INLINE_NODEBUG constexpr OperandSignature fromValue(const T& value) noexcept {
return OperandSignature{uint32_t(value) << Support::ConstCTZ<kFieldMask>::value};
}
- static inline constexpr OperandSignature fromOpType(OperandType opType) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr OperandSignature fromOpType(OperandType opType) noexcept {
return OperandSignature{uint32_t(opType) << kOpTypeShift};
}
- static inline constexpr OperandSignature fromRegType(RegType regType) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr OperandSignature fromRegType(RegType regType) noexcept {
return OperandSignature{uint32_t(regType) << kRegTypeShift};
}
- static inline constexpr OperandSignature fromRegGroup(RegGroup regGroup) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr OperandSignature fromRegGroup(RegGroup regGroup) noexcept {
return OperandSignature{uint32_t(regGroup) << kRegGroupShift};
}
- static inline constexpr OperandSignature fromRegTypeAndGroup(RegType regType, RegGroup regGroup) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr OperandSignature fromRegTypeAndGroup(RegType regType, RegGroup regGroup) noexcept {
return fromRegType(regType) | fromRegGroup(regGroup);
}
- static inline constexpr OperandSignature fromMemBaseType(RegType baseType) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr OperandSignature fromMemBaseType(RegType baseType) noexcept {
return OperandSignature{uint32_t(baseType) << kMemBaseTypeShift};
}
- static inline constexpr OperandSignature fromMemIndexType(RegType indexType) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr OperandSignature fromMemIndexType(RegType indexType) noexcept {
return OperandSignature{uint32_t(indexType) << kMemIndexTypeShift};
}
- static inline constexpr OperandSignature fromPredicate(uint32_t predicate) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr OperandSignature fromPredicate(uint32_t predicate) noexcept {
return OperandSignature{predicate << kPredicateShift};
}
- static inline constexpr OperandSignature fromSize(uint32_t size) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr OperandSignature fromSize(uint32_t size) noexcept {
return OperandSignature{size << kSizeShift};
}
@@ -506,18 +510,18 @@ struct Operand_ {
//! 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); }
+ static ASMJIT_INLINE_NODEBUG 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 inline uint32_t indexToVirtId(uint32_t id) noexcept { return id + kVirtIdMin; }
+ static ASMJIT_INLINE_NODEBUG uint32_t indexToVirtId(uint32_t id) noexcept { return id + kVirtIdMin; }
//! Converts a packed-id back to real-id.
- static inline uint32_t virtIdToIndex(uint32_t id) noexcept { return id - kVirtIdMin; }
+ static ASMJIT_INLINE_NODEBUG 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(const Signature& signature, uint32_t id) noexcept {
+ ASMJIT_INLINE_NODEBUG void _initReg(const Signature& signature, uint32_t id) noexcept {
_signature = signature;
_baseId = id;
_data[0] = 0;
@@ -526,7 +530,12 @@ struct Operand_ {
//! \endcond
//! Initializes the operand from `other` operand (used by operator overloads).
- inline void copyFrom(const Operand_& other) noexcept { memcpy(this, &other, sizeof(Operand_)); }
+ ASMJIT_INLINE_NODEBUG void copyFrom(const Operand_& other) noexcept {
+ _signature._bits = other._signature._bits;
+ _baseId = other._baseId;
+ _data[0] = other._data[0];
+ _data[1] = other._data[1];
+ }
//! Resets the `Operand` to none.
//!
@@ -555,7 +564,7 @@ struct Operand_ {
//! memset(&b, 0, sizeof(Operand));
//! assert(a == b);
//! ```
- inline void reset() noexcept {
+ ASMJIT_INLINE_NODEBUG void reset() noexcept {
_signature.reset();
_baseId = 0;
_data[0] = 0;
@@ -568,9 +577,9 @@ struct Operand_ {
//! \{
//! Tests whether this operand is the same as `other`.
- inline constexpr bool operator==(const Operand_& other) const noexcept { return equals(other); }
+ ASMJIT_INLINE_NODEBUG constexpr bool operator==(const Operand_& other) const noexcept { return equals(other); }
//! Tests whether this operand is not the same as `other`.
- inline constexpr bool operator!=(const Operand_& other) const noexcept { return !equals(other); }
+ ASMJIT_INLINE_NODEBUG constexpr bool operator!=(const Operand_& other) const noexcept { return !equals(other); }
//! \}
@@ -579,11 +588,27 @@ struct Operand_ {
//! Casts this operand to `T` type.
template<typename T>
- inline T& as() noexcept { return static_cast<T&>(*this); }
+ ASMJIT_INLINE_NODEBUG T& as() noexcept { return static_cast<T&>(*this); }
//! Casts this operand to `T` type (const).
template<typename T>
- inline const T& as() const noexcept { return static_cast<const T&>(*this); }
+ ASMJIT_INLINE_NODEBUG const T& as() const noexcept { return static_cast<const T&>(*this); }
+
+ //! \}
+
+ //! \name Equality
+ //! \{
+
+ //! 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.
+ ASMJIT_INLINE_NODEBUG constexpr bool equals(const Operand_& other) const noexcept {
+ return bool(unsigned(_signature == other._signature) &
+ unsigned(_baseId == other._baseId ) &
+ unsigned(_data[0] == other._data[0] ) &
+ unsigned(_data[1] == other._data[1] ));
+ }
//! \}
@@ -591,55 +616,44 @@ struct Operand_ {
//! \{
//! Tests whether the operand's signature matches the signature of the `other` operand.
- inline constexpr bool hasSignature(const Operand_& other) const noexcept { return _signature == other._signature; }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG 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 packed 4 bytes at once than having to check these bytes individually.
- inline constexpr Signature signature() const noexcept { return _signature; }
+ ASMJIT_INLINE_NODEBUG 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(const Signature& signature) noexcept { _signature = signature; }
+ ASMJIT_INLINE_NODEBUG void setSignature(const Signature& signature) noexcept { _signature = signature; }
+ //! \overload
+ ASMJIT_INLINE_NODEBUG void setSignature(uint32_t signature) noexcept { _signature._bits = signature; }
//! Returns the type of the operand, see `OpType`.
- inline constexpr OperandType opType() const noexcept { return _signature.opType(); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG constexpr bool isReg() const noexcept { return opType() == OperandType::kReg; }
+ //! Tests whether the operand is a register-list.
+ //!
+ //! \note Register-list is currently only used by 32-bit ARM architecture.
+ ASMJIT_INLINE_NODEBUG constexpr bool isRegList() const noexcept { return opType() == OperandType::kRegList; }
//! Tests whether the operand is a memory location (`OperandType::kMem`).
- inline constexpr bool isMem() const noexcept { return opType() == OperandType::kMem; }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG constexpr bool isLabel() const noexcept { return opType() == OperandType::kLabel; }
//! Tests whether the operand is a physical register.
- inline constexpr bool isPhysReg() const noexcept { return isReg() && _baseId < 0xFFu; }
+ ASMJIT_INLINE_NODEBUG constexpr bool isPhysReg() const noexcept { return isReg() && _baseId < 0xFFu; }
//! Tests whether the operand is a virtual register.
- inline constexpr bool isVirtReg() const noexcept { return isReg() && _baseId > 0xFFu; }
-
- //! Tests whether the operand specifies a size (i.e. the size is not zero).
- inline constexpr bool hasSize() const noexcept { return _signature.hasField<Signature::kSizeMask>(); }
- //! Tests whether the size of the operand matches `size`.
- 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).
- //! * Mem - Size is optional and will be in most cases zero.
- //! * Imm - Should always return zero size.
- //! * Label - Should always return zero size.
- inline constexpr uint32_t size() const noexcept { return _signature.getField<Signature::kSizeMask>(); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isVirtReg() const noexcept { return isReg() && _baseId > 0xFFu; }
//! Returns the operand id.
//!
@@ -650,35 +664,98 @@ struct Operand_ {
//! * 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.
- 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.
- 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] ) ;
- }
+ ASMJIT_INLINE_NODEBUG constexpr uint32_t id() const noexcept { return _baseId; }
//! Tests whether the operand is a register matching the given register `type`.
- inline constexpr bool isReg(RegType type) const noexcept {
+ ASMJIT_INLINE_NODEBUG 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 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 of the provided register group `regGroup`.
+ ASMJIT_INLINE_NODEBUG constexpr bool isReg(RegGroup regGroup) const noexcept {
+ return _signature.subset(Signature::kOpTypeMask | Signature::kRegGroupMask) == (Signature::fromOpType(OperandType::kReg) | Signature::fromRegGroup(regGroup));
+ }
+
+ //! Tests whether the operand is register and of register type `regType` and `regId`.
+ ASMJIT_INLINE_NODEBUG constexpr bool isReg(RegType regType, uint32_t regId) const noexcept { return isReg(regType) && _baseId == regId; }
+ //! Tests whether the operand is register and of register group `regGroup` and `regId`.
+ ASMJIT_INLINE_NODEBUG constexpr bool isReg(RegGroup regGroup, uint32_t regId) const noexcept { return isReg(regGroup) && _baseId == regId; }
+
+ //! Tests whether the register is a general purpose register (any size).
+ ASMJIT_INLINE_NODEBUG constexpr bool isGp() const noexcept { return isReg(RegGroup::kGp); }
+ //! Tests whether the register is a 32-bit general purpose register.
+ ASMJIT_INLINE_NODEBUG constexpr bool isGp32() const noexcept { return isReg(RegType::kGp32); }
+ //! Tests whether the register is a 64-bit general purpose register.
+ ASMJIT_INLINE_NODEBUG constexpr bool isGp64() const noexcept { return isReg(RegType::kGp64); }
+
+ //! Tests whether the register is a vector register of any size.
+ ASMJIT_INLINE_NODEBUG constexpr bool isVec() const noexcept { return isReg(RegGroup::kVec); }
+ //! Tests whether the register is an 8-bit vector register or view (AArch64).
+ ASMJIT_INLINE_NODEBUG constexpr bool isVec8() const noexcept { return isReg(RegType::kVec8); }
+ //! Tests whether the register is a 16-bit vector register or view (AArch64).
+ ASMJIT_INLINE_NODEBUG constexpr bool isVec16() const noexcept { return isReg(RegType::kVec16); }
+ //! Tests whether the register is a 32-bit vector register or view (AArch32, AArch64).
+ ASMJIT_INLINE_NODEBUG constexpr bool isVec32() const noexcept { return isReg(RegType::kVec32); }
+ //! Tests whether the register is a 64-bit vector register or view (AArch32, AArch64).
+ ASMJIT_INLINE_NODEBUG constexpr bool isVec64() const noexcept { return isReg(RegType::kVec64); }
+ //! Tests whether the register is a 128-bit vector register or view (AArch32, AArch64, X86, X86_64).
+ ASMJIT_INLINE_NODEBUG constexpr bool isVec128() const noexcept { return isReg(RegType::kVec128); }
+ //! Tests whether the register is a 256-bit vector register or view (X86, X86_64).
+ ASMJIT_INLINE_NODEBUG constexpr bool isVec256() const noexcept { return isReg(RegType::kVec256); }
+ //! Tests whether the register is a 512-bit vector register or view (X86, X86_64).
+ ASMJIT_INLINE_NODEBUG constexpr bool isVec512() const noexcept { return isReg(RegType::kVec512); }
+
+ //! Tests whether the register is a mask register of any size.
+ ASMJIT_INLINE_NODEBUG constexpr bool isMask() const noexcept { return isReg(RegGroup::kMask); }
+
+ //! Tests whether the operand is a register matching the given register `type`.
+ ASMJIT_INLINE_NODEBUG constexpr bool isRegList(RegType type) const noexcept {
+ return _signature.subset(Signature::kOpTypeMask | Signature::kRegTypeMask) == (Signature::fromOpType(OperandType::kRegList) | Signature::fromRegType(type));
}
//! Tests whether the operand is a register or memory.
- inline constexpr bool isRegOrMem() const noexcept {
+ //!
+ //! \note This is useful on X86 and X86_64 architectures as many instructions support Reg/Mem operand combination.
+ //! So if the user code works with just \ref Operand, it's possible to check whether the operand is either a register
+ //! or memory location with a single check.
+ ASMJIT_INLINE_NODEBUG constexpr bool isRegOrMem() const noexcept {
return Support::isBetween<uint32_t>(uint32_t(opType()), uint32_t(OperandType::kReg), uint32_t(OperandType::kMem));
}
+ //! Tests whether the operand is a register, register-list, or memory.
+ //!
+ //! \note This is useful on 32-bit ARM architecture to check whether an operand references a register. It can be
+ //! used in other architectures too, but it would work identically to \ref isRegOrMem() as other architectures
+ //! don't provide register lists.
+ ASMJIT_INLINE_NODEBUG constexpr bool isRegOrRegListOrMem() const noexcept {
+ return Support::isBetween<uint32_t>(uint32_t(opType()), uint32_t(OperandType::kReg), uint32_t(OperandType::kRegList));
+ }
+
//! \}
+
+ //! \name Accessors (X86 Specific)
+ //! \{
+
+ //! Returns a size of a register or an X86 memory operand.
+ //!
+ //! \remarks At the moment only X86 and X86_64 memory operands have a size - other memory operands can use bits
+ //! that represent size as an additional payload. This means that memory size is architecture specific and should
+ //! be accessed via \ref x86::Mem::size(). Sometimes when the user knows that the operand is either a register or
+ //! memory operand this function can be helpful as it avoids casting, but it only works when it targets X86 and X86_64.
+ ASMJIT_INLINE_NODEBUG constexpr uint32_t x86RmSize() const noexcept { return _signature.size(); }
+
+ //! \}
+
+#if !defined(ASMJIT_NO_DEPRECATED)
+ ASMJIT_DEPRECATED("hasSize() is no longer portable - use x86RmSize() or x86::Mem::hasSize() instead, if your target is X86/X86_64")
+ ASMJIT_INLINE_NODEBUG constexpr bool hasSize() const noexcept { return x86RmSize() != 0u; }
+
+ ASMJIT_DEPRECATED("hasSize() is no longer portable - use x86RmSize() or x86::Mem::hasSize() instead, if your target is X86/X86_64")
+ ASMJIT_INLINE_NODEBUG constexpr bool hasSize(uint32_t s) const noexcept { return x86RmSize() == s; }
+
+ ASMJIT_DEPRECATED("size() is no longer portable - use x86RmSize() or x86::Mem::size() instead, if your target is X86/X86_64")
+ ASMJIT_INLINE_NODEBUG constexpr uint32_t size() const noexcept { return _signature.getField<Signature::kSizeMask>(); }
+#endif
};
//! Base class representing an operand in AsmJit (default constructed version).
@@ -688,30 +765,30 @@ public:
//! \{
//! Creates `kOpNone` operand having all members initialized to zero.
- inline constexpr Operand() noexcept
+ ASMJIT_INLINE_NODEBUG constexpr Operand() noexcept
: Operand_{ Signature::fromOpType(OperandType::kNone), 0u, { 0u, 0u }} {}
//! Creates a cloned `other` operand.
- inline constexpr Operand(const Operand& other) noexcept = default;
+ ASMJIT_INLINE_NODEBUG constexpr Operand(const Operand& other) noexcept = default;
//! Creates a cloned `other` operand.
- inline constexpr explicit Operand(const Operand_& other)
+ ASMJIT_INLINE_NODEBUG constexpr explicit Operand(const Operand_& other)
: Operand_(other) {}
//! Creates an operand initialized to raw `[u0, u1, u2, u3]` values.
- inline constexpr Operand(Globals::Init_, const Signature& u0, uint32_t u1, uint32_t u2, uint32_t u3) noexcept
- : Operand_{ u0, u1, { u2, u3 }} {}
+ ASMJIT_INLINE_NODEBUG constexpr Operand(Globals::Init_, const Signature& u0, uint32_t u1, uint32_t u2, uint32_t u3) noexcept
+ : Operand_{{u0._bits}, u1, {u2, u3}} {}
//! Creates an uninitialized operand (dangerous).
- inline explicit Operand(Globals::NoInit_) noexcept {}
+ ASMJIT_INLINE_NODEBUG explicit Operand(Globals::NoInit_) noexcept {}
//! \}
//! \name Overloaded Operators
//! \{
- inline Operand& operator=(const Operand& other) noexcept = default;
- inline Operand& operator=(const Operand_& other) noexcept { return operator=(static_cast<const Operand&>(other)); }
+ ASMJIT_INLINE_NODEBUG Operand& operator=(const Operand& other) noexcept = default;
+ ASMJIT_INLINE_NODEBUG Operand& operator=(const Operand_& other) noexcept { return operator=(static_cast<const Operand&>(other)); }
//! \}
@@ -719,7 +796,7 @@ public:
//! \{
//! Clones this operand and returns its copy.
- inline constexpr Operand clone() const noexcept { return Operand(*this); }
+ ASMJIT_INLINE_NODEBUG constexpr Operand clone() const noexcept { return Operand(*this); }
//! \}
};
@@ -756,22 +833,22 @@ public:
//! \{
//! Creates a label operand without ID (you must set the ID to make it valid).
- inline constexpr Label() noexcept
+ ASMJIT_INLINE_NODEBUG constexpr Label() noexcept
: Operand(Globals::Init, Signature::fromOpType(OperandType::kLabel), Globals::kInvalidId, 0, 0) {}
//! Creates a cloned label operand of `other`.
- inline constexpr Label(const Label& other) noexcept
+ ASMJIT_INLINE_NODEBUG constexpr Label(const Label& other) noexcept
: Operand(other) {}
//! Creates a label operand of the given `id`.
- inline constexpr explicit Label(uint32_t id) noexcept
+ ASMJIT_INLINE_NODEBUG constexpr explicit Label(uint32_t id) noexcept
: Operand(Globals::Init, Signature::fromOpType(OperandType::kLabel), id, 0, 0) {}
- inline explicit Label(Globals::NoInit_) noexcept
+ ASMJIT_INLINE_NODEBUG 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 {
+ ASMJIT_INLINE_NODEBUG void reset() noexcept {
_signature = Signature::fromOpType(OperandType::kLabel);
_baseId = Globals::kInvalidId;
_data[0] = 0;
@@ -783,7 +860,7 @@ public:
//! \name Overloaded Operators
//! \{
- inline Label& operator=(const Label& other) noexcept = default;
+ ASMJIT_INLINE_NODEBUG Label& operator=(const Label& other) noexcept = default;
//! \}
@@ -791,9 +868,9 @@ public:
//! \{
//! Tests whether the label was created by CodeHolder and/or an attached emitter.
- inline constexpr bool isValid() const noexcept { return _baseId != Globals::kInvalidId; }
+ ASMJIT_INLINE_NODEBUG constexpr bool isValid() const noexcept { return _baseId != Globals::kInvalidId; }
//! Sets the label `id`.
- inline void setId(uint32_t id) noexcept { _baseId = id; }
+ ASMJIT_INLINE_NODEBUG void setId(uint32_t id) noexcept { _baseId = id; }
//! \}
};
@@ -806,10 +883,8 @@ struct BaseRegTraits {
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).
+ //! Zero type by default (defaults to None).
kType = uint32_t(RegType::kNone),
//! Zero group by default (defaults to GP).
kGroup = uint32_t(RegGroup::kGp),
@@ -822,7 +897,7 @@ struct BaseRegTraits {
};
//! \endcond
-//! Physical or virtual register operand.
+//! Physical or virtual register operand (base).
class BaseReg : public Operand {
public:
//! \name Constants
@@ -848,22 +923,22 @@ public:
//! \{
//! Creates a dummy register operand.
- inline constexpr BaseReg() noexcept
+ ASMJIT_INLINE_NODEBUG constexpr BaseReg() noexcept
: Operand(Globals::Init, Signature::fromOpType(OperandType::kReg), kIdBad, 0, 0) {}
//! Creates a new register operand which is the same as `other` .
- inline constexpr BaseReg(const BaseReg& other) noexcept
+ ASMJIT_INLINE_NODEBUG constexpr BaseReg(const BaseReg& other) noexcept
: Operand(other) {}
//! Creates a new register operand compatible with `other`, but with a different `id`.
- inline constexpr BaseReg(const BaseReg& other, uint32_t id) noexcept
+ ASMJIT_INLINE_NODEBUG constexpr BaseReg(const BaseReg& other, uint32_t id) noexcept
: Operand(Globals::Init, other._signature, id, 0, 0) {}
//! Creates a register initialized to the given `signature` and `id`.
- inline constexpr BaseReg(const Signature& signature, uint32_t id) noexcept
+ ASMJIT_INLINE_NODEBUG constexpr BaseReg(const Signature& signature, uint32_t id) noexcept
: Operand(Globals::Init, signature, id, 0, 0) {}
- inline explicit BaseReg(Globals::NoInit_) noexcept
+ ASMJIT_INLINE_NODEBUG explicit BaseReg(Globals::NoInit_) noexcept
: Operand(Globals::NoInit) {}
//! \}
@@ -871,7 +946,7 @@ public:
//! \name Overloaded Operators
//! \{
- inline BaseReg& operator=(const BaseReg& other) noexcept = default;
+ ASMJIT_INLINE_NODEBUG BaseReg& operator=(const BaseReg& other) noexcept = default;
//! \}
@@ -883,14 +958,14 @@ public:
//! 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.
- inline constexpr OperandSignature baseSignature() const noexcept { return _signature & kBaseSignatureMask; }
+ ASMJIT_INLINE_NODEBUG constexpr OperandSignature baseSignature() const noexcept { return _signature & kBaseSignatureMask; }
//! Tests whether the operand's base signature matches the given signature `sign`.
- inline constexpr bool hasBaseSignature(uint32_t signature) const noexcept { return baseSignature() == signature; }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG 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.
- inline constexpr bool hasBaseSignature(const BaseReg& other) const noexcept { return baseSignature() == other.baseSignature(); }
+ ASMJIT_INLINE_NODEBUG constexpr bool hasBaseSignature(const BaseReg& other) const noexcept { return baseSignature() == other.baseSignature(); }
//! Tests whether this register is the same as `other`.
//!
@@ -899,79 +974,90 @@ public:
//! 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.
- inline constexpr bool isSame(const BaseReg& other) const noexcept {
+ ASMJIT_INLINE_NODEBUG 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).
- inline constexpr bool isValid() const noexcept { return (_signature != 0) & (_baseId != kIdBad); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isValid() const noexcept { return bool(unsigned(_signature != 0) & unsigned(_baseId != kIdBad)); }
//! Tests whether this is a physical register.
- inline constexpr bool isPhysReg() const noexcept { return _baseId < kIdBad; }
+ ASMJIT_INLINE_NODEBUG constexpr bool isPhysReg() const noexcept { return _baseId < kIdBad; }
//! Tests whether this is a virtual register.
- inline constexpr bool isVirtReg() const noexcept { return _baseId > kIdBad; }
+ ASMJIT_INLINE_NODEBUG constexpr bool isVirtReg() const noexcept { return _baseId > kIdBad; }
//! Tests whether the register type matches `type` - same as `isReg(type)`, provided for convenience.
- inline constexpr bool isType(RegType type) const noexcept { return _signature.subset(Signature::kRegTypeMask) == Signature::fromRegType(type); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isType(RegType type) const noexcept { return _signature.subset(Signature::kRegTypeMask) == Signature::fromRegType(type); }
//! Tests whether the register group matches `group`.
- inline constexpr bool isGroup(RegGroup group) const noexcept { return _signature.subset(Signature::kRegGroupMask) == Signature::fromRegGroup(group); }
+ ASMJIT_INLINE_NODEBUG 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).
- inline constexpr bool isGp() const noexcept { return isGroup(RegGroup::kGp); }
- //! Tests whether the register is a vector register.
- inline constexpr bool isVec() const noexcept { return isGroup(RegGroup::kVec); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isGp() const noexcept { return isGroup(RegGroup::kGp); }
+ //! Tests whether the register is a vector register of any size.
+ ASMJIT_INLINE_NODEBUG constexpr bool isVec() const noexcept { return isGroup(RegGroup::kVec); }
+ //! Tests whether the register is a mask register of any size.
+ ASMJIT_INLINE_NODEBUG constexpr bool isMask() const noexcept { return isGroup(RegGroup::kMask); }
using Operand_::isReg;
//! Same as `isType()`, provided for convenience.
- inline constexpr bool isReg(RegType rType) const noexcept { return isType(rType); }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG constexpr bool isReg(RegType rType, uint32_t id) const noexcept { return isType(rType) && this->id() == id; }
//! Returns the register type.
- inline constexpr RegType type() const noexcept { return _signature.regType(); }
+ ASMJIT_INLINE_NODEBUG constexpr RegType type() const noexcept { return _signature.regType(); }
//! Returns the register group.
- inline constexpr RegGroup group() const noexcept { return _signature.regGroup(); }
+ ASMJIT_INLINE_NODEBUG constexpr RegGroup group() const noexcept { return _signature.regGroup(); }
+
+ //! Tests whether the register specifies a size (i.e. the size is not zero).
+ ASMJIT_INLINE_NODEBUG constexpr bool hasSize() const noexcept { return _signature.hasField<Signature::kSizeMask>(); }
+ //! Tests whether the register size matches size `s`.
+ ASMJIT_INLINE_NODEBUG constexpr bool hasSize(uint32_t s) const noexcept { return size() == s; }
+
+ //! Returns the size of the register in bytes. 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).
+ ASMJIT_INLINE_NODEBUG constexpr uint32_t size() const noexcept { return _signature.getField<Signature::kSizeMask>(); }
//! Returns operation predicate of the register (ARM/AArch64).
//!
//! 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>(); }
+ ASMJIT_INLINE_NODEBUG 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::ShiftOp
//! of the register.
- inline void setPredicate(uint32_t predicate) noexcept { _signature.setField<Signature::kPredicateMask>(predicate); }
+ ASMJIT_INLINE_NODEBUG 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 { _signature.setField<Signature::kPredicateMask>(0); }
+ ASMJIT_INLINE_NODEBUG void resetPredicate() noexcept { _signature.setField<Signature::kPredicateMask>(0); }
//! Clones the register operand.
- inline constexpr BaseReg clone() const noexcept { return BaseReg(*this); }
+ ASMJIT_INLINE_NODEBUG 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>
- inline constexpr RegT cloneAs() const noexcept { return RegT(Signature(RegT::kSignature), id()); }
+ ASMJIT_INLINE_NODEBUG 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>
- inline constexpr RegT cloneAs(const RegT& other) const noexcept { return RegT(other.signature(), id()); }
+ ASMJIT_INLINE_NODEBUG constexpr RegT cloneAs(const RegT& other) const noexcept { return RegT(other.signature(), id()); }
//! Sets the register id to `id`.
- inline void setId(uint32_t id) noexcept { _baseId = id; }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG void setSignatureT() noexcept { _signature = RegT::kSignature; }
//! Sets the register `signature` and `id`.
- inline void setSignatureAndId(const OperandSignature& signature, uint32_t id) noexcept {
+ ASMJIT_INLINE_NODEBUG void setSignatureAndId(const OperandSignature& signature, uint32_t id) noexcept {
_signature = signature;
_baseId = id;
}
@@ -982,21 +1068,21 @@ public:
//! \{
//! Tests whether the `op` operand is a general purpose register.
- static inline bool isGp(const Operand_& op) noexcept {
+ static ASMJIT_INLINE_NODEBUG bool isGp(const Operand_& op) noexcept {
// Check operand type and register group. Not interested in register type and size.
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 {
+ static ASMJIT_INLINE_NODEBUG bool isVec(const Operand_& op) noexcept {
// Check operand type and register group. Not interested in register type and size.
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 `id`.
- static inline bool isGp(const Operand_& op, uint32_t id) noexcept { return isGp(op) & (op.id() == id); }
+ static ASMJIT_INLINE_NODEBUG bool isGp(const Operand_& op, uint32_t id) noexcept { return bool(unsigned(isGp(op)) & unsigned(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); }
+ static ASMJIT_INLINE_NODEBUG bool isVec(const Operand_& op, uint32_t id) noexcept { return bool(unsigned(isVec(op)) & unsigned(op.id() == id)); }
//! \}
};
@@ -1021,16 +1107,16 @@ struct RegOnly {
//! \{
//! Initializes the `RegOnly` instance to hold register `signature` and `id`.
- inline void init(const OperandSignature& signature, uint32_t id) noexcept {
+ ASMJIT_INLINE_NODEBUG void init(const OperandSignature& signature, uint32_t id) noexcept {
_signature = signature;
_id = id;
}
- inline void init(const BaseReg& reg) noexcept { init(reg.signature(), reg.id()); }
- inline void init(const RegOnly& reg) noexcept { init(reg.signature(), reg.id()); }
+ ASMJIT_INLINE_NODEBUG void init(const BaseReg& reg) noexcept { init(reg.signature(), reg.id()); }
+ ASMJIT_INLINE_NODEBUG void init(const RegOnly& reg) noexcept { init(reg.signature(), reg.id()); }
//! Resets the `RegOnly` members to zeros (none).
- inline void reset() noexcept { init(Signature::fromBits(0), 0); }
+ ASMJIT_INLINE_NODEBUG void reset() noexcept { init(Signature::fromBits(0), 0); }
//! \}
@@ -1038,30 +1124,30 @@ struct RegOnly {
//! \{
//! Tests whether this ExtraReg is none (same as calling `Operand_::isNone()`).
- inline constexpr bool isNone() const noexcept { return _signature == 0; }
+ ASMJIT_INLINE_NODEBUG constexpr bool isNone() const noexcept { return _signature == 0; }
//! Tests whether the register is valid (either virtual or physical).
- inline constexpr bool isReg() const noexcept { return _signature != 0; }
+ ASMJIT_INLINE_NODEBUG constexpr bool isReg() const noexcept { return _signature != 0; }
//! Tests whether this is a physical register.
- inline constexpr bool isPhysReg() const noexcept { return _id < BaseReg::kIdBad; }
+ ASMJIT_INLINE_NODEBUG constexpr bool isPhysReg() const noexcept { return _id < BaseReg::kIdBad; }
//! Tests whether this is a virtual register (used by `BaseCompiler`).
- inline constexpr bool isVirtReg() const noexcept { return _id > BaseReg::kIdBad; }
+ ASMJIT_INLINE_NODEBUG constexpr bool isVirtReg() const noexcept { return _id > BaseReg::kIdBad; }
//! Returns the register signature or 0 if no register is assigned.
- inline constexpr OperandSignature signature() const noexcept { return _signature; }
+ ASMJIT_INLINE_NODEBUG 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.
- inline constexpr uint32_t id() const noexcept { return _id; }
+ ASMJIT_INLINE_NODEBUG constexpr uint32_t id() const noexcept { return _id; }
//! Sets the register id.
- inline void setId(uint32_t id) noexcept { _id = id; }
+ ASMJIT_INLINE_NODEBUG void setId(uint32_t id) noexcept { _id = id; }
//! Returns the register type.
- inline constexpr RegType type() const noexcept { return _signature.regType(); }
+ ASMJIT_INLINE_NODEBUG constexpr RegType type() const noexcept { return _signature.regType(); }
//! Returns the register group.
- inline constexpr RegGroup group() const noexcept { return _signature.regGroup(); }
+ ASMJIT_INLINE_NODEBUG constexpr RegGroup group() const noexcept { return _signature.regGroup(); }
//! \}
@@ -1070,85 +1156,270 @@ struct RegOnly {
//! Converts this ExtraReg to a real `RegT` operand.
template<typename RegT>
- inline constexpr RegT toReg() const noexcept { return RegT(_signature, _id); }
+ ASMJIT_INLINE_NODEBUG constexpr RegT toReg() const noexcept { return RegT(_signature, _id); }
//! \}
};
//! \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(), \
- }; \
+#define ASMJIT_DEFINE_REG_TRAITS(REG_TYPE, GROUP, SIZE, TYPE_ID) \
+template<> \
+struct RegTraits<REG_TYPE> { \
+ static constexpr uint32_t kValid = 1; \
+ static constexpr RegType kType = REG_TYPE; \
+ static constexpr RegGroup kGroup = GROUP; \
+ static constexpr uint32_t kSize = SIZE; \
+ static constexpr TypeId kTypeId = TYPE_ID; \
+ \
+ static constexpr uint32_t kSignature = \
+ (OperandSignature::fromOpType(OperandType::kReg) | \
+ OperandSignature::fromRegType(kType) | \
+ OperandSignature::fromRegGroup(kGroup) | \
+ 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;
+#define ASMJIT_DEFINE_ABSTRACT_REG(REG, BASE) \
+public: \
+ /*! Default constructor that only setups basics. */ \
+ ASMJIT_INLINE_NODEBUG constexpr REG() noexcept \
+ : BASE(Signature{kSignature}, kIdBad) {} \
+ \
+ /*! Makes a copy of the `other` register operand. */ \
+ ASMJIT_INLINE_NODEBUG constexpr REG(const REG& other) noexcept \
+ : BASE(other) {} \
+ \
+ /*! Makes a copy of the `other` register having id set to `id` */ \
+ ASMJIT_INLINE_NODEBUG constexpr REG(const BaseReg& other, uint32_t id) noexcept \
+ : BASE(other, id) {} \
+ \
+ /*! Creates a register based on `signature` and `id`. */ \
+ ASMJIT_INLINE_NODEBUG constexpr REG(const OperandSignature& sgn, uint32_t id) noexcept \
+ : BASE(sgn, id) {} \
+ \
+ /*! Creates a completely uninitialized REG register operand (garbage). */ \
+ ASMJIT_INLINE_NODEBUG explicit REG(Globals::NoInit_) noexcept \
+ : BASE(Globals::NoInit) {} \
+ \
+ /*! Creates a new register from register type and id. */ \
+ static ASMJIT_INLINE_NODEBUG REG fromTypeAndId(RegType type, uint32_t id) noexcept { \
+ return REG(signatureOf(type), id); \
+ } \
+ \
+ /*! Clones the register operand. */ \
+ ASMJIT_INLINE_NODEBUG constexpr REG clone() const noexcept { return REG(*this); } \
+ \
+ ASMJIT_INLINE_NODEBUG 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 \
+#define ASMJIT_DEFINE_FINAL_REG(REG, BASE, TRAITS) \
+public: \
+ static constexpr RegType kThisType = TRAITS::kType; \
+ static constexpr RegGroup 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 `id`. */ \
+ ASMJIT_INLINE_NODEBUG constexpr explicit REG(uint32_t id) noexcept \
: BASE(Signature{kSignature}, id) {}
//! \endcond
+//! List of physical registers (base).
+//!
+//! \note List of registers is only used by some ARM instructions at the moment.
+class BaseRegList : public Operand {
+public:
+ //! \name Constants
+ //! \{
+
+ enum : uint32_t {
+ kSignature = Signature::fromOpType(OperandType::kRegList).bits()
+ };
+
+ //! \}
+
+ //! \name Construction & Destruction
+ //! \{
+
+ //! Creates a dummy register operand.
+ ASMJIT_INLINE_NODEBUG constexpr BaseRegList() noexcept
+ : Operand(Globals::Init, Signature::fromOpType(OperandType::kRegList), 0, 0, 0) {}
+
+ //! Creates a new register operand which is the same as `other` .
+ ASMJIT_INLINE_NODEBUG constexpr BaseRegList(const BaseRegList& other) noexcept
+ : Operand(other) {}
+
+ //! Creates a new register operand compatible with `other`, but with a different `id`.
+ ASMJIT_INLINE_NODEBUG constexpr BaseRegList(const BaseRegList& other, RegMask regMask) noexcept
+ : Operand(Globals::Init, other._signature, regMask, 0, 0) {}
+
+ //! Creates a register initialized to the given `signature` and `id`.
+ ASMJIT_INLINE_NODEBUG constexpr BaseRegList(const Signature& signature, RegMask regMask) noexcept
+ : Operand(Globals::Init, signature, regMask, 0, 0) {}
+
+ ASMJIT_INLINE_NODEBUG explicit BaseRegList(Globals::NoInit_) noexcept
+ : Operand(Globals::NoInit) {}
+
+ //! \}
+
+ //! \name Overloaded Operators
+ //! \{
+
+ ASMJIT_INLINE_NODEBUG BaseRegList& operator=(const BaseRegList& other) noexcept = default;
+
+ //! \}
+
+ //! \name Accessors
+ //! \{
+
+ //! Tests whether the register-list is valid, which means it has a type and at least a single register in the list.
+ ASMJIT_INLINE_NODEBUG constexpr bool isValid() const noexcept { return bool(unsigned(_signature != 0u) & unsigned(_baseId != 0u)); }
+
+ //! Tests whether the register type matches `type` - same as `isReg(type)`, provided for convenience.
+ ASMJIT_INLINE_NODEBUG constexpr bool isType(RegType type) const noexcept { return _signature.subset(Signature::kRegTypeMask) == Signature::fromRegType(type); }
+ //! Tests whether the register group matches `group`.
+ ASMJIT_INLINE_NODEBUG 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).
+ ASMJIT_INLINE_NODEBUG constexpr bool isGp() const noexcept { return isGroup(RegGroup::kGp); }
+ //! Tests whether the register is a vector register.
+ ASMJIT_INLINE_NODEBUG constexpr bool isVec() const noexcept { return isGroup(RegGroup::kVec); }
+
+ //! Returns the register type.
+ ASMJIT_INLINE_NODEBUG constexpr RegType type() const noexcept { return _signature.regType(); }
+ //! Returns the register group.
+ ASMJIT_INLINE_NODEBUG constexpr RegGroup group() const noexcept { return _signature.regGroup(); }
+ //! Returns the size of a single register in this register-list or 0 if unspecified.
+ ASMJIT_INLINE_NODEBUG constexpr uint32_t size() const noexcept { return _signature.getField<Signature::kSizeMask>(); }
+
+ //! Returns the register list as a mask, where each bit represents one physical register.
+ ASMJIT_INLINE_NODEBUG constexpr RegMask list() const noexcept { return _baseId; }
+ //! Sets the register list to `mask`.
+ ASMJIT_INLINE_NODEBUG void setList(RegMask mask) noexcept { _baseId = mask; }
+ //! Remoes all registers from the register-list by making the underlying register-mask zero.
+ ASMJIT_INLINE_NODEBUG void resetList() noexcept { _baseId = 0; }
+
+ //! Adds registers passed by a register `mask` to the register-list.
+ ASMJIT_INLINE_NODEBUG void addList(RegMask mask) noexcept { _baseId |= mask; }
+ //! Removes registers passed by a register `mask` to the register-list.
+ ASMJIT_INLINE_NODEBUG void clearList(RegMask mask) noexcept { _baseId &= ~mask; }
+ //! Uses AND operator to combine the current register-list with other register `mask`.
+ ASMJIT_INLINE_NODEBUG void andList(RegMask mask) noexcept { _baseId &= mask; }
+ //! Uses XOR operator to combine the current register-list with other register `mask`.
+ ASMJIT_INLINE_NODEBUG void xorList(RegMask mask) noexcept { _baseId ^= mask; }
+
+ //! Checks whether a physical register `physId` is in the register-list.
+ ASMJIT_INLINE_NODEBUG bool hasReg(uint32_t physId) const noexcept { return physId < 32u ? (_baseId & (1u << physId)) != 0 : false; }
+ //! Adds a physical register `physId` to the register-list.
+ ASMJIT_INLINE_NODEBUG void addReg(uint32_t physId) noexcept { addList(1u << physId); }
+ //! Removes a physical register `physId` from the register-list.
+ ASMJIT_INLINE_NODEBUG void clearReg(uint32_t physId) noexcept { clearList(1u << physId); }
+
+ //! Clones the register-list operand.
+ ASMJIT_INLINE_NODEBUG constexpr BaseRegList clone() const noexcept { return BaseRegList(*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 RegListT>
+ ASMJIT_INLINE_NODEBUG constexpr RegListT cloneAs() const noexcept { return RegListT(Signature(RegListT::kSignature), list()); }
+
+ //! Casts this register to `other` by also changing its signature.
+ //!
+ //! \note Improper use of `cloneAs()` can lead to hard-to-debug errors.
+ template<typename RegListT>
+ ASMJIT_INLINE_NODEBUG constexpr RegListT cloneAs(const RegListT& other) const noexcept { return RegListT(other.signature(), list()); }
+
+ //! \}
+};
+
+template<typename RegT>
+class RegListT : public BaseRegList {
+public:
+ //! \name Construction & Destruction
+ //! \{
+
+ //! Creates a dummy register operand.
+ ASMJIT_INLINE_NODEBUG constexpr RegListT() noexcept
+ : BaseRegList() {}
+
+ //! Creates a new register operand which is the same as `other` .
+ ASMJIT_INLINE_NODEBUG constexpr RegListT(const RegListT& other) noexcept
+ : BaseRegList(other) {}
+
+ //! Creates a new register operand compatible with `other`, but with a different `id`.
+ ASMJIT_INLINE_NODEBUG constexpr RegListT(const RegListT& other, RegMask regMask) noexcept
+ : BaseRegList(other, regMask) {}
+
+ //! Creates a register initialized to the given `signature` and `id`.
+ ASMJIT_INLINE_NODEBUG constexpr RegListT(const Signature& signature, RegMask regMask) noexcept
+ : BaseRegList(signature, regMask) {}
+
+ //! Creates a register initialized to the given `signature` and `regs`.
+ ASMJIT_INLINE_NODEBUG RegListT(const Signature& signature, std::initializer_list<RegT> regs) noexcept
+ : BaseRegList(signature, RegMask(0)) { addRegs(regs); }
+
+ ASMJIT_INLINE_NODEBUG explicit RegListT(Globals::NoInit_) noexcept
+ : BaseRegList(Globals::NoInit) {}
+
+ //! \}
+
+ //! \name Overloaded Operators
+ //! \{
+
+ ASMJIT_INLINE_NODEBUG RegListT& operator=(const RegListT& other) noexcept = default;
+
+ //! \}
+
+ //! \name Accessors
+ //! \{
+
+ using BaseRegList::addList;
+ using BaseRegList::clearList;
+ using BaseRegList::andList;
+ using BaseRegList::xorList;
+
+ //! Adds registers to this register-list as provided by `other` register-list.
+ ASMJIT_INLINE_NODEBUG void addList(const RegListT<RegT>& other) noexcept { addList(other.list()); }
+ //! Removes registers contained in `other` register-list.
+ ASMJIT_INLINE_NODEBUG void clearList(const RegListT<RegT>& other) noexcept { clearList(other.list()); }
+ //! Uses AND operator to combine the current register-list with `other` register-list.
+ ASMJIT_INLINE_NODEBUG void andList(const RegListT<RegT>& other) noexcept { andList(other.list()); }
+ //! Uses XOR operator to combine the current register-list with `other` register-list.
+ ASMJIT_INLINE_NODEBUG void xorList(const RegListT<RegT>& other) noexcept { xorList(other.list()); }
+
+ using BaseRegList::addReg;
+ using BaseRegList::clearReg;
+
+ ASMJIT_INLINE_NODEBUG void addReg(const RegT& reg) noexcept {
+ if (reg.id() < 32u)
+ addReg(reg.id());
+ }
+
+ ASMJIT_INLINE_NODEBUG void addRegs(std::initializer_list<RegT> regs) noexcept {
+ for (const RegT& reg : regs)
+ addReg(reg);
+ }
+
+ ASMJIT_INLINE_NODEBUG void clearReg(const RegT& reg) noexcept {
+ if (reg.id() < 32u)
+ clearReg(reg.id());
+ }
+
+ ASMJIT_INLINE_NODEBUG void clearRegs(std::initializer_list<RegT> regs) noexcept {
+ for (const RegT& reg : regs)
+ clearReg(reg);
+ }
+
+ //! \}
+};
+
//! Base class for all memory operands.
//!
//! The data is split into the following parts:
@@ -1174,18 +1445,18 @@ public:
//! \{
//! Creates a default `BaseMem` operand, that points to [0].
- inline constexpr BaseMem() noexcept
+ ASMJIT_INLINE_NODEBUG constexpr BaseMem() noexcept
: Operand(Globals::Init, Signature::fromOpType(OperandType::kMem), 0, 0, 0) {}
//! Creates a `BaseMem` operand that is a clone of `other`.
- inline constexpr BaseMem(const BaseMem& other) noexcept
+ ASMJIT_INLINE_NODEBUG 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.
- inline constexpr explicit BaseMem(const BaseReg& baseReg, int32_t offset = 0) noexcept
+ ASMJIT_INLINE_NODEBUG constexpr explicit BaseMem(const BaseReg& baseReg, int32_t offset = 0) noexcept
: Operand(Globals::Init,
Signature::fromOpType(OperandType::kMem) | Signature::fromMemBaseType(baseReg.type()),
baseReg.id(),
@@ -1194,16 +1465,16 @@ public:
//! \cond INTERNAL
//! Creates a `BaseMem` operand from 4 integers as used by `Operand_` struct.
- inline constexpr BaseMem(const OperandSignature& u0, uint32_t baseId, uint32_t indexId, int32_t offset) noexcept
+ ASMJIT_INLINE_NODEBUG 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.
- inline explicit BaseMem(Globals::NoInit_) noexcept
+ ASMJIT_INLINE_NODEBUG explicit BaseMem(Globals::NoInit_) noexcept
: Operand(Globals::NoInit) {}
//! Resets the memory operand - after the reset the memory points to [0].
- inline void reset() noexcept {
+ ASMJIT_INLINE_NODEBUG void reset() noexcept {
_signature = Signature::fromOpType(OperandType::kMem);
_baseId = 0;
_data[0] = 0;
@@ -1215,7 +1486,7 @@ public:
//! \name Overloaded Operators
//! \{
- inline BaseMem& operator=(const BaseMem& other) noexcept { copyFrom(other); return *this; }
+ ASMJIT_INLINE_NODEBUG BaseMem& operator=(const BaseMem& other) noexcept { copyFrom(other); return *this; }
//! \}
@@ -1223,54 +1494,54 @@ public:
//! \{
//! Clones the memory operand.
- inline constexpr BaseMem clone() const noexcept { return BaseMem(*this); }
+ ASMJIT_INLINE_NODEBUG 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 {
+ ASMJIT_INLINE_NODEBUG BaseMem cloneAdjusted(int64_t off) const noexcept {
BaseMem result(*this);
result.addOffset(off);
return result;
}
//! Tests whether this memory operand is a register home (only used by \ref asmjit_compiler)
- inline constexpr bool isRegHome() const noexcept { return _signature.hasField<Signature::kMemRegHomeFlag>(); }
+ ASMJIT_INLINE_NODEBUG 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 |= Signature::kMemRegHomeFlag; }
+ ASMJIT_INLINE_NODEBUG 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 &= ~Signature::kMemRegHomeFlag; }
+ ASMJIT_INLINE_NODEBUG void clearRegHome() noexcept { _signature &= ~Signature::kMemRegHomeFlag; }
//! Tests whether the memory operand has a BASE register or label specified.
- inline constexpr bool hasBase() const noexcept {
+ ASMJIT_INLINE_NODEBUG constexpr bool hasBase() const noexcept {
return (_signature & Signature::kMemBaseTypeMask) != 0;
}
//! Tests whether the memory operand has an INDEX register specified.
- inline constexpr bool hasIndex() const noexcept {
+ ASMJIT_INLINE_NODEBUG constexpr bool hasIndex() const noexcept {
return (_signature & Signature::kMemIndexTypeMask) != 0;
}
//! Tests whether the memory operand has BASE or INDEX register.
- inline constexpr bool hasBaseOrIndex() const noexcept {
+ ASMJIT_INLINE_NODEBUG constexpr bool hasBaseOrIndex() const noexcept {
return (_signature & Signature::kMemBaseIndexMask) != 0;
}
//! Tests whether the memory operand has BASE and INDEX register.
- inline constexpr bool hasBaseAndIndex() const noexcept {
+ ASMJIT_INLINE_NODEBUG constexpr bool hasBaseAndIndex() const noexcept {
return (_signature & Signature::kMemBaseTypeMask) != 0 && (_signature & Signature::kMemIndexTypeMask) != 0;
}
//! Tests whether the BASE operand is a label.
- inline constexpr bool hasBaseLabel() const noexcept {
+ ASMJIT_INLINE_NODEBUG constexpr bool hasBaseLabel() const noexcept {
return _signature.subset(Signature::kMemBaseTypeMask) == Signature::fromMemBaseType(RegType::kLabelTag);
}
//! Tests whether the BASE operand is a register (registers start after `RegType::kLabelTag`).
- inline constexpr bool hasBaseReg() const noexcept {
+ ASMJIT_INLINE_NODEBUG 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 {
+ ASMJIT_INLINE_NODEBUG constexpr bool hasIndexReg() const noexcept {
return _signature.subset(Signature::kMemIndexTypeMask).bits() > Signature::fromMemIndexType(RegType::kLabelTag).bits();
}
@@ -1278,76 +1549,78 @@ public:
//!
//! \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(); }
+ ASMJIT_INLINE_NODEBUG 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).
- inline constexpr RegType indexType() const noexcept { return _signature.memIndexType(); }
+ ASMJIT_INLINE_NODEBUG constexpr RegType indexType() const noexcept { return _signature.memIndexType(); }
//! This is used internally for BASE+INDEX validation.
- inline constexpr uint32_t baseAndIndexTypes() const noexcept { return _signature.getField<Signature::kMemBaseIndexMask>(); }
+ ASMJIT_INLINE_NODEBUG 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.
//!
//! \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; }
+ ASMJIT_INLINE_NODEBUG constexpr uint32_t baseId() const noexcept { return _baseId; }
//! Returns the id of the INDEX register.
- inline constexpr uint32_t indexId() const noexcept { return _data[kDataMemIndexId]; }
+ ASMJIT_INLINE_NODEBUG 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 id) noexcept { _baseId = id; }
+ ASMJIT_INLINE_NODEBUG void setBaseId(uint32_t id) noexcept { _baseId = id; }
+ //! Sets the register type of the BASE register (without modifying its id).
+ ASMJIT_INLINE_NODEBUG void setBaseType(RegType regType) noexcept { _signature.setMemBaseType(regType); }
+
//! Sets the id of the INDEX register (without modifying its type).
- inline void setIndexId(uint32_t id) noexcept { _data[kDataMemIndexId] = id; }
+ ASMJIT_INLINE_NODEBUG void setIndexId(uint32_t id) noexcept { _data[kDataMemIndexId] = id; }
+ //! Sets the register type of the INDEX register (without modifying its id).
+ ASMJIT_INLINE_NODEBUG void setIndexType(RegType regType) noexcept { _signature.setMemIndexType(regType); }
//! 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()); }
+ ASMJIT_INLINE_NODEBUG void setBase(const BaseReg& base) noexcept { return _setBase(base.type(), base.id()); }
//! Sets the index register to type and id of the given `index` operand.
- inline void setIndex(const BaseReg& index) noexcept { return _setIndex(index.type(), index.id()); }
+ ASMJIT_INLINE_NODEBUG void setIndex(const BaseReg& index) noexcept { return _setIndex(index.type(), index.id()); }
//! \cond INTERNAL
- inline void _setBase(RegType type, uint32_t id) noexcept {
+ ASMJIT_INLINE_NODEBUG void _setBase(RegType type, uint32_t id) noexcept {
_signature.setField<Signature::kMemBaseTypeMask>(uint32_t(type));
_baseId = id;
}
- inline void _setIndex(RegType type, uint32_t id) noexcept {
+ ASMJIT_INLINE_NODEBUG 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(RegType::kNone, 0); }
+ ASMJIT_INLINE_NODEBUG void resetBase() noexcept { _setBase(RegType::kNone, 0); }
//! Resets the memory operand's INDEX register.
- inline void resetIndex() noexcept { _setIndex(RegType::kNone, 0); }
-
- //! Sets the memory operand size (in bytes).
- inline void setSize(uint32_t size) noexcept { _signature.setField<Signature::kSizeMask>(size); }
+ ASMJIT_INLINE_NODEBUG void resetIndex() noexcept { _setIndex(RegType::kNone, 0); }
//! Tests whether the memory operand has a 64-bit offset or absolute address.
//!
//! If this is true then `hasBase()` must always report false.
- inline constexpr bool isOffset64Bit() const noexcept { return baseType() == RegType::kNone; }
+ ASMJIT_INLINE_NODEBUG constexpr bool isOffset64Bit() const noexcept { return baseType() == RegType::kNone; }
//! Tests whether the memory operand has a non-zero offset or absolute address.
- inline constexpr bool hasOffset() const noexcept {
+ ASMJIT_INLINE_NODEBUG 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.
- inline constexpr int64_t offset() const noexcept {
+ ASMJIT_INLINE_NODEBUG 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.
- inline constexpr int32_t offsetLo32() const noexcept { return int32_t(_data[kDataMemOffsetLo]); }
+ ASMJIT_INLINE_NODEBUG 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.
- inline constexpr int32_t offsetHi32() const noexcept { return int32_t(_baseId); }
+ ASMJIT_INLINE_NODEBUG constexpr int32_t offsetHi32() const noexcept { return int32_t(_baseId); }
//! Sets a 64-bit offset or an absolute address to `offset`.
//!
@@ -1383,15 +1656,20 @@ public:
}
//! 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); }
+ ASMJIT_INLINE_NODEBUG void addOffsetLo32(int32_t offset) noexcept { _data[kDataMemOffsetLo] += uint32_t(offset); }
//! Resets the memory offset to zero.
- inline void resetOffset() noexcept { setOffset(0); }
+ ASMJIT_INLINE_NODEBUG void resetOffset() noexcept { setOffset(0); }
//! 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_INLINE_NODEBUG void resetOffsetLo32() noexcept { setOffsetLo32(0); }
//! \}
+
+#if !defined(ASMJIT_NO_DEPRECATED)
+ ASMJIT_DEPRECATED("setSize() is no longer portable - use setX86RmSize() or x86::Mem::setSize() instead, if your target is X86/X86_64")
+ ASMJIT_INLINE_NODEBUG void setSize(uint32_t size) noexcept { _signature.setField<Signature::kSizeMask>(size); }
+#endif
};
//! Type of the an immediate value.
@@ -1423,15 +1701,15 @@ public:
//! \{
//! Creates a new immediate value (initial value is 0).
- inline constexpr Imm() noexcept
+ ASMJIT_INLINE_NODEBUG constexpr Imm() noexcept
: Operand(Globals::Init, Signature::fromOpType(OperandType::kImm), 0, 0, 0) {}
//! Creates a new immediate value from `other`.
- inline constexpr Imm(const Imm& other) noexcept
+ ASMJIT_INLINE_NODEBUG constexpr Imm(const Imm& other) noexcept
: Operand(other) {}
//! Creates a new immediate value from ARM/AArch64 specific `shift`.
- inline constexpr Imm(const arm::Shift& shift) noexcept
+ ASMJIT_INLINE_NODEBUG constexpr Imm(const arm::Shift& shift) noexcept
: Operand(Globals::Init,
Signature::fromOpType(OperandType::kImm) | Signature::fromPredicate(uint32_t(shift.op())),
0,
@@ -1443,28 +1721,28 @@ public:
//!
//! \note Predicate is currently only used by ARM architectures.
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
+ ASMJIT_INLINE_NODEBUG constexpr Imm(const T& val, const uint32_t predicate = 0) noexcept
: 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
+ ASMJIT_INLINE_NODEBUG Imm(const float& val, const uint32_t predicate = 0) noexcept
: 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
+ ASMJIT_INLINE_NODEBUG Imm(const double& val, const uint32_t predicate = 0) noexcept
: Operand(Globals::Init,
Signature::fromOpType(OperandType::kImm) | Signature::fromPredicate(predicate),
0,
0,
0) { setValue(val); }
- inline explicit Imm(Globals::NoInit_) noexcept
+ ASMJIT_INLINE_NODEBUG explicit Imm(Globals::NoInit_) noexcept
: Operand(Globals::NoInit) {}
//! \}
@@ -1473,7 +1751,7 @@ public:
//! \{
//! Assigns the value of the `other` operand to this immediate.
- inline Imm& operator=(const Imm& other) noexcept { copyFrom(other); return *this; }
+ ASMJIT_INLINE_NODEBUG Imm& operator=(const Imm& other) noexcept { copyFrom(other); return *this; }
//! \}
@@ -1481,73 +1759,73 @@ public:
//! \{
//! Returns immediate type.
- inline constexpr ImmType type() const noexcept { return (ImmType)_signature.getField<Signature::kImmTypeMask>(); }
+ ASMJIT_INLINE_NODEBUG 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)); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG 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::ShiftOp
//! of the immediate.
- inline constexpr uint32_t predicate() const noexcept { return _signature.getField<Signature::kPredicateMask>(); }
+ ASMJIT_INLINE_NODEBUG 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::ShiftOp
//! of the immediate.
- inline void setPredicate(uint32_t predicate) noexcept { _signature.setField<Signature::kPredicateMask>(predicate); }
+ ASMJIT_INLINE_NODEBUG 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 { _signature.setField<Signature::kPredicateMask>(0); }
+ ASMJIT_INLINE_NODEBUG void resetPredicate() noexcept { _signature.setField<Signature::kPredicateMask>(0); }
//! Returns the immediate value as `int64_t`, which is the internal format Imm uses.
- inline constexpr int64_t value() const noexcept {
+ ASMJIT_INLINE_NODEBUG 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.
- inline constexpr uint32_t isInt() const noexcept { return type() == ImmType::kInt; }
+ ASMJIT_INLINE_NODEBUG constexpr uint32_t isInt() const noexcept { return type() == ImmType::kInt; }
//! Tests whether this immediate value is a double precision floating point value.
- inline constexpr uint32_t isDouble() const noexcept { return type() == ImmType::kDouble; }
+ ASMJIT_INLINE_NODEBUG constexpr uint32_t isDouble() const noexcept { return type() == ImmType::kDouble; }
//! Tests whether the immediate can be casted to 8-bit signed integer.
- inline constexpr bool isInt8() const noexcept { return type() == ImmType::kInt && Support::isInt8(value()); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isInt8() const noexcept { return type() == ImmType::kInt && Support::isInt8(value()); }
//! Tests whether the immediate can be casted to 8-bit unsigned integer.
- inline constexpr bool isUInt8() const noexcept { return type() == ImmType::kInt && Support::isUInt8(value()); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isUInt8() const noexcept { return type() == ImmType::kInt && Support::isUInt8(value()); }
//! Tests whether the immediate can be casted to 16-bit signed integer.
- inline constexpr bool isInt16() const noexcept { return type() == ImmType::kInt && Support::isInt16(value()); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isInt16() const noexcept { return type() == ImmType::kInt && Support::isInt16(value()); }
//! Tests whether the immediate can be casted to 16-bit unsigned integer.
- inline constexpr bool isUInt16() const noexcept { return type() == ImmType::kInt && Support::isUInt16(value()); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isUInt16() const noexcept { return type() == ImmType::kInt && Support::isUInt16(value()); }
//! Tests whether the immediate can be casted to 32-bit signed integer.
- inline constexpr bool isInt32() const noexcept { return type() == ImmType::kInt && Support::isInt32(value()); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isInt32() const noexcept { return type() == ImmType::kInt && Support::isInt32(value()); }
//! Tests whether the immediate can be casted to 32-bit unsigned integer.
- inline constexpr bool isUInt32() const noexcept { return type() == ImmType::kInt && _data[kDataImmValueHi] == 0; }
+ ASMJIT_INLINE_NODEBUG 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.
template<typename T>
- inline T valueAs() const noexcept { return Support::immediateToT<T>(value()); }
+ ASMJIT_INLINE_NODEBUG T valueAs() const noexcept { return Support::immediateToT<T>(value()); }
//! Returns low 32-bit signed integer.
- inline constexpr int32_t int32Lo() const noexcept { return int32_t(_data[kDataImmValueLo]); }
+ ASMJIT_INLINE_NODEBUG constexpr int32_t int32Lo() const noexcept { return int32_t(_data[kDataImmValueLo]); }
//! Returns high 32-bit signed integer.
- inline constexpr int32_t int32Hi() const noexcept { return int32_t(_data[kDataImmValueHi]); }
+ ASMJIT_INLINE_NODEBUG constexpr int32_t int32Hi() const noexcept { return int32_t(_data[kDataImmValueHi]); }
//! Returns low 32-bit signed integer.
- inline constexpr uint32_t uint32Lo() const noexcept { return _data[kDataImmValueLo]; }
+ ASMJIT_INLINE_NODEBUG constexpr uint32_t uint32Lo() const noexcept { return _data[kDataImmValueLo]; }
//! Returns high 32-bit signed integer.
- inline constexpr uint32_t uint32Hi() const noexcept { return _data[kDataImmValueHi]; }
+ ASMJIT_INLINE_NODEBUG 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 {
+ ASMJIT_INLINE_NODEBUG void setValue(const T& val) noexcept {
_setValueInternal(Support::immediateFromT(val), std::is_floating_point<T>::value ? ImmType::kDouble : ImmType::kInt);
}
- inline void _setValueInternal(int64_t val, ImmType type) noexcept {
+ ASMJIT_INLINE_NODEBUG 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);
@@ -1559,22 +1837,22 @@ public:
//! \{
//! Clones the immediate operand.
- inline constexpr Imm clone() const noexcept { return Imm(*this); }
+ ASMJIT_INLINE_NODEBUG 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>())); }
- inline void signExtend32Bits() noexcept { setValue(int64_t(valueAs<int32_t>())); }
+ ASMJIT_INLINE_NODEBUG void signExtend8Bits() noexcept { setValue(int64_t(valueAs<int8_t>())); }
+ ASMJIT_INLINE_NODEBUG void signExtend16Bits() noexcept { setValue(int64_t(valueAs<int16_t>())); }
+ ASMJIT_INLINE_NODEBUG void signExtend32Bits() noexcept { setValue(int64_t(valueAs<int32_t>())); }
- inline void zeroExtend8Bits() noexcept { setValue(valueAs<uint8_t>()); }
- inline void zeroExtend16Bits() noexcept { setValue(valueAs<uint16_t>()); }
- inline void zeroExtend32Bits() noexcept { _data[kDataImmValueHi] = 0u; }
+ ASMJIT_INLINE_NODEBUG void zeroExtend8Bits() noexcept { setValue(valueAs<uint8_t>()); }
+ ASMJIT_INLINE_NODEBUG void zeroExtend16Bits() noexcept { setValue(valueAs<uint16_t>()); }
+ ASMJIT_INLINE_NODEBUG void zeroExtend32Bits() noexcept { _data[kDataImmValueHi] = 0u; }
//! \}
};
//! Creates a new immediate operand.
template<typename T>
-static inline constexpr Imm imm(const T& val) noexcept { return Imm(val); }
+static ASMJIT_INLINE_NODEBUG constexpr Imm imm(const T& val) noexcept { return Imm(val); }
//! \}
@@ -1590,12 +1868,12 @@ namespace Support {
template<typename T, bool kIsImm>
struct ForwardOpImpl {
- static inline const T& forward(const T& value) noexcept { return value; }
+ static ASMJIT_INLINE_NODEBUG const T& forward(const T& value) noexcept { return value; }
};
template<typename T>
struct ForwardOpImpl<T, true> {
- static inline Imm forward(const T& value) noexcept { return Imm(value); }
+ static ASMJIT_INLINE_NODEBUG Imm forward(const T& value) noexcept { return Imm(value); }
};
//! Either forwards operand T or returns a new operand that wraps it if T is a type convertible to operand.
diff --git a/3rdparty/asmjit/src/asmjit/core/osutils.cpp b/3rdparty/asmjit/src/asmjit/core/osutils.cpp
index fa900bfbb4c..2d390697f89 100644
--- a/3rdparty/asmjit/src/asmjit/core/osutils.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/osutils.cpp
@@ -4,81 +4,37 @@
// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
-#include "../core/osutils.h"
+#include "../core/osutils_p.h"
#include "../core/support.h"
-#if defined(_WIN32)
- #include <atomic>
-#elif defined(__APPLE__)
- #include <mach/mach_time.h>
-#else
- #include <time.h>
+#if !defined(_WIN32)
+ #include <fcntl.h>
#include <unistd.h>
#endif
ASMJIT_BEGIN_NAMESPACE
-uint32_t OSUtils::getTickCount() noexcept {
-#if defined(_WIN32)
- enum HiResStatus : uint32_t {
- kHiResUnknown = 0,
- kHiResAvailable = 1,
- kHiResNotAvailable = 2
- };
+#if !defined(_WIN32)
+Error OSUtils::readFile(const char* name, String& dst, size_t maxSize) noexcept {
+ char* buffer = dst.prepare(String::ModifyOp::kAssign, maxSize);
+ if (ASMJIT_UNLIKELY(!buffer))
+ return DebugUtils::errored(kErrorOutOfMemory);
- static std::atomic<uint32_t> _hiResStatus(kHiResUnknown);
- static volatile double _hiResFreq(0);
-
- uint32_t status = _hiResStatus.load();
- LARGE_INTEGER now, qpf;
-
- if (status != kHiResNotAvailable && ::QueryPerformanceCounter(&now)) {
- double freq = _hiResFreq;
- if (status == kHiResUnknown) {
- // Detects the availability of high resolution counter.
- if (::QueryPerformanceFrequency(&qpf)) {
- freq = double(qpf.QuadPart) / 1000.0;
- _hiResFreq = freq;
- _hiResStatus.compare_exchange_strong(status, kHiResAvailable);
- status = kHiResAvailable;
- }
- else {
- // High resolution not available.
- _hiResStatus.compare_exchange_strong(status, kHiResNotAvailable);
- }
- }
-
- if (status == kHiResAvailable)
- return uint32_t(uint64_t(int64_t(double(now.QuadPart) / freq)) & 0xFFFFFFFFu);
+ int fd = ASMJIT_FILE64_API(::open)(name, O_RDONLY);
+ if (fd < 0) {
+ dst.clear();
+ return DebugUtils::errored(kErrorFailedToOpenFile);
}
- // Bail to `GetTickCount()` if we cannot use high resolution.
- return ::GetTickCount();
-#elif defined(__APPLE__)
- // See Apple's QA1398.
- static mach_timebase_info_data_t _machTime;
-
- uint32_t denom = _machTime.denom;
- if (ASMJIT_UNLIKELY(!denom)) {
- if (mach_timebase_info(&_machTime) != KERN_SUCCESS || !(denom = _machTime.denom))
- return 0;
+ intptr_t len = ::read(fd, buffer, maxSize);
+ if (len >= 0) {
+ buffer[len] = '\0';
+ dst._setSize(size_t(len));
}
- // `mach_absolute_time()` returns nanoseconds, we want milliseconds.
- uint64_t t = mach_absolute_time() / 1000000u;
- t = (t * _machTime.numer) / _machTime.denom;
- return uint32_t(t & 0xFFFFFFFFu);
-#elif defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0
- struct timespec ts;
- if (ASMJIT_UNLIKELY(clock_gettime(CLOCK_MONOTONIC, &ts) != 0))
- return 0;
-
- uint64_t t = (uint64_t(ts.tv_sec ) * 1000u) + (uint64_t(ts.tv_nsec) / 1000000u);
- return uint32_t(t & 0xFFFFFFFFu);
-#else
- #pragma message("asmjit::OSUtils::getTickCount() doesn't have implementation for the target OS.")
- return 0;
-#endif
+ ::close(fd);
+ return kErrorOk;
}
+#endif
ASMJIT_END_NAMESPACE
diff --git a/3rdparty/asmjit/src/asmjit/core/osutils.h b/3rdparty/asmjit/src/asmjit/core/osutils.h
index 3c5c3d94c1e..c6588373425 100644
--- a/3rdparty/asmjit/src/asmjit/core/osutils.h
+++ b/3rdparty/asmjit/src/asmjit/core/osutils.h
@@ -13,13 +13,6 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_utilities
//! \{
-//! Operating system utilities.
-namespace OSUtils {
- //! Gets the current CPU tick count, used for benchmarking (1ms resolution).
- ASMJIT_API uint32_t getTickCount() noexcept;
-};
-
-
//! \cond INTERNAL
//! Lock.
//!
@@ -46,11 +39,11 @@ public:
Handle _handle;
#endif
- ASMJIT_FORCE_INLINE Lock() noexcept;
- ASMJIT_FORCE_INLINE ~Lock() noexcept;
+ ASMJIT_INLINE_NODEBUG Lock() noexcept;
+ ASMJIT_INLINE_NODEBUG ~Lock() noexcept;
- ASMJIT_FORCE_INLINE void lock() noexcept;
- ASMJIT_FORCE_INLINE void unlock() noexcept;
+ ASMJIT_INLINE_NODEBUG void lock() noexcept;
+ ASMJIT_INLINE_NODEBUG void unlock() noexcept;
};
//! \endcond
diff --git a/3rdparty/asmjit/src/asmjit/core/osutils_p.h b/3rdparty/asmjit/src/asmjit/core/osutils_p.h
index fd87e731123..0d9d36909e8 100644
--- a/3rdparty/asmjit/src/asmjit/core/osutils_p.h
+++ b/3rdparty/asmjit/src/asmjit/core/osutils_p.h
@@ -7,6 +7,7 @@
#define ASMJIT_CORE_OSUTILS_P_H_INCLUDED
#include "../core/osutils.h"
+#include "../core/string.h"
ASMJIT_BEGIN_NAMESPACE
@@ -20,30 +21,30 @@ ASMJIT_BEGIN_NAMESPACE
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");
-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)); }
+ASMJIT_INLINE_NODEBUG Lock::Lock() noexcept { InitializeCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&_handle)); }
+ASMJIT_INLINE_NODEBUG Lock::~Lock() noexcept { DeleteCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&_handle)); }
+ASMJIT_INLINE_NODEBUG void Lock::lock() noexcept { EnterCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&_handle)); }
+ASMJIT_INLINE_NODEBUG void Lock::unlock() noexcept { LeaveCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&_handle)); }
#elif !defined(__EMSCRIPTEN__)
// PThread implementation.
#ifdef PTHREAD_MUTEX_INITIALIZER
-ASMJIT_FORCE_INLINE Lock::Lock() noexcept : _handle(PTHREAD_MUTEX_INITIALIZER) {}
+ASMJIT_INLINE_NODEBUG Lock::Lock() noexcept : _handle(PTHREAD_MUTEX_INITIALIZER) {}
#else
-ASMJIT_FORCE_INLINE Lock::Lock() noexcept { pthread_mutex_init(&_handle, nullptr); }
+ASMJIT_INLINE_NODEBUG Lock::Lock() noexcept { pthread_mutex_init(&_handle, nullptr); }
#endif
-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); }
+ASMJIT_INLINE_NODEBUG Lock::~Lock() noexcept { pthread_mutex_destroy(&_handle); }
+ASMJIT_INLINE_NODEBUG void Lock::lock() noexcept { pthread_mutex_lock(&_handle); }
+ASMJIT_INLINE_NODEBUG void Lock::unlock() noexcept { pthread_mutex_unlock(&_handle); }
#else
// Dummy implementation - Emscripten or other unsupported platform.
-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 {}
+ASMJIT_INLINE_NODEBUG Lock::Lock() noexcept {}
+ASMJIT_INLINE_NODEBUG Lock::~Lock() noexcept {}
+ASMJIT_INLINE_NODEBUG void Lock::lock() noexcept {}
+ASMJIT_INLINE_NODEBUG void Lock::unlock() noexcept {}
#endif
@@ -54,11 +55,20 @@ public:
Lock& _target;
- inline LockGuard(Lock& target) noexcept
+ ASMJIT_INLINE_NODEBUG LockGuard(Lock& target) noexcept
: _target(target) { _target.lock(); }
- inline ~LockGuard() noexcept { _target.unlock(); }
+ ASMJIT_INLINE_NODEBUG ~LockGuard() noexcept { _target.unlock(); }
};
+#if !defined(_WIN32)
+namespace OSUtils {
+
+//! Reads a file, only used on non-Windows platforms to access /sys or other files when necessary.
+Error readFile(const char* name, String& dst, size_t maxSize) noexcept;
+
+} // {OSUtils}
+#endif
+
//! \}
//! \endcond
diff --git a/3rdparty/asmjit/src/asmjit/core/raassignment_p.h b/3rdparty/asmjit/src/asmjit/core/raassignment_p.h
index 54183293111..0865ece7548 100644
--- a/3rdparty/asmjit/src/asmjit/core/raassignment_p.h
+++ b/3rdparty/asmjit/src/asmjit/core/raassignment_p.h
@@ -66,7 +66,7 @@ public:
//! PhysReg to WorkReg mapping.
uint32_t workIds[1 /* ... */];
- static inline size_t sizeOf(size_t count) noexcept {
+ static ASMJIT_INLINE_NODEBUG size_t sizeOf(size_t count) noexcept {
return sizeof(PhysToWorkMap) - sizeof(uint32_t) + count * sizeof(uint32_t);
}
@@ -163,16 +163,16 @@ public:
//! \name Accessors
//! \{
- inline PhysToWorkMap* physToWorkMap() const noexcept { return _physToWorkMap; }
- inline WorkToPhysMap* workToPhysMap() const noexcept { return _workToPhysMap; }
+ ASMJIT_INLINE_NODEBUG PhysToWorkMap* physToWorkMap() const noexcept { return _physToWorkMap; }
+ ASMJIT_INLINE_NODEBUG WorkToPhysMap* workToPhysMap() const noexcept { return _workToPhysMap; }
- inline RARegMask& assigned() noexcept { return _physToWorkMap->assigned; }
- inline const RARegMask& assigned() const noexcept { return _physToWorkMap->assigned; }
- inline uint32_t assigned(RegGroup group) const noexcept { return _physToWorkMap->assigned[group]; }
+ ASMJIT_INLINE_NODEBUG RARegMask& assigned() noexcept { return _physToWorkMap->assigned; }
+ ASMJIT_INLINE_NODEBUG const RARegMask& assigned() const noexcept { return _physToWorkMap->assigned; }
+ ASMJIT_INLINE_NODEBUG 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 RegMask dirty(RegGroup group) const noexcept { return _physToWorkMap->dirty[group]; }
+ ASMJIT_INLINE_NODEBUG RARegMask& dirty() noexcept { return _physToWorkMap->dirty; }
+ ASMJIT_INLINE_NODEBUG const RARegMask& dirty() const noexcept { return _physToWorkMap->dirty; }
+ ASMJIT_INLINE_NODEBUG RegMask dirty(RegGroup group) const noexcept { return _physToWorkMap->dirty[group]; }
inline uint32_t workToPhysId(RegGroup group, uint32_t workId) const noexcept {
DebugUtils::unused(group);
diff --git a/3rdparty/asmjit/src/asmjit/core/rabuilders_p.h b/3rdparty/asmjit/src/asmjit/core/rabuilders_p.h
index 1b763030c45..9d9b4282d2b 100644
--- a/3rdparty/asmjit/src/asmjit/core/rabuilders_p.h
+++ b/3rdparty/asmjit/src/asmjit/core/rabuilders_p.h
@@ -401,7 +401,7 @@ public:
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))
+ if (ASMJIT_UNLIKELY(_curBlock && _hasCode))
return DebugUtils::errored(kErrorInvalidState);
break;
}
diff --git a/3rdparty/asmjit/src/asmjit/core/radefs_p.h b/3rdparty/asmjit/src/asmjit/core/radefs_p.h
index 15c50ff728c..32503961068 100644
--- a/3rdparty/asmjit/src/asmjit/core/radefs_p.h
+++ b/3rdparty/asmjit/src/asmjit/core/radefs_p.h
@@ -67,7 +67,7 @@ public:
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::kMask] = Support::lsbMask<RegMask>(8);
_availableRegs[RegGroup::kExtraVirt3] = Support::lsbMask<RegMask>(8);
return kErrorOk;
}
@@ -75,7 +75,7 @@ public:
case Arch::kAArch64: {
_availableRegs[RegGroup::kGp] = 0xFFFFFFFFu & ~Support::bitMask(18, 31u);
_availableRegs[RegGroup::kVec] = 0xFFFFFFFFu;
- _availableRegs[RegGroup::kExtraVirt2] = 0;
+ _availableRegs[RegGroup::kMask] = 0;
_availableRegs[RegGroup::kExtraVirt3] = 0;
return kErrorOk;
}
@@ -115,20 +115,20 @@ struct RAStrategy {
//! \name Accessors
//! \{
- inline void reset() noexcept {
+ ASMJIT_INLINE_NODEBUG 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_INLINE_NODEBUG RAStrategyType type() const noexcept { return _type; }
+ ASMJIT_INLINE_NODEBUG void setType(RAStrategyType type) noexcept { _type = type; }
- inline bool isSimple() const noexcept { return _type == RAStrategyType::kSimple; }
- inline bool isComplex() const noexcept { return _type >= RAStrategyType::kComplex; }
+ ASMJIT_INLINE_NODEBUG bool isSimple() const noexcept { return _type == RAStrategyType::kSimple; }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG RAStrategyFlags flags() const noexcept { return _flags; }
+ ASMJIT_INLINE_NODEBUG bool hasFlag(RAStrategyFlags flag) const noexcept { return Support::test(_flags, flag); }
+ ASMJIT_INLINE_NODEBUG void addFlags(RAStrategyFlags flags) noexcept { _flags |= flags; }
//! \}
};
@@ -153,7 +153,7 @@ struct RARegCount {
//! \{
//! Resets all counters to zero.
- inline void reset() noexcept { _packed = 0; }
+ ASMJIT_INLINE_NODEBUG void reset() noexcept { _packed = 0; }
//! \}
@@ -170,8 +170,8 @@ struct RARegCount {
return _regs[size_t(group)];
}
- inline bool operator==(const RARegCount& other) const noexcept { return _packed == other._packed; }
- inline bool operator!=(const RARegCount& other) const noexcept { return _packed != other._packed; }
+ ASMJIT_INLINE_NODEBUG bool operator==(const RARegCount& other) const noexcept { return _packed == other._packed; }
+ ASMJIT_INLINE_NODEBUG bool operator!=(const RARegCount& other) const noexcept { return _packed != other._packed; }
//! \}
@@ -233,17 +233,17 @@ struct RARegMask {
//! \name Construction & Destruction
//! \{
- inline void init(const RARegMask& other) noexcept { _masks = other._masks; }
+ ASMJIT_INLINE_NODEBUG void init(const RARegMask& other) noexcept { _masks = other._masks; }
//! Reset all register masks to zero.
- inline void reset() noexcept { _masks.fill(0); }
+ ASMJIT_INLINE_NODEBUG void reset() noexcept { _masks.fill(0); }
//! \}
//! \name Overloaded Operators
//! \{
- inline bool operator==(const RARegMask& other) const noexcept { return _masks == other._masks; }
- inline bool operator!=(const RARegMask& other) const noexcept { return _masks != other._masks; }
+ ASMJIT_INLINE_NODEBUG bool operator==(const RARegMask& other) const noexcept { return _masks == other._masks; }
+ ASMJIT_INLINE_NODEBUG bool operator!=(const RARegMask& other) const noexcept { return _masks != other._masks; }
template<typename Index>
inline uint32_t& operator[](const Index& index) noexcept { return _masks[index]; }
@@ -315,20 +315,20 @@ public:
//! \name Accessors
//! \{
- inline void reset() noexcept { _packed = 0; }
- inline void combineWith(const RARegsStats& other) noexcept { _packed |= other._packed; }
+ ASMJIT_INLINE_NODEBUG void reset() noexcept { _packed = 0; }
+ ASMJIT_INLINE_NODEBUG void combineWith(const RARegsStats& other) noexcept { _packed |= other._packed; }
- inline bool hasUsed() const noexcept { return (_packed & kMaskUsed) != 0u; }
- 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)); }
+ ASMJIT_INLINE_NODEBUG bool hasUsed() const noexcept { return (_packed & kMaskUsed) != 0u; }
+ ASMJIT_INLINE_NODEBUG bool hasUsed(RegGroup group) const noexcept { return (_packed & Support::bitMask(kIndexUsed + uint32_t(group))) != 0u; }
+ ASMJIT_INLINE_NODEBUG void makeUsed(RegGroup group) noexcept { _packed |= Support::bitMask(kIndexUsed + uint32_t(group)); }
- inline bool hasFixed() const noexcept { return (_packed & kMaskFixed) != 0u; }
- 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)); }
+ ASMJIT_INLINE_NODEBUG bool hasFixed() const noexcept { return (_packed & kMaskFixed) != 0u; }
+ ASMJIT_INLINE_NODEBUG bool hasFixed(RegGroup group) const noexcept { return (_packed & Support::bitMask(kIndexFixed + uint32_t(group))) != 0u; }
+ ASMJIT_INLINE_NODEBUG void makeFixed(RegGroup group) noexcept { _packed |= Support::bitMask(kIndexFixed + uint32_t(group)); }
- inline bool hasClobbered() const noexcept { return (_packed & kMaskClobbered) != 0u; }
- 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_INLINE_NODEBUG bool hasClobbered() const noexcept { return (_packed & kMaskClobbered) != 0u; }
+ ASMJIT_INLINE_NODEBUG bool hasClobbered(RegGroup group) const noexcept { return (_packed & Support::bitMask(kIndexClobbered + uint32_t(group))) != 0u; }
+ ASMJIT_INLINE_NODEBUG void makeClobbered(RegGroup group) noexcept { _packed |= Support::bitMask(kIndexClobbered + uint32_t(group)); }
//! \}
};
@@ -346,18 +346,18 @@ public:
//! \name Construction & Destruction
//! \{
- inline RALiveCount() noexcept = default;
- inline RALiveCount(const RALiveCount& other) noexcept = default;
+ ASMJIT_INLINE_NODEBUG RALiveCount() noexcept = default;
+ ASMJIT_INLINE_NODEBUG RALiveCount(const RALiveCount& other) noexcept = default;
- inline void init(const RALiveCount& other) noexcept { n = other.n; }
- inline void reset() noexcept { n.fill(0); }
+ ASMJIT_INLINE_NODEBUG void init(const RALiveCount& other) noexcept { n = other.n; }
+ ASMJIT_INLINE_NODEBUG void reset() noexcept { n.fill(0); }
//! \}
//! \name Overloaded Operators
//! \{
- inline RALiveCount& operator=(const RALiveCount& other) noexcept = default;
+ ASMJIT_INLINE_NODEBUG RALiveCount& operator=(const RALiveCount& other) noexcept = default;
inline uint32_t& operator[](RegGroup group) noexcept { return n[group]; }
inline const uint32_t& operator[](RegGroup group) const noexcept { return n[group]; }
@@ -394,31 +394,31 @@ struct RALiveInterval {
//! \name Construction & Destruction
//! \{
- inline RALiveInterval() noexcept : a(0), b(0) {}
- inline RALiveInterval(uint32_t a, uint32_t b) noexcept : a(a), b(b) {}
- inline RALiveInterval(const RALiveInterval& other) noexcept : a(other.a), b(other.b) {}
+ ASMJIT_INLINE_NODEBUG RALiveInterval() noexcept : a(0), b(0) {}
+ ASMJIT_INLINE_NODEBUG RALiveInterval(uint32_t a, uint32_t b) noexcept : a(a), b(b) {}
+ ASMJIT_INLINE_NODEBUG RALiveInterval(const RALiveInterval& other) noexcept : a(other.a), b(other.b) {}
- inline void init(uint32_t aVal, uint32_t bVal) noexcept {
+ ASMJIT_INLINE_NODEBUG void init(uint32_t aVal, uint32_t bVal) noexcept {
a = aVal;
b = bVal;
}
- inline void init(const RALiveInterval& other) noexcept { init(other.a, other.b); }
- inline void reset() noexcept { init(0, 0); }
+ ASMJIT_INLINE_NODEBUG void init(const RALiveInterval& other) noexcept { init(other.a, other.b); }
+ ASMJIT_INLINE_NODEBUG void reset() noexcept { init(0, 0); }
//! \}
//! \name Overloaded Operators
//! \{
- inline RALiveInterval& operator=(const RALiveInterval& other) = default;
+ ASMJIT_INLINE_NODEBUG RALiveInterval& operator=(const RALiveInterval& other) = default;
//! \}
//! \name Accessors
//! \{
- inline bool isValid() const noexcept { return a < b; }
- inline uint32_t width() const noexcept { return b - a; }
+ ASMJIT_INLINE_NODEBUG bool isValid() const noexcept { return a < b; }
+ ASMJIT_INLINE_NODEBUG uint32_t width() const noexcept { return b - a; }
//! \}
};
@@ -437,23 +437,23 @@ public:
//! \name Construction & Destruction
//! \{
- inline RALiveSpan() noexcept : RALiveInterval(), T() {}
- inline RALiveSpan(const RALiveSpan<T>& other) noexcept : RALiveInterval(other), T() {}
- inline RALiveSpan(const RALiveInterval& interval, const T& data) noexcept : RALiveInterval(interval), T(data) {}
- inline RALiveSpan(uint32_t a, uint32_t b) noexcept : RALiveInterval(a, b), T() {}
- inline RALiveSpan(uint32_t a, uint32_t b, const T& data) noexcept : RALiveInterval(a, b), T(data) {}
+ ASMJIT_INLINE_NODEBUG RALiveSpan() noexcept : RALiveInterval(), T() {}
+ ASMJIT_INLINE_NODEBUG RALiveSpan(const RALiveSpan<T>& other) noexcept : RALiveInterval(other), T() {}
+ ASMJIT_INLINE_NODEBUG RALiveSpan(const RALiveInterval& interval, const T& data) noexcept : RALiveInterval(interval), T(data) {}
+ ASMJIT_INLINE_NODEBUG RALiveSpan(uint32_t a, uint32_t b) noexcept : RALiveInterval(a, b), T() {}
+ ASMJIT_INLINE_NODEBUG RALiveSpan(uint32_t a, uint32_t b, const T& data) noexcept : RALiveInterval(a, b), T(data) {}
- inline void init(const RALiveSpan<T>& other) noexcept {
+ ASMJIT_INLINE_NODEBUG void init(const RALiveSpan<T>& other) noexcept {
RALiveInterval::init(static_cast<const RALiveInterval&>(other));
T::init(static_cast<const T&>(other));
}
- inline void init(const RALiveSpan<T>& span, const T& data) noexcept {
+ ASMJIT_INLINE_NODEBUG void init(const RALiveSpan<T>& span, const T& data) noexcept {
RALiveInterval::init(static_cast<const RALiveInterval&>(span));
T::init(data);
}
- inline void init(const RALiveInterval& interval, const T& data) noexcept {
+ ASMJIT_INLINE_NODEBUG void init(const RALiveInterval& interval, const T& data) noexcept {
RALiveInterval::init(interval);
T::init(data);
}
@@ -463,7 +463,7 @@ public:
//! \name Overloaded Operators
//! \{
- inline RALiveSpan& operator=(const RALiveSpan& other) {
+ ASMJIT_INLINE_NODEBUG RALiveSpan& operator=(const RALiveSpan& other) {
init(other);
return *this;
}
@@ -483,23 +483,23 @@ public:
//! \name Construction & Destruction
//! \{
- inline RALiveSpans() noexcept : _data() {}
+ ASMJIT_INLINE_NODEBUG RALiveSpans() noexcept : _data() {}
- inline void reset() noexcept { _data.reset(); }
- inline void release(ZoneAllocator* allocator) noexcept { _data.release(allocator); }
+ ASMJIT_INLINE_NODEBUG void reset() noexcept { _data.reset(); }
+ ASMJIT_INLINE_NODEBUG void release(ZoneAllocator* allocator) noexcept { _data.release(allocator); }
//! \}
//! \name Accessors
//! \{
- inline bool empty() const noexcept { return _data.empty(); }
- inline uint32_t size() const noexcept { return _data.size(); }
+ ASMJIT_INLINE_NODEBUG bool empty() const noexcept { return _data.empty(); }
+ ASMJIT_INLINE_NODEBUG uint32_t size() const noexcept { return _data.size(); }
- inline T* data() noexcept { return _data.data(); }
- inline const T* data() const noexcept { return _data.data(); }
+ ASMJIT_INLINE_NODEBUG T* data() noexcept { return _data.data(); }
+ ASMJIT_INLINE_NODEBUG const T* data() const noexcept { return _data.data(); }
- inline bool isOpen() const noexcept {
+ ASMJIT_INLINE_NODEBUG bool isOpen() const noexcept {
uint32_t size = _data.size();
return size > 0 && _data[size - 1].b == RALiveInterval::kInf;
}
@@ -509,7 +509,7 @@ public:
//! \name Utilities
//! \{
- inline void swap(RALiveSpans<T>& other) noexcept { _data.swap(other._data); }
+ ASMJIT_INLINE_NODEBUG void swap(RALiveSpans<T>& other) noexcept { _data.swap(other._data); }
//! Open the current live span.
ASMJIT_FORCE_INLINE Error openAt(ZoneAllocator* allocator, uint32_t start, uint32_t end) noexcept {
@@ -550,16 +550,16 @@ public:
return width;
}
- inline T& operator[](uint32_t index) noexcept { return _data[index]; }
- inline const T& operator[](uint32_t index) const noexcept { return _data[index]; }
+ ASMJIT_INLINE_NODEBUG T& operator[](uint32_t index) noexcept { return _data[index]; }
+ ASMJIT_INLINE_NODEBUG const T& operator[](uint32_t index) const noexcept { return _data[index]; }
- inline bool intersects(const RALiveSpans<T>& other) const noexcept {
+ ASMJIT_INLINE_NODEBUG bool intersects(const RALiveSpans<T>& other) const noexcept {
return intersects(*this, other);
}
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));
+ ASMJIT_PROPAGATE(_data.growingReserve(allocator, finalSize));
T* dstPtr = _data.data();
const T* xSpan = x.data();
@@ -655,9 +655,9 @@ public:
//! \name Accessors
//! \{
- inline uint32_t width() const noexcept { return _width; }
- inline float freq() const noexcept { return _freq; }
- inline float priority() const noexcept { return _priority; }
+ ASMJIT_INLINE_NODEBUG uint32_t width() const noexcept { return _width; }
+ ASMJIT_INLINE_NODEBUG float freq() const noexcept { return _freq; }
+ ASMJIT_INLINE_NODEBUG float priority() const noexcept { return _priority; }
//! \}
};
@@ -665,13 +665,13 @@ public:
struct LiveRegData {
uint32_t id;
- inline explicit LiveRegData(uint32_t id = BaseReg::kIdBad) noexcept : id(id) {}
- inline LiveRegData(const LiveRegData& other) noexcept : id(other.id) {}
+ ASMJIT_INLINE_NODEBUG explicit LiveRegData(uint32_t id = BaseReg::kIdBad) noexcept : id(id) {}
+ ASMJIT_INLINE_NODEBUG LiveRegData(const LiveRegData& other) noexcept = default;
- inline void init(const LiveRegData& other) noexcept { id = other.id; }
+ ASMJIT_INLINE_NODEBUG void init(const LiveRegData& other) noexcept { id = other.id; }
- inline bool operator==(const LiveRegData& other) const noexcept { return id == other.id; }
- inline bool operator!=(const LiveRegData& other) const noexcept { return id != other.id; }
+ ASMJIT_INLINE_NODEBUG bool operator==(const LiveRegData& other) const noexcept { return id == other.id; }
+ ASMJIT_INLINE_NODEBUG bool operator!=(const LiveRegData& other) const noexcept { return id != other.id; }
};
typedef RALiveSpan<LiveRegData> LiveRegSpan;
@@ -694,7 +694,7 @@ typedef RALiveSpans<LiveRegSpan> LiveRegSpans;
//! - 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
+//! information, which is then merged to RATiedReg's flags. However, we also need to represent the possibility
//! 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 {
@@ -740,6 +740,11 @@ enum class RATiedFlags : uint32_t {
kLeadConsecutive = 0x00001000u,
kConsecutiveData = 0x00006000u,
+ // Other Constraints
+ // -----------------
+
+ kUnique = 0x00008000u,
+
// Liveness Flags
// --------------
@@ -762,6 +767,12 @@ enum class RATiedFlags : uint32_t {
// Instruction Flags (Never used by RATiedReg)
// -------------------------------------------
+ //! Instruction has been patched to address a memory location instead of a register.
+ //!
+ //! This is currently only possible on X86 or X86_64 targets. It informs rewriter to rewrite the instruction if
+ //! necessary.
+ kInst_RegToMemPatched = 0x40000000u,
+
//! 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
@@ -853,51 +864,54 @@ struct RATiedReg {
//! \{
//! Returns the associated WorkReg id.
- inline uint32_t workId() const noexcept { return _workId; }
+ ASMJIT_INLINE_NODEBUG uint32_t workId() const noexcept { return _workId; }
- 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); }
+ ASMJIT_INLINE_NODEBUG bool hasConsecutiveParent() const noexcept { return _consecutiveParent != Globals::kInvalidId; }
+ ASMJIT_INLINE_NODEBUG uint32_t consecutiveParent() const noexcept { return _consecutiveParent; }
+ ASMJIT_INLINE_NODEBUG uint32_t consecutiveData() const noexcept { return consecutiveDataFromFlags(_flags); }
//! Returns TiedReg flags.
- inline RATiedFlags flags() const noexcept { return _flags; }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG bool hasFlag(RATiedFlags flag) const noexcept { return Support::test(_flags, flag); }
//! Adds tied register flags.
- inline void addFlags(RATiedFlags flags) noexcept { _flags |= flags; }
+ ASMJIT_INLINE_NODEBUG 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(RATiedFlags::kRead); }
+ ASMJIT_INLINE_NODEBUG 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(RATiedFlags::kWrite); }
+ ASMJIT_INLINE_NODEBUG bool isWrite() const noexcept { return hasFlag(RATiedFlags::kWrite); }
//! Tests whether the register is read only.
- inline bool isReadOnly() const noexcept { return (_flags & RATiedFlags::kRW) == RATiedFlags::kRead; }
+ ASMJIT_INLINE_NODEBUG bool isReadOnly() const noexcept { return (_flags & RATiedFlags::kRW) == RATiedFlags::kRead; }
//! Tests whether the register is write only.
- inline bool isWriteOnly() const noexcept { return (_flags & RATiedFlags::kRW) == RATiedFlags::kWrite; }
+ ASMJIT_INLINE_NODEBUG 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 & RATiedFlags::kRW) == RATiedFlags::kRW; }
+ ASMJIT_INLINE_NODEBUG 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(RATiedFlags::kUse); }
+ ASMJIT_INLINE_NODEBUG bool isUse() const noexcept { return hasFlag(RATiedFlags::kUse); }
//! Tests whether the tied register has out operand (Write).
- inline bool isOut() const noexcept { return hasFlag(RATiedFlags::kOut); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG bool isOutConsecutive() const noexcept { return hasFlag(RATiedFlags::kOutConsecutive); }
+
+ //! Tests whether the tied register must be unique (cannot be allocated to any other allocated register).
+ ASMJIT_INLINE_NODEBUG bool isUnique() const noexcept { return hasFlag(RATiedFlags::kUnique); }
//! Tests whether the tied register has any consecutive flag.
- inline bool hasAnyConsecutiveFlag() const noexcept { return hasFlag(RATiedFlags::kLeadConsecutive | RATiedFlags::kUseConsecutive | RATiedFlags::kOutConsecutive); }
+ ASMJIT_INLINE_NODEBUG 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(RATiedFlags::kUseRM); }
+ ASMJIT_INLINE_NODEBUG 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(RATiedFlags::kOutRM); }
+ ASMJIT_INLINE_NODEBUG bool hasOutRM() const noexcept { return hasFlag(RATiedFlags::kOutRM); }
- inline uint32_t rmSize() const noexcept { return _rmSize; }
+ ASMJIT_INLINE_NODEBUG uint32_t rmSize() const noexcept { return _rmSize; }
inline void makeReadOnly() noexcept {
_flags = (_flags & ~(RATiedFlags::kOut | RATiedFlags::kWrite)) | RATiedFlags::kUse;
@@ -912,47 +926,47 @@ struct RATiedReg {
}
//! Tests whether the register would duplicate.
- inline bool isDuplicate() const noexcept { return hasFlag(RATiedFlags::kDuplicate); }
+ ASMJIT_INLINE_NODEBUG 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(RATiedFlags::kLast); }
+ ASMJIT_INLINE_NODEBUG 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(RATiedFlags::kKill); }
+ ASMJIT_INLINE_NODEBUG 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(RATiedFlags::kOut | RATiedFlags::kKill); }
+ ASMJIT_INLINE_NODEBUG bool isOutOrKill() const noexcept { return hasFlag(RATiedFlags::kOut | RATiedFlags::kKill); }
//! Returns a register mask that describes allocable USE registers (Read/ReadWrite access).
- inline RegMask useRegMask() const noexcept { return _useRegMask; }
+ ASMJIT_INLINE_NODEBUG RegMask useRegMask() const noexcept { return _useRegMask; }
//! Returns a register mask that describes allocable OUT registers (WriteOnly access).
- inline RegMask outRegMask() const noexcept { return _outRegMask; }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG uint32_t refCount() const noexcept { return _refCount; }
+ ASMJIT_INLINE_NODEBUG void addRefCount(uint32_t n = 1) noexcept { _refCount = uint8_t(_refCount + n); }
//! Tests whether the register must be allocated to a fixed physical register before it's used.
- inline bool hasUseId() const noexcept { return _useId != BaseReg::kIdBad; }
+ ASMJIT_INLINE_NODEBUG bool hasUseId() const noexcept { return _useId != BaseReg::kIdBad; }
//! Tests whether the register must be allocated to a fixed physical register before it's written.
- inline bool hasOutId() const noexcept { return _outId != BaseReg::kIdBad; }
+ ASMJIT_INLINE_NODEBUG bool hasOutId() const noexcept { return _outId != BaseReg::kIdBad; }
//! Returns a physical register id used for 'use' operation.
- inline uint32_t useId() const noexcept { return _useId; }
+ ASMJIT_INLINE_NODEBUG uint32_t useId() const noexcept { return _useId; }
//! Returns a physical register id used for 'out' operation.
- inline uint32_t outId() const noexcept { return _outId; }
+ ASMJIT_INLINE_NODEBUG uint32_t outId() const noexcept { return _outId; }
- inline uint32_t useRewriteMask() const noexcept { return _useRewriteMask; }
- inline uint32_t outRewriteMask() const noexcept { return _outRewriteMask; }
+ ASMJIT_INLINE_NODEBUG uint32_t useRewriteMask() const noexcept { return _useRewriteMask; }
+ ASMJIT_INLINE_NODEBUG uint32_t outRewriteMask() const noexcept { return _outRewriteMask; }
//! Sets a physical register used for 'use' operation.
- inline void setUseId(uint32_t index) noexcept { _useId = uint8_t(index); }
+ ASMJIT_INLINE_NODEBUG void setUseId(uint32_t index) noexcept { _useId = uint8_t(index); }
//! Sets a physical register used for 'out' operation.
- inline void setOutId(uint32_t index) noexcept { _outId = uint8_t(index); }
+ ASMJIT_INLINE_NODEBUG void setOutId(uint32_t index) noexcept { _outId = uint8_t(index); }
- inline bool isUseDone() const noexcept { return hasFlag(RATiedFlags::kUseDone); }
- inline bool isOutDone() const noexcept { return hasFlag(RATiedFlags::kUseDone); }
+ ASMJIT_INLINE_NODEBUG bool isUseDone() const noexcept { return hasFlag(RATiedFlags::kUseDone); }
+ ASMJIT_INLINE_NODEBUG bool isOutDone() const noexcept { return hasFlag(RATiedFlags::kUseDone); }
- inline void markUseDone() noexcept { addFlags(RATiedFlags::kUseDone); }
- inline void markOutDone() noexcept { addFlags(RATiedFlags::kUseDone); }
+ ASMJIT_INLINE_NODEBUG void markUseDone() noexcept { addFlags(RATiedFlags::kUseDone); }
+ ASMJIT_INLINE_NODEBUG void markOutDone() noexcept { addFlags(RATiedFlags::kUseDone); }
//! \}
};
@@ -1082,7 +1096,7 @@ public:
//! \name Construction & Destruction
//! \{
- inline RAWorkReg(VirtReg* vReg, uint32_t workId) noexcept
+ ASMJIT_INLINE_NODEBUG RAWorkReg(VirtReg* vReg, uint32_t workId) noexcept
: _workId(workId),
_virtId(vReg->id()),
_virtReg(vReg),
@@ -1093,97 +1107,97 @@ public:
//! \name Accessors
//! \{
- inline uint32_t workId() const noexcept { return _workId; }
- inline uint32_t virtId() const noexcept { return _virtId; }
+ ASMJIT_INLINE_NODEBUG uint32_t workId() const noexcept { return _workId; }
+ ASMJIT_INLINE_NODEBUG uint32_t virtId() const noexcept { return _virtId; }
- inline const char* name() const noexcept { return _virtReg->name(); }
- inline uint32_t nameSize() const noexcept { return _virtReg->nameSize(); }
+ ASMJIT_INLINE_NODEBUG const char* name() const noexcept { return _virtReg->name(); }
+ ASMJIT_INLINE_NODEBUG uint32_t nameSize() const noexcept { return _virtReg->nameSize(); }
- inline TypeId typeId() const noexcept { return _virtReg->typeId(); }
+ ASMJIT_INLINE_NODEBUG TypeId typeId() const noexcept { return _virtReg->typeId(); }
- 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; }
+ ASMJIT_INLINE_NODEBUG RAWorkRegFlags flags() const noexcept { return _flags; }
+ ASMJIT_INLINE_NODEBUG bool hasFlag(RAWorkRegFlags flag) const noexcept { return Support::test(_flags, flag); }
+ ASMJIT_INLINE_NODEBUG void addFlags(RAWorkRegFlags flags) noexcept { _flags |= flags; }
- inline bool isAllocated() const noexcept { return hasFlag(RAWorkRegFlags::kAllocated); }
- inline void markAllocated() noexcept { addFlags(RAWorkRegFlags::kAllocated); }
+ ASMJIT_INLINE_NODEBUG bool isAllocated() const noexcept { return hasFlag(RAWorkRegFlags::kAllocated); }
+ ASMJIT_INLINE_NODEBUG void markAllocated() noexcept { addFlags(RAWorkRegFlags::kAllocated); }
- inline bool isLeadConsecutive() const noexcept { return hasFlag(RAWorkRegFlags::kLeadConsecutive); }
- inline void markLeadConsecutive() noexcept { addFlags(RAWorkRegFlags::kLeadConsecutive); }
+ ASMJIT_INLINE_NODEBUG bool isLeadConsecutive() const noexcept { return hasFlag(RAWorkRegFlags::kLeadConsecutive); }
+ ASMJIT_INLINE_NODEBUG void markLeadConsecutive() noexcept { addFlags(RAWorkRegFlags::kLeadConsecutive); }
- inline bool isProcessedConsecutive() const noexcept { return hasFlag(RAWorkRegFlags::kProcessedConsecutive); }
- inline void markProcessedConsecutive() noexcept { addFlags(RAWorkRegFlags::kProcessedConsecutive); }
+ ASMJIT_INLINE_NODEBUG bool isProcessedConsecutive() const noexcept { return hasFlag(RAWorkRegFlags::kProcessedConsecutive); }
+ ASMJIT_INLINE_NODEBUG void markProcessedConsecutive() noexcept { addFlags(RAWorkRegFlags::kProcessedConsecutive); }
- inline bool isStackUsed() const noexcept { return hasFlag(RAWorkRegFlags::kStackUsed); }
- inline void markStackUsed() noexcept { addFlags(RAWorkRegFlags::kStackUsed); }
+ ASMJIT_INLINE_NODEBUG bool isStackUsed() const noexcept { return hasFlag(RAWorkRegFlags::kStackUsed); }
+ ASMJIT_INLINE_NODEBUG void markStackUsed() noexcept { addFlags(RAWorkRegFlags::kStackUsed); }
- inline bool isStackPreferred() const noexcept { return hasFlag(RAWorkRegFlags::kStackPreferred); }
- inline void markStackPreferred() noexcept { addFlags(RAWorkRegFlags::kStackPreferred); }
+ ASMJIT_INLINE_NODEBUG bool isStackPreferred() const noexcept { return hasFlag(RAWorkRegFlags::kStackPreferred); }
+ ASMJIT_INLINE_NODEBUG 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(RAWorkRegFlags::kCoalesced); }
+ ASMJIT_INLINE_NODEBUG bool isCoalesced() const noexcept { return hasFlag(RAWorkRegFlags::kCoalesced); }
- inline OperandSignature signature() const noexcept { return _signature; }
- inline RegType type() const noexcept { return _signature.regType(); }
- inline RegGroup group() const noexcept { return _signature.regGroup(); }
+ ASMJIT_INLINE_NODEBUG OperandSignature signature() const noexcept { return _signature; }
+ ASMJIT_INLINE_NODEBUG RegType type() const noexcept { return _signature.regType(); }
+ ASMJIT_INLINE_NODEBUG RegGroup group() const noexcept { return _signature.regGroup(); }
- inline VirtReg* virtReg() const noexcept { return _virtReg; }
+ ASMJIT_INLINE_NODEBUG VirtReg* virtReg() const noexcept { return _virtReg; }
- inline bool hasTiedReg() const noexcept { return _tiedReg != nullptr; }
- inline RATiedReg* tiedReg() const noexcept { return _tiedReg; }
- inline void setTiedReg(RATiedReg* tiedReg) noexcept { _tiedReg = tiedReg; }
- inline void resetTiedReg() noexcept { _tiedReg = nullptr; }
+ ASMJIT_INLINE_NODEBUG bool hasTiedReg() const noexcept { return _tiedReg != nullptr; }
+ ASMJIT_INLINE_NODEBUG RATiedReg* tiedReg() const noexcept { return _tiedReg; }
+ ASMJIT_INLINE_NODEBUG void setTiedReg(RATiedReg* tiedReg) noexcept { _tiedReg = tiedReg; }
+ ASMJIT_INLINE_NODEBUG void resetTiedReg() noexcept { _tiedReg = nullptr; }
- inline bool hasStackSlot() const noexcept { return _stackSlot != nullptr; }
- inline RAStackSlot* stackSlot() const noexcept { return _stackSlot; }
+ ASMJIT_INLINE_NODEBUG bool hasStackSlot() const noexcept { return _stackSlot != nullptr; }
+ ASMJIT_INLINE_NODEBUG RAStackSlot* stackSlot() const noexcept { return _stackSlot; }
- inline LiveRegSpans& liveSpans() noexcept { return _liveSpans; }
- inline const LiveRegSpans& liveSpans() const noexcept { return _liveSpans; }
+ ASMJIT_INLINE_NODEBUG LiveRegSpans& liveSpans() noexcept { return _liveSpans; }
+ ASMJIT_INLINE_NODEBUG const LiveRegSpans& liveSpans() const noexcept { return _liveSpans; }
- inline RALiveStats& liveStats() noexcept { return _liveStats; }
- inline const RALiveStats& liveStats() const noexcept { return _liveStats; }
+ ASMJIT_INLINE_NODEBUG RALiveStats& liveStats() noexcept { return _liveStats; }
+ ASMJIT_INLINE_NODEBUG const RALiveStats& liveStats() const noexcept { return _liveStats; }
- inline bool hasArgIndex() const noexcept { return _argIndex != kNoArgIndex; }
- inline uint32_t argIndex() const noexcept { return _argIndex; }
- inline uint32_t argValueIndex() const noexcept { return _argValueIndex; }
+ ASMJIT_INLINE_NODEBUG bool hasArgIndex() const noexcept { return _argIndex != kNoArgIndex; }
+ ASMJIT_INLINE_NODEBUG uint32_t argIndex() const noexcept { return _argIndex; }
+ ASMJIT_INLINE_NODEBUG uint32_t argValueIndex() const noexcept { return _argValueIndex; }
inline void setArgIndex(uint32_t argIndex, uint32_t valueIndex) noexcept {
_argIndex = uint8_t(argIndex);
_argValueIndex = uint8_t(valueIndex);
}
- inline bool hasHomeRegId() const noexcept { return _homeRegId != BaseReg::kIdBad; }
- inline uint32_t homeRegId() const noexcept { return _homeRegId; }
- inline void setHomeRegId(uint32_t physId) noexcept { _homeRegId = uint8_t(physId); }
+ ASMJIT_INLINE_NODEBUG bool hasHomeRegId() const noexcept { return _homeRegId != BaseReg::kIdBad; }
+ ASMJIT_INLINE_NODEBUG uint32_t homeRegId() const noexcept { return _homeRegId; }
+ ASMJIT_INLINE_NODEBUG void setHomeRegId(uint32_t physId) noexcept { _homeRegId = uint8_t(physId); }
- inline bool hasHintRegId() const noexcept { return _hintRegId != BaseReg::kIdBad; }
- inline uint32_t hintRegId() const noexcept { return _hintRegId; }
- inline void setHintRegId(uint32_t physId) noexcept { _hintRegId = uint8_t(physId); }
+ ASMJIT_INLINE_NODEBUG bool hasHintRegId() const noexcept { return _hintRegId != BaseReg::kIdBad; }
+ ASMJIT_INLINE_NODEBUG uint32_t hintRegId() const noexcept { return _hintRegId; }
+ ASMJIT_INLINE_NODEBUG void setHintRegId(uint32_t physId) noexcept { _hintRegId = uint8_t(physId); }
- 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; }
+ ASMJIT_INLINE_NODEBUG RegMask useIdMask() const noexcept { return _useIdMask; }
+ ASMJIT_INLINE_NODEBUG bool hasUseIdMask() const noexcept { return _useIdMask != 0u; }
+ ASMJIT_INLINE_NODEBUG bool hasMultipleUseIds() const noexcept { return _useIdMask != 0u && !Support::isPowerOf2(_useIdMask); }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG RegMask preferredMask() const noexcept { return _preferredMask; }
+ ASMJIT_INLINE_NODEBUG bool hasPreferredMask() const noexcept { return _preferredMask != 0xFFFFFFFFu; }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG RegMask consecutiveMask() const noexcept { return _consecutiveMask; }
+ ASMJIT_INLINE_NODEBUG bool hasConsecutiveMask() const noexcept { return _consecutiveMask != 0xFFFFFFFFu; }
+ ASMJIT_INLINE_NODEBUG void restrictConsecutiveMask(RegMask mask) noexcept { _consecutiveMask &= mask; }
- inline RegMask clobberSurvivalMask() const noexcept { return _clobberSurvivalMask; }
- inline void addClobberSurvivalMask(RegMask mask) noexcept { _clobberSurvivalMask |= mask; }
+ ASMJIT_INLINE_NODEBUG RegMask clobberSurvivalMask() const noexcept { return _clobberSurvivalMask; }
+ ASMJIT_INLINE_NODEBUG void addClobberSurvivalMask(RegMask mask) noexcept { _clobberSurvivalMask |= mask; }
- inline RegMask allocatedMask() const noexcept { return _allocatedMask; }
- inline void addAllocatedMask(RegMask mask) noexcept { _allocatedMask |= mask; }
+ ASMJIT_INLINE_NODEBUG RegMask allocatedMask() const noexcept { return _allocatedMask; }
+ ASMJIT_INLINE_NODEBUG void addAllocatedMask(RegMask mask) noexcept { _allocatedMask |= mask; }
- inline uint64_t regByteMask() const noexcept { return _regByteMask; }
- inline void setRegByteMask(uint64_t mask) noexcept { _regByteMask = mask; }
+ ASMJIT_INLINE_NODEBUG uint64_t regByteMask() const noexcept { return _regByteMask; }
+ ASMJIT_INLINE_NODEBUG void setRegByteMask(uint64_t mask) noexcept { _regByteMask = mask; }
- inline bool hasImmediateConsecutives() const noexcept { return !_immediateConsecutives.empty(); }
- inline const ZoneBitVector& immediateConsecutives() const noexcept { return _immediateConsecutives; }
+ ASMJIT_INLINE_NODEBUG bool hasImmediateConsecutives() const noexcept { return !_immediateConsecutives.empty(); }
+ ASMJIT_INLINE_NODEBUG const ZoneBitVector& immediateConsecutives() const noexcept { return _immediateConsecutives; }
inline Error addImmediateConsecutive(ZoneAllocator* allocator, uint32_t workId) noexcept {
if (_immediateConsecutives.size() <= workId)
diff --git a/3rdparty/asmjit/src/asmjit/core/ralocal.cpp b/3rdparty/asmjit/src/asmjit/core/ralocal.cpp
index b4d92446b3c..358fbf58f8b 100644
--- a/3rdparty/asmjit/src/asmjit/core/ralocal.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/ralocal.cpp
@@ -21,8 +21,8 @@ static ASMJIT_FORCE_INLINE RATiedReg* RALocal_findTiedRegByWorkId(RATiedReg* tie
return nullptr;
}
-// RALocalAllocator - Init & Reset
-// ===============================
+// RALocalAllocator - Initialization & Reset
+// =========================================
Error RALocalAllocator::init() noexcept {
PhysToWorkMap* physToWorkMap;
@@ -137,9 +137,6 @@ Error RALocalAllocator::switchToAssignment(PhysToWorkMap* dstPhysToWorkMap, cons
dst.initMaps(dstPhysToWorkMap, _tmpWorkToPhysMap);
dst.assignWorkIdsFromPhysIds();
- if (tryMode)
- return kErrorOk;
-
for (RegGroup group : RegGroupVirtValues{}) {
// STEP 1
// ------
@@ -597,10 +594,14 @@ Error RALocalAllocator::allocInst(InstNode* node) noexcept {
if (rmSize <= workReg->virtReg()->virtSize()) {
Operand& op = node->operands()[opIndex];
op = _pass->workRegAsMem(workReg);
- op.as<BaseMem>().setSize(rmSize);
+
+ // NOTE: We cannot use `x86::Mem::setSize()` from here, so let's manipulate the signature directly.
+ op._signature.setSize(rmSize);
+
tiedReg->_useRewriteMask = 0;
tiedReg->markUseDone();
+ raInst->addFlags(RATiedFlags::kInst_RegToMemPatched);
usePending--;
rmAllocated = true;
@@ -687,7 +688,7 @@ Error RALocalAllocator::allocInst(InstNode* node) noexcept {
// ------
//
// 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
+ // complicated as the allocation is iterative. In some cases we have to wait before allocating a particular
// 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).
//
@@ -836,7 +837,7 @@ Error RALocalAllocator::allocInst(InstNode* node) noexcept {
// STEP 9
// ------
//
- // Vector registers can be cloberred partially by invoke - find if that's the case and clobber when necessary.
+ // Vector registers can be clobbered partially by invoke - find if that's the case and clobber when necessary.
if (node->isInvoke() && group == RegGroup::kVec) {
const InvokeNode* invokeNode = node->as<InvokeNode>();
@@ -927,6 +928,10 @@ Error RALocalAllocator::allocInst(InstNode* node) noexcept {
if (!tiedReg->isOut())
continue;
+ RegMask avoidOut = avoidRegs;
+ if (tiedReg->isUnique())
+ avoidOut |= willUse;
+
uint32_t workId = tiedReg->workId();
uint32_t assignedId = _curAssignment.workToPhysId(group, workId);
@@ -935,7 +940,7 @@ Error RALocalAllocator::allocInst(InstNode* node) noexcept {
uint32_t physId = tiedReg->outId();
if (physId == RAAssignment::kPhysNone) {
- RegMask allocableRegs = tiedReg->outRegMask() & ~(outRegs | avoidRegs);
+ RegMask allocableRegs = tiedReg->outRegMask() & ~(outRegs | avoidOut);
if (!(allocableRegs & ~liveRegs)) {
// There are no more registers, decide which one to spill.
diff --git a/3rdparty/asmjit/src/asmjit/core/ralocal_p.h b/3rdparty/asmjit/src/asmjit/core/ralocal_p.h
index b40e8674274..63fd1b78aba 100644
--- a/3rdparty/asmjit/src/asmjit/core/ralocal_p.h
+++ b/3rdparty/asmjit/src/asmjit/core/ralocal_p.h
@@ -29,52 +29,45 @@ public:
typedef RAAssignment::WorkToPhysMap WorkToPhysMap;
//! Link to `BaseRAPass`.
- BaseRAPass* _pass;
+ BaseRAPass* _pass {};
//! Link to `BaseCompiler`.
- BaseCompiler* _cc;
+ BaseCompiler* _cc {};
//! Architecture traits.
- const ArchTraits* _archTraits;
+ const ArchTraits* _archTraits {};
//! Registers available to the allocator.
- RARegMask _availableRegs;
+ RARegMask _availableRegs {};
//! Registers clobbered by the allocator.
- RARegMask _clobberedRegs;
+ RARegMask _clobberedRegs {};
//! Register assignment (current).
- RAAssignment _curAssignment;
+ RAAssignment _curAssignment {};
//! Register assignment used temporarily during assignment switches.
- RAAssignment _tmpAssignment;
+ RAAssignment _tmpAssignment {};
//! Link to the current `RABlock`.
- RABlock* _block;
+ RABlock* _block {};
//! InstNode.
- InstNode* _node;
+ InstNode* _node {};
//! RA instruction.
- RAInst* _raInst;
+ RAInst* _raInst {};
//! Count of all TiedReg's.
- uint32_t _tiedTotal;
+ uint32_t _tiedTotal {};
//! TiedReg's total counter.
- RARegCount _tiedCount;
+ RARegCount _tiedCount {};
//! Temporary workToPhysMap that can be used freely by the allocator.
- WorkToPhysMap* _tmpWorkToPhysMap;
+ WorkToPhysMap* _tmpWorkToPhysMap {};
//! \name Construction & Destruction
//! \{
- inline RALocalAllocator(BaseRAPass* pass) noexcept
+ inline explicit RALocalAllocator(BaseRAPass* pass) noexcept
: _pass(pass),
_cc(pass->cc()),
_archTraits(pass->_archTraits),
- _availableRegs(pass->_availableRegs),
- _clobberedRegs(),
- _curAssignment(),
- _block(nullptr),
- _node(nullptr),
- _raInst(nullptr),
- _tiedTotal(),
- _tiedCount() {}
+ _availableRegs(pass->_availableRegs) {}
Error init() noexcept;
@@ -83,31 +76,31 @@ public:
//! \name Accessors
//! \{
- inline RAWorkReg* workRegById(uint32_t workId) const noexcept { return _pass->workRegById(workId); }
- inline PhysToWorkMap* physToWorkMap() const noexcept { return _curAssignment.physToWorkMap(); }
- inline WorkToPhysMap* workToPhysMap() const noexcept { return _curAssignment.workToPhysMap(); }
+ ASMJIT_INLINE_NODEBUG RAWorkReg* workRegById(uint32_t workId) const noexcept { return _pass->workRegById(workId); }
+ ASMJIT_INLINE_NODEBUG PhysToWorkMap* physToWorkMap() const noexcept { return _curAssignment.physToWorkMap(); }
+ ASMJIT_INLINE_NODEBUG WorkToPhysMap* workToPhysMap() const noexcept { return _curAssignment.workToPhysMap(); }
//! Returns the currently processed block.
- inline RABlock* block() const noexcept { return _block; }
+ ASMJIT_INLINE_NODEBUG RABlock* block() const noexcept { return _block; }
//! Sets the currently processed block.
- inline void setBlock(RABlock* block) noexcept { _block = block; }
+ ASMJIT_INLINE_NODEBUG void setBlock(RABlock* block) noexcept { _block = block; }
//! Returns the currently processed `InstNode`.
- inline InstNode* node() const noexcept { return _node; }
+ ASMJIT_INLINE_NODEBUG InstNode* node() const noexcept { return _node; }
//! Returns the currently processed `RAInst`.
- inline RAInst* raInst() const noexcept { return _raInst; }
+ ASMJIT_INLINE_NODEBUG RAInst* raInst() const noexcept { return _raInst; }
//! Returns all tied regs as `RATiedReg` array.
- inline RATiedReg* tiedRegs() const noexcept { return _raInst->tiedRegs(); }
+ ASMJIT_INLINE_NODEBUG RATiedReg* tiedRegs() const noexcept { return _raInst->tiedRegs(); }
//! Returns tied registers grouped by the given `group`.
- inline RATiedReg* tiedRegs(RegGroup group) const noexcept { return _raInst->tiedRegs(group); }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG uint32_t tiedCount() const noexcept { return _tiedTotal; }
//! Returns count of TiedRegs used by the given register `group`.
- inline uint32_t tiedCount(RegGroup group) const noexcept { return _tiedCount.get(group); }
+ ASMJIT_INLINE_NODEBUG uint32_t tiedCount(RegGroup group) const noexcept { return _tiedCount.get(group); }
- inline bool isGroupUsed(RegGroup group) const noexcept { return _tiedCount[group] != 0; }
+ ASMJIT_INLINE_NODEBUG bool isGroupUsed(RegGroup group) const noexcept { return _tiedCount[group] != 0; }
//! \}
@@ -126,7 +119,7 @@ public:
//! a code sequence that is always executed regardless of the flow.
Error switchToAssignment(PhysToWorkMap* dstPhysToWorkMap, const ZoneBitVector& liveIn, bool dstReadOnly, bool tryMode) noexcept;
- inline Error spillRegsBeforeEntry(RABlock* block) noexcept {
+ ASMJIT_INLINE_NODEBUG Error spillRegsBeforeEntry(RABlock* block) noexcept {
return spillScratchGpRegsBeforeEntry(block->entryScratchGpRegs());
}
@@ -153,7 +146,7 @@ public:
kCostOfDirtyFlag = kCostOfFrequency / 4
};
- inline uint32_t costByFrequency(float freq) const noexcept {
+ ASMJIT_INLINE_NODEBUG uint32_t costByFrequency(float freq) const noexcept {
return uint32_t(int32_t(freq * float(kCostOfFrequency)));
}
diff --git a/3rdparty/asmjit/src/asmjit/core/rapass.cpp b/3rdparty/asmjit/src/asmjit/core/rapass.cpp
index 0e87ab6a259..837cbe291cd 100644
--- a/3rdparty/asmjit/src/asmjit/core/rapass.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/rapass.cpp
@@ -114,11 +114,14 @@ Error BaseRAPass::runOnFunction(Zone* zone, Logger* logger, FuncNode* func) {
#ifndef ASMJIT_NO_LOGGING
_logger = logger;
_formatOptions.reset();
- _diagnosticOptions = DiagnosticOptions::kNone;
+ _diagnosticOptions = _cb->diagnosticOptions();
if (logger) {
_formatOptions = logger->options();
- _diagnosticOptions = _cb->diagnosticOptions();
+ }
+ else {
+ _diagnosticOptions &= ~(DiagnosticOptions::kRADebugCFG |
+ DiagnosticOptions::kRADebugUnreachable);
}
#else
DebugUtils::unused(logger);
@@ -193,6 +196,12 @@ Error BaseRAPass::onPerformAllSteps() noexcept {
return kErrorOk;
}
+// BaseRAPass - Events
+// ===================
+
+void BaseRAPass::onInit() noexcept {}
+void BaseRAPass::onDone() noexcept {}
+
// BaseRAPass - CFG - Basic Block Management
// =========================================
@@ -304,6 +313,11 @@ Error BaseRAPass::addBlock(RABlock* block) noexcept {
// BaseRAPass - CFG - Build
// ========================
+// [[pure virtual]]
+Error BaseRAPass::buildCFG() noexcept {
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
Error BaseRAPass::initSharedAssignments(const ZoneVector<uint32_t>& sharedAssignmentsMap) noexcept {
if (sharedAssignmentsMap.empty())
return kErrorOk;
@@ -328,9 +342,14 @@ Error BaseRAPass::initSharedAssignments(const ZoneVector<uint32_t>& sharedAssign
RABlock* firstSuccessor = successors[0];
// 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());
+ if (firstSuccessor->hasSharedAssignmentId()) {
+ RASharedAssignment& sa = _sharedAssignments[firstSuccessor->sharedAssignmentId()];
+ sa.addEntryScratchGpRegs(block->exitScratchGpRegs());
+ }
+ else {
+ // This is only allowed if there is a single successor - in that case shared assignment is not necessary.
+ ASMJIT_ASSERT(successors.size() == 1u);
+ }
}
}
if (block->hasSharedAssignmentId()) {
@@ -347,21 +366,18 @@ Error BaseRAPass::initSharedAssignments(const ZoneVector<uint32_t>& sharedAssign
class RABlockVisitItem {
public:
+ RABlock* _block {};
+ uint32_t _index {};
+
inline RABlockVisitItem(RABlock* block, uint32_t index) noexcept
: _block(block),
_index(index) {}
- inline RABlockVisitItem(const RABlockVisitItem& other) noexcept
- : _block(other._block),
- _index(other._index) {}
-
+ inline RABlockVisitItem(const RABlockVisitItem& other) noexcept = default;
inline RABlockVisitItem& operator=(const RABlockVisitItem& other) noexcept = default;
inline RABlock* block() const noexcept { return _block; }
inline uint32_t index() const noexcept { return _index; }
-
- RABlock* _block;
- uint32_t _index;
};
Error BaseRAPass::buildCFGViews() noexcept {
@@ -460,12 +476,18 @@ Error BaseRAPass::buildCFGDominators() noexcept {
entryBlock->setIDom(entryBlock);
bool changed = true;
- uint32_t nIters = 0;
+
+#ifndef ASMJIT_NO_LOGGING
+ uint32_t numIters = 0;
+#endif
while (changed) {
- nIters++;
changed = false;
+#ifndef ASMJIT_NO_LOGGING
+ numIters++;
+#endif
+
uint32_t i = _pov.size();
while (i) {
RABlock* block = _pov[--i];
@@ -492,7 +514,7 @@ Error BaseRAPass::buildCFGDominators() noexcept {
}
}
- ASMJIT_RA_LOG_FORMAT(" Done (%u iterations)\n", nIters);
+ ASMJIT_RA_LOG_FORMAT(" Done (%u iterations)\n", numIters);
return kErrorOk;
}
@@ -740,6 +762,13 @@ namespace LiveOps {
static ASMJIT_FORCE_INLINE bool op(BitWord* dst, const BitWord* a, const BitWord* b, const BitWord* c, uint32_t n) noexcept {
BitWord changed = 0;
+#if defined(_MSC_VER) && _MSC_VER <= 1938
+ // MSVC workaround (see #427).
+ //
+ // MSVC incorrectly auto-vectorizes this loop when used with <In> operator. For some reason it trashes a content
+ // of a register, which causes the result to be incorrect. It's a compiler bug we have to prevent unfortunately.
+ #pragma loop(no_vector)
+#endif
for (uint32_t i = 0; i < n; i++) {
BitWord before = dst[i];
BitWord after = Operator::op(before, a[i], b[i], c[i]);
@@ -751,7 +780,7 @@ namespace LiveOps {
return changed != 0;
}
- static ASMJIT_FORCE_INLINE bool recalcInOut(RABlock* block, uint32_t numBitWords, bool initial = false) noexcept {
+ static ASMJIT_NOINLINE bool recalcInOut(RABlock* block, uint32_t numBitWords, bool initial = false) noexcept {
bool changed = initial;
const RABlocks& successors = block->successors();
@@ -782,7 +811,6 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::buildLiveness() noexcept {
uint32_t numAllBlocks = blockCount();
uint32_t numReachableBlocks = reachableBlockCount();
- uint32_t numVisits = numReachableBlocks;
uint32_t numWorkRegs = workRegCount();
uint32_t numBitWords = ZoneBitVector::_wordsPerBits(numWorkRegs);
@@ -852,7 +880,7 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::buildLiveness() noexcept {
if (tiedReg->hasConsecutiveParent()) {
RAWorkReg* consecutiveParentReg = workRegById(tiedReg->consecutiveParent());
- consecutiveParentReg->addImmediateConsecutive(allocator(), workId);
+ ASMJIT_PROPAGATE(consecutiveParentReg->addImmediateConsecutive(allocator(), workId));
}
}
@@ -872,6 +900,10 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::buildLiveness() noexcept {
// Calculate IN/OUT of Each Block
// ------------------------------
+#ifndef ASMJIT_NO_LOGGING
+ uint32_t numVisits = numReachableBlocks;
+#endif
+
{
ZoneStack<RABlock*> workList;
ZoneBitVector workBits;
@@ -902,7 +934,9 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::buildLiveness() noexcept {
}
}
}
+#ifndef ASMJIT_NO_LOGGING
numVisits++;
+#endif
}
workList.reset();
@@ -1146,7 +1180,7 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::initGlobalLiveSpans() noexcept {
return DebugUtils::errored(kErrorOutOfMemory);
for (size_t physId = 0; physId < physCount; physId++)
- new(&liveSpans[physId]) LiveRegSpans();
+ new(Support::PlacementNew{&liveSpans[physId]}) LiveRegSpans();
}
_globalLiveSpans[group] = liveSpans;
@@ -1189,6 +1223,7 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::binPack(RegGroup group) noexcept {
uint32_t numWorkRegs = workRegs.size();
RegMask availableRegs = _availableRegs[group];
+ RegMask preservedRegs = func()->frame().preservedRegs(group);
// First try to pack everything that provides register-id hint as these are most likely function arguments and fixed
// (precolored) virtual registers.
@@ -1320,18 +1355,30 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::binPack(RegGroup group) noexcept {
if (workReg->isAllocated())
continue;
- RegMask physRegs = availableRegs;
- if (physRegs & workReg->preferredMask())
- physRegs &= workReg->preferredMask();
+ RegMask remainingPhysRegs = availableRegs;
+ if (remainingPhysRegs & workReg->preferredMask())
+ remainingPhysRegs &= workReg->preferredMask();
- while (physRegs) {
- RegMask preferredMask = physRegs;
- uint32_t physId = Support::ctz(preferredMask);
+ RegMask physRegs = remainingPhysRegs & ~preservedRegs;
+ remainingPhysRegs &= preservedRegs;
+
+ for (;;) {
+ if (!physRegs) {
+ if (!remainingPhysRegs)
+ break;
+ physRegs = remainingPhysRegs;
+ remainingPhysRegs = 0;
+ }
+
+ uint32_t physId = Support::ctz(physRegs);
if (workReg->clobberSurvivalMask()) {
- preferredMask &= workReg->clobberSurvivalMask();
- if (preferredMask)
+ RegMask preferredMask = (physRegs | remainingPhysRegs) & workReg->clobberSurvivalMask();
+ if (preferredMask) {
+ if (preferredMask & ~remainingPhysRegs)
+ preferredMask &= ~remainingPhysRegs;
physId = Support::ctz(preferredMask);
+ }
}
LiveRegSpans& live = _globalLiveSpans[group][physId];
@@ -1347,7 +1394,8 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::binPack(RegGroup group) noexcept {
if (ASMJIT_UNLIKELY(err != 0xFFFFFFFFu))
return err;
- physRegs ^= Support::bitMask(physId);
+ physRegs &= ~Support::bitMask(physId);
+ remainingPhysRegs &= ~Support::bitMask(physId);
}
// Keep it in `workRegs` if it was not allocated.
@@ -1806,6 +1854,50 @@ Error BaseRAPass::rewrite() noexcept {
return _rewrite(_func, _stop);
}
+// [[pure virtual]]
+Error BaseRAPass::_rewrite(BaseNode* first, BaseNode* stop) noexcept {
+ DebugUtils::unused(first, stop);
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
+// BaseRAPass - Emit
+// =================
+
+// [[pure virtual]]
+Error BaseRAPass::emitMove(uint32_t workId, uint32_t dstPhysId, uint32_t srcPhysId) noexcept {
+ DebugUtils::unused(workId, dstPhysId, srcPhysId);
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
+// [[pure virtual]]
+Error BaseRAPass::emitSwap(uint32_t aWorkId, uint32_t aPhysId, uint32_t bWorkId, uint32_t bPhysId) noexcept {
+ DebugUtils::unused(aWorkId, aPhysId, bWorkId, bPhysId);
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
+// [[pure virtual]]
+Error BaseRAPass::emitLoad(uint32_t workId, uint32_t dstPhysId) noexcept {
+ DebugUtils::unused(workId, dstPhysId);
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
+// [[pure virtual]]
+Error BaseRAPass::emitSave(uint32_t workId, uint32_t srcPhysId) noexcept {
+ DebugUtils::unused(workId, srcPhysId);
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
+// [[pure virtual]]
+Error BaseRAPass::emitJump(const Label& label) noexcept {
+ DebugUtils::unused(label);
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
+Error BaseRAPass::emitPreCall(InvokeNode* invokeNode) noexcept {
+ DebugUtils::unused(invokeNode);
+ return DebugUtils::errored(kErrorOk);
+}
+
// BaseRAPass - Logging
// ====================
diff --git a/3rdparty/asmjit/src/asmjit/core/rapass_p.h b/3rdparty/asmjit/src/asmjit/core/rapass_p.h
index 94738293667..967624045c5 100644
--- a/3rdparty/asmjit/src/asmjit/core/rapass_p.h
+++ b/3rdparty/asmjit/src/asmjit/core/rapass_p.h
@@ -137,7 +137,7 @@ public:
//! \name Construction & Destruction
//! \{
- inline RABlock(BaseRAPass* ra) noexcept
+ ASMJIT_INLINE_NODEBUG RABlock(BaseRAPass* ra) noexcept
: _ra(ra) {}
//! \}
@@ -145,96 +145,96 @@ public:
//! \name Accessors
//! \{
- inline BaseRAPass* pass() const noexcept { return _ra; }
- inline ZoneAllocator* allocator() const noexcept;
+ ASMJIT_INLINE_NODEBUG BaseRAPass* pass() const noexcept { return _ra; }
+ ASMJIT_INLINE_NODEBUG ZoneAllocator* allocator() const noexcept;
- inline uint32_t blockId() const noexcept { return _blockId; }
- inline RABlockFlags flags() const noexcept { return _flags; }
+ ASMJIT_INLINE_NODEBUG uint32_t blockId() const noexcept { return _blockId; }
+ ASMJIT_INLINE_NODEBUG RABlockFlags flags() const noexcept { return _flags; }
- inline bool hasFlag(RABlockFlags flag) const noexcept { return Support::test(_flags, flag); }
- inline void addFlags(RABlockFlags flags) noexcept { _flags |= flags; }
+ ASMJIT_INLINE_NODEBUG bool hasFlag(RABlockFlags flag) const noexcept { return Support::test(_flags, flag); }
+ ASMJIT_INLINE_NODEBUG void addFlags(RABlockFlags flags) noexcept { _flags |= flags; }
- inline bool isAssigned() const noexcept { return _blockId != kUnassignedId; }
+ ASMJIT_INLINE_NODEBUG bool isAssigned() const noexcept { return _blockId != kUnassignedId; }
- 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); }
+ ASMJIT_INLINE_NODEBUG bool isConstructed() const noexcept { return hasFlag(RABlockFlags::kIsConstructed); }
+ ASMJIT_INLINE_NODEBUG bool isReachable() const noexcept { return hasFlag(RABlockFlags::kIsReachable); }
+ ASMJIT_INLINE_NODEBUG bool isTargetable() const noexcept { return hasFlag(RABlockFlags::kIsTargetable); }
+ ASMJIT_INLINE_NODEBUG bool isAllocated() const noexcept { return hasFlag(RABlockFlags::kIsAllocated); }
+ ASMJIT_INLINE_NODEBUG bool isFuncExit() const noexcept { return hasFlag(RABlockFlags::kIsFuncExit); }
+ ASMJIT_INLINE_NODEBUG bool hasTerminator() const noexcept { return hasFlag(RABlockFlags::kHasTerminator); }
+ ASMJIT_INLINE_NODEBUG bool hasConsecutive() const noexcept { return hasFlag(RABlockFlags::kHasConsecutive); }
+ ASMJIT_INLINE_NODEBUG bool hasJumpTable() const noexcept { return hasFlag(RABlockFlags::kHasJumpTable); }
- inline void makeConstructed(const RARegsStats& regStats) noexcept {
+ ASMJIT_INLINE_NODEBUG void makeConstructed(const RARegsStats& regStats) noexcept {
_flags |= RABlockFlags::kIsConstructed;
_regsStats.combineWith(regStats);
}
- inline void makeReachable() noexcept { _flags |= RABlockFlags::kIsReachable; }
- inline void makeTargetable() noexcept { _flags |= RABlockFlags::kIsTargetable; }
- inline void makeAllocated() noexcept { _flags |= RABlockFlags::kIsAllocated; }
+ ASMJIT_INLINE_NODEBUG void makeReachable() noexcept { _flags |= RABlockFlags::kIsReachable; }
+ ASMJIT_INLINE_NODEBUG void makeTargetable() noexcept { _flags |= RABlockFlags::kIsTargetable; }
+ ASMJIT_INLINE_NODEBUG void makeAllocated() noexcept { _flags |= RABlockFlags::kIsAllocated; }
- inline const RARegsStats& regsStats() const noexcept { return _regsStats; }
+ ASMJIT_INLINE_NODEBUG const RARegsStats& regsStats() const noexcept { return _regsStats; }
- inline bool hasPredecessors() const noexcept { return !_predecessors.empty(); }
- inline bool hasSuccessors() const noexcept { return !_successors.empty(); }
+ ASMJIT_INLINE_NODEBUG bool hasPredecessors() const noexcept { return !_predecessors.empty(); }
+ ASMJIT_INLINE_NODEBUG bool hasSuccessors() const noexcept { return !_successors.empty(); }
- inline bool hasSuccessor(RABlock* block) noexcept {
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG const RABlocks& predecessors() const noexcept { return _predecessors; }
+ ASMJIT_INLINE_NODEBUG const RABlocks& successors() const noexcept { return _successors; }
- inline BaseNode* first() const noexcept { return _first; }
- inline BaseNode* last() const noexcept { return _last; }
+ ASMJIT_INLINE_NODEBUG BaseNode* first() const noexcept { return _first; }
+ ASMJIT_INLINE_NODEBUG BaseNode* last() const noexcept { return _last; }
- inline void setFirst(BaseNode* node) noexcept { _first = node; }
- inline void setLast(BaseNode* node) noexcept { _last = node; }
+ ASMJIT_INLINE_NODEBUG void setFirst(BaseNode* node) noexcept { _first = node; }
+ ASMJIT_INLINE_NODEBUG void setLast(BaseNode* node) noexcept { _last = node; }
- inline uint32_t firstPosition() const noexcept { return _firstPosition; }
- inline void setFirstPosition(uint32_t position) noexcept { _firstPosition = position; }
+ ASMJIT_INLINE_NODEBUG uint32_t firstPosition() const noexcept { return _firstPosition; }
+ ASMJIT_INLINE_NODEBUG void setFirstPosition(uint32_t position) noexcept { _firstPosition = position; }
- inline uint32_t endPosition() const noexcept { return _endPosition; }
- inline void setEndPosition(uint32_t position) noexcept { _endPosition = position; }
+ ASMJIT_INLINE_NODEBUG uint32_t endPosition() const noexcept { return _endPosition; }
+ ASMJIT_INLINE_NODEBUG void setEndPosition(uint32_t position) noexcept { _endPosition = position; }
- inline uint32_t povOrder() const noexcept { return _povOrder; }
+ ASMJIT_INLINE_NODEBUG uint32_t povOrder() const noexcept { return _povOrder; }
- inline RegMask entryScratchGpRegs() const noexcept;
- inline RegMask exitScratchGpRegs() const noexcept { return _exitScratchGpRegs; }
+ ASMJIT_INLINE_NODEBUG RegMask entryScratchGpRegs() const noexcept;
+ ASMJIT_INLINE_NODEBUG RegMask exitScratchGpRegs() const noexcept { return _exitScratchGpRegs; }
- inline void addEntryScratchGpRegs(RegMask regMask) noexcept { _entryScratchGpRegs |= regMask; }
- inline void addExitScratchGpRegs(RegMask regMask) noexcept { _exitScratchGpRegs |= regMask; }
+ ASMJIT_INLINE_NODEBUG void addEntryScratchGpRegs(RegMask regMask) noexcept { _entryScratchGpRegs |= regMask; }
+ ASMJIT_INLINE_NODEBUG void addExitScratchGpRegs(RegMask regMask) noexcept { _exitScratchGpRegs |= regMask; }
- inline bool hasSharedAssignmentId() const noexcept { return _sharedAssignmentId != Globals::kInvalidId; }
- inline uint32_t sharedAssignmentId() const noexcept { return _sharedAssignmentId; }
- inline void setSharedAssignmentId(uint32_t id) noexcept { _sharedAssignmentId = id; }
+ ASMJIT_INLINE_NODEBUG bool hasSharedAssignmentId() const noexcept { return _sharedAssignmentId != Globals::kInvalidId; }
+ ASMJIT_INLINE_NODEBUG uint32_t sharedAssignmentId() const noexcept { return _sharedAssignmentId; }
+ ASMJIT_INLINE_NODEBUG void setSharedAssignmentId(uint32_t id) noexcept { _sharedAssignmentId = id; }
- inline uint64_t timestamp() const noexcept { return _timestamp; }
- inline bool hasTimestamp(uint64_t ts) const noexcept { return _timestamp == ts; }
- inline void setTimestamp(uint64_t ts) const noexcept { _timestamp = ts; }
- inline void resetTimestamp() const noexcept { _timestamp = 0; }
+ ASMJIT_INLINE_NODEBUG uint64_t timestamp() const noexcept { return _timestamp; }
+ ASMJIT_INLINE_NODEBUG bool hasTimestamp(uint64_t ts) const noexcept { return _timestamp == ts; }
+ ASMJIT_INLINE_NODEBUG void setTimestamp(uint64_t ts) const noexcept { _timestamp = ts; }
+ ASMJIT_INLINE_NODEBUG void resetTimestamp() const noexcept { _timestamp = 0; }
- inline RABlock* consecutive() const noexcept { return hasConsecutive() ? _successors[0] : nullptr; }
+ ASMJIT_INLINE_NODEBUG RABlock* consecutive() const noexcept { return hasConsecutive() ? _successors[0] : nullptr; }
- inline RABlock* iDom() noexcept { return _idom; }
- inline const RABlock* iDom() const noexcept { return _idom; }
- inline void setIDom(RABlock* block) noexcept { _idom = block; }
+ ASMJIT_INLINE_NODEBUG RABlock* iDom() noexcept { return _idom; }
+ ASMJIT_INLINE_NODEBUG const RABlock* iDom() const noexcept { return _idom; }
+ ASMJIT_INLINE_NODEBUG void setIDom(RABlock* block) noexcept { _idom = block; }
- inline ZoneBitVector& liveIn() noexcept { return _liveBits[kLiveIn]; }
- inline const ZoneBitVector& liveIn() const noexcept { return _liveBits[kLiveIn]; }
+ ASMJIT_INLINE_NODEBUG ZoneBitVector& liveIn() noexcept { return _liveBits[kLiveIn]; }
+ ASMJIT_INLINE_NODEBUG const ZoneBitVector& liveIn() const noexcept { return _liveBits[kLiveIn]; }
- inline ZoneBitVector& liveOut() noexcept { return _liveBits[kLiveOut]; }
- inline const ZoneBitVector& liveOut() const noexcept { return _liveBits[kLiveOut]; }
+ ASMJIT_INLINE_NODEBUG ZoneBitVector& liveOut() noexcept { return _liveBits[kLiveOut]; }
+ ASMJIT_INLINE_NODEBUG const ZoneBitVector& liveOut() const noexcept { return _liveBits[kLiveOut]; }
- inline ZoneBitVector& gen() noexcept { return _liveBits[kLiveGen]; }
- inline const ZoneBitVector& gen() const noexcept { return _liveBits[kLiveGen]; }
+ ASMJIT_INLINE_NODEBUG ZoneBitVector& gen() noexcept { return _liveBits[kLiveGen]; }
+ ASMJIT_INLINE_NODEBUG const ZoneBitVector& gen() const noexcept { return _liveBits[kLiveGen]; }
- inline ZoneBitVector& kill() noexcept { return _liveBits[kLiveKill]; }
- inline const ZoneBitVector& kill() const noexcept { return _liveBits[kLiveKill]; }
+ ASMJIT_INLINE_NODEBUG ZoneBitVector& kill() noexcept { return _liveBits[kLiveKill]; }
+ ASMJIT_INLINE_NODEBUG const ZoneBitVector& kill() const noexcept { return _liveBits[kLiveKill]; }
inline Error resizeLiveBits(uint32_t size) noexcept {
ASMJIT_PROPAGATE(_liveBits[kLiveIn ].resize(allocator(), size));
@@ -244,9 +244,9 @@ public:
return kErrorOk;
}
- inline bool hasEntryAssignment() const noexcept { return _entryPhysToWorkMap != nullptr; }
- inline PhysToWorkMap* entryPhysToWorkMap() const noexcept { return _entryPhysToWorkMap; }
- inline void setEntryAssignment(PhysToWorkMap* physToWorkMap) noexcept { _entryPhysToWorkMap = physToWorkMap; }
+ ASMJIT_INLINE_NODEBUG bool hasEntryAssignment() const noexcept { return _entryPhysToWorkMap != nullptr; }
+ ASMJIT_INLINE_NODEBUG PhysToWorkMap* entryPhysToWorkMap() const noexcept { return _entryPhysToWorkMap; }
+ ASMJIT_INLINE_NODEBUG void setEntryAssignment(PhysToWorkMap* physToWorkMap) noexcept { _entryPhysToWorkMap = physToWorkMap; }
//! \}
@@ -318,38 +318,40 @@ public:
//! \{
//! Returns instruction RW flags.
- inline InstRWFlags instRWFlags() const noexcept { return _instRWFlags; };
+ ASMJIT_INLINE_NODEBUG InstRWFlags instRWFlags() const noexcept { return _instRWFlags; };
//! Tests whether the given `flag` is present in instruction RW flags.
- inline bool hasInstRWFlag(InstRWFlags flag) const noexcept { return Support::test(_instRWFlags, flag); }
+ ASMJIT_INLINE_NODEBUG bool hasInstRWFlag(InstRWFlags flag) const noexcept { return Support::test(_instRWFlags, flag); }
//! Adds `flags` to instruction RW flags.
- inline void addInstRWFlags(InstRWFlags flags) noexcept { _instRWFlags |= flags; }
+ ASMJIT_INLINE_NODEBUG void addInstRWFlags(InstRWFlags flags) noexcept { _instRWFlags |= flags; }
//! Returns the instruction flags.
- inline RATiedFlags flags() const noexcept { return _flags; }
+ ASMJIT_INLINE_NODEBUG RATiedFlags flags() const noexcept { return _flags; }
//! Tests whether the instruction has flag `flag`.
- inline bool hasFlag(RATiedFlags flag) const noexcept { return Support::test(_flags, flag); }
+ ASMJIT_INLINE_NODEBUG bool hasFlag(RATiedFlags flag) const noexcept { return Support::test(_flags, flag); }
//! Replaces the existing instruction flags with `flags`.
- inline void setFlags(RATiedFlags flags) noexcept { _flags = flags; }
+ ASMJIT_INLINE_NODEBUG void setFlags(RATiedFlags flags) noexcept { _flags = flags; }
//! Adds instruction `flags` to this RAInst.
- inline void addFlags(RATiedFlags flags) noexcept { _flags |= flags; }
+ ASMJIT_INLINE_NODEBUG void addFlags(RATiedFlags flags) noexcept { _flags |= flags; }
//! Clears instruction `flags` from this RAInst.
- inline void clearFlags(RATiedFlags flags) noexcept { _flags &= ~flags; }
+ ASMJIT_INLINE_NODEBUG void clearFlags(RATiedFlags flags) noexcept { _flags &= ~flags; }
+ //! Tests whether one operand of this instruction has been patched from Reg to Mem.
+ ASMJIT_INLINE_NODEBUG bool isRegToMemPatched() const noexcept { return hasFlag(RATiedFlags::kInst_RegToMemPatched); }
//! Tests whether this instruction can be transformed to another instruction if necessary.
- inline bool isTransformable() const noexcept { return hasFlag(RATiedFlags::kInst_IsTransformable); }
+ ASMJIT_INLINE_NODEBUG bool isTransformable() const noexcept { return hasFlag(RATiedFlags::kInst_IsTransformable); }
//! Returns the associated block with this RAInst.
- inline RABlock* block() const noexcept { return _block; }
+ ASMJIT_INLINE_NODEBUG RABlock* block() const noexcept { return _block; }
//! Returns tied registers (all).
- inline RATiedReg* tiedRegs() const noexcept { return const_cast<RATiedReg*>(_tiedRegs); }
+ ASMJIT_INLINE_NODEBUG RATiedReg* tiedRegs() const noexcept { return const_cast<RATiedReg*>(_tiedRegs); }
//! Returns tied registers for a given `group`.
- inline RATiedReg* tiedRegs(RegGroup group) const noexcept { return const_cast<RATiedReg*>(_tiedRegs) + _tiedIndex.get(group); }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG uint32_t tiedCount() const noexcept { return _tiedTotal; }
//! Returns count of tied registers of a given `group`.
- inline uint32_t tiedCount(RegGroup group) const noexcept { return _tiedCount[group]; }
+ ASMJIT_INLINE_NODEBUG uint32_t tiedCount(RegGroup group) const noexcept { return _tiedCount[group]; }
//! Returns `RATiedReg` at the given `index`.
inline RATiedReg* tiedAt(uint32_t index) const noexcept {
@@ -371,7 +373,7 @@ public:
//! \name Static Functions
//! \{
- static inline size_t sizeOf(uint32_t tiedRegCount) noexcept {
+ static ASMJIT_INLINE_NODEBUG size_t sizeOf(uint32_t tiedRegCount) noexcept {
return sizeof(RAInst) - sizeof(RATiedReg) + tiedRegCount * sizeof(RATiedReg);
}
@@ -409,10 +411,10 @@ public:
//! \name Construction & Destruction
//! \{
- inline RAInstBuilder() noexcept { reset(); }
+ ASMJIT_INLINE_NODEBUG RAInstBuilder() noexcept { reset(); }
- inline void init() noexcept { reset(); }
- inline void reset() noexcept {
+ ASMJIT_INLINE_NODEBUG void init() noexcept { reset(); }
+ ASMJIT_INLINE_NODEBUG void reset() noexcept {
_instRWFlags = InstRWFlags::kNone;
_aggregatedFlags = RATiedFlags::kNone;
_forbiddenFlags = RATiedFlags::kNone;
@@ -428,25 +430,25 @@ public:
//! \name Accessors
//! \{
- inline InstRWFlags instRWFlags() const noexcept { return _instRWFlags; }
- inline bool hasInstRWFlag(InstRWFlags flag) const noexcept { return Support::test(_instRWFlags, flag); }
- inline void addInstRWFlags(InstRWFlags flags) noexcept { _instRWFlags |= flags; }
- inline void clearInstRWFlags(InstRWFlags flags) noexcept { _instRWFlags &= ~flags; }
+ ASMJIT_INLINE_NODEBUG InstRWFlags instRWFlags() const noexcept { return _instRWFlags; }
+ ASMJIT_INLINE_NODEBUG bool hasInstRWFlag(InstRWFlags flag) const noexcept { return Support::test(_instRWFlags, flag); }
+ ASMJIT_INLINE_NODEBUG void addInstRWFlags(InstRWFlags flags) noexcept { _instRWFlags |= flags; }
+ ASMJIT_INLINE_NODEBUG void clearInstRWFlags(InstRWFlags flags) noexcept { _instRWFlags &= ~flags; }
- inline RATiedFlags aggregatedFlags() const noexcept { return _aggregatedFlags; }
- inline void addAggregatedFlags(RATiedFlags flags) noexcept { _aggregatedFlags |= flags; }
+ ASMJIT_INLINE_NODEBUG RATiedFlags aggregatedFlags() const noexcept { return _aggregatedFlags; }
+ ASMJIT_INLINE_NODEBUG void addAggregatedFlags(RATiedFlags flags) noexcept { _aggregatedFlags |= flags; }
- inline RATiedFlags forbiddenFlags() const noexcept { return _forbiddenFlags; }
- inline void addForbiddenFlags(RATiedFlags flags) noexcept { _forbiddenFlags |= flags; }
+ ASMJIT_INLINE_NODEBUG RATiedFlags forbiddenFlags() const noexcept { return _forbiddenFlags; }
+ ASMJIT_INLINE_NODEBUG 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)); }
+ ASMJIT_INLINE_NODEBUG uint32_t tiedRegCount() const noexcept { return uint32_t((size_t)(_cur - _tiedRegs)); }
- inline RATiedReg* begin() noexcept { return _tiedRegs; }
- inline RATiedReg* end() noexcept { return _cur; }
+ ASMJIT_INLINE_NODEBUG RATiedReg* begin() noexcept { return _tiedRegs; }
+ ASMJIT_INLINE_NODEBUG RATiedReg* end() noexcept { return _cur; }
- inline const RATiedReg* begin() const noexcept { return _tiedRegs; }
- inline const RATiedReg* end() const noexcept { return _cur; }
+ ASMJIT_INLINE_NODEBUG const RATiedReg* begin() const noexcept { return _tiedRegs; }
+ ASMJIT_INLINE_NODEBUG const RATiedReg* end() const noexcept { return _cur; }
//! Returns `RATiedReg` at the given `index`.
inline RATiedReg* operator[](uint32_t index) noexcept {
@@ -634,15 +636,15 @@ public:
//! \name Accessors
//! \{
- inline bool empty() const noexcept { return _physToWorkMap == nullptr; }
+ ASMJIT_INLINE_NODEBUG bool empty() const noexcept { return _physToWorkMap == nullptr; }
- inline RegMask entryScratchGpRegs() const noexcept { return _entryScratchGpRegs; }
- inline void addEntryScratchGpRegs(RegMask mask) noexcept { _entryScratchGpRegs |= mask; }
+ ASMJIT_INLINE_NODEBUG RegMask entryScratchGpRegs() const noexcept { return _entryScratchGpRegs; }
+ ASMJIT_INLINE_NODEBUG void addEntryScratchGpRegs(RegMask mask) noexcept { _entryScratchGpRegs |= mask; }
- inline const ZoneBitVector& liveIn() const noexcept { return _liveIn; }
+ ASMJIT_INLINE_NODEBUG const ZoneBitVector& liveIn() const noexcept { return _liveIn; }
- inline PhysToWorkMap* physToWorkMap() const noexcept { return _physToWorkMap; }
- inline void assignPhysToWorkMap(PhysToWorkMap* physToWorkMap) noexcept { _physToWorkMap = physToWorkMap; }
+ ASMJIT_INLINE_NODEBUG PhysToWorkMap* physToWorkMap() const noexcept { return _physToWorkMap; }
+ ASMJIT_INLINE_NODEBUG void assignPhysToWorkMap(PhysToWorkMap* physToWorkMap) noexcept { _physToWorkMap = physToWorkMap; }
//! \}
};
@@ -754,7 +756,7 @@ public:
//! \{
BaseRAPass() noexcept;
- virtual ~BaseRAPass() noexcept;
+ ~BaseRAPass() noexcept override;
//! \}
@@ -762,38 +764,38 @@ public:
//! \{
//! Returns \ref Logger passed to \ref runOnFunction().
- inline Logger* logger() const noexcept { return _logger; }
+ ASMJIT_INLINE_NODEBUG Logger* logger() const noexcept { return _logger; }
//! 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; }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG 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(); }
+ ASMJIT_INLINE_NODEBUG Zone* zone() const noexcept { return _allocator.zone(); }
//! Returns \ref ZoneAllocator used by the register allocator.
- inline ZoneAllocator* allocator() const noexcept { return const_cast<ZoneAllocator*>(&_allocator); }
+ ASMJIT_INLINE_NODEBUG ZoneAllocator* allocator() const noexcept { return const_cast<ZoneAllocator*>(&_allocator); }
- inline const ZoneVector<RASharedAssignment>& sharedAssignments() const { return _sharedAssignments; }
- inline uint32_t sharedAssignmentCount() const noexcept { return _sharedAssignments.size(); }
+ ASMJIT_INLINE_NODEBUG const ZoneVector<RASharedAssignment>& sharedAssignments() const { return _sharedAssignments; }
+ ASMJIT_INLINE_NODEBUG uint32_t sharedAssignmentCount() const noexcept { return _sharedAssignments.size(); }
//! Returns the current function node.
- inline FuncNode* func() const noexcept { return _func; }
+ ASMJIT_INLINE_NODEBUG FuncNode* func() const noexcept { return _func; }
//! Returns the stop of the current function.
- inline BaseNode* stop() const noexcept { return _stop; }
+ ASMJIT_INLINE_NODEBUG BaseNode* stop() const noexcept { return _stop; }
//! Returns an extra block used by the current function being processed.
- inline BaseNode* extraBlock() const noexcept { return _extraBlock; }
+ ASMJIT_INLINE_NODEBUG BaseNode* extraBlock() const noexcept { return _extraBlock; }
//! Sets an extra block, see `extraBlock()`.
- inline void setExtraBlock(BaseNode* node) noexcept { _extraBlock = node; }
+ ASMJIT_INLINE_NODEBUG void setExtraBlock(BaseNode* node) noexcept { _extraBlock = node; }
- inline uint32_t endPosition() const noexcept { return _instructionCount * 2; }
+ ASMJIT_INLINE_NODEBUG uint32_t endPosition() const noexcept { return _instructionCount * 2; }
- inline const RARegMask& availableRegs() const noexcept { return _availableRegs; }
- inline const RARegMask& cloberredRegs() const noexcept { return _clobberedRegs; }
+ ASMJIT_INLINE_NODEBUG const RARegMask& availableRegs() const noexcept { return _availableRegs; }
+ ASMJIT_INLINE_NODEBUG const RARegMask& clobberedRegs() const noexcept { return _clobberedRegs; }
//! \}
@@ -818,11 +820,11 @@ public:
//! Called by \ref runOnFunction() before the register allocation to initialize
//! architecture-specific data and constraints.
- virtual void onInit() noexcept = 0;
+ virtual void onInit() noexcept;
//! Called by \ref runOnFunction(` after register allocation to clean everything
//! up. Called even if the register allocation failed.
- virtual void onDone() noexcept = 0;
+ virtual void onDone() noexcept;
//! \}
@@ -842,26 +844,26 @@ public:
}
//! Returns all basic blocks of this function.
- inline RABlocks& blocks() noexcept { return _blocks; }
+ ASMJIT_INLINE_NODEBUG RABlocks& blocks() noexcept { return _blocks; }
//! \overload
- inline const RABlocks& blocks() const noexcept { return _blocks; }
+ ASMJIT_INLINE_NODEBUG const RABlocks& blocks() const noexcept { return _blocks; }
//! Returns the count of basic blocks (returns size of `_blocks` array).
- inline uint32_t blockCount() const noexcept { return _blocks.size(); }
+ ASMJIT_INLINE_NODEBUG uint32_t blockCount() const noexcept { return _blocks.size(); }
//! Returns the count of reachable basic blocks (returns size of `_pov` array).
- inline uint32_t reachableBlockCount() const noexcept { return _pov.size(); }
+ ASMJIT_INLINE_NODEBUG 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.
//!
//! \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(); }
+ ASMJIT_INLINE_NODEBUG bool hasDanglingBlocks() const noexcept { return _createdBlockCount != blockCount(); }
//! Gest a next timestamp to be used to mark CFG blocks.
- inline uint64_t nextTimestamp() const noexcept { return ++_lastTimestamp; }
+ ASMJIT_INLINE_NODEBUG uint64_t nextTimestamp() const noexcept { return ++_lastTimestamp; }
- //! Createss a new `RABlock` instance.
+ //! Creates a new `RABlock` instance.
//!
//! \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;
@@ -882,7 +884,7 @@ public:
void* p = zone()->alloc(RAInst::sizeOf(tiedRegCount));
if (ASMJIT_UNLIKELY(!p))
return nullptr;
- return new(p) RAInst(block, instRWFlags, flags, tiedRegCount, clobberedRegs);
+ return new(Support::PlacementNew{p}) RAInst(block, instRWFlags, flags, tiedRegCount, clobberedRegs);
}
ASMJIT_FORCE_INLINE Error assignRAInst(BaseNode* node, RABlock* block, RAInstBuilder& ib) noexcept {
@@ -945,7 +947,7 @@ public:
//! analysis and register allocation.
//!
//! Use `RACFGBuilderT` template that provides the necessary boilerplate.
- virtual Error buildCFG() noexcept = 0;
+ virtual Error buildCFG() noexcept;
//! Called after the CFG is built.
Error initSharedAssignments(const ZoneVector<uint32_t>& sharedAssignmentsMap) noexcept;
@@ -974,14 +976,14 @@ public:
const RABlock* _nearestCommonDominator(const RABlock* a, const RABlock* b) const noexcept;
//! Tests whether the basic block `a` dominates `b` - non-strict, returns true when `a == b`.
- inline bool dominates(const RABlock* a, const RABlock* b) const noexcept { return a == b ? true : _strictlyDominates(a, b); }
+ ASMJIT_INLINE_NODEBUG bool dominates(const RABlock* a, const RABlock* b) const noexcept { return a == b ? true : _strictlyDominates(a, b); }
//! Tests whether the basic block `a` dominates `b` - strict dominance check, returns false when `a == b`.
- inline bool strictlyDominates(const RABlock* a, const RABlock* b) const noexcept { return a == b ? false : _strictlyDominates(a, b); }
+ ASMJIT_INLINE_NODEBUG bool strictlyDominates(const RABlock* a, const RABlock* b) const noexcept { return a == b ? false : _strictlyDominates(a, b); }
//! Returns a nearest common dominator of `a` and `b`.
- inline RABlock* nearestCommonDominator(RABlock* a, RABlock* b) const noexcept { return const_cast<RABlock*>(_nearestCommonDominator(a, b)); }
+ ASMJIT_INLINE_NODEBUG RABlock* nearestCommonDominator(RABlock* a, RABlock* b) const noexcept { return const_cast<RABlock*>(_nearestCommonDominator(a, b)); }
//! Returns a nearest common dominator of `a` and `b` (const).
- inline const RABlock* nearestCommonDominator(const RABlock* a, const RABlock* b) const noexcept { return _nearestCommonDominator(a, b); }
+ ASMJIT_INLINE_NODEBUG const RABlock* nearestCommonDominator(const RABlock* a, const RABlock* b) const noexcept { return _nearestCommonDominator(a, b); }
//! \}
@@ -1005,27 +1007,27 @@ 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(RegGroup group) const noexcept { return _availableRegCount[group]; }
+ ASMJIT_INLINE_NODEBUG uint32_t registerSize() const noexcept { return _sp.size(); }
+ ASMJIT_INLINE_NODEBUG uint32_t availableRegCount(RegGroup group) const noexcept { return _availableRegCount[group]; }
- inline RAWorkReg* workRegById(uint32_t workId) const noexcept { return _workRegs[workId]; }
+ ASMJIT_INLINE_NODEBUG RAWorkReg* workRegById(uint32_t workId) const noexcept { return _workRegs[workId]; }
- inline RAWorkRegs& workRegs() noexcept { return _workRegs; }
- inline RAWorkRegs& workRegs(RegGroup group) noexcept { return _workRegsOfGroup[group]; }
+ ASMJIT_INLINE_NODEBUG RAWorkRegs& workRegs() noexcept { return _workRegs; }
+ ASMJIT_INLINE_NODEBUG RAWorkRegs& workRegs(RegGroup group) noexcept { return _workRegsOfGroup[group]; }
- inline const RAWorkRegs& workRegs() const noexcept { return _workRegs; }
- inline const RAWorkRegs& workRegs(RegGroup group) const noexcept { return _workRegsOfGroup[group]; }
+ ASMJIT_INLINE_NODEBUG const RAWorkRegs& workRegs() const noexcept { return _workRegs; }
+ ASMJIT_INLINE_NODEBUG const RAWorkRegs& workRegs(RegGroup group) const noexcept { return _workRegsOfGroup[group]; }
- inline uint32_t workRegCount() const noexcept { return _workRegs.size(); }
- inline uint32_t workRegCount(RegGroup group) const noexcept { return _workRegsOfGroup[group].size(); }
+ ASMJIT_INLINE_NODEBUG uint32_t workRegCount() const noexcept { return _workRegs.size(); }
+ ASMJIT_INLINE_NODEBUG uint32_t workRegCount(RegGroup group) const noexcept { return _workRegsOfGroup[group].size(); }
inline void _buildPhysIndex() noexcept {
_physRegIndex.buildIndexes(_physRegCount);
_physRegTotal = uint32_t(_physRegIndex[RegGroup::kMaxVirt]) +
uint32_t(_physRegCount[RegGroup::kMaxVirt]) ;
}
- inline uint32_t physRegIndex(RegGroup group) const noexcept { return _physRegIndex[group]; }
- inline uint32_t physRegTotal() const noexcept { return _physRegTotal; }
+ ASMJIT_INLINE_NODEBUG uint32_t physRegIndex(RegGroup group) const noexcept { return _physRegIndex[group]; }
+ ASMJIT_INLINE_NODEBUG uint32_t physRegTotal() const noexcept { return _physRegTotal; }
Error _asWorkReg(VirtReg* vReg, RAWorkReg** out) noexcept;
@@ -1133,7 +1135,7 @@ public:
//! \{
Error rewrite() noexcept;
- virtual Error _rewrite(BaseNode* first, BaseNode* stop) noexcept = 0;
+ virtual Error _rewrite(BaseNode* first, BaseNode* stop) noexcept;
//! \}
@@ -1153,14 +1155,14 @@ public:
//! \name Emit
//! \{
- virtual Error emitMove(uint32_t workId, uint32_t dstPhysId, uint32_t srcPhysId) noexcept = 0;
- virtual Error emitSwap(uint32_t aWorkId, uint32_t aPhysId, uint32_t bWorkId, uint32_t bPhysId) noexcept = 0;
+ virtual Error emitMove(uint32_t workId, uint32_t dstPhysId, uint32_t srcPhysId) noexcept;
+ virtual Error emitSwap(uint32_t aWorkId, uint32_t aPhysId, uint32_t bWorkId, uint32_t bPhysId) noexcept;
- virtual Error emitLoad(uint32_t workId, uint32_t dstPhysId) noexcept = 0;
- virtual Error emitSave(uint32_t workId, uint32_t srcPhysId) noexcept = 0;
+ virtual Error emitLoad(uint32_t workId, uint32_t dstPhysId) noexcept;
+ virtual Error emitSave(uint32_t workId, uint32_t srcPhysId) noexcept;
- virtual Error emitJump(const Label& label) noexcept = 0;
- virtual Error emitPreCall(InvokeNode* invokeNode) noexcept = 0;
+ virtual Error emitJump(const Label& label) noexcept;
+ virtual Error emitPreCall(InvokeNode* invokeNode) noexcept;
//! \}
};
diff --git a/3rdparty/asmjit/src/asmjit/core/rastack.cpp b/3rdparty/asmjit/src/asmjit/core/rastack.cpp
index 2b7ed592df5..318fbded4b3 100644
--- a/3rdparty/asmjit/src/asmjit/core/rastack.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/rastack.cpp
@@ -62,7 +62,7 @@ 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
+ // Update usage based on the size of the slot. We boost smaller slots in a way that 32-bit register has a 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) {
diff --git a/3rdparty/asmjit/src/asmjit/core/rastack_p.h b/3rdparty/asmjit/src/asmjit/core/rastack_p.h
index 90640b4dea8..15db8e97948 100644
--- a/3rdparty/asmjit/src/asmjit/core/rastack_p.h
+++ b/3rdparty/asmjit/src/asmjit/core/rastack_p.h
@@ -104,13 +104,13 @@ public:
//! \{
//! Allocator used to allocate internal data.
- ZoneAllocator* _allocator;
+ ZoneAllocator* _allocator {};
//! Count of bytes used by all slots.
- uint32_t _bytesUsed;
+ uint32_t _bytesUsed {};
//! Calculated stack size (can be a bit greater than `_bytesUsed`).
- uint32_t _stackSize;
+ uint32_t _stackSize {};
//! Minimum stack alignment.
- uint32_t _alignment;
+ uint32_t _alignment = 1;
//! Stack slots vector.
RAStackSlots _slots;
@@ -119,14 +119,9 @@ public:
//! \name Construction & Destruction
//! \{
- inline RAStackAllocator() noexcept
- : _allocator(nullptr),
- _bytesUsed(0),
- _stackSize(0),
- _alignment(1),
- _slots() {}
+ ASMJIT_INLINE_NODEBUG RAStackAllocator() noexcept {}
- inline void reset(ZoneAllocator* allocator) noexcept {
+ ASMJIT_INLINE_NODEBUG void reset(ZoneAllocator* allocator) noexcept {
_allocator = allocator;
_bytesUsed = 0;
_stackSize = 0;
@@ -139,15 +134,15 @@ public:
//! \name Accessors
//! \{
- inline ZoneAllocator* allocator() const noexcept { return _allocator; }
+ ASMJIT_INLINE_NODEBUG ZoneAllocator* allocator() const noexcept { return _allocator; }
- inline uint32_t bytesUsed() const noexcept { return _bytesUsed; }
- inline uint32_t stackSize() const noexcept { return _stackSize; }
- inline uint32_t alignment() const noexcept { return _alignment; }
+ ASMJIT_INLINE_NODEBUG uint32_t bytesUsed() const noexcept { return _bytesUsed; }
+ ASMJIT_INLINE_NODEBUG uint32_t stackSize() const noexcept { return _stackSize; }
+ ASMJIT_INLINE_NODEBUG uint32_t alignment() const noexcept { return _alignment; }
- inline RAStackSlots& slots() noexcept { return _slots; }
- inline const RAStackSlots& slots() const noexcept { return _slots; }
- inline uint32_t slotCount() const noexcept { return _slots.size(); }
+ ASMJIT_INLINE_NODEBUG RAStackSlots& slots() noexcept { return _slots; }
+ ASMJIT_INLINE_NODEBUG const RAStackSlots& slots() const noexcept { return _slots; }
+ ASMJIT_INLINE_NODEBUG uint32_t slotCount() const noexcept { return _slots.size(); }
//! \}
diff --git a/3rdparty/asmjit/src/asmjit/core/string.cpp b/3rdparty/asmjit/src/asmjit/core/string.cpp
index 83dc6efdaac..369d060e248 100644
--- a/3rdparty/asmjit/src/asmjit/core/string.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/string.cpp
@@ -14,9 +14,51 @@ ASMJIT_BEGIN_NAMESPACE
static const char String_baseN[] = "0123456789ABCDEF";
-constexpr size_t kMinAllocSize = 64;
+constexpr size_t kMinAllocSize = 128;
constexpr size_t kMaxAllocSize = SIZE_MAX - Globals::kGrowThreshold;
+// Based on ZoneVector_growCapacity().
+//
+// NOTE: The sizes here include null terminators - that way we can have aligned allocations that are power of 2s
+// initially.
+static ASMJIT_FORCE_INLINE size_t String_growCapacity(size_t byteSize, size_t minimumByteSize) noexcept {
+ static constexpr size_t kGrowThreshold = Globals::kGrowThreshold;
+
+ ASMJIT_ASSERT(minimumByteSize < kMaxAllocSize);
+
+ // This is more than exponential growth at the beginning.
+ if (byteSize < kMinAllocSize) {
+ byteSize = kMinAllocSize;
+ }
+ else if (byteSize < 512) {
+ byteSize = 512;
+ }
+
+ if (byteSize < minimumByteSize) {
+ // Exponential growth before we reach `kGrowThreshold`.
+ byteSize = Support::alignUpPowerOf2(minimumByteSize);
+
+ // Bail to `minimumByteSize` in case of overflow - most likely whatever that is happening afterwards would just fail.
+ if (byteSize < minimumByteSize) {
+ return minimumByteSize;
+ }
+
+ // Pretty much chunked growth advancing by `kGrowThreshold` after we exceed it.
+ if (byteSize > kGrowThreshold) {
+ // Align to kGrowThreshold.
+ size_t remainder = minimumByteSize % kGrowThreshold;
+
+ byteSize = minimumByteSize + remainder;
+
+ // Bail to `minimumByteSize` in case of overflow.
+ if (byteSize < minimumByteSize)
+ return minimumByteSize;
+ }
+ }
+
+ return Support::min<size_t>(byteSize, kMaxAllocSize);
+}
+
// String - Clear & Reset
// ======================
@@ -49,13 +91,13 @@ char* String::prepare(ModifyOp op, size_t size) noexcept {
size_t curCapacity;
if (isLargeOrExternal()) {
- curData = this->_large.data;
- curSize = this->_large.size;
- curCapacity = this->_large.capacity;
+ curData = _large.data;
+ curSize = _large.size;
+ curCapacity = _large.capacity;
}
else {
- curData = this->_small.data;
- curSize = this->_small.type;
+ curData = _small.data;
+ curSize = _small.type;
curCapacity = kSSOCapacity;
}
@@ -90,25 +132,20 @@ char* String::prepare(ModifyOp op, size_t size) noexcept {
}
else {
// Prevent arithmetic overflow.
- if (ASMJIT_UNLIKELY(size >= kMaxAllocSize - curSize))
+ if (ASMJIT_UNLIKELY(size >= kMaxAllocSize - curSize - 1))
return nullptr;
size_t newSize = size + curSize;
size_t newSizePlusOne = newSize + 1;
- if (newSizePlusOne > curCapacity) {
- size_t newCapacity = Support::max<size_t>(curCapacity + 1, kMinAllocSize);
-
- if (newCapacity < newSizePlusOne && newCapacity < Globals::kGrowThreshold)
- newCapacity = Support::alignUpPowerOf2(newCapacity);
-
- if (newCapacity < newSizePlusOne)
- newCapacity = Support::alignUp(newSizePlusOne, Globals::kGrowThreshold);
+ if (newSize > curCapacity) {
+ size_t newCapacityPlusOne = String_growCapacity(size + 1u, newSizePlusOne);
+ ASMJIT_ASSERT(newCapacityPlusOne >= newSizePlusOne);
- if (ASMJIT_UNLIKELY(newCapacity < newSizePlusOne))
+ if (ASMJIT_UNLIKELY(newCapacityPlusOne < newSizePlusOne))
return nullptr;
- char* newData = static_cast<char*>(::malloc(newCapacity));
+ char* newData = static_cast<char*>(::malloc(newCapacityPlusOne));
if (ASMJIT_UNLIKELY(!newData))
return nullptr;
@@ -119,7 +156,7 @@ char* String::prepare(ModifyOp op, size_t size) noexcept {
_large.type = kTypeLarge;
_large.size = newSize;
- _large.capacity = newCapacity - 1;
+ _large.capacity = newCapacityPlusOne - 1;
_large.data = newData;
newData[newSize] = '\0';
@@ -463,7 +500,7 @@ Error String::truncate(size_t newSize) noexcept {
return kErrorOk;
}
-bool String::eq(const char* other, size_t size) const noexcept {
+bool String::equals(const char* other, size_t size) const noexcept {
const char* aData = data();
const char* bData = other;
@@ -488,71 +525,92 @@ bool String::eq(const char* other, size_t size) const noexcept {
// ==============
#if defined(ASMJIT_TEST)
+static void test_string_grow() noexcept {
+ String s;
+ size_t c = s.capacity();
+
+ INFO("Testing string grow strategy (SSO capacity: %zu)", c);
+ for (size_t i = 0; i < 1000000; i++) {
+ s.append('x');
+ if (s.capacity() != c) {
+ c = s.capacity();
+ INFO(" String reallocated to new capacity: %zu", c);
+ }
+ }
+
+ // We don't expect a 1 million character string to occupy 4MiB, for example. So verify that!
+ EXPECT_LT(c, size_t(4 * 1024 * 1024));
+}
+
UNIT(core_string) {
String s;
- EXPECT(s.isLargeOrExternal() == false);
- EXPECT(s.isExternal() == false);
-
- EXPECT(s.assign('a') == kErrorOk);
- EXPECT(s.size() == 1);
- EXPECT(s.capacity() == String::kSSOCapacity);
- EXPECT(s.data()[0] == 'a');
- EXPECT(s.data()[1] == '\0');
- EXPECT(s.eq("a") == true);
- EXPECT(s.eq("a", 1) == true);
-
- EXPECT(s.assignChars('b', 4) == kErrorOk);
- EXPECT(s.size() == 4);
- EXPECT(s.capacity() == String::kSSOCapacity);
- EXPECT(s.data()[0] == 'b');
- EXPECT(s.data()[1] == 'b');
- EXPECT(s.data()[2] == 'b');
- EXPECT(s.data()[3] == 'b');
- EXPECT(s.data()[4] == '\0');
- EXPECT(s.eq("bbbb") == true);
- EXPECT(s.eq("bbbb", 4) == true);
-
- EXPECT(s.assign("abc") == kErrorOk);
- EXPECT(s.size() == 3);
- EXPECT(s.capacity() == String::kSSOCapacity);
- EXPECT(s.data()[0] == 'a');
- EXPECT(s.data()[1] == 'b');
- EXPECT(s.data()[2] == 'c');
- EXPECT(s.data()[3] == '\0');
- EXPECT(s.eq("abc") == true);
- EXPECT(s.eq("abc", 3) == true);
+ INFO("Testing string functionality");
+
+ EXPECT_FALSE(s.isLargeOrExternal());
+ EXPECT_FALSE(s.isExternal());
+
+ EXPECT_EQ(s.assign('a'), kErrorOk);
+ EXPECT_EQ(s.size(), 1u);
+ EXPECT_EQ(s.capacity(), String::kSSOCapacity);
+ EXPECT_EQ(s.data()[0], 'a');
+ EXPECT_EQ(s.data()[1], '\0');
+ EXPECT_TRUE(s.equals("a"));
+ EXPECT_TRUE(s.equals("a", 1));
+
+ EXPECT_EQ(s.assignChars('b', 4), kErrorOk);
+ EXPECT_EQ(s.size(), 4u);
+ EXPECT_EQ(s.capacity(), String::kSSOCapacity);
+ EXPECT_EQ(s.data()[0], 'b');
+ EXPECT_EQ(s.data()[1], 'b');
+ EXPECT_EQ(s.data()[2], 'b');
+ EXPECT_EQ(s.data()[3], 'b');
+ EXPECT_EQ(s.data()[4], '\0');
+ EXPECT_TRUE(s.equals("bbbb"));
+ EXPECT_TRUE(s.equals("bbbb", 4));
+
+ EXPECT_EQ(s.assign("abc"), kErrorOk);
+ EXPECT_EQ(s.size(), 3u);
+ EXPECT_EQ(s.capacity(), String::kSSOCapacity);
+ EXPECT_EQ(s.data()[0], 'a');
+ EXPECT_EQ(s.data()[1], 'b');
+ EXPECT_EQ(s.data()[2], 'c');
+ EXPECT_EQ(s.data()[3], '\0');
+ EXPECT_TRUE(s.equals("abc"));
+ EXPECT_TRUE(s.equals("abc", 3));
const char* large = "Large string that will not fit into SSO buffer";
- EXPECT(s.assign(large) == kErrorOk);
- EXPECT(s.isLargeOrExternal() == true);
- EXPECT(s.size() == strlen(large));
- EXPECT(s.capacity() > String::kSSOCapacity);
- EXPECT(s.eq(large) == true);
- EXPECT(s.eq(large, strlen(large)) == true);
+ EXPECT_EQ(s.assign(large), kErrorOk);
+ EXPECT_TRUE(s.isLargeOrExternal());
+ EXPECT_EQ(s.size(), strlen(large));
+ EXPECT_GT(s.capacity(), String::kSSOCapacity);
+ EXPECT_TRUE(s.equals(large));
+ EXPECT_TRUE(s.equals(large, strlen(large)));
const char* additional = " (additional content)";
- EXPECT(s.isLargeOrExternal() == true);
- EXPECT(s.append(additional) == kErrorOk);
- EXPECT(s.size() == strlen(large) + strlen(additional));
+ EXPECT_TRUE(s.isLargeOrExternal());
+ EXPECT_EQ(s.append(additional), kErrorOk);
+ EXPECT_EQ(s.size(), strlen(large) + strlen(additional));
- EXPECT(s.clear() == kErrorOk);
- EXPECT(s.size() == 0);
- EXPECT(s.empty() == true);
- EXPECT(s.data()[0] == '\0');
- EXPECT(s.isLargeOrExternal() == true); // Clear should never release the memory.
+ EXPECT_EQ(s.clear(), kErrorOk);
+ EXPECT_EQ(s.size(), 0u);
+ EXPECT_TRUE(s.empty());
+ EXPECT_EQ(s.data()[0], '\0');
+ EXPECT_TRUE(s.isLargeOrExternal()); // Clear should never release the memory.
- EXPECT(s.appendUInt(1234) == kErrorOk);
- EXPECT(s.eq("1234") == true);
+ EXPECT_EQ(s.appendUInt(1234), kErrorOk);
+ EXPECT_TRUE(s.equals("1234"));
- EXPECT(s.assignUInt(0xFFFF, 16, 0, StringFormatFlags::kAlternate) == kErrorOk);
- EXPECT(s.eq("0xFFFF"));
+ EXPECT_EQ(s.assignUInt(0xFFFF, 16, 0, StringFormatFlags::kAlternate), kErrorOk);
+ EXPECT_TRUE(s.equals("0xFFFF"));
StringTmp<64> sTmp;
- EXPECT(sTmp.isLargeOrExternal());
- EXPECT(sTmp.isExternal());
- EXPECT(sTmp.appendChars(' ', 1000) == kErrorOk);
- EXPECT(!sTmp.isExternal());
+ EXPECT_TRUE(sTmp.isLargeOrExternal());
+ EXPECT_TRUE(sTmp.isExternal());
+ EXPECT_EQ(sTmp.appendChars(' ', 1000), kErrorOk);
+ EXPECT_FALSE(sTmp.isExternal());
+
+ test_string_grow();
}
#endif
diff --git a/3rdparty/asmjit/src/asmjit/core/string.h b/3rdparty/asmjit/src/asmjit/core/string.h
index 2562e66194a..c4dee14b00e 100644
--- a/3rdparty/asmjit/src/asmjit/core/string.h
+++ b/3rdparty/asmjit/src/asmjit/core/string.h
@@ -53,9 +53,12 @@ union FixedString {
//! \name Utilities
//! \{
- inline bool eq(const char* other) const noexcept {
- return strcmp(str, other) == 0;
- }
+ inline bool equals(const char* other) const noexcept { return strcmp(str, other) == 0; }
+
+#if !defined(ASMJIT_NO_DEPRECATED)
+ ASMJIT_DEPRECATED("Use FixedString::equals() instead")
+ inline bool eq(const char* other) const noexcept { return equals(other); }
+#endif // !ASMJIT_NO_DEPRECATED
//! \}
};
@@ -131,16 +134,16 @@ public:
//! \{
//! Creates a default-initialized string if zero length.
- inline String() noexcept
+ ASMJIT_INLINE_NODEBUG String() noexcept
: _small {} {}
//! Creates a string that takes ownership of the content of the `other` string.
- inline String(String&& other) noexcept {
+ ASMJIT_INLINE_NODEBUG String(String&& other) noexcept {
_raw = other._raw;
other._resetInternal();
}
- inline ~String() noexcept {
+ ASMJIT_INLINE_NODEBUG ~String() noexcept {
reset();
}
@@ -158,37 +161,37 @@ public:
return *this;
}
- inline bool operator==(const char* other) const noexcept { return eq(other); }
- inline bool operator!=(const char* other) const noexcept { return !eq(other); }
+ ASMJIT_INLINE_NODEBUG bool operator==(const char* other) const noexcept { return equals(other); }
+ ASMJIT_INLINE_NODEBUG bool operator!=(const char* other) const noexcept { return !equals(other); }
- inline bool operator==(const String& other) const noexcept { return eq(other); }
- inline bool operator!=(const String& other) const noexcept { return !eq(other); }
+ ASMJIT_INLINE_NODEBUG bool operator==(const String& other) const noexcept { return equals(other); }
+ ASMJIT_INLINE_NODEBUG bool operator!=(const String& other) const noexcept { return !equals(other); }
//! \}
//! \name Accessors
//! \{
- inline bool isExternal() const noexcept { return _type == kTypeExternal; }
- inline bool isLargeOrExternal() const noexcept { return _type >= kTypeLarge; }
+ ASMJIT_INLINE_NODEBUG bool isExternal() const noexcept { return _type == kTypeExternal; }
+ ASMJIT_INLINE_NODEBUG bool isLargeOrExternal() const noexcept { return _type >= kTypeLarge; }
//! Tests whether the string is empty.
- inline bool empty() const noexcept { return size() == 0; }
+ ASMJIT_INLINE_NODEBUG bool empty() const noexcept { return size() == 0; }
//! Returns the size of the string.
- inline size_t size() const noexcept { return isLargeOrExternal() ? size_t(_large.size) : size_t(_type); }
+ ASMJIT_INLINE_NODEBUG size_t size() const noexcept { return isLargeOrExternal() ? size_t(_large.size) : size_t(_type); }
//! Returns the capacity of the string.
- inline size_t capacity() const noexcept { return isLargeOrExternal() ? _large.capacity : size_t(kSSOCapacity); }
+ ASMJIT_INLINE_NODEBUG size_t capacity() const noexcept { return isLargeOrExternal() ? _large.capacity : size_t(kSSOCapacity); }
//! Returns the data of the string.
- inline char* data() noexcept { return isLargeOrExternal() ? _large.data : _small.data; }
+ ASMJIT_INLINE_NODEBUG char* data() noexcept { return isLargeOrExternal() ? _large.data : _small.data; }
//! \overload
- inline const char* data() const noexcept { return isLargeOrExternal() ? _large.data : _small.data; }
+ ASMJIT_INLINE_NODEBUG const char* data() const noexcept { return isLargeOrExternal() ? _large.data : _small.data; }
- inline char* start() noexcept { return data(); }
- inline const char* start() const noexcept { return data(); }
+ ASMJIT_INLINE_NODEBUG char* start() noexcept { return data(); }
+ ASMJIT_INLINE_NODEBUG const char* start() const noexcept { return data(); }
- inline char* end() noexcept { return data() + size(); }
- inline const char* end() const noexcept { return data() + size(); }
+ ASMJIT_INLINE_NODEBUG char* end() noexcept { return data() + size(); }
+ ASMJIT_INLINE_NODEBUG const char* end() const noexcept { return data() + size(); }
//! \}
@@ -196,7 +199,7 @@ public:
//! \{
//! Swaps the content of this string with `other`.
- inline void swap(String& other) noexcept {
+ ASMJIT_INLINE_NODEBUG void swap(String& other) noexcept {
std::swap(_raw, other._raw);
}
@@ -219,91 +222,91 @@ public:
ASMJIT_API Error assign(const char* data, size_t size = SIZE_MAX) noexcept;
//! Replaces the current of the string with `other` string.
- inline Error assign(const String& other) noexcept {
+ ASMJIT_INLINE_NODEBUG Error assign(const String& other) noexcept {
return assign(other.data(), other.size());
}
//! Replaces the current of the string by a single `c` character.
- inline Error assign(char c) noexcept {
+ ASMJIT_INLINE_NODEBUG Error assign(char c) noexcept {
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 {
+ ASMJIT_INLINE_NODEBUG Error assignChars(char c, size_t n) noexcept {
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, StringFormatFlags flags = StringFormatFlags::kNone) noexcept {
+ ASMJIT_INLINE_NODEBUG 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, StringFormatFlags flags = StringFormatFlags::kNone) noexcept {
+ ASMJIT_INLINE_NODEBUG 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 {
+ ASMJIT_INLINE_NODEBUG Error assignHex(const void* data, size_t size, char separator = '\0') noexcept {
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 {
+ ASMJIT_INLINE_NODEBUG Error assignFormat(const char* fmt, Args&&... args) noexcept {
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 {
+ ASMJIT_INLINE_NODEBUG Error assignVFormat(const char* fmt, va_list ap) noexcept {
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 {
+ ASMJIT_INLINE_NODEBUG Error append(const char* str, size_t size = SIZE_MAX) noexcept {
return _opString(ModifyOp::kAppend, str, size);
}
//! Appends `other` string to this string.
- inline Error append(const String& other) noexcept {
+ ASMJIT_INLINE_NODEBUG Error append(const String& other) noexcept {
return append(other.data(), other.size());
}
//! Appends a single `c` character.
- inline Error append(char c) noexcept {
+ ASMJIT_INLINE_NODEBUG Error append(char c) noexcept {
return _opChar(ModifyOp::kAppend, c);
}
//! Appends `c` character repeated `n` times.
- inline Error appendChars(char c, size_t n) noexcept {
+ ASMJIT_INLINE_NODEBUG Error appendChars(char c, size_t n) noexcept {
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, StringFormatFlags flags = StringFormatFlags::kNone) noexcept {
+ ASMJIT_INLINE_NODEBUG 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, StringFormatFlags flags = StringFormatFlags::kNone) noexcept {
+ ASMJIT_INLINE_NODEBUG 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 {
+ ASMJIT_INLINE_NODEBUG Error appendHex(const void* data, size_t size, char separator = '\0') noexcept {
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 {
+ ASMJIT_INLINE_NODEBUG Error appendFormat(const char* fmt, Args&&... args) noexcept {
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 {
+ ASMJIT_INLINE_NODEBUG Error appendVFormat(const char* fmt, va_list ap) noexcept {
return _opVFormat(ModifyOp::kAppend, fmt, ap);
}
@@ -312,8 +315,16 @@ public:
//! Truncate the string length into `newSize`.
ASMJIT_API Error truncate(size_t newSize) noexcept;
- ASMJIT_API bool eq(const char* other, size_t size = SIZE_MAX) const noexcept;
- inline bool eq(const String& other) const noexcept { return eq(other.data(), other.size()); }
+ ASMJIT_API bool equals(const char* other, size_t size = SIZE_MAX) const noexcept;
+ ASMJIT_INLINE_NODEBUG bool equals(const String& other) const noexcept { return equals(other.data(), other.size()); }
+
+#if !defined(ASMJIT_NO_DEPRECATED)
+ ASMJIT_DEPRECATED("Use String::equals() instead")
+ ASMJIT_INLINE_NODEBUG bool eq(const char* other, size_t size = SIZE_MAX) const noexcept { return equals(other, size); }
+
+ ASMJIT_DEPRECATED("Use String::equals() instead")
+ ASMJIT_INLINE_NODEBUG bool eq(const String& other) const noexcept { return equals(other.data(), other.size()); }
+#endif // !ASMJIT_NO_DEPRECATED
//! \}
@@ -351,7 +362,7 @@ public:
//! \name Construction & Destruction
//! \{
- inline StringTmp() noexcept {
+ ASMJIT_INLINE_NODEBUG StringTmp() noexcept {
_resetToTemporary();
}
diff --git a/3rdparty/asmjit/src/asmjit/core/support.cpp b/3rdparty/asmjit/src/asmjit/core/support.cpp
index 245398fe732..bebabbcc2de 100644
--- a/3rdparty/asmjit/src/asmjit/core/support.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/support.cpp
@@ -15,74 +15,76 @@ ASMJIT_BEGIN_NAMESPACE
template<typename T>
static void testArrays(const T* a, const T* b, size_t size) noexcept {
for (size_t i = 0; i < size; i++)
- EXPECT(a[i] == b[i], "Mismatch at %u", unsigned(i));
+ EXPECT_EQ(a[i], b[i])
+ .message("Mismatch at %u", unsigned(i));
}
static void testAlignment() noexcept {
INFO("Support::isAligned()");
- EXPECT(Support::isAligned<size_t>(0xFFFF, 4) == false);
- EXPECT(Support::isAligned<size_t>(0xFFF4, 4) == true);
- EXPECT(Support::isAligned<size_t>(0xFFF8, 8) == true);
- EXPECT(Support::isAligned<size_t>(0xFFF0, 16) == true);
+ EXPECT_FALSE(Support::isAligned<size_t>(0xFFFF, 4u));
+ EXPECT_TRUE(Support::isAligned<size_t>(0xFFF4, 4u));
+ EXPECT_TRUE(Support::isAligned<size_t>(0xFFF8, 8u));
+ EXPECT_TRUE(Support::isAligned<size_t>(0xFFF0, 16u));
INFO("Support::alignUp()");
- EXPECT(Support::alignUp<size_t>(0xFFFF, 4) == 0x10000);
- EXPECT(Support::alignUp<size_t>(0xFFF4, 4) == 0x0FFF4);
- EXPECT(Support::alignUp<size_t>(0xFFF8, 8) == 0x0FFF8);
- EXPECT(Support::alignUp<size_t>(0xFFF0, 16) == 0x0FFF0);
- EXPECT(Support::alignUp<size_t>(0xFFF0, 32) == 0x10000);
+ EXPECT_EQ(Support::alignUp<size_t>(0xFFFF, 4), 0x10000u);
+ EXPECT_EQ(Support::alignUp<size_t>(0xFFF4, 4), 0x0FFF4u);
+ EXPECT_EQ(Support::alignUp<size_t>(0xFFF8, 8), 0x0FFF8u);
+ EXPECT_EQ(Support::alignUp<size_t>(0xFFF0, 16), 0x0FFF0u);
+ EXPECT_EQ(Support::alignUp<size_t>(0xFFF0, 32), 0x10000u);
INFO("Support::alignUpDiff()");
- EXPECT(Support::alignUpDiff<size_t>(0xFFFF, 4) == 1);
- EXPECT(Support::alignUpDiff<size_t>(0xFFF4, 4) == 0);
- EXPECT(Support::alignUpDiff<size_t>(0xFFF8, 8) == 0);
- EXPECT(Support::alignUpDiff<size_t>(0xFFF0, 16) == 0);
- EXPECT(Support::alignUpDiff<size_t>(0xFFF0, 32) == 16);
+ EXPECT_EQ(Support::alignUpDiff<size_t>(0xFFFF, 4), 1u);
+ EXPECT_EQ(Support::alignUpDiff<size_t>(0xFFF4, 4), 0u);
+ EXPECT_EQ(Support::alignUpDiff<size_t>(0xFFF8, 8), 0u);
+ EXPECT_EQ(Support::alignUpDiff<size_t>(0xFFF0, 16), 0u);
+ EXPECT_EQ(Support::alignUpDiff<size_t>(0xFFF0, 32), 16u);
INFO("Support::alignUpPowerOf2()");
- EXPECT(Support::alignUpPowerOf2<size_t>(0x0000) == 0x00000);
- EXPECT(Support::alignUpPowerOf2<size_t>(0xFFFF) == 0x10000);
- EXPECT(Support::alignUpPowerOf2<size_t>(0xF123) == 0x10000);
- EXPECT(Support::alignUpPowerOf2<size_t>(0x0F00) == 0x01000);
- EXPECT(Support::alignUpPowerOf2<size_t>(0x0100) == 0x00100);
- EXPECT(Support::alignUpPowerOf2<size_t>(0x1001) == 0x02000);
+ EXPECT_EQ(Support::alignUpPowerOf2<size_t>(0x0000), 0x00000u);
+ EXPECT_EQ(Support::alignUpPowerOf2<size_t>(0xFFFF), 0x10000u);
+ EXPECT_EQ(Support::alignUpPowerOf2<size_t>(0xF123), 0x10000u);
+ EXPECT_EQ(Support::alignUpPowerOf2<size_t>(0x0F00), 0x01000u);
+ EXPECT_EQ(Support::alignUpPowerOf2<size_t>(0x0100), 0x00100u);
+ EXPECT_EQ(Support::alignUpPowerOf2<size_t>(0x1001), 0x02000u);
}
static void testBitUtils() noexcept {
uint32_t i;
INFO("Support::shl() / shr()");
- EXPECT(Support::shl(int32_t(0x00001111), 16) == int32_t(0x11110000u));
- EXPECT(Support::shl(uint32_t(0x00001111), 16) == uint32_t(0x11110000u));
- EXPECT(Support::shr(int32_t(0x11110000u), 16) == int32_t(0x00001111u));
- EXPECT(Support::shr(uint32_t(0x11110000u), 16) == uint32_t(0x00001111u));
- EXPECT(Support::sar(int32_t(0xFFFF0000u), 16) == int32_t(0xFFFFFFFFu));
- EXPECT(Support::sar(uint32_t(0xFFFF0000u), 16) == uint32_t(0xFFFFFFFFu));
+ EXPECT_EQ(Support::shl(int32_t(0x00001111), 16), int32_t(0x11110000u));
+ EXPECT_EQ(Support::shl(uint32_t(0x00001111), 16), uint32_t(0x11110000u));
+ EXPECT_EQ(Support::shr(int32_t(0x11110000u), 16), int32_t(0x00001111u));
+ EXPECT_EQ(Support::shr(uint32_t(0x11110000u), 16), uint32_t(0x00001111u));
+ EXPECT_EQ(Support::sar(int32_t(0xFFFF0000u), 16), int32_t(0xFFFFFFFFu));
+ EXPECT_EQ(Support::sar(uint32_t(0xFFFF0000u), 16), uint32_t(0xFFFFFFFFu));
INFO("Support::blsi()");
- for (i = 0; i < 32; i++) EXPECT(Support::blsi(uint32_t(1) << i) == uint32_t(1) << i);
- for (i = 0; i < 31; i++) EXPECT(Support::blsi(uint32_t(3) << i) == uint32_t(1) << i);
- for (i = 0; i < 64; i++) EXPECT(Support::blsi(uint64_t(1) << i) == uint64_t(1) << i);
- for (i = 0; i < 63; i++) EXPECT(Support::blsi(uint64_t(3) << i) == uint64_t(1) << i);
+ for (i = 0; i < 32; i++) EXPECT_EQ(Support::blsi(uint32_t(1) << i), uint32_t(1) << i);
+ for (i = 0; i < 31; i++) EXPECT_EQ(Support::blsi(uint32_t(3) << i), uint32_t(1) << i);
+ for (i = 0; i < 64; i++) EXPECT_EQ(Support::blsi(uint64_t(1) << i), uint64_t(1) << i);
+ for (i = 0; i < 63; i++) EXPECT_EQ(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_EQ(Support::Internal::clzFallback(uint32_t(1) << i), 31 - i);
+ for (i = 0; i < 64; i++) EXPECT_EQ(Support::Internal::clzFallback(uint64_t(1) << i), 63 - i);
+ for (i = 0; i < 32; i++) EXPECT_EQ(Support::Internal::ctzFallback(uint32_t(1) << i), i);
+ for (i = 0; i < 64; i++) EXPECT_EQ(Support::Internal::ctzFallback(uint64_t(1) << i), i);
+ for (i = 0; i < 32; i++) EXPECT_EQ(Support::clz(uint32_t(1) << i), 31 - i);
+ for (i = 0; i < 64; i++) EXPECT_EQ(Support::clz(uint64_t(1) << i), 63 - i);
+ for (i = 0; i < 32; i++) EXPECT_EQ(Support::ctz(uint32_t(1) << i), i);
+ for (i = 0; i < 64; i++) EXPECT_EQ(Support::ctz(uint64_t(1) << i), i);
INFO("Support::bitMask()");
- EXPECT(Support::bitMask(0, 1, 7) == 0x83u);
+ EXPECT_EQ(Support::bitMask(0, 1, 7), 0x83u);
for (i = 0; i < 32; i++)
- EXPECT(Support::bitMask(i) == (1u << i));
+ EXPECT_EQ(Support::bitMask(i), (1u << i));
INFO("Support::bitTest()");
for (i = 0; i < 32; i++) {
- EXPECT(Support::bitTest((1 << i), i) == true, "Support::bitTest(%X, %u) should return true", (1 << i), i);
+ EXPECT_TRUE(Support::bitTest((1 << i), i))
+ .message("Support::bitTest(%X, %u) should return true", (1 << i), i);
}
INFO("Support::lsbMask<uint32_t>()");
@@ -90,7 +92,7 @@ static void testBitUtils() noexcept {
uint32_t expectedBits = 0;
for (uint32_t b = 0; b < i; b++)
expectedBits |= uint32_t(1) << b;
- EXPECT(Support::lsbMask<uint32_t>(i) == expectedBits);
+ EXPECT_EQ(Support::lsbMask<uint32_t>(i), expectedBits);
}
INFO("Support::lsbMask<uint64_t>()");
@@ -98,31 +100,31 @@ static void testBitUtils() noexcept {
uint64_t expectedBits = 0;
for (uint32_t b = 0; b < i; b++)
expectedBits |= uint64_t(1) << b;
- EXPECT(Support::lsbMask<uint64_t>(i) == expectedBits);
+ EXPECT_EQ(Support::lsbMask<uint64_t>(i), expectedBits);
}
INFO("Support::popcnt()");
- for (i = 0; i < 32; i++) EXPECT(Support::popcnt((uint32_t(1) << i)) == 1);
- for (i = 0; i < 64; i++) EXPECT(Support::popcnt((uint64_t(1) << i)) == 1);
- EXPECT(Support::popcnt(0x000000F0) == 4);
- EXPECT(Support::popcnt(0x10101010) == 4);
- EXPECT(Support::popcnt(0xFF000000) == 8);
- EXPECT(Support::popcnt(0xFFFFFFF7) == 31);
- EXPECT(Support::popcnt(0x7FFFFFFF) == 31);
+ for (i = 0; i < 32; i++) EXPECT_EQ(Support::popcnt((uint32_t(1) << i)), 1u);
+ for (i = 0; i < 64; i++) EXPECT_EQ(Support::popcnt((uint64_t(1) << i)), 1u);
+ EXPECT_EQ(Support::popcnt(0x000000F0), 4u);
+ EXPECT_EQ(Support::popcnt(0x10101010), 4u);
+ EXPECT_EQ(Support::popcnt(0xFF000000), 8u);
+ EXPECT_EQ(Support::popcnt(0xFFFFFFF7), 31u);
+ EXPECT_EQ(Support::popcnt(0x7FFFFFFF), 31u);
INFO("Support::isPowerOf2()");
for (i = 0; i < 64; i++) {
- EXPECT(Support::isPowerOf2(uint64_t(1) << i) == true);
- EXPECT(Support::isPowerOf2((uint64_t(1) << i) ^ 0x001101) == false);
+ EXPECT_TRUE(Support::isPowerOf2(uint64_t(1) << i));
+ EXPECT_FALSE(Support::isPowerOf2((uint64_t(1) << i) ^ 0x001101));
}
}
static void testIntUtils() noexcept {
INFO("Support::byteswap()");
- EXPECT(Support::byteswap16(int32_t(0x0102)) == int32_t(0x0201));
- EXPECT(Support::byteswap32(int32_t(0x01020304)) == int32_t(0x04030201));
- EXPECT(Support::byteswap32(uint32_t(0x01020304)) == uint32_t(0x04030201));
- EXPECT(Support::byteswap64(uint64_t(0x0102030405060708)) == uint64_t(0x0807060504030201));
+ EXPECT_EQ(Support::byteswap16(0x0102), 0x0201u);
+ EXPECT_EQ(Support::byteswap32(0x01020304), 0x04030201u);
+ EXPECT_EQ(Support::byteswap32(0x01020304), 0x04030201u);
+ EXPECT_EQ(Support::byteswap64(uint64_t(0x0102030405060708)), uint64_t(0x0807060504030201));
INFO("Support::bytepack()");
union BytePackData {
@@ -131,60 +133,60 @@ static void testIntUtils() noexcept {
} bpdata;
bpdata.u32 = Support::bytepack32_4x8(0x00, 0x11, 0x22, 0x33);
- EXPECT(bpdata.bytes[0] == 0x00);
- EXPECT(bpdata.bytes[1] == 0x11);
- EXPECT(bpdata.bytes[2] == 0x22);
- EXPECT(bpdata.bytes[3] == 0x33);
+ EXPECT_EQ(bpdata.bytes[0], 0x00);
+ EXPECT_EQ(bpdata.bytes[1], 0x11);
+ EXPECT_EQ(bpdata.bytes[2], 0x22);
+ EXPECT_EQ(bpdata.bytes[3], 0x33);
INFO("Support::isBetween()");
- EXPECT(Support::isBetween<int>(10 , 10, 20) == true);
- EXPECT(Support::isBetween<int>(11 , 10, 20) == true);
- EXPECT(Support::isBetween<int>(20 , 10, 20) == true);
- EXPECT(Support::isBetween<int>(9 , 10, 20) == false);
- EXPECT(Support::isBetween<int>(21 , 10, 20) == false);
- EXPECT(Support::isBetween<int>(101, 10, 20) == false);
+ EXPECT_TRUE(Support::isBetween<int>(10 , 10, 20));
+ EXPECT_TRUE(Support::isBetween<int>(11 , 10, 20));
+ EXPECT_TRUE(Support::isBetween<int>(20 , 10, 20));
+ EXPECT_FALSE(Support::isBetween<int>(9 , 10, 20));
+ EXPECT_FALSE(Support::isBetween<int>(21 , 10, 20));
+ EXPECT_FALSE(Support::isBetween<int>(101, 10, 20));
INFO("Support::isInt8()");
- EXPECT(Support::isInt8(-128) == true);
- EXPECT(Support::isInt8( 127) == true);
- EXPECT(Support::isInt8(-129) == false);
- EXPECT(Support::isInt8( 128) == false);
+ EXPECT_TRUE(Support::isInt8(-128));
+ EXPECT_TRUE(Support::isInt8( 127));
+ EXPECT_FALSE(Support::isInt8(-129));
+ EXPECT_FALSE(Support::isInt8( 128));
INFO("Support::isInt16()");
- EXPECT(Support::isInt16(-32768) == true);
- EXPECT(Support::isInt16( 32767) == true);
- EXPECT(Support::isInt16(-32769) == false);
- EXPECT(Support::isInt16( 32768) == false);
+ EXPECT_TRUE(Support::isInt16(-32768));
+ EXPECT_TRUE(Support::isInt16( 32767));
+ EXPECT_FALSE(Support::isInt16(-32769));
+ EXPECT_FALSE(Support::isInt16( 32768));
INFO("Support::isInt32()");
- EXPECT(Support::isInt32( 2147483647 ) == true);
- EXPECT(Support::isInt32(-2147483647 - 1) == true);
- EXPECT(Support::isInt32(uint64_t(2147483648u)) == false);
- EXPECT(Support::isInt32(uint64_t(0xFFFFFFFFu)) == false);
- EXPECT(Support::isInt32(uint64_t(0xFFFFFFFFu) + 1) == false);
+ EXPECT_TRUE(Support::isInt32( 2147483647 ));
+ EXPECT_TRUE(Support::isInt32(-2147483647 - 1));
+ EXPECT_FALSE(Support::isInt32(uint64_t(2147483648u)));
+ EXPECT_FALSE(Support::isInt32(uint64_t(0xFFFFFFFFu)));
+ EXPECT_FALSE(Support::isInt32(uint64_t(0xFFFFFFFFu) + 1));
INFO("Support::isUInt8()");
- EXPECT(Support::isUInt8(0) == true);
- EXPECT(Support::isUInt8(255) == true);
- EXPECT(Support::isUInt8(256) == false);
- EXPECT(Support::isUInt8(-1) == false);
+ EXPECT_TRUE(Support::isUInt8(0) );
+ EXPECT_TRUE(Support::isUInt8(255));
+ EXPECT_FALSE(Support::isUInt8(256));
+ EXPECT_FALSE(Support::isUInt8(-1) );
INFO("Support::isUInt12()");
- EXPECT(Support::isUInt12(0) == true);
- EXPECT(Support::isUInt12(4095) == true);
- EXPECT(Support::isUInt12(4096) == false);
- EXPECT(Support::isUInt12(-1) == false);
+ EXPECT_TRUE(Support::isUInt12(0) );
+ EXPECT_TRUE(Support::isUInt12(4095));
+ EXPECT_FALSE(Support::isUInt12(4096));
+ EXPECT_FALSE(Support::isUInt12(-1) );
INFO("Support::isUInt16()");
- EXPECT(Support::isUInt16(0) == true);
- EXPECT(Support::isUInt16(65535) == true);
- EXPECT(Support::isUInt16(65536) == false);
- EXPECT(Support::isUInt16(-1) == false);
+ EXPECT_TRUE(Support::isUInt16(0) );
+ EXPECT_TRUE(Support::isUInt16(65535));
+ EXPECT_FALSE(Support::isUInt16(65536));
+ EXPECT_FALSE(Support::isUInt16(-1) );
INFO("Support::isUInt32()");
- EXPECT(Support::isUInt32(uint64_t(0xFFFFFFFF)) == true);
- EXPECT(Support::isUInt32(uint64_t(0xFFFFFFFF) + 1) == false);
- EXPECT(Support::isUInt32(-1) == false);
+ EXPECT_TRUE(Support::isUInt32(uint64_t(0xFFFFFFFF)));
+ EXPECT_FALSE(Support::isUInt32(uint64_t(0xFFFFFFFF) + 1));
+ EXPECT_FALSE(Support::isUInt32(-1));
}
static void testReadWrite() noexcept {
@@ -194,17 +196,17 @@ static void testReadWrite() noexcept {
Support::writeU16uBE(arr + 1, 0x0102u);
Support::writeU16uBE(arr + 3, 0x0304u);
- EXPECT(Support::readU32uBE(arr + 1) == 0x01020304u);
- EXPECT(Support::readU32uLE(arr + 1) == 0x04030201u);
- EXPECT(Support::readU32uBE(arr + 2) == 0x02030400u);
- EXPECT(Support::readU32uLE(arr + 2) == 0x00040302u);
+ EXPECT_EQ(Support::readU32uBE(arr + 1), 0x01020304u);
+ EXPECT_EQ(Support::readU32uLE(arr + 1), 0x04030201u);
+ EXPECT_EQ(Support::readU32uBE(arr + 2), 0x02030400u);
+ EXPECT_EQ(Support::readU32uLE(arr + 2), 0x00040302u);
Support::writeU32uLE(arr + 5, 0x05060708u);
- EXPECT(Support::readU64uBE(arr + 1) == 0x0102030408070605u);
- EXPECT(Support::readU64uLE(arr + 1) == 0x0506070804030201u);
+ EXPECT_EQ(Support::readU64uBE(arr + 1), 0x0102030408070605u);
+ EXPECT_EQ(Support::readU64uLE(arr + 1), 0x0506070804030201u);
Support::writeU64uLE(arr + 7, 0x1122334455667788u);
- EXPECT(Support::readU32uBE(arr + 8) == 0x77665544u);
+ EXPECT_EQ(Support::readU32uBE(arr + 8), 0x77665544u);
}
static void testBitVector() noexcept {
@@ -212,132 +214,132 @@ static void testBitVector() noexcept {
{
uint32_t vec[3] = { 0 };
Support::bitVectorFill(vec, 1, 64);
- EXPECT(vec[0] == 0xFFFFFFFEu);
- EXPECT(vec[1] == 0xFFFFFFFFu);
- EXPECT(vec[2] == 0x00000001u);
+ EXPECT_EQ(vec[0], 0xFFFFFFFEu);
+ EXPECT_EQ(vec[1], 0xFFFFFFFFu);
+ EXPECT_EQ(vec[2], 0x00000001u);
Support::bitVectorClear(vec, 1, 1);
- EXPECT(vec[0] == 0xFFFFFFFCu);
- EXPECT(vec[1] == 0xFFFFFFFFu);
- EXPECT(vec[2] == 0x00000001u);
+ EXPECT_EQ(vec[0], 0xFFFFFFFCu);
+ EXPECT_EQ(vec[1], 0xFFFFFFFFu);
+ EXPECT_EQ(vec[2], 0x00000001u);
Support::bitVectorFill(vec, 0, 32);
- EXPECT(vec[0] == 0xFFFFFFFFu);
- EXPECT(vec[1] == 0xFFFFFFFFu);
- EXPECT(vec[2] == 0x00000001u);
+ EXPECT_EQ(vec[0], 0xFFFFFFFFu);
+ EXPECT_EQ(vec[1], 0xFFFFFFFFu);
+ EXPECT_EQ(vec[2], 0x00000001u);
Support::bitVectorClear(vec, 0, 32);
- EXPECT(vec[0] == 0x00000000u);
- EXPECT(vec[1] == 0xFFFFFFFFu);
- EXPECT(vec[2] == 0x00000001u);
+ EXPECT_EQ(vec[0], 0x00000000u);
+ EXPECT_EQ(vec[1], 0xFFFFFFFFu);
+ EXPECT_EQ(vec[2], 0x00000001u);
Support::bitVectorFill(vec, 1, 30);
- EXPECT(vec[0] == 0x7FFFFFFEu);
- EXPECT(vec[1] == 0xFFFFFFFFu);
- EXPECT(vec[2] == 0x00000001u);
+ EXPECT_EQ(vec[0], 0x7FFFFFFEu);
+ EXPECT_EQ(vec[1], 0xFFFFFFFFu);
+ EXPECT_EQ(vec[2], 0x00000001u);
Support::bitVectorClear(vec, 1, 95);
- EXPECT(vec[0] == 0x00000000u);
- EXPECT(vec[1] == 0x00000000u);
- EXPECT(vec[2] == 0x00000000u);
+ EXPECT_EQ(vec[0], 0x00000000u);
+ EXPECT_EQ(vec[1], 0x00000000u);
+ EXPECT_EQ(vec[2], 0x00000000u);
Support::bitVectorFill(vec, 32, 64);
- EXPECT(vec[0] == 0x00000000u);
- EXPECT(vec[1] == 0xFFFFFFFFu);
- EXPECT(vec[2] == 0xFFFFFFFFu);
+ EXPECT_EQ(vec[0], 0x00000000u);
+ EXPECT_EQ(vec[1], 0xFFFFFFFFu);
+ EXPECT_EQ(vec[2], 0xFFFFFFFFu);
Support::bitVectorSetBit(vec, 1, true);
- EXPECT(vec[0] == 0x00000002u);
- EXPECT(vec[1] == 0xFFFFFFFFu);
- EXPECT(vec[2] == 0xFFFFFFFFu);
+ EXPECT_EQ(vec[0], 0x00000002u);
+ EXPECT_EQ(vec[1], 0xFFFFFFFFu);
+ EXPECT_EQ(vec[2], 0xFFFFFFFFu);
Support::bitVectorSetBit(vec, 95, false);
- EXPECT(vec[0] == 0x00000002u);
- EXPECT(vec[1] == 0xFFFFFFFFu);
- EXPECT(vec[2] == 0x7FFFFFFFu);
+ EXPECT_EQ(vec[0], 0x00000002u);
+ EXPECT_EQ(vec[1], 0xFFFFFFFFu);
+ EXPECT_EQ(vec[2], 0x7FFFFFFFu);
Support::bitVectorClear(vec, 33, 32);
- EXPECT(vec[0] == 0x00000002u);
- EXPECT(vec[1] == 0x00000001u);
- EXPECT(vec[2] == 0x7FFFFFFEu);
+ EXPECT_EQ(vec[0], 0x00000002u);
+ EXPECT_EQ(vec[1], 0x00000001u);
+ EXPECT_EQ(vec[2], 0x7FFFFFFEu);
}
INFO("Support::bitVectorIndexOf");
{
uint32_t vec1[1] = { 0x80000000 };
- EXPECT(Support::bitVectorIndexOf(vec1, 0, true) == 31);
- EXPECT(Support::bitVectorIndexOf(vec1, 1, true) == 31);
- EXPECT(Support::bitVectorIndexOf(vec1, 31, true) == 31);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec1, 0, true), 31u);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec1, 1, true), 31u);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec1, 31, true), 31u);
uint32_t vec2[2] = { 0x00000000, 0x80000000 };
- EXPECT(Support::bitVectorIndexOf(vec2, 0, true) == 63);
- EXPECT(Support::bitVectorIndexOf(vec2, 1, true) == 63);
- EXPECT(Support::bitVectorIndexOf(vec2, 31, true) == 63);
- EXPECT(Support::bitVectorIndexOf(vec2, 32, true) == 63);
- EXPECT(Support::bitVectorIndexOf(vec2, 33, true) == 63);
- EXPECT(Support::bitVectorIndexOf(vec2, 63, true) == 63);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec2, 0, true), 63u);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec2, 1, true), 63u);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec2, 31, true), 63u);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec2, 32, true), 63u);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec2, 33, true), 63u);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec2, 63, true), 63u);
uint32_t vec3[3] = { 0x00000001, 0x00000000, 0x80000000 };
- EXPECT(Support::bitVectorIndexOf(vec3, 0, true) == 0);
- EXPECT(Support::bitVectorIndexOf(vec3, 1, true) == 95);
- EXPECT(Support::bitVectorIndexOf(vec3, 2, true) == 95);
- EXPECT(Support::bitVectorIndexOf(vec3, 31, true) == 95);
- EXPECT(Support::bitVectorIndexOf(vec3, 32, true) == 95);
- EXPECT(Support::bitVectorIndexOf(vec3, 63, true) == 95);
- EXPECT(Support::bitVectorIndexOf(vec3, 64, true) == 95);
- EXPECT(Support::bitVectorIndexOf(vec3, 95, true) == 95);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec3, 0, true), 0u);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec3, 1, true), 95u);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec3, 2, true), 95u);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec3, 31, true), 95u);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec3, 32, true), 95u);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec3, 63, true), 95u);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec3, 64, true), 95u);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec3, 95, true), 95u);
uint32_t vec4[3] = { ~vec3[0], ~vec3[1], ~vec3[2] };
- EXPECT(Support::bitVectorIndexOf(vec4, 0, false) == 0);
- EXPECT(Support::bitVectorIndexOf(vec4, 1, false) == 95);
- EXPECT(Support::bitVectorIndexOf(vec4, 2, false) == 95);
- EXPECT(Support::bitVectorIndexOf(vec4, 31, false) == 95);
- EXPECT(Support::bitVectorIndexOf(vec4, 32, false) == 95);
- EXPECT(Support::bitVectorIndexOf(vec4, 63, false) == 95);
- EXPECT(Support::bitVectorIndexOf(vec4, 64, false) == 95);
- EXPECT(Support::bitVectorIndexOf(vec4, 95, false) == 95);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec4, 0, false), 0u);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec4, 1, false), 95u);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec4, 2, false), 95u);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec4, 31, false), 95u);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec4, 32, false), 95u);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec4, 63, false), 95u);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec4, 64, false), 95u);
+ EXPECT_EQ(Support::bitVectorIndexOf(vec4, 95, false), 95u);
}
INFO("Support::BitWordIterator<uint32_t>");
{
Support::BitWordIterator<uint32_t> it(0x80000F01u);
- EXPECT(it.hasNext());
- EXPECT(it.next() == 0);
- EXPECT(it.hasNext());
- EXPECT(it.next() == 8);
- EXPECT(it.hasNext());
- EXPECT(it.next() == 9);
- EXPECT(it.hasNext());
- EXPECT(it.next() == 10);
- EXPECT(it.hasNext());
- EXPECT(it.next() == 11);
- EXPECT(it.hasNext());
- EXPECT(it.next() == 31);
- EXPECT(!it.hasNext());
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 0u);
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 8u);
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 9u);
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 10u);
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 11u);
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 31u);
+ EXPECT_FALSE(it.hasNext());
// No bits set.
it.init(0x00000000u);
- ASMJIT_ASSERT(!it.hasNext());
+ EXPECT_FALSE(it.hasNext());
// Only first bit set.
it.init(0x00000001u);
- EXPECT(it.hasNext());
- EXPECT(it.next() == 0);
- ASMJIT_ASSERT(!it.hasNext());
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 0u);
+ EXPECT_FALSE(it.hasNext());
// Only last bit set (special case).
it.init(0x80000000u);
- ASMJIT_ASSERT(it.hasNext());
- ASMJIT_ASSERT(it.next() == 31);
- ASMJIT_ASSERT(!it.hasNext());
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 31u);
+ EXPECT_FALSE(it.hasNext());
}
INFO("Support::BitWordIterator<uint64_t>");
{
Support::BitWordIterator<uint64_t> it(uint64_t(1) << 63);
- ASMJIT_ASSERT(it.hasNext());
- ASMJIT_ASSERT(it.next() == 63);
- ASMJIT_ASSERT(!it.hasNext());
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 63u);
+ EXPECT_FALSE(it.hasNext());
}
INFO("Support::BitVectorIterator<uint32_t>");
@@ -346,63 +348,63 @@ static void testBitVector() noexcept {
static const uint32_t bitsNone[] = { 0xFFFFFFFFu };
Support::BitVectorIterator<uint32_t> it(bitsNone, 0);
- EXPECT(!it.hasNext());
+ EXPECT_FALSE(it.hasNext());
it.init(bitsNone, 0, 1);
- EXPECT(!it.hasNext());
+ EXPECT_FALSE(it.hasNext());
it.init(bitsNone, 0, 128);
- EXPECT(!it.hasNext());
+ EXPECT_FALSE(it.hasNext());
static const uint32_t bits1[] = { 0x80000008u, 0x80000001u, 0x00000000u, 0x80000000u, 0x00000000u, 0x00000000u, 0x00003000u };
it.init(bits1, ASMJIT_ARRAY_SIZE(bits1));
- EXPECT(it.hasNext());
- EXPECT(it.next() == 3);
- EXPECT(it.hasNext());
- EXPECT(it.next() == 31);
- EXPECT(it.hasNext());
- EXPECT(it.next() == 32);
- EXPECT(it.hasNext());
- EXPECT(it.next() == 63);
- EXPECT(it.hasNext());
- EXPECT(it.next() == 127);
- EXPECT(it.hasNext());
- EXPECT(it.next() == 204);
- EXPECT(it.hasNext());
- EXPECT(it.next() == 205);
- EXPECT(!it.hasNext());
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 3u);
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 31u);
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 32u);
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 63u);
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 127u);
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 204u);
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 205u);
+ EXPECT_FALSE(it.hasNext());
it.init(bits1, ASMJIT_ARRAY_SIZE(bits1), 4);
- EXPECT(it.hasNext());
- EXPECT(it.next() == 31);
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 31u);
it.init(bits1, ASMJIT_ARRAY_SIZE(bits1), 64);
- EXPECT(it.hasNext());
- EXPECT(it.next() == 127);
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 127u);
it.init(bits1, ASMJIT_ARRAY_SIZE(bits1), 127);
- EXPECT(it.hasNext());
- EXPECT(it.next() == 127);
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 127u);
static const uint32_t bits2[] = { 0x80000000u, 0x80000000u, 0x00000000u, 0x80000000u };
it.init(bits2, ASMJIT_ARRAY_SIZE(bits2));
- EXPECT(it.hasNext());
- EXPECT(it.next() == 31);
- EXPECT(it.hasNext());
- EXPECT(it.next() == 63);
- EXPECT(it.hasNext());
- EXPECT(it.next() == 127);
- EXPECT(!it.hasNext());
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 31u);
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 63u);
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 127u);
+ EXPECT_FALSE(it.hasNext());
static const uint32_t bits3[] = { 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u };
it.init(bits3, ASMJIT_ARRAY_SIZE(bits3));
- EXPECT(!it.hasNext());
+ EXPECT_FALSE(it.hasNext());
static const uint32_t bits4[] = { 0x00000000u, 0x00000000u, 0x00000000u, 0x80000000u };
it.init(bits4, ASMJIT_ARRAY_SIZE(bits4));
- EXPECT(it.hasNext());
- EXPECT(it.next() == 127);
- EXPECT(!it.hasNext());
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 127u);
+ EXPECT_FALSE(it.hasNext());
}
INFO("Support::BitVectorIterator<uint64_t>");
@@ -410,20 +412,20 @@ static void testBitVector() noexcept {
static const uint64_t bits1[] = { 0x80000000u, 0x80000000u, 0x00000000u, 0x80000000u };
Support::BitVectorIterator<uint64_t> it(bits1, ASMJIT_ARRAY_SIZE(bits1));
- EXPECT(it.hasNext());
- EXPECT(it.next() == 31);
- EXPECT(it.hasNext());
- EXPECT(it.next() == 95);
- EXPECT(it.hasNext());
- EXPECT(it.next() == 223);
- EXPECT(!it.hasNext());
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 31u);
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 95u);
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 223u);
+ EXPECT_FALSE(it.hasNext());
static const uint64_t bits2[] = { 0x8000000000000000u, 0, 0, 0 };
it.init(bits2, ASMJIT_ARRAY_SIZE(bits2));
- EXPECT(it.hasNext());
- EXPECT(it.next() == 63);
- EXPECT(!it.hasNext());
+ EXPECT_TRUE(it.hasNext());
+ EXPECT_EQ(it.next(), 63u);
+ EXPECT_FALSE(it.hasNext());
}
}
diff --git a/3rdparty/asmjit/src/asmjit/core/support.h b/3rdparty/asmjit/src/asmjit/core/support.h
index e55b8084dbf..b5be91bcd3e 100644
--- a/3rdparty/asmjit/src/asmjit/core/support.h
+++ b/3rdparty/asmjit/src/asmjit/core/support.h
@@ -68,29 +68,29 @@ namespace Internal {
//! \endcond
template<typename T>
-static constexpr bool isUnsigned() noexcept { return std::is_unsigned<T>::value; }
+static ASMJIT_INLINE_NODEBUG constexpr bool isUnsigned() noexcept { return std::is_unsigned<T>::value; }
//! 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 {
+static ASMJIT_INLINE_NODEBUG constexpr typename Internal::Int32Or64<T, 0>::Type asInt(const T& x) noexcept {
return (typename Internal::Int32Or64<T, 0>::Type)x;
}
//! Casts an integer `x` to either `uint32_t` or `uint64_t` depending on `T`.
template<typename T>
-static constexpr typename Internal::Int32Or64<T, 1>::Type asUInt(const T& x) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr typename Internal::Int32Or64<T, 1>::Type asUInt(const T& x) noexcept {
return (typename Internal::Int32Or64<T, 1>::Type)x;
}
//! Casts an integer `x` to either `int32_t`, uint32_t`, `int64_t`, or `uint64_t` depending on `T`.
template<typename T>
-static constexpr typename Internal::Int32Or64<T>::Type asNormalized(const T& x) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr typename Internal::Int32Or64<T>::Type asNormalized(const T& x) noexcept {
return (typename Internal::Int32Or64<T>::Type)x;
}
//! Casts an integer `x` to the same type as defined by `<stdint.h>`.
template<typename T>
-static constexpr typename Internal::StdInt<sizeof(T), isUnsigned<T>()>::Type asStdInt(const T& x) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr typename Internal::StdInt<sizeof(T), isUnsigned<T>()>::Type asStdInt(const T& x) noexcept {
return (typename Internal::StdInt<sizeof(T), isUnsigned<T>()>::Type)x;
}
@@ -102,15 +102,15 @@ struct EnumValues {
struct Iterator {
ValueType value;
- inline T operator*() const { return (T)value; }
- inline void operator++() { ++value; }
+ ASMJIT_INLINE_NODEBUG T operator*() const { return (T)value; }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG bool operator==(const Iterator& other) const noexcept { return value == other.value; }
+ ASMJIT_INLINE_NODEBUG 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}; }
+ ASMJIT_INLINE_NODEBUG Iterator begin() const noexcept { return Iterator{ValueType(from)}; }
+ ASMJIT_INLINE_NODEBUG Iterator end() const noexcept { return Iterator{ValueType(to) + 1}; }
};
// Support - BitCast
@@ -120,7 +120,7 @@ struct EnumValues {
namespace Internal {
template<typename DstT, typename SrcT>
union BitCastUnion {
- inline BitCastUnion(SrcT src) noexcept : src(src) {}
+ ASMJIT_INLINE_NODEBUG BitCastUnion(SrcT src) noexcept : src(src) {}
SrcT src;
DstT dst;
};
@@ -131,7 +131,7 @@ namespace Internal {
//!
//! Useful to bit-cast between integers and floating points.
template<typename Dst, typename Src>
-static inline Dst bitCast(const Src& x) noexcept { return Internal::BitCastUnion<Dst, Src>(x).dst; }
+static ASMJIT_INLINE_NODEBUG Dst bitCast(const Src& x) noexcept { return Internal::BitCastUnion<Dst, Src>(x).dst; }
// Support - BitOps
// ================
@@ -140,62 +140,62 @@ static inline Dst bitCast(const Src& x) noexcept { return Internal::BitCastUnion
typedef Internal::StdInt<sizeof(uintptr_t), 1>::Type BitWord;
template<typename T>
-static constexpr uint32_t bitSizeOf() noexcept { return uint32_t(sizeof(T) * 8u); }
+static ASMJIT_INLINE_NODEBUG constexpr uint32_t bitSizeOf() noexcept { return uint32_t(sizeof(T) * 8u); }
//! Number of bits stored in a single `BitWord`.
static constexpr uint32_t kBitWordSizeInBits = bitSizeOf<BitWord>();
//! Returns `0 - x` in a safe way (no undefined behavior), works for unsigned numbers as well.
template<typename T>
-static constexpr T neg(const T& x) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr T neg(const T& x) noexcept {
typedef typename std::make_unsigned<T>::type U;
return T(U(0) - U(x));
}
template<typename T>
-static constexpr T allOnes() noexcept { return neg<T>(T(1)); }
+static ASMJIT_INLINE_NODEBUG constexpr T allOnes() noexcept { return neg<T>(T(1)); }
//! Returns `x << y` (shift left logical) by explicitly casting `x` to an unsigned type and back.
template<typename X, typename Y>
-static constexpr X shl(const X& x, const Y& y) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr X shl(const X& x, const Y& y) noexcept {
typedef typename std::make_unsigned<X>::type U;
return X(U(x) << y);
}
//! Returns `x >> y` (shift right logical) by explicitly casting `x` to an unsigned type and back.
template<typename X, typename Y>
-static constexpr X shr(const X& x, const Y& y) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr X shr(const X& x, const Y& y) noexcept {
typedef typename std::make_unsigned<X>::type U;
return X(U(x) >> y);
}
//! Returns `x >> y` (shift right arithmetic) by explicitly casting `x` to a signed type and back.
template<typename X, typename Y>
-static constexpr X sar(const X& x, const Y& y) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr X sar(const X& x, const Y& y) noexcept {
typedef typename std::make_signed<X>::type S;
return X(S(x) >> y);
}
template<typename X, typename Y>
-static constexpr X ror(const X& x, const Y& y) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr X ror(const X& x, const Y& y) noexcept {
typedef typename std::make_unsigned<X>::type U;
- return X((U(x) >> y) | (U(x) << (bitSizeOf<U>() - y)));
+ return X((U(x) >> y) | (U(x) << (bitSizeOf<U>() - U(y))));
}
//! Returns `x | (x >> y)` - helper used by some bit manipulation helpers.
template<typename X, typename Y>
-static constexpr X or_shr(const X& x, const Y& y) noexcept { return X(x | shr(x, y)); }
+static ASMJIT_INLINE_NODEBUG constexpr X or_shr(const X& x, const Y& y) noexcept { return X(x | shr(x, y)); }
//! Returns `x & -x` - extracts lowest set isolated bit (like BLSI instruction).
template<typename T>
-static constexpr T blsi(T x) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr T blsi(T x) noexcept {
typedef typename std::make_unsigned<T>::type U;
return T(U(x) & neg(U(x)));
}
//! Tests whether the given value `x` has `n`th bit set.
template<typename T, typename IndexT>
-static constexpr bool bitTest(T x, IndexT n) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr bool bitTest(T x, IndexT n) noexcept {
typedef typename std::make_unsigned<T>::type U;
return (U(x) & (U(1) << asStdInt(n))) != 0;
}
@@ -203,7 +203,7 @@ static constexpr bool bitTest(T x, IndexT n) noexcept {
// Tests whether the given `value` is a consecutive mask of bits that starts at
// the least significant bit.
template<typename T>
-static inline constexpr bool isLsbMask(const T& value) {
+static ASMJIT_INLINE_NODEBUG constexpr bool isLsbMask(const T& value) {
typedef typename std::make_unsigned<T>::type U;
return value && ((U(value) + 1u) & U(value)) == 0;
}
@@ -214,14 +214,14 @@ static inline constexpr bool isLsbMask(const T& value) {
// This function is similar to \ref isLsbMask(), but the mask doesn't have to
// start at a least significant bit.
template<typename T>
-static inline constexpr bool isConsecutiveMask(const T& value) {
+static ASMJIT_INLINE_NODEBUG constexpr bool isConsecutiveMask(const T& value) {
typedef typename std::make_unsigned<T>::type U;
return value && isLsbMask((U(value) - 1u) | U(value));
}
//! Generates a trailing bit-mask that has `n` least significant (trailing) bits set.
template<typename T, typename CountT>
-static constexpr T lsbMask(const CountT& n) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr T lsbMask(const CountT& n) noexcept {
typedef typename std::make_unsigned<T>::type U;
return (sizeof(U) < sizeof(uintptr_t))
// Prevent undefined behavior by using a larger type than T.
@@ -230,9 +230,9 @@ static constexpr T lsbMask(const CountT& n) noexcept {
: n ? T(shr(allOnes<T>(), bitSizeOf<T>() - size_t(n))) : T(0);
}
-//! Generats a leading bit-mask that has `n` most significant (leading) bits set.
+//! Generates a leading bit-mask that has `n` most significant (leading) bits set.
template<typename T, typename CountT>
-static constexpr T msbMask(const CountT& n) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr T msbMask(const CountT& n) noexcept {
typedef typename std::make_unsigned<T>::type U;
return (sizeof(U) < sizeof(uintptr_t))
// Prevent undefined behavior by using a larger type than T.
@@ -243,15 +243,15 @@ static constexpr T msbMask(const CountT& n) noexcept {
//! Returns a bit-mask that has `x` bit set.
template<typename Index>
-static constexpr uint32_t bitMask(const Index& x) noexcept { return (1u << asUInt(x)); }
+static ASMJIT_INLINE_NODEBUG 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 Index, typename... Args>
-static constexpr uint32_t bitMask(const Index& x, Args... args) noexcept { return bitMask(x) | bitMask(args...); }
+static ASMJIT_INLINE_NODEBUG 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>
-static constexpr DstT bitMaskFromBool(SrcT b) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr DstT bitMaskFromBool(SrcT b) noexcept {
typedef typename std::make_unsigned<DstT>::type U;
return DstT(U(0) - U(b));
}
@@ -263,19 +263,19 @@ static inline constexpr bool test(A a, B b) noexcept { return (asUInt(a) & asUIn
//! \cond
namespace Internal {
// Fills all trailing bits right from the first most significant bit set.
- static constexpr uint8_t fillTrailingBitsImpl(uint8_t x) noexcept { return or_shr(or_shr(or_shr(x, 1), 2), 4); }
+ static ASMJIT_INLINE_NODEBUG constexpr uint8_t fillTrailingBitsImpl(uint8_t x) noexcept { return or_shr(or_shr(or_shr(x, 1), 2), 4); }
// Fills all trailing bits right from the first most significant bit set.
- static constexpr uint16_t fillTrailingBitsImpl(uint16_t x) noexcept { return or_shr(or_shr(or_shr(or_shr(x, 1), 2), 4), 8); }
+ static ASMJIT_INLINE_NODEBUG constexpr uint16_t fillTrailingBitsImpl(uint16_t x) noexcept { return or_shr(or_shr(or_shr(or_shr(x, 1), 2), 4), 8); }
// Fills all trailing bits right from the first most significant bit set.
- static constexpr uint32_t fillTrailingBitsImpl(uint32_t x) noexcept { return or_shr(or_shr(or_shr(or_shr(or_shr(x, 1), 2), 4), 8), 16); }
+ static ASMJIT_INLINE_NODEBUG constexpr uint32_t fillTrailingBitsImpl(uint32_t x) noexcept { return or_shr(or_shr(or_shr(or_shr(or_shr(x, 1), 2), 4), 8), 16); }
// Fills all trailing bits right from the first most significant bit set.
- static constexpr uint64_t fillTrailingBitsImpl(uint64_t x) noexcept { return or_shr(or_shr(or_shr(or_shr(or_shr(or_shr(x, 1), 2), 4), 8), 16), 32); }
+ static ASMJIT_INLINE_NODEBUG constexpr uint64_t fillTrailingBitsImpl(uint64_t x) noexcept { return or_shr(or_shr(or_shr(or_shr(or_shr(or_shr(x, 1), 2), 4), 8), 16), 32); }
}
//! \endcond
// Fills all trailing bits right from the first most significant bit set.
template<typename T>
-static constexpr T fillTrailingBits(const T& x) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr T fillTrailingBits(const T& x) noexcept {
typedef typename std::make_unsigned<T>::type U;
return T(Internal::fillTrailingBitsImpl(U(x)));
}
@@ -292,59 +292,59 @@ struct BitScanData { T x; uint32_t n; };
template<typename T, uint32_t N>
struct BitScanCalc {
- static constexpr BitScanData<T> advanceLeft(const BitScanData<T>& data, uint32_t n) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr BitScanData<T> advanceLeft(const BitScanData<T>& data, uint32_t n) noexcept {
return BitScanData<T> { data.x << n, data.n + n };
}
- static constexpr BitScanData<T> advanceRight(const BitScanData<T>& data, uint32_t n) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr BitScanData<T> advanceRight(const BitScanData<T>& data, uint32_t n) noexcept {
return BitScanData<T> { data.x >> n, data.n + n };
}
- static constexpr BitScanData<T> clz(const BitScanData<T>& data) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr BitScanData<T> clz(const BitScanData<T>& data) noexcept {
return BitScanCalc<T, N / 2>::clz(advanceLeft(data, data.x & (allOnes<T>() << (bitSizeOf<T>() - N)) ? uint32_t(0) : N));
}
- static constexpr BitScanData<T> ctz(const BitScanData<T>& data) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr BitScanData<T> ctz(const BitScanData<T>& data) noexcept {
return BitScanCalc<T, N / 2>::ctz(advanceRight(data, data.x & (allOnes<T>() >> (bitSizeOf<T>() - N)) ? uint32_t(0) : N));
}
};
template<typename T>
struct BitScanCalc<T, 0> {
- static constexpr BitScanData<T> clz(const BitScanData<T>& ctx) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr BitScanData<T> clz(const BitScanData<T>& ctx) noexcept {
return BitScanData<T> { 0, ctx.n - uint32_t(ctx.x >> (bitSizeOf<T>() - 1)) };
}
- static constexpr BitScanData<T> ctz(const BitScanData<T>& ctx) noexcept {
+ static ASMJIT_INLINE_NODEBUG constexpr BitScanData<T> ctz(const BitScanData<T>& ctx) noexcept {
return BitScanData<T> { 0, ctx.n - uint32_t(ctx.x & 0x1) };
}
};
template<typename T>
-constexpr uint32_t clzFallback(const T& x) noexcept {
+ASMJIT_INLINE_NODEBUG constexpr uint32_t clzFallback(const T& x) noexcept {
return BitScanCalc<T, bitSizeOf<T>() / 2u>::clz(BitScanData<T>{x, 1}).n;
}
template<typename T>
-constexpr uint32_t ctzFallback(const T& x) noexcept {
+ASMJIT_INLINE_NODEBUG constexpr uint32_t ctzFallback(const T& x) noexcept {
return BitScanCalc<T, bitSizeOf<T>() / 2u>::ctz(BitScanData<T>{x, 1}).n;
}
-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)); }
+template<typename T> ASMJIT_INLINE_NODEBUG uint32_t clzImpl(const T& x) noexcept { return clzFallback(asUInt(x)); }
+template<typename T> ASMJIT_INLINE_NODEBUG uint32_t ctzImpl(const T& x) noexcept { return ctzFallback(asUInt(x)); }
#if !defined(ASMJIT_NO_INTRINSICS)
# if defined(__GNUC__)
-template<> inline uint32_t clzImpl(const uint32_t& x) noexcept { return uint32_t(__builtin_clz(x)); }
-template<> inline uint32_t clzImpl(const uint64_t& x) noexcept { return uint32_t(__builtin_clzll(x)); }
-template<> inline uint32_t ctzImpl(const uint32_t& x) noexcept { return uint32_t(__builtin_ctz(x)); }
-template<> inline uint32_t ctzImpl(const uint64_t& x) noexcept { return uint32_t(__builtin_ctzll(x)); }
+template<> ASMJIT_INLINE_NODEBUG uint32_t clzImpl(const uint32_t& x) noexcept { return uint32_t(__builtin_clz(x)); }
+template<> ASMJIT_INLINE_NODEBUG uint32_t clzImpl(const uint64_t& x) noexcept { return uint32_t(__builtin_clzll(x)); }
+template<> ASMJIT_INLINE_NODEBUG uint32_t ctzImpl(const uint32_t& x) noexcept { return uint32_t(__builtin_ctz(x)); }
+template<> ASMJIT_INLINE_NODEBUG uint32_t ctzImpl(const uint64_t& x) noexcept { return uint32_t(__builtin_ctzll(x)); }
# elif defined(_MSC_VER)
-template<> inline uint32_t clzImpl(const uint32_t& x) noexcept { unsigned long i; _BitScanReverse(&i, x); return uint32_t(i ^ 31); }
-template<> inline uint32_t ctzImpl(const uint32_t& x) noexcept { unsigned long i; _BitScanForward(&i, x); return uint32_t(i); }
+template<> ASMJIT_INLINE_NODEBUG uint32_t clzImpl(const uint32_t& x) noexcept { unsigned long i; _BitScanReverse(&i, x); return uint32_t(i ^ 31); }
+template<> ASMJIT_INLINE_NODEBUG uint32_t ctzImpl(const uint32_t& x) noexcept { unsigned long i; _BitScanForward(&i, x); return uint32_t(i); }
# if ASMJIT_ARCH_X86 == 64 || ASMJIT_ARCH_ARM == 64
-template<> inline uint32_t clzImpl(const uint64_t& x) noexcept { unsigned long i; _BitScanReverse64(&i, x); return uint32_t(i ^ 63); }
-template<> inline uint32_t ctzImpl(const uint64_t& x) noexcept { unsigned long i; _BitScanForward64(&i, x); return uint32_t(i); }
+template<> ASMJIT_INLINE_NODEBUG uint32_t clzImpl(const uint64_t& x) noexcept { unsigned long i; _BitScanReverse64(&i, x); return uint32_t(i ^ 63); }
+template<> ASMJIT_INLINE_NODEBUG uint32_t ctzImpl(const uint64_t& x) noexcept { unsigned long i; _BitScanForward64(&i, x); return uint32_t(i); }
# endif
# endif
#endif
@@ -357,13 +357,13 @@ template<> inline uint32_t ctzImpl(const uint64_t& x) noexcept { unsigned long i
//!
//! \note The input MUST NOT be zero, otherwise the result is undefined.
template<typename T>
-static inline uint32_t clz(T x) noexcept { return Internal::clzImpl(asUInt(x)); }
+static ASMJIT_INLINE_NODEBUG uint32_t clz(T x) noexcept { return Internal::clzImpl(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)); }
+static ASMJIT_INLINE_NODEBUG uint32_t ctz(T x) noexcept { return Internal::ctzImpl(asUInt(x)); }
template<uint64_t kInput>
struct ConstCTZ {
@@ -450,49 +450,48 @@ struct ConstCTZ {
//! \cond
namespace Internal {
- static inline uint32_t constPopcntImpl(uint32_t x) noexcept {
+ static ASMJIT_INLINE_NODEBUG uint32_t constPopcntImpl(uint32_t x) noexcept {
x = x - ((x >> 1) & 0x55555555u);
x = (x & 0x33333333u) + ((x >> 2) & 0x33333333u);
return (((x + (x >> 4)) & 0x0F0F0F0Fu) * 0x01010101u) >> 24;
}
- static inline uint32_t constPopcntImpl(uint64_t x) noexcept {
- if (ASMJIT_ARCH_BITS >= 64) {
- x = x - ((x >> 1) & 0x5555555555555555u);
- x = (x & 0x3333333333333333u) + ((x >> 2) & 0x3333333333333333u);
- return uint32_t((((x + (x >> 4)) & 0x0F0F0F0F0F0F0F0Fu) * 0x0101010101010101u) >> 56);
- }
- else {
- return constPopcntImpl(uint32_t(x >> 32)) +
- constPopcntImpl(uint32_t(x & 0xFFFFFFFFu));
- }
+ static ASMJIT_INLINE_NODEBUG uint32_t constPopcntImpl(uint64_t x) noexcept {
+#if ASMJIT_ARCH_BITS >= 64
+ x = x - ((x >> 1) & 0x5555555555555555u);
+ x = (x & 0x3333333333333333u) + ((x >> 2) & 0x3333333333333333u);
+ return uint32_t((((x + (x >> 4)) & 0x0F0F0F0F0F0F0F0Fu) * 0x0101010101010101u) >> 56);
+#else
+ return constPopcntImpl(uint32_t(x >> 32)) +
+ constPopcntImpl(uint32_t(x & 0xFFFFFFFFu));
+#endif
}
- static inline uint32_t popcntImpl(uint32_t x) noexcept {
- #if defined(__GNUC__)
+ static ASMJIT_INLINE_NODEBUG uint32_t popcntImpl(uint32_t x) noexcept {
+#if defined(__GNUC__)
return uint32_t(__builtin_popcount(x));
- #else
+#else
return constPopcntImpl(asUInt(x));
- #endif
+#endif
}
- static inline uint32_t popcntImpl(uint64_t x) noexcept {
- #if defined(__GNUC__)
+ static ASMJIT_INLINE_NODEBUG uint32_t popcntImpl(uint64_t x) noexcept {
+#if defined(__GNUC__)
return uint32_t(__builtin_popcountll(x));
- #else
+#else
return constPopcntImpl(asUInt(x));
- #endif
+#endif
}
}
//! \endcond
//! Calculates count of bits in `x`.
template<typename T>
-static inline uint32_t popcnt(T x) noexcept { return Internal::popcntImpl(asUInt(x)); }
+static ASMJIT_INLINE_NODEBUG uint32_t popcnt(T x) noexcept { return Internal::popcntImpl(asUInt(x)); }
//! Calculates count of bits in `x` (useful in constant expressions).
template<typename T>
-static inline uint32_t constPopcnt(T x) noexcept { return Internal::constPopcntImpl(asUInt(x)); }
+static ASMJIT_INLINE_NODEBUG uint32_t constPopcnt(T x) noexcept { return Internal::constPopcntImpl(asUInt(x)); }
// Support - Min/Max
// =================
@@ -502,16 +501,16 @@ static inline uint32_t constPopcnt(T x) noexcept { return Internal::constPopcntI
// a reference to `a` or `b` but it's a new value instead.
template<typename T>
-static constexpr T min(const T& a, const T& b) noexcept { return b < a ? b : a; }
+static ASMJIT_INLINE_NODEBUG constexpr T min(const T& a, const T& b) noexcept { return b < a ? b : a; }
template<typename T, typename... Args>
-static constexpr T min(const T& a, const T& b, Args&&... args) noexcept { return min(min(a, b), std::forward<Args>(args)...); }
+static ASMJIT_INLINE_NODEBUG constexpr T min(const T& a, const T& b, Args&&... args) noexcept { return min(min(a, b), std::forward<Args>(args)...); }
template<typename T>
-static constexpr T max(const T& a, const T& b) noexcept { return a < b ? b : a; }
+static ASMJIT_INLINE_NODEBUG 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)...); }
+static ASMJIT_INLINE_NODEBUG constexpr T max(const T& a, const T& b, Args&&... args) noexcept { return max(max(a, b), std::forward<Args>(args)...); }
// Support - Immediate Helpers
// ===========================
@@ -519,22 +518,22 @@ static constexpr T max(const T& a, const T& b, Args&&... args) noexcept { return
namespace Internal {
template<typename T, bool IsFloat>
struct ImmConv {
- static inline int64_t fromT(const T& x) noexcept { return int64_t(x); }
- static inline T toT(int64_t x) noexcept { return T(uint64_t(x) & Support::allOnes<typename std::make_unsigned<T>::type>()); }
+ static ASMJIT_INLINE_NODEBUG int64_t fromT(const T& x) noexcept { return int64_t(x); }
+ static ASMJIT_INLINE_NODEBUG T toT(int64_t x) noexcept { return T(uint64_t(x) & Support::allOnes<typename std::make_unsigned<T>::type>()); }
};
template<typename T>
struct ImmConv<T, true> {
- static inline int64_t fromT(const T& x) noexcept { return int64_t(bitCast<int64_t>(double(x))); }
- static inline T toT(int64_t x) noexcept { return T(bitCast<double>(x)); }
+ static ASMJIT_INLINE_NODEBUG int64_t fromT(const T& x) noexcept { return int64_t(bitCast<int64_t>(double(x))); }
+ static ASMJIT_INLINE_NODEBUG T toT(int64_t x) noexcept { return T(bitCast<double>(x)); }
};
}
template<typename T>
-static inline int64_t immediateFromT(const T& x) noexcept { return Internal::ImmConv<T, std::is_floating_point<T>::value>::fromT(x); }
+static ASMJIT_INLINE_NODEBUG int64_t immediateFromT(const T& x) noexcept { return Internal::ImmConv<T, std::is_floating_point<T>::value>::fromT(x); }
template<typename T>
-static inline T immediateToT(int64_t x) noexcept { return Internal::ImmConv<T, std::is_floating_point<T>::value>::toT(x); }
+static ASMJIT_INLINE_NODEBUG T immediateToT(int64_t x) noexcept { return Internal::ImmConv<T, std::is_floating_point<T>::value>::toT(x); }
// Support - Overflow Arithmetic
// =============================
@@ -596,9 +595,9 @@ namespace Internal {
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) \
+#if defined(__GNUC__) && !defined(ASMJIT_NO_INTRINSICS)
+#if defined(__clang__) || __GNUC__ >= 5
+#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; \
@@ -617,13 +616,13 @@ namespace Internal {
ASMJIT_ARITH_OVERFLOW_SPECIALIZE(mulOverflowImpl, uint32_t, unsigned int , __builtin_umul_overflow )
ASMJIT_ARITH_OVERFLOW_SPECIALIZE(mulOverflowImpl, int64_t , long long , __builtin_smulll_overflow)
ASMJIT_ARITH_OVERFLOW_SPECIALIZE(mulOverflowImpl, uint64_t, unsigned long long, __builtin_umulll_overflow)
- #undef ASMJIT_ARITH_OVERFLOW_SPECIALIZE
- #endif
- #endif
+#undef ASMJIT_ARITH_OVERFLOW_SPECIALIZE
+#endif
+#endif
// 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) \
+#if defined(_MSC_VER) && 0
+#define ASMJIT_ARITH_OVERFLOW_SPECIALIZE(FUNC, T, ALT_T, BUILTIN) \
template<> \
inline T FUNC(T x, T y, FastUInt8* of) noexcept { \
ALT_T result; \
@@ -632,12 +631,12 @@ namespace Internal {
}
ASMJIT_ARITH_OVERFLOW_SPECIALIZE(addOverflowImpl, uint32_t, unsigned int , _addcarry_u32 )
ASMJIT_ARITH_OVERFLOW_SPECIALIZE(subOverflowImpl, uint32_t, unsigned int , _subborrow_u32)
- #if ARCH_BITS >= 64
+#if ARCH_BITS >= 64
ASMJIT_ARITH_OVERFLOW_SPECIALIZE(addOverflowImpl, uint64_t, unsigned __int64 , _addcarry_u64 )
ASMJIT_ARITH_OVERFLOW_SPECIALIZE(subOverflowImpl, uint64_t, unsigned __int64 , _subborrow_u64)
- #endif
- #undef ASMJIT_ARITH_OVERFLOW_SPECIALIZE
- #endif
+#endif
+#undef ASMJIT_ARITH_OVERFLOW_SPECIALIZE
+#endif
} // {Internal}
//! \endcond
@@ -654,26 +653,26 @@ static inline T mulOverflow(const T& x, const T& y, FastUInt8* of) noexcept { re
// ===================
template<typename X, typename Y>
-static constexpr bool isAligned(X base, Y alignment) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr bool isAligned(X base, Y alignment) noexcept {
typedef typename Internal::StdInt<sizeof(X), 1>::Type U;
return ((U)base % (U)alignment) == 0;
}
//! Tests whether the `x` is a power of two (only one bit is set).
template<typename T>
-static constexpr bool isPowerOf2(T x) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr bool isPowerOf2(T x) noexcept {
typedef typename std::make_unsigned<T>::type U;
return x && !(U(x) & (U(x) - U(1)));
}
template<typename X, typename Y>
-static constexpr X alignUp(X x, Y alignment) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr X alignUp(X x, Y alignment) noexcept {
typedef typename Internal::StdInt<sizeof(X), 1>::Type U;
return (X)( ((U)x + ((U)(alignment) - 1u)) & ~((U)(alignment) - 1u) );
}
template<typename T>
-static constexpr T alignUpPowerOf2(T x) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr T alignUpPowerOf2(T x) noexcept {
typedef typename Internal::StdInt<sizeof(T), 1>::Type U;
return (T)(fillTrailingBits(U(x) - 1u) + 1u);
}
@@ -681,13 +680,13 @@ static constexpr T alignUpPowerOf2(T x) noexcept {
//! Returns either zero or a positive difference between `base` and `base` when
//! aligned to `alignment`.
template<typename X, typename Y>
-static constexpr typename Internal::StdInt<sizeof(X), 1>::Type alignUpDiff(X base, Y alignment) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr typename Internal::StdInt<sizeof(X), 1>::Type alignUpDiff(X base, Y alignment) noexcept {
typedef typename Internal::StdInt<sizeof(X), 1>::Type U;
return alignUp(U(base), alignment) - U(base);
}
template<typename X, typename Y>
-static constexpr X alignDown(X x, Y alignment) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr X alignDown(X x, Y alignment) noexcept {
typedef typename Internal::StdInt<sizeof(X), 1>::Type U;
return (X)( (U)x & ~((U)(alignment) - 1u) );
}
@@ -699,7 +698,7 @@ static constexpr X alignDown(X x, Y alignment) noexcept {
//! granularized by `granularity`. This function can be used to calculate
//! the number of BitWords to represent N bits, for example.
template<typename X, typename Y>
-static constexpr X numGranularized(X base, Y granularity) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr X numGranularized(X base, Y granularity) noexcept {
typedef typename Internal::StdInt<sizeof(X), 1>::Type U;
return X((U(base) + U(granularity) - 1) / U(granularity));
}
@@ -709,7 +708,7 @@ static constexpr X numGranularized(X base, Y granularity) noexcept {
//! Checks whether `x` is greater than or equal to `a` and lesser than or equal to `b`.
template<typename T>
-static constexpr bool isBetween(const T& x, const T& a, const T& b) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr bool isBetween(const T& x, const T& a, const T& b) noexcept {
return x >= a && x <= b;
}
@@ -718,7 +717,7 @@ static constexpr bool isBetween(const T& x, const T& a, const T& b) noexcept {
//! Checks whether the given integer `x` can be casted to a 4-bit signed integer.
template<typename T>
-static constexpr bool isInt4(T x) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr bool isInt4(T x) noexcept {
typedef typename std::make_signed<T>::type S;
typedef typename std::make_unsigned<T>::type U;
@@ -727,7 +726,7 @@ static constexpr bool isInt4(T x) noexcept {
//! Checks whether the given integer `x` can be casted to a 7-bit signed integer.
template<typename T>
-static constexpr bool isInt7(T x) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr bool isInt7(T x) noexcept {
typedef typename std::make_signed<T>::type S;
typedef typename std::make_unsigned<T>::type U;
@@ -736,7 +735,7 @@ static constexpr bool isInt7(T x) noexcept {
//! Checks whether the given integer `x` can be casted to an 8-bit signed integer.
template<typename T>
-static constexpr bool isInt8(T x) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr bool isInt8(T x) noexcept {
typedef typename std::make_signed<T>::type S;
typedef typename std::make_unsigned<T>::type U;
@@ -745,7 +744,7 @@ static constexpr bool isInt8(T x) noexcept {
//! Checks whether the given integer `x` can be casted to a 9-bit signed integer.
template<typename T>
-static constexpr bool isInt9(T x) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr bool isInt9(T x) noexcept {
typedef typename std::make_signed<T>::type S;
typedef typename std::make_unsigned<T>::type U;
@@ -755,7 +754,7 @@ static constexpr bool isInt9(T x) noexcept {
//! Checks whether the given integer `x` can be casted to a 10-bit signed integer.
template<typename T>
-static constexpr bool isInt10(T x) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr bool isInt10(T x) noexcept {
typedef typename std::make_signed<T>::type S;
typedef typename std::make_unsigned<T>::type U;
@@ -765,7 +764,7 @@ static constexpr bool isInt10(T x) noexcept {
//! Checks whether the given integer `x` can be casted to a 16-bit signed integer.
template<typename T>
-static constexpr bool isInt16(T x) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr bool isInt16(T x) noexcept {
typedef typename std::make_signed<T>::type S;
typedef typename std::make_unsigned<T>::type U;
@@ -775,7 +774,7 @@ static constexpr bool isInt16(T x) noexcept {
//! Checks whether the given integer `x` can be casted to a 32-bit signed integer.
template<typename T>
-static constexpr bool isInt32(T x) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr bool isInt32(T x) noexcept {
typedef typename std::make_signed<T>::type S;
typedef typename std::make_unsigned<T>::type U;
@@ -785,7 +784,7 @@ static constexpr bool isInt32(T x) noexcept {
//! Checks whether the given integer `x` can be casted to a 4-bit unsigned integer.
template<typename T>
-static constexpr bool isUInt4(T x) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr bool isUInt4(T x) noexcept {
typedef typename std::make_unsigned<T>::type U;
return std::is_signed<T>::value ? x >= T(0) && x <= T(15)
@@ -794,7 +793,7 @@ static constexpr bool isUInt4(T x) noexcept {
//! Checks whether the given integer `x` can be casted to an 8-bit unsigned integer.
template<typename T>
-static constexpr bool isUInt8(T x) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr bool isUInt8(T x) noexcept {
typedef typename std::make_unsigned<T>::type U;
return std::is_signed<T>::value ? (sizeof(T) <= 1 || T(x) <= T(255)) && x >= T(0)
@@ -803,7 +802,7 @@ static constexpr bool isUInt8(T x) noexcept {
//! Checks whether the given integer `x` can be casted to a 12-bit unsigned integer (ARM specific).
template<typename T>
-static constexpr bool isUInt12(T x) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr bool isUInt12(T x) noexcept {
typedef typename std::make_unsigned<T>::type U;
return std::is_signed<T>::value ? (sizeof(T) <= 1 || T(x) <= T(4095)) && x >= T(0)
@@ -812,7 +811,7 @@ static constexpr bool isUInt12(T x) noexcept {
//! Checks whether the given integer `x` can be casted to a 16-bit unsigned integer.
template<typename T>
-static constexpr bool isUInt16(T x) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr bool isUInt16(T x) noexcept {
typedef typename std::make_unsigned<T>::type U;
return std::is_signed<T>::value ? (sizeof(T) <= 2 || T(x) <= T(65535)) && x >= T(0)
@@ -821,7 +820,7 @@ static constexpr bool isUInt16(T x) noexcept {
//! Checks whether the given integer `x` can be casted to a 32-bit unsigned integer.
template<typename T>
-static constexpr bool isUInt32(T x) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr bool isUInt32(T x) noexcept {
typedef typename std::make_unsigned<T>::type U;
return std::is_signed<T>::value ? (sizeof(T) <= 4 || T(x) <= T(4294967295u)) && x >= T(0)
@@ -830,16 +829,16 @@ static constexpr bool isUInt32(T x) noexcept {
//! Checks whether the given integer `x` can be casted to a 32-bit unsigned integer.
template<typename T>
-static constexpr bool isIntOrUInt32(T x) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr bool isIntOrUInt32(T x) noexcept {
return sizeof(T) <= 4 ? true : (uint32_t(uint64_t(x) >> 32) + 1u) <= 1u;
}
-static bool inline isEncodableOffset32(int32_t offset, uint32_t nBits) noexcept {
+static bool ASMJIT_INLINE_NODEBUG isEncodableOffset32(int32_t offset, uint32_t nBits) noexcept {
uint32_t nRev = 32 - nBits;
return Support::sar(Support::shl(offset, nRev), nRev) == offset;
}
-static bool inline isEncodableOffset64(int64_t offset, uint32_t nBits) noexcept {
+static bool ASMJIT_INLINE_NODEBUG isEncodableOffset64(int64_t offset, uint32_t nBits) noexcept {
uint32_t nRev = 64 - nBits;
return Support::sar(Support::shl(offset, nRev), nRev) == offset;
}
@@ -847,15 +846,15 @@ static bool inline isEncodableOffset64(int64_t offset, uint32_t nBits) noexcept
// Support - ByteSwap
// ==================
-static inline uint16_t byteswap16(uint16_t x) noexcept {
+static ASMJIT_INLINE_NODEBUG uint16_t byteswap16(uint16_t x) noexcept {
return uint16_t(((x >> 8) & 0xFFu) | ((x & 0xFFu) << 8));
}
-static inline uint32_t byteswap32(uint32_t x) noexcept {
+static ASMJIT_INLINE_NODEBUG uint32_t byteswap32(uint32_t x) noexcept {
return (x << 24) | (x >> 24) | ((x << 8) & 0x00FF0000u) | ((x >> 8) & 0x0000FF00);
}
-static inline uint64_t byteswap64(uint64_t x) noexcept {
+static ASMJIT_INLINE_NODEBUG uint64_t byteswap64(uint64_t x) noexcept {
#if (defined(__GNUC__) || defined(__clang__)) && !defined(ASMJIT_NO_INTRINSICS)
return uint64_t(__builtin_bswap64(uint64_t(x)));
#elif defined(_MSC_VER) && !defined(ASMJIT_NO_INTRINSICS)
@@ -870,20 +869,20 @@ static inline uint64_t byteswap64(uint64_t x) noexcept {
// ===========================
//! 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 {
+static ASMJIT_INLINE_NODEBUG constexpr uint32_t bytepack32_4x8(uint32_t a, uint32_t b, uint32_t c, uint32_t d) noexcept {
return ASMJIT_ARCH_LE ? (a | (b << 8) | (c << 16) | (d << 24))
: (d | (c << 8) | (b << 16) | (a << 24));
}
template<typename T>
-static constexpr uint32_t unpackU32At0(T x) noexcept { return ASMJIT_ARCH_LE ? uint32_t(uint64_t(x) & 0xFFFFFFFFu) : uint32_t(uint64_t(x) >> 32); }
+static ASMJIT_INLINE_NODEBUG constexpr uint32_t unpackU32At0(T x) noexcept { return ASMJIT_ARCH_LE ? uint32_t(uint64_t(x) & 0xFFFFFFFFu) : uint32_t(uint64_t(x) >> 32); }
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); }
+static ASMJIT_INLINE_NODEBUG constexpr uint32_t unpackU32At1(T x) noexcept { return ASMJIT_ARCH_BE ? uint32_t(uint64_t(x) & 0xFFFFFFFFu) : uint32_t(uint64_t(x) >> 32); }
// Support - Position of byte (in bit-shift)
// =========================================
-static inline uint32_t byteShiftOfDWordStruct(uint32_t index) noexcept {
+static ASMJIT_INLINE_NODEBUG uint32_t byteShiftOfDWordStruct(uint32_t index) noexcept {
return ASMJIT_ARCH_LE ? index * 8 : (uint32_t(sizeof(uint32_t)) - 1u - index) * 8;
}
@@ -891,31 +890,31 @@ static inline uint32_t byteShiftOfDWordStruct(uint32_t index) noexcept {
// ==========================
template<typename T>
-static constexpr T asciiToLower(T c) noexcept { return T(c ^ T(T(c >= T('A') && c <= T('Z')) << 5)); }
+static ASMJIT_INLINE_NODEBUG constexpr T asciiToLower(T c) noexcept { return T(c ^ T(T(c >= T('A') && c <= T('Z')) << 5)); }
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_NODEBUG constexpr T asciiToUpper(T c) noexcept { return T(c ^ T(T(c >= T('a') && c <= T('z')) << 5)); }
-static ASMJIT_FORCE_INLINE size_t strLen(const char* s, size_t maxSize) noexcept {
+static ASMJIT_INLINE_NODEBUG size_t strLen(const char* s, size_t maxSize) noexcept {
size_t i = 0;
while (i < maxSize && s[i] != '\0')
i++;
return i;
}
-static constexpr uint32_t hashRound(uint32_t hash, uint32_t c) noexcept { return hash * 65599 + c; }
+static ASMJIT_INLINE_NODEBUG constexpr uint32_t hashRound(uint32_t hash, uint32_t c) noexcept { return hash * 65599 + c; }
// Gets a hash of the given string `data` of size `size`. Size must be valid
// as this function doesn't check for a null terminator and allows it in the
// middle of the string.
-static inline uint32_t hashString(const char* data, size_t size) noexcept {
+static ASMJIT_INLINE_NODEBUG uint32_t hashString(const char* data, size_t size) noexcept {
uint32_t hashCode = 0;
for (uint32_t i = 0; i < size; i++)
hashCode = hashRound(hashCode, uint8_t(data[i]));
return hashCode;
}
-static ASMJIT_FORCE_INLINE const char* findPackedString(const char* p, uint32_t id) noexcept {
+static ASMJIT_INLINE_NODEBUG const char* findPackedString(const char* p, uint32_t id) noexcept {
uint32_t i = 0;
while (i < id) {
while (p[0])
@@ -926,68 +925,68 @@ static ASMJIT_FORCE_INLINE const char* findPackedString(const char* p, uint32_t
return p;
}
-//! Compares two instruction names.
-//!
-//! `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_FORCE_INLINE int cmpInstName(const char* a, const char* b, size_t size) noexcept {
+//! Compares two string views.
+static ASMJIT_FORCE_INLINE int compareStringViews(const char* aData, size_t aSize, const char* bData, size_t bSize) noexcept {
+ size_t size = Support::min(aSize, bSize);
+
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;
+ int c = int(uint8_t(aData[i])) - int(uint8_t(bData[i]));
+ if (c != 0)
+ return c;
}
- return int(uint8_t(a[size]));
+
+ return int(aSize) - int(bSize);
}
// Support - Memory Read Access - 8 Bits
// =====================================
-static inline uint8_t readU8(const void* p) noexcept { return static_cast<const uint8_t*>(p)[0]; }
-static inline int8_t readI8(const void* p) noexcept { return static_cast<const int8_t*>(p)[0]; }
+static ASMJIT_INLINE_NODEBUG uint8_t readU8(const void* p) noexcept { return static_cast<const uint8_t*>(p)[0]; }
+static ASMJIT_INLINE_NODEBUG int8_t readI8(const void* p) noexcept { return static_cast<const int8_t*>(p)[0]; }
// Support - Memory Read Access - 16 Bits
// ======================================
template<ByteOrder BO, size_t Alignment>
-static inline uint16_t readU16x(const void* p) noexcept {
+static ASMJIT_INLINE_NODEBUG uint16_t readU16x(const void* p) noexcept {
typedef typename Internal::AliasedUInt<uint16_t, Alignment>::T U16AlignedToN;
uint16_t x = static_cast<const U16AlignedToN*>(p)[0];
return BO == ByteOrder::kNative ? x : byteswap16(x);
}
template<size_t Alignment = 1>
-static inline uint16_t readU16u(const void* p) noexcept { return readU16x<ByteOrder::kNative, Alignment>(p); }
+static ASMJIT_INLINE_NODEBUG uint16_t readU16u(const void* p) noexcept { return readU16x<ByteOrder::kNative, Alignment>(p); }
template<size_t Alignment = 1>
-static inline uint16_t readU16uLE(const void* p) noexcept { return readU16x<ByteOrder::kLE, Alignment>(p); }
+static ASMJIT_INLINE_NODEBUG uint16_t readU16uLE(const void* p) noexcept { return readU16x<ByteOrder::kLE, Alignment>(p); }
template<size_t Alignment = 1>
-static inline uint16_t readU16uBE(const void* p) noexcept { return readU16x<ByteOrder::kBE, Alignment>(p); }
+static ASMJIT_INLINE_NODEBUG uint16_t readU16uBE(const void* p) noexcept { return readU16x<ByteOrder::kBE, Alignment>(p); }
-static inline uint16_t readU16a(const void* p) noexcept { return readU16x<ByteOrder::kNative, 2>(p); }
-static inline uint16_t readU16aLE(const void* p) noexcept { return readU16x<ByteOrder::kLE, 2>(p); }
-static inline uint16_t readU16aBE(const void* p) noexcept { return readU16x<ByteOrder::kBE, 2>(p); }
+static ASMJIT_INLINE_NODEBUG uint16_t readU16a(const void* p) noexcept { return readU16x<ByteOrder::kNative, 2>(p); }
+static ASMJIT_INLINE_NODEBUG uint16_t readU16aLE(const void* p) noexcept { return readU16x<ByteOrder::kLE, 2>(p); }
+static ASMJIT_INLINE_NODEBUG uint16_t readU16aBE(const void* p) noexcept { return readU16x<ByteOrder::kBE, 2>(p); }
template<ByteOrder BO, size_t Alignment>
-static inline int16_t readI16x(const void* p) noexcept { return int16_t(readU16x<BO, Alignment>(p)); }
+static ASMJIT_INLINE_NODEBUG int16_t readI16x(const void* p) noexcept { return int16_t(readU16x<BO, Alignment>(p)); }
template<size_t Alignment = 1>
-static inline int16_t readI16u(const void* p) noexcept { return int16_t(readU16x<ByteOrder::kNative, Alignment>(p)); }
+static ASMJIT_INLINE_NODEBUG int16_t readI16u(const void* p) noexcept { return int16_t(readU16x<ByteOrder::kNative, Alignment>(p)); }
template<size_t Alignment = 1>
-static inline int16_t readI16uLE(const void* p) noexcept { return int16_t(readU16x<ByteOrder::kLE, Alignment>(p)); }
+static ASMJIT_INLINE_NODEBUG int16_t readI16uLE(const void* p) noexcept { return int16_t(readU16x<ByteOrder::kLE, Alignment>(p)); }
template<size_t Alignment = 1>
-static inline int16_t readI16uBE(const void* p) noexcept { return int16_t(readU16x<ByteOrder::kBE, Alignment>(p)); }
+static ASMJIT_INLINE_NODEBUG int16_t readI16uBE(const void* p) noexcept { return int16_t(readU16x<ByteOrder::kBE, Alignment>(p)); }
-static inline int16_t readI16a(const void* p) noexcept { return int16_t(readU16x<ByteOrder::kNative, 2>(p)); }
-static inline int16_t readI16aLE(const void* p) noexcept { return int16_t(readU16x<ByteOrder::kLE, 2>(p)); }
-static inline int16_t readI16aBE(const void* p) noexcept { return int16_t(readU16x<ByteOrder::kBE, 2>(p)); }
+static ASMJIT_INLINE_NODEBUG int16_t readI16a(const void* p) noexcept { return int16_t(readU16x<ByteOrder::kNative, 2>(p)); }
+static ASMJIT_INLINE_NODEBUG int16_t readI16aLE(const void* p) noexcept { return int16_t(readU16x<ByteOrder::kLE, 2>(p)); }
+static ASMJIT_INLINE_NODEBUG int16_t readI16aBE(const void* p) noexcept { return int16_t(readU16x<ByteOrder::kBE, 2>(p)); }
// Support - Memory Read Access - 24 Bits
// ======================================
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));
- uint32_t b2 = readU8(static_cast<const uint8_t*>(p) + (BO == ByteOrder::kLE ? 0 : 2));
+ uint32_t b0 = readU8(static_cast<const uint8_t*>(p) + (BO == ByteOrder::kLE ? 2u : 0u));
+ uint32_t b1 = readU8(static_cast<const uint8_t*>(p) + 1u);
+ uint32_t b2 = readU8(static_cast<const uint8_t*>(p) + (BO == ByteOrder::kLE ? 0u : 2u));
return (b0 << 16) | (b1 << 8) | b2;
}
@@ -998,108 +997,108 @@ static inline uint32_t readU24uBE(const void* p) noexcept { return readU24u<Byte
// ======================================
template<ByteOrder BO, size_t Alignment>
-static inline uint32_t readU32x(const void* p) noexcept {
+static ASMJIT_INLINE_NODEBUG uint32_t readU32x(const void* p) noexcept {
typedef typename Internal::AliasedUInt<uint32_t, Alignment>::T U32AlignedToN;
uint32_t x = static_cast<const U32AlignedToN*>(p)[0];
return BO == ByteOrder::kNative ? x : byteswap32(x);
}
template<size_t Alignment = 1>
-static inline uint32_t readU32u(const void* p) noexcept { return readU32x<ByteOrder::kNative, Alignment>(p); }
+static ASMJIT_INLINE_NODEBUG uint32_t readU32u(const void* p) noexcept { return readU32x<ByteOrder::kNative, Alignment>(p); }
template<size_t Alignment = 1>
-static inline uint32_t readU32uLE(const void* p) noexcept { return readU32x<ByteOrder::kLE, Alignment>(p); }
+static ASMJIT_INLINE_NODEBUG uint32_t readU32uLE(const void* p) noexcept { return readU32x<ByteOrder::kLE, Alignment>(p); }
template<size_t Alignment = 1>
-static inline uint32_t readU32uBE(const void* p) noexcept { return readU32x<ByteOrder::kBE, Alignment>(p); }
+static ASMJIT_INLINE_NODEBUG uint32_t readU32uBE(const void* p) noexcept { return readU32x<ByteOrder::kBE, Alignment>(p); }
-static inline uint32_t readU32a(const void* p) noexcept { return readU32x<ByteOrder::kNative, 4>(p); }
-static inline uint32_t readU32aLE(const void* p) noexcept { return readU32x<ByteOrder::kLE, 4>(p); }
-static inline uint32_t readU32aBE(const void* p) noexcept { return readU32x<ByteOrder::kBE, 4>(p); }
+static ASMJIT_INLINE_NODEBUG uint32_t readU32a(const void* p) noexcept { return readU32x<ByteOrder::kNative, 4>(p); }
+static ASMJIT_INLINE_NODEBUG uint32_t readU32aLE(const void* p) noexcept { return readU32x<ByteOrder::kLE, 4>(p); }
+static ASMJIT_INLINE_NODEBUG uint32_t readU32aBE(const void* p) noexcept { return readU32x<ByteOrder::kBE, 4>(p); }
template<ByteOrder BO, size_t Alignment>
-static inline uint32_t readI32x(const void* p) noexcept { return int32_t(readU32x<BO, Alignment>(p)); }
+static ASMJIT_INLINE_NODEBUG uint32_t readI32x(const void* p) noexcept { return int32_t(readU32x<BO, Alignment>(p)); }
template<size_t Alignment = 1>
-static inline int32_t readI32u(const void* p) noexcept { return int32_t(readU32x<ByteOrder::kNative, Alignment>(p)); }
+static ASMJIT_INLINE_NODEBUG int32_t readI32u(const void* p) noexcept { return int32_t(readU32x<ByteOrder::kNative, Alignment>(p)); }
template<size_t Alignment = 1>
-static inline int32_t readI32uLE(const void* p) noexcept { return int32_t(readU32x<ByteOrder::kLE, Alignment>(p)); }
+static ASMJIT_INLINE_NODEBUG int32_t readI32uLE(const void* p) noexcept { return int32_t(readU32x<ByteOrder::kLE, Alignment>(p)); }
template<size_t Alignment = 1>
-static inline int32_t readI32uBE(const void* p) noexcept { return int32_t(readU32x<ByteOrder::kBE, Alignment>(p)); }
+static ASMJIT_INLINE_NODEBUG int32_t readI32uBE(const void* p) noexcept { return int32_t(readU32x<ByteOrder::kBE, Alignment>(p)); }
-static inline int32_t readI32a(const void* p) noexcept { return int32_t(readU32x<ByteOrder::kNative, 4>(p)); }
-static inline int32_t readI32aLE(const void* p) noexcept { return int32_t(readU32x<ByteOrder::kLE, 4>(p)); }
-static inline int32_t readI32aBE(const void* p) noexcept { return int32_t(readU32x<ByteOrder::kBE, 4>(p)); }
+static ASMJIT_INLINE_NODEBUG int32_t readI32a(const void* p) noexcept { return int32_t(readU32x<ByteOrder::kNative, 4>(p)); }
+static ASMJIT_INLINE_NODEBUG int32_t readI32aLE(const void* p) noexcept { return int32_t(readU32x<ByteOrder::kLE, 4>(p)); }
+static ASMJIT_INLINE_NODEBUG int32_t readI32aBE(const void* p) noexcept { return int32_t(readU32x<ByteOrder::kBE, 4>(p)); }
// Support - Memory Read Access - 64 Bits
// ======================================
template<ByteOrder BO, size_t Alignment>
-static inline uint64_t readU64x(const void* p) noexcept {
+static ASMJIT_INLINE_NODEBUG uint64_t readU64x(const void* p) noexcept {
typedef typename Internal::AliasedUInt<uint64_t, Alignment>::T U64AlignedToN;
uint64_t x = static_cast<const U64AlignedToN*>(p)[0];
return BO == ByteOrder::kNative ? x : byteswap64(x);
}
template<size_t Alignment = 1>
-static inline uint64_t readU64u(const void* p) noexcept { return readU64x<ByteOrder::kNative, Alignment>(p); }
+static ASMJIT_INLINE_NODEBUG uint64_t readU64u(const void* p) noexcept { return readU64x<ByteOrder::kNative, Alignment>(p); }
template<size_t Alignment = 1>
-static inline uint64_t readU64uLE(const void* p) noexcept { return readU64x<ByteOrder::kLE, Alignment>(p); }
+static ASMJIT_INLINE_NODEBUG uint64_t readU64uLE(const void* p) noexcept { return readU64x<ByteOrder::kLE, Alignment>(p); }
template<size_t Alignment = 1>
-static inline uint64_t readU64uBE(const void* p) noexcept { return readU64x<ByteOrder::kBE, Alignment>(p); }
+static ASMJIT_INLINE_NODEBUG uint64_t readU64uBE(const void* p) noexcept { return readU64x<ByteOrder::kBE, Alignment>(p); }
-static inline uint64_t readU64a(const void* p) noexcept { return readU64x<ByteOrder::kNative, 8>(p); }
-static inline uint64_t readU64aLE(const void* p) noexcept { return readU64x<ByteOrder::kLE, 8>(p); }
-static inline uint64_t readU64aBE(const void* p) noexcept { return readU64x<ByteOrder::kBE, 8>(p); }
+static ASMJIT_INLINE_NODEBUG uint64_t readU64a(const void* p) noexcept { return readU64x<ByteOrder::kNative, 8>(p); }
+static ASMJIT_INLINE_NODEBUG uint64_t readU64aLE(const void* p) noexcept { return readU64x<ByteOrder::kLE, 8>(p); }
+static ASMJIT_INLINE_NODEBUG uint64_t readU64aBE(const void* p) noexcept { return readU64x<ByteOrder::kBE, 8>(p); }
template<ByteOrder BO, size_t Alignment>
-static inline int64_t readI64x(const void* p) noexcept { return int64_t(readU64x<BO, Alignment>(p)); }
+static ASMJIT_INLINE_NODEBUG int64_t readI64x(const void* p) noexcept { return int64_t(readU64x<BO, Alignment>(p)); }
template<size_t Alignment = 1>
-static inline int64_t readI64u(const void* p) noexcept { return int64_t(readU64x<ByteOrder::kNative, Alignment>(p)); }
+static ASMJIT_INLINE_NODEBUG int64_t readI64u(const void* p) noexcept { return int64_t(readU64x<ByteOrder::kNative, Alignment>(p)); }
template<size_t Alignment = 1>
-static inline int64_t readI64uLE(const void* p) noexcept { return int64_t(readU64x<ByteOrder::kLE, Alignment>(p)); }
+static ASMJIT_INLINE_NODEBUG int64_t readI64uLE(const void* p) noexcept { return int64_t(readU64x<ByteOrder::kLE, Alignment>(p)); }
template<size_t Alignment = 1>
-static inline int64_t readI64uBE(const void* p) noexcept { return int64_t(readU64x<ByteOrder::kBE, Alignment>(p)); }
+static ASMJIT_INLINE_NODEBUG int64_t readI64uBE(const void* p) noexcept { return int64_t(readU64x<ByteOrder::kBE, Alignment>(p)); }
-static inline int64_t readI64a(const void* p) noexcept { return int64_t(readU64x<ByteOrder::kNative, 8>(p)); }
-static inline int64_t readI64aLE(const void* p) noexcept { return int64_t(readU64x<ByteOrder::kLE, 8>(p)); }
-static inline int64_t readI64aBE(const void* p) noexcept { return int64_t(readU64x<ByteOrder::kBE, 8>(p)); }
+static ASMJIT_INLINE_NODEBUG int64_t readI64a(const void* p) noexcept { return int64_t(readU64x<ByteOrder::kNative, 8>(p)); }
+static ASMJIT_INLINE_NODEBUG int64_t readI64aLE(const void* p) noexcept { return int64_t(readU64x<ByteOrder::kLE, 8>(p)); }
+static ASMJIT_INLINE_NODEBUG int64_t readI64aBE(const void* p) noexcept { return int64_t(readU64x<ByteOrder::kBE, 8>(p)); }
// Support - Memory Write Access - 8 Bits
// ======================================
-static inline void writeU8(void* p, uint8_t x) noexcept { static_cast<uint8_t*>(p)[0] = x; }
-static inline void writeI8(void* p, int8_t x) noexcept { static_cast<int8_t*>(p)[0] = x; }
+static ASMJIT_INLINE_NODEBUG void writeU8(void* p, uint8_t x) noexcept { static_cast<uint8_t*>(p)[0] = x; }
+static ASMJIT_INLINE_NODEBUG void writeI8(void* p, int8_t x) noexcept { static_cast<int8_t*>(p)[0] = x; }
// Support - Memory Write Access - 16 Bits
// =======================================
template<ByteOrder BO = ByteOrder::kNative, size_t Alignment = 1>
-static inline void writeU16x(void* p, uint16_t x) noexcept {
+static ASMJIT_INLINE_NODEBUG void writeU16x(void* p, uint16_t x) noexcept {
typedef typename Internal::AliasedUInt<uint16_t, Alignment>::T U16AlignedToN;
static_cast<U16AlignedToN*>(p)[0] = BO == ByteOrder::kNative ? x : byteswap16(x);
}
template<size_t Alignment = 1>
-static inline void writeU16uLE(void* p, uint16_t x) noexcept { writeU16x<ByteOrder::kLE, Alignment>(p, x); }
+static ASMJIT_INLINE_NODEBUG void writeU16uLE(void* p, uint16_t x) noexcept { writeU16x<ByteOrder::kLE, Alignment>(p, x); }
template<size_t Alignment = 1>
-static inline void writeU16uBE(void* p, uint16_t x) noexcept { writeU16x<ByteOrder::kBE, Alignment>(p, x); }
+static ASMJIT_INLINE_NODEBUG void writeU16uBE(void* p, uint16_t x) noexcept { writeU16x<ByteOrder::kBE, Alignment>(p, x); }
-static inline void writeU16a(void* p, uint16_t x) noexcept { writeU16x<ByteOrder::kNative, 2>(p, x); }
-static inline void writeU16aLE(void* p, uint16_t x) noexcept { writeU16x<ByteOrder::kLE, 2>(p, x); }
-static inline void writeU16aBE(void* p, uint16_t x) noexcept { writeU16x<ByteOrder::kBE, 2>(p, x); }
+static ASMJIT_INLINE_NODEBUG void writeU16a(void* p, uint16_t x) noexcept { writeU16x<ByteOrder::kNative, 2>(p, x); }
+static ASMJIT_INLINE_NODEBUG void writeU16aLE(void* p, uint16_t x) noexcept { writeU16x<ByteOrder::kLE, 2>(p, x); }
+static ASMJIT_INLINE_NODEBUG void writeU16aBE(void* p, uint16_t x) noexcept { writeU16x<ByteOrder::kBE, 2>(p, x); }
template<ByteOrder BO = ByteOrder::kNative, size_t Alignment = 1>
-static inline void writeI16x(void* p, int16_t x) noexcept { writeU16x<BO, Alignment>(p, uint16_t(x)); }
+static ASMJIT_INLINE_NODEBUG void writeI16x(void* p, int16_t x) noexcept { writeU16x<BO, Alignment>(p, uint16_t(x)); }
template<size_t Alignment = 1>
-static inline void writeI16uLE(void* p, int16_t x) noexcept { writeU16x<ByteOrder::kLE, Alignment>(p, uint16_t(x)); }
+static ASMJIT_INLINE_NODEBUG void writeI16uLE(void* p, int16_t x) noexcept { writeU16x<ByteOrder::kLE, Alignment>(p, uint16_t(x)); }
template<size_t Alignment = 1>
-static inline void writeI16uBE(void* p, int16_t x) noexcept { writeU16x<ByteOrder::kBE, Alignment>(p, uint16_t(x)); }
+static ASMJIT_INLINE_NODEBUG void writeI16uBE(void* p, int16_t x) noexcept { writeU16x<ByteOrder::kBE, Alignment>(p, uint16_t(x)); }
-static inline void writeI16a(void* p, int16_t x) noexcept { writeU16x<ByteOrder::kNative, 2>(p, uint16_t(x)); }
-static inline void writeI16aLE(void* p, int16_t x) noexcept { writeU16x<ByteOrder::kLE, 2>(p, uint16_t(x)); }
-static inline void writeI16aBE(void* p, int16_t x) noexcept { writeU16x<ByteOrder::kBE, 2>(p, uint16_t(x)); }
+static ASMJIT_INLINE_NODEBUG void writeI16a(void* p, int16_t x) noexcept { writeU16x<ByteOrder::kNative, 2>(p, uint16_t(x)); }
+static ASMJIT_INLINE_NODEBUG void writeI16aLE(void* p, int16_t x) noexcept { writeU16x<ByteOrder::kLE, 2>(p, uint16_t(x)); }
+static ASMJIT_INLINE_NODEBUG void writeI16aBE(void* p, int16_t x) noexcept { writeU16x<ByteOrder::kBE, 2>(p, uint16_t(x)); }
// Support - Memory Write Access - 24 Bits
// =======================================
@@ -1107,7 +1106,7 @@ static inline void writeI16aBE(void* p, int16_t x) noexcept { writeU16x<ByteOrde
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)[1] = uint8_t((v >> 8) & 0xFFu);
static_cast<uint8_t*>(p)[2] = uint8_t((v >> (BO == ByteOrder::kLE ? 16 : 0)) & 0xFFu);
}
@@ -1118,85 +1117,85 @@ static inline void writeU24uBE(void* p, uint32_t v) noexcept { writeU24u<ByteOrd
// =======================================
template<ByteOrder BO = ByteOrder::kNative, size_t Alignment = 1>
-static inline void writeU32x(void* p, uint32_t x) noexcept {
+static ASMJIT_INLINE_NODEBUG void writeU32x(void* p, uint32_t x) noexcept {
typedef typename Internal::AliasedUInt<uint32_t, Alignment>::T U32AlignedToN;
static_cast<U32AlignedToN*>(p)[0] = (BO == ByteOrder::kNative) ? x : Support::byteswap32(x);
}
template<size_t Alignment = 1>
-static inline void writeU32u(void* p, uint32_t x) noexcept { writeU32x<ByteOrder::kNative, Alignment>(p, x); }
+static ASMJIT_INLINE_NODEBUG void writeU32u(void* p, uint32_t x) noexcept { writeU32x<ByteOrder::kNative, Alignment>(p, x); }
template<size_t Alignment = 1>
-static inline void writeU32uLE(void* p, uint32_t x) noexcept { writeU32x<ByteOrder::kLE, Alignment>(p, x); }
+static ASMJIT_INLINE_NODEBUG void writeU32uLE(void* p, uint32_t x) noexcept { writeU32x<ByteOrder::kLE, Alignment>(p, x); }
template<size_t Alignment = 1>
-static inline void writeU32uBE(void* p, uint32_t x) noexcept { writeU32x<ByteOrder::kBE, Alignment>(p, x); }
+static ASMJIT_INLINE_NODEBUG void writeU32uBE(void* p, uint32_t x) noexcept { writeU32x<ByteOrder::kBE, Alignment>(p, x); }
-static inline void writeU32a(void* p, uint32_t x) noexcept { writeU32x<ByteOrder::kNative, 4>(p, x); }
-static inline void writeU32aLE(void* p, uint32_t x) noexcept { writeU32x<ByteOrder::kLE, 4>(p, x); }
-static inline void writeU32aBE(void* p, uint32_t x) noexcept { writeU32x<ByteOrder::kBE, 4>(p, x); }
+static ASMJIT_INLINE_NODEBUG void writeU32a(void* p, uint32_t x) noexcept { writeU32x<ByteOrder::kNative, 4>(p, x); }
+static ASMJIT_INLINE_NODEBUG void writeU32aLE(void* p, uint32_t x) noexcept { writeU32x<ByteOrder::kLE, 4>(p, x); }
+static ASMJIT_INLINE_NODEBUG void writeU32aBE(void* p, uint32_t x) noexcept { writeU32x<ByteOrder::kBE, 4>(p, 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)); }
+static ASMJIT_INLINE_NODEBUG void writeI32x(void* p, int32_t x) noexcept { writeU32x<BO, Alignment>(p, uint32_t(x)); }
template<size_t Alignment = 1>
-static inline void writeI32u(void* p, int32_t x) noexcept { writeU32x<ByteOrder::kNative, Alignment>(p, uint32_t(x)); }
+static ASMJIT_INLINE_NODEBUG void writeI32u(void* p, int32_t x) noexcept { writeU32x<ByteOrder::kNative, Alignment>(p, uint32_t(x)); }
template<size_t Alignment = 1>
-static inline void writeI32uLE(void* p, int32_t x) noexcept { writeU32x<ByteOrder::kLE, Alignment>(p, uint32_t(x)); }
+static ASMJIT_INLINE_NODEBUG void writeI32uLE(void* p, int32_t x) noexcept { writeU32x<ByteOrder::kLE, Alignment>(p, uint32_t(x)); }
template<size_t Alignment = 1>
-static inline void writeI32uBE(void* p, int32_t x) noexcept { writeU32x<ByteOrder::kBE, Alignment>(p, uint32_t(x)); }
+static ASMJIT_INLINE_NODEBUG void writeI32uBE(void* p, int32_t x) noexcept { writeU32x<ByteOrder::kBE, Alignment>(p, uint32_t(x)); }
-static inline void writeI32a(void* p, int32_t x) noexcept { writeU32x<ByteOrder::kNative, 4>(p, uint32_t(x)); }
-static inline void writeI32aLE(void* p, int32_t x) noexcept { writeU32x<ByteOrder::kLE, 4>(p, uint32_t(x)); }
-static inline void writeI32aBE(void* p, int32_t x) noexcept { writeU32x<ByteOrder::kBE, 4>(p, uint32_t(x)); }
+static ASMJIT_INLINE_NODEBUG void writeI32a(void* p, int32_t x) noexcept { writeU32x<ByteOrder::kNative, 4>(p, uint32_t(x)); }
+static ASMJIT_INLINE_NODEBUG void writeI32aLE(void* p, int32_t x) noexcept { writeU32x<ByteOrder::kLE, 4>(p, uint32_t(x)); }
+static ASMJIT_INLINE_NODEBUG void writeI32aBE(void* p, int32_t x) noexcept { writeU32x<ByteOrder::kBE, 4>(p, uint32_t(x)); }
// Support - Memory Write Access - 64 Bits
// =======================================
template<ByteOrder BO = ByteOrder::kNative, size_t Alignment = 1>
-static inline void writeU64x(void* p, uint64_t x) noexcept {
+static ASMJIT_INLINE_NODEBUG void writeU64x(void* p, uint64_t x) noexcept {
typedef typename Internal::AliasedUInt<uint64_t, Alignment>::T U64AlignedToN;
static_cast<U64AlignedToN*>(p)[0] = BO == ByteOrder::kNative ? x : byteswap64(x);
}
template<size_t Alignment = 1>
-static inline void writeU64u(void* p, uint64_t x) noexcept { writeU64x<ByteOrder::kNative, Alignment>(p, x); }
+static ASMJIT_INLINE_NODEBUG void writeU64u(void* p, uint64_t x) noexcept { writeU64x<ByteOrder::kNative, Alignment>(p, x); }
template<size_t Alignment = 1>
-static inline void writeU64uLE(void* p, uint64_t x) noexcept { writeU64x<ByteOrder::kLE, Alignment>(p, x); }
+static ASMJIT_INLINE_NODEBUG void writeU64uLE(void* p, uint64_t x) noexcept { writeU64x<ByteOrder::kLE, Alignment>(p, x); }
template<size_t Alignment = 1>
-static inline void writeU64uBE(void* p, uint64_t x) noexcept { writeU64x<ByteOrder::kBE, Alignment>(p, x); }
+static ASMJIT_INLINE_NODEBUG void writeU64uBE(void* p, uint64_t x) noexcept { writeU64x<ByteOrder::kBE, Alignment>(p, x); }
-static inline void writeU64a(void* p, uint64_t x) noexcept { writeU64x<ByteOrder::kNative, 8>(p, x); }
-static inline void writeU64aLE(void* p, uint64_t x) noexcept { writeU64x<ByteOrder::kLE, 8>(p, x); }
-static inline void writeU64aBE(void* p, uint64_t x) noexcept { writeU64x<ByteOrder::kBE, 8>(p, x); }
+static ASMJIT_INLINE_NODEBUG void writeU64a(void* p, uint64_t x) noexcept { writeU64x<ByteOrder::kNative, 8>(p, x); }
+static ASMJIT_INLINE_NODEBUG void writeU64aLE(void* p, uint64_t x) noexcept { writeU64x<ByteOrder::kLE, 8>(p, x); }
+static ASMJIT_INLINE_NODEBUG void writeU64aBE(void* p, uint64_t x) noexcept { writeU64x<ByteOrder::kBE, 8>(p, 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)); }
+static ASMJIT_INLINE_NODEBUG void writeI64x(void* p, int64_t x) noexcept { writeU64x<BO, Alignment>(p, uint64_t(x)); }
template<size_t Alignment = 1>
-static inline void writeI64u(void* p, int64_t x) noexcept { writeU64x<ByteOrder::kNative, Alignment>(p, uint64_t(x)); }
+static ASMJIT_INLINE_NODEBUG void writeI64u(void* p, int64_t x) noexcept { writeU64x<ByteOrder::kNative, Alignment>(p, uint64_t(x)); }
template<size_t Alignment = 1>
-static inline void writeI64uLE(void* p, int64_t x) noexcept { writeU64x<ByteOrder::kLE, Alignment>(p, uint64_t(x)); }
+static ASMJIT_INLINE_NODEBUG void writeI64uLE(void* p, int64_t x) noexcept { writeU64x<ByteOrder::kLE, Alignment>(p, uint64_t(x)); }
template<size_t Alignment = 1>
-static inline void writeI64uBE(void* p, int64_t x) noexcept { writeU64x<ByteOrder::kBE, Alignment>(p, uint64_t(x)); }
+static ASMJIT_INLINE_NODEBUG void writeI64uBE(void* p, int64_t x) noexcept { writeU64x<ByteOrder::kBE, Alignment>(p, uint64_t(x)); }
-static inline void writeI64a(void* p, int64_t x) noexcept { writeU64x<ByteOrder::kNative, 8>(p, uint64_t(x)); }
-static inline void writeI64aLE(void* p, int64_t x) noexcept { writeU64x<ByteOrder::kLE, 8>(p, uint64_t(x)); }
-static inline void writeI64aBE(void* p, int64_t x) noexcept { writeU64x<ByteOrder::kBE, 8>(p, uint64_t(x)); }
+static ASMJIT_INLINE_NODEBUG void writeI64a(void* p, int64_t x) noexcept { writeU64x<ByteOrder::kNative, 8>(p, uint64_t(x)); }
+static ASMJIT_INLINE_NODEBUG void writeI64aLE(void* p, int64_t x) noexcept { writeU64x<ByteOrder::kLE, 8>(p, uint64_t(x)); }
+static ASMJIT_INLINE_NODEBUG void writeI64aBE(void* p, int64_t x) noexcept { writeU64x<ByteOrder::kBE, 8>(p, uint64_t(x)); }
// Support - Operators
// ===================
//! \cond INTERNAL
-struct Set { template<typename T> static inline T op(T x, T y) noexcept { DebugUtils::unused(x); return y; } };
-struct SetNot { template<typename T> static inline T op(T x, T y) noexcept { DebugUtils::unused(x); return ~y; } };
-struct And { template<typename T> static inline T op(T x, T y) noexcept { return x & y; } };
-struct AndNot { template<typename T> static inline T op(T x, T y) noexcept { return x & ~y; } };
-struct NotAnd { template<typename T> static inline T op(T x, T y) noexcept { return ~x & y; } };
-struct Or { template<typename T> static inline T op(T x, T y) noexcept { return x | y; } };
-struct Xor { template<typename T> static inline T op(T x, T y) noexcept { return x ^ y; } };
-struct Add { template<typename T> static inline T op(T x, T y) noexcept { return x + y; } };
-struct Sub { template<typename T> static inline T op(T x, T y) noexcept { return x - y; } };
-struct Min { template<typename T> static inline T op(T x, T y) noexcept { return min<T>(x, y); } };
-struct Max { template<typename T> static inline T op(T x, T y) noexcept { return max<T>(x, y); } };
+struct Set { template<typename T> static ASMJIT_INLINE_NODEBUG T op(T x, T y) noexcept { DebugUtils::unused(x); return y; } };
+struct SetNot { template<typename T> static ASMJIT_INLINE_NODEBUG T op(T x, T y) noexcept { DebugUtils::unused(x); return ~y; } };
+struct And { template<typename T> static ASMJIT_INLINE_NODEBUG T op(T x, T y) noexcept { return x & y; } };
+struct AndNot { template<typename T> static ASMJIT_INLINE_NODEBUG T op(T x, T y) noexcept { return x & ~y; } };
+struct NotAnd { template<typename T> static ASMJIT_INLINE_NODEBUG T op(T x, T y) noexcept { return ~x & y; } };
+struct Or { template<typename T> static ASMJIT_INLINE_NODEBUG T op(T x, T y) noexcept { return x | y; } };
+struct Xor { template<typename T> static ASMJIT_INLINE_NODEBUG T op(T x, T y) noexcept { return x ^ y; } };
+struct Add { template<typename T> static ASMJIT_INLINE_NODEBUG T op(T x, T y) noexcept { return x + y; } };
+struct Sub { template<typename T> static ASMJIT_INLINE_NODEBUG T op(T x, T y) noexcept { return x - y; } };
+struct Min { template<typename T> static ASMJIT_INLINE_NODEBUG T op(T x, T y) noexcept { return min<T>(x, y); } };
+struct Max { template<typename T> static ASMJIT_INLINE_NODEBUG T op(T x, T y) noexcept { return max<T>(x, y); } };
//! \endcond
// Support - BitWordIterator
@@ -1218,43 +1217,20 @@ struct Max { template<typename T> static inline T op(T x, T y) noexcept { ret
template<typename T>
class BitWordIterator {
public:
- ASMJIT_FORCE_INLINE explicit BitWordIterator(T bitWord) noexcept
+ ASMJIT_INLINE_NODEBUG explicit BitWordIterator(T bitWord) noexcept
: _bitWord(bitWord) {}
- ASMJIT_FORCE_INLINE void init(T bitWord) noexcept { _bitWord = bitWord; }
- ASMJIT_FORCE_INLINE bool hasNext() const noexcept { return _bitWord != 0; }
+ ASMJIT_INLINE_NODEBUG void init(T bitWord) noexcept { _bitWord = bitWord; }
+ ASMJIT_INLINE_NODEBUG bool hasNext() const noexcept { return _bitWord != 0; }
ASMJIT_FORCE_INLINE uint32_t next() noexcept {
ASMJIT_ASSERT(_bitWord != 0);
uint32_t index = ctz(_bitWord);
- _bitWord ^= T(1u) << index;
- return index;
- }
-
- T _bitWord;
-};
-
-// Support - BitWordFlipIterator
-// =============================
-
-template<typename T>
-class BitWordFlipIterator {
-public:
- ASMJIT_FORCE_INLINE explicit BitWordFlipIterator(T bitWord) noexcept
- : _bitWord(bitWord) {}
-
- ASMJIT_FORCE_INLINE void init(T bitWord) noexcept { _bitWord = bitWord; }
- ASMJIT_FORCE_INLINE bool hasNext() const noexcept { return _bitWord != 0; }
-
- ASMJIT_FORCE_INLINE uint32_t nextAndFlip() noexcept {
- ASMJIT_ASSERT(_bitWord != 0);
- uint32_t index = ctz(_bitWord);
- _bitWord ^= T(1u) << index;
+ _bitWord &= T(_bitWord - 1);
return index;
}
T _bitWord;
- T _xorMask;
};
// Support - BitVectorOps
@@ -1263,7 +1239,7 @@ public:
//! \cond
namespace Internal {
template<typename T, class OperatorT, class FullWordOpT>
- static inline void bitVectorOp(T* buf, size_t index, size_t count) noexcept {
+ static ASMJIT_FORCE_INLINE void bitVectorOp(T* buf, size_t index, size_t count) noexcept {
if (count == 0)
return;
@@ -1297,7 +1273,7 @@ namespace Internal {
//! Sets bit in a bit-vector `buf` at `index`.
template<typename T>
-static inline bool bitVectorGetBit(T* buf, size_t index) noexcept {
+static ASMJIT_INLINE_NODEBUG bool bitVectorGetBit(T* buf, size_t index) noexcept {
const size_t kTSizeInBits = bitSizeOf<T>();
size_t vecIndex = index / kTSizeInBits;
@@ -1308,7 +1284,7 @@ static inline bool bitVectorGetBit(T* buf, size_t index) noexcept {
//! Sets bit in a bit-vector `buf` at `index` to `value`.
template<typename T>
-static inline void bitVectorSetBit(T* buf, size_t index, bool value) noexcept {
+static ASMJIT_INLINE_NODEBUG void bitVectorSetBit(T* buf, size_t index, bool value) noexcept {
const size_t kTSizeInBits = bitSizeOf<T>();
size_t vecIndex = index / kTSizeInBits;
@@ -1323,7 +1299,7 @@ static inline void bitVectorSetBit(T* buf, size_t index, bool value) noexcept {
//! Sets bit in a bit-vector `buf` at `index` to `value`.
template<typename T>
-static inline void bitVectorFlipBit(T* buf, size_t index) noexcept {
+static ASMJIT_INLINE_NODEBUG void bitVectorFlipBit(T* buf, size_t index) noexcept {
const size_t kTSizeInBits = bitSizeOf<T>();
size_t vecIndex = index / kTSizeInBits;
@@ -1335,14 +1311,14 @@ static inline void bitVectorFlipBit(T* buf, size_t index) noexcept {
//! Fills `count` bits in bit-vector `buf` starting at bit-index `index`.
template<typename T>
-static inline void bitVectorFill(T* buf, size_t index, size_t count) noexcept { Internal::bitVectorOp<T, Or, Set>(buf, index, count); }
+static ASMJIT_INLINE_NODEBUG void bitVectorFill(T* buf, size_t index, size_t count) noexcept { Internal::bitVectorOp<T, Or, Set>(buf, index, count); }
//! Clears `count` bits in bit-vector `buf` starting at bit-index `index`.
template<typename T>
-static inline void bitVectorClear(T* buf, size_t index, size_t count) noexcept { Internal::bitVectorOp<T, AndNot, SetNot>(buf, index, count); }
+static ASMJIT_INLINE_NODEBUG void bitVectorClear(T* buf, size_t index, size_t count) noexcept { Internal::bitVectorOp<T, AndNot, SetNot>(buf, index, count); }
template<typename T>
-static inline size_t bitVectorIndexOf(T* buf, size_t start, bool value) noexcept {
+static ASMJIT_FORCE_INLINE size_t bitVectorIndexOf(T* buf, size_t start, bool value) noexcept {
const size_t kTSizeInBits = bitSizeOf<T>();
size_t vecIndex = start / kTSizeInBits; // T[]
size_t bitIndex = start % kTSizeInBits; // T[][]
@@ -1373,9 +1349,9 @@ public:
size_t _end;
T _current;
- ASMJIT_FORCE_INLINE BitVectorIterator(const BitVectorIterator& other) noexcept = default;
+ ASMJIT_INLINE_NODEBUG BitVectorIterator(const BitVectorIterator& other) noexcept = default;
- ASMJIT_FORCE_INLINE BitVectorIterator(const T* data, size_t numBitWords, size_t start = 0) noexcept {
+ ASMJIT_INLINE_NODEBUG BitVectorIterator(const T* data, size_t numBitWords, size_t start = 0) noexcept {
init(data, numBitWords, start);
}
@@ -1397,7 +1373,7 @@ public:
_current = bitWord;
}
- ASMJIT_FORCE_INLINE bool hasNext() const noexcept {
+ ASMJIT_INLINE_NODEBUG bool hasNext() const noexcept {
return _current != T(0);
}
@@ -1406,7 +1382,7 @@ public:
ASMJIT_ASSERT(bitWord != T(0));
uint32_t bit = ctz(bitWord);
- bitWord ^= T(1u) << bit;
+ bitWord &= T(bitWord - 1u);
size_t n = _idx + bit;
while (!bitWord && (_idx += bitSizeOf<T>()) < _end)
@@ -1438,7 +1414,7 @@ public:
size_t _end;
T _current;
- ASMJIT_FORCE_INLINE BitVectorOpIterator(const T* aData, const T* bData, size_t numBitWords, size_t start = 0) noexcept {
+ ASMJIT_INLINE_NODEBUG BitVectorOpIterator(const T* aData, const T* bData, size_t numBitWords, size_t start = 0) noexcept {
init(aData, bData, numBitWords, start);
}
@@ -1462,7 +1438,7 @@ public:
_current = bitWord;
}
- ASMJIT_FORCE_INLINE bool hasNext() noexcept {
+ ASMJIT_INLINE_NODEBUG bool hasNext() noexcept {
return _current != T(0);
}
@@ -1471,7 +1447,7 @@ public:
ASMJIT_ASSERT(bitWord != T(0));
uint32_t bit = ctz(bitWord);
- bitWord ^= T(1u) << bit;
+ bitWord &= T(bitWord - 1u);
size_t n = _idx + bit;
while (!bitWord && (_idx += kTSizeInBits) < _end)
@@ -1498,7 +1474,7 @@ enum class SortOrder : uint32_t {
template<SortOrder kOrder = SortOrder::kAscending>
struct Compare {
template<typename A, typename B>
- inline int operator()(const A& a, const B& b) const noexcept {
+ ASMJIT_INLINE_NODEBUG int operator()(const A& a, const B& b) const noexcept {
return kOrder == SortOrder::kAscending ? int(a > b) - int(a < b) : int(a < b) - int(a > b);
}
};
@@ -1587,10 +1563,79 @@ namespace Internal {
//! 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 {
+static ASMJIT_INLINE_NODEBUG void qSort(T* base, size_t size, const CompareT& cmp = CompareT()) noexcept {
Internal::QSortImpl<T, CompareT>::sort(base, size, cmp);
}
+// Support - ReverseIterator
+// =========================
+
+//! Reverse iterator to avoid including `<iterator>` header for iteration over arrays, specialized for
+//! AsmJit use (noexcept by design).
+template<typename T>
+class ArrayReverseIterator {
+public:
+ //! \name Members
+ //! \{
+
+ T* _ptr {};
+
+ //! \}
+
+ //! \name Construction & Destruction
+ //! \{
+
+ ASMJIT_INLINE_NODEBUG constexpr ArrayReverseIterator() noexcept = default;
+ ASMJIT_INLINE_NODEBUG constexpr ArrayReverseIterator(const ArrayReverseIterator& other) noexcept = default;
+ ASMJIT_INLINE_NODEBUG constexpr ArrayReverseIterator(T* ptr) noexcept : _ptr(ptr) {}
+
+ //! \}
+
+ //! \name Overloaded Operators
+ //! \{
+
+ ASMJIT_INLINE_NODEBUG ArrayReverseIterator& operator=(const ArrayReverseIterator& other) noexcept = default;
+
+ ASMJIT_INLINE_NODEBUG bool operator==(const T* other) const noexcept { return _ptr == other; }
+ ASMJIT_INLINE_NODEBUG bool operator==(const ArrayReverseIterator& other) const noexcept { return _ptr == other._ptr; }
+
+ ASMJIT_INLINE_NODEBUG bool operator!=(const T* other) const noexcept { return _ptr != other; }
+ ASMJIT_INLINE_NODEBUG bool operator!=(const ArrayReverseIterator& other) const noexcept { return _ptr != other._ptr; }
+
+ ASMJIT_INLINE_NODEBUG bool operator<(const T* other) const noexcept { return _ptr < other; }
+ ASMJIT_INLINE_NODEBUG bool operator<(const ArrayReverseIterator& other) const noexcept { return _ptr < other._ptr; }
+
+ ASMJIT_INLINE_NODEBUG bool operator<=(const T* other) const noexcept { return _ptr <= other; }
+ ASMJIT_INLINE_NODEBUG bool operator<=(const ArrayReverseIterator& other) const noexcept { return _ptr <= other._ptr; }
+
+ ASMJIT_INLINE_NODEBUG bool operator>(const T* other) const noexcept { return _ptr > other; }
+ ASMJIT_INLINE_NODEBUG bool operator>(const ArrayReverseIterator& other) const noexcept { return _ptr > other._ptr; }
+
+ ASMJIT_INLINE_NODEBUG bool operator>=(const T* other) const noexcept { return _ptr >= other; }
+ ASMJIT_INLINE_NODEBUG bool operator>=(const ArrayReverseIterator& other) const noexcept { return _ptr >= other._ptr; }
+
+ ASMJIT_INLINE_NODEBUG ArrayReverseIterator& operator++() noexcept { _ptr--; return *this; }
+ ASMJIT_INLINE_NODEBUG ArrayReverseIterator& operator--() noexcept { _ptr++; return *this; }
+
+ ASMJIT_INLINE_NODEBUG ArrayReverseIterator operator++(int) noexcept { ArrayReverseIterator prev(*this); _ptr--; return prev; }
+ ASMJIT_INLINE_NODEBUG ArrayReverseIterator operator--(int) noexcept { ArrayReverseIterator prev(*this); _ptr++; return prev; }
+
+ template<typename Diff> ASMJIT_INLINE_NODEBUG ArrayReverseIterator operator+(const Diff& n) noexcept { return ArrayReverseIterator(_ptr -= n); }
+ template<typename Diff> ASMJIT_INLINE_NODEBUG ArrayReverseIterator operator-(const Diff& n) noexcept { return ArrayReverseIterator(_ptr += n); }
+
+ template<typename Diff> ASMJIT_INLINE_NODEBUG ArrayReverseIterator& operator+=(const Diff& n) noexcept { _ptr -= n; return *this; }
+ template<typename Diff> ASMJIT_INLINE_NODEBUG ArrayReverseIterator& operator-=(const Diff& n) noexcept { _ptr += n; return *this; }
+
+ ASMJIT_INLINE_NODEBUG constexpr T& operator*() const noexcept { return _ptr[-1]; }
+ ASMJIT_INLINE_NODEBUG constexpr T* operator->() const noexcept { return &_ptr[-1]; }
+
+ template<typename Diff> ASMJIT_INLINE_NODEBUG T& operator[](const Diff& n) noexcept { return *(_ptr - n - 1); }
+
+ ASMJIT_INLINE_NODEBUG operator T*() const noexcept { return _ptr; }
+
+ //! \}
+};
+
// Support - Array
// ===============
@@ -1656,26 +1701,26 @@ struct Array {
//! \name Accessors
//! \{
- inline bool empty() const noexcept { return false; }
- inline size_t size() const noexcept { return N; }
+ ASMJIT_INLINE_NODEBUG bool empty() const noexcept { return false; }
+ ASMJIT_INLINE_NODEBUG size_t size() const noexcept { return N; }
- inline T* data() noexcept { return _data; }
- inline const T* data() const noexcept { return _data; }
+ ASMJIT_INLINE_NODEBUG T* data() noexcept { return _data; }
+ ASMJIT_INLINE_NODEBUG const T* data() const noexcept { return _data; }
- inline T& front() noexcept { return _data[0]; }
- inline const T& front() const noexcept { return _data[0]; }
+ ASMJIT_INLINE_NODEBUG T& front() noexcept { return _data[0]; }
+ ASMJIT_INLINE_NODEBUG 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]; }
+ ASMJIT_INLINE_NODEBUG T& back() noexcept { return _data[N - 1]; }
+ ASMJIT_INLINE_NODEBUG const T& back() const noexcept { return _data[N - 1]; }
- inline T* begin() noexcept { return _data; }
- inline T* end() noexcept { return _data + N; }
+ ASMJIT_INLINE_NODEBUG T* begin() noexcept { return _data; }
+ ASMJIT_INLINE_NODEBUG T* end() noexcept { return _data + N; }
- inline const T* begin() const noexcept { return _data; }
- inline const T* end() const noexcept { return _data + N; }
+ ASMJIT_INLINE_NODEBUG const T* begin() const noexcept { return _data; }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG const T* cbegin() const noexcept { return _data; }
+ ASMJIT_INLINE_NODEBUG const T* cend() const noexcept { return _data + N; }
//! \}
@@ -1738,8 +1783,8 @@ struct Temporary {
//! \name Construction & Destruction
//! \{
- inline constexpr Temporary(const Temporary& other) noexcept = default;
- inline constexpr Temporary(void* data, size_t size) noexcept
+ ASMJIT_INLINE_NODEBUG constexpr Temporary(const Temporary& other) noexcept = default;
+ ASMJIT_INLINE_NODEBUG constexpr Temporary(void* data, size_t size) noexcept
: _data(data),
_size(size) {}
@@ -1748,7 +1793,7 @@ struct Temporary {
//! \name Overloaded Operators
//! \{
- inline Temporary& operator=(const Temporary& other) noexcept = default;
+ ASMJIT_INLINE_NODEBUG Temporary& operator=(const Temporary& other) noexcept = default;
//! \}
@@ -1757,9 +1802,9 @@ struct Temporary {
//! Returns the data storage.
template<typename T = void>
- inline constexpr T* data() const noexcept { return static_cast<T*>(_data); }
+ ASMJIT_INLINE_NODEBUG constexpr T* data() const noexcept { return static_cast<T*>(_data); }
//! Returns the data storage size in bytes.
- inline constexpr size_t size() const noexcept { return _size; }
+ ASMJIT_INLINE_NODEBUG constexpr size_t size() const noexcept { return _size; }
//! \}
};
diff --git a/3rdparty/asmjit/src/asmjit/core/support_p.h b/3rdparty/asmjit/src/asmjit/core/support_p.h
new file mode 100644
index 00000000000..1caec9344a4
--- /dev/null
+++ b/3rdparty/asmjit/src/asmjit/core/support_p.h
@@ -0,0 +1,27 @@
+// 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_SUPPORT_P_H_INCLUDED
+#define ASMJIT_CORE_SUPPORT_P_H_INCLUDED
+
+#include "../core/support.h"
+
+ASMJIT_BEGIN_NAMESPACE
+
+//! \addtogroup asmjit_utilities
+//! \{
+
+namespace Support {
+
+//! \cond INTERNAL
+//! \endcond
+
+} // {Support}
+
+//! \}
+
+ASMJIT_END_NAMESPACE
+
+#endif // ASMJIT_CORE_SUPPORT_P_H_INCLUDED
diff --git a/3rdparty/asmjit/src/asmjit/core/target.cpp b/3rdparty/asmjit/src/asmjit/core/target.cpp
index fef025d709a..cbc6ab51092 100644
--- a/3rdparty/asmjit/src/asmjit/core/target.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/target.cpp
@@ -8,7 +8,9 @@
ASMJIT_BEGIN_NAMESPACE
-Target::Target() noexcept : _environment() {}
+Target::Target() noexcept
+ : _environment{},
+ _cpuFeatures{} {}
Target::~Target() noexcept {}
ASMJIT_END_NAMESPACE
diff --git a/3rdparty/asmjit/src/asmjit/core/target.h b/3rdparty/asmjit/src/asmjit/core/target.h
index 23b0c6294c9..4365be14011 100644
--- a/3rdparty/asmjit/src/asmjit/core/target.h
+++ b/3rdparty/asmjit/src/asmjit/core/target.h
@@ -7,6 +7,7 @@
#define ASMJIT_CORE_TARGET_H_INCLUDED
#include "../core/archtraits.h"
+#include "../core/cpuinfo.h"
#include "../core/func.h"
ASMJIT_BEGIN_NAMESPACE
@@ -22,6 +23,8 @@ public:
//! Target environment information.
Environment _environment;
+ //! Target CPU features.
+ CpuFeatures _cpuFeatures;
//! \name Construction & Destruction
//! \{
@@ -37,11 +40,14 @@ public:
//! \{
//! Returns target's environment.
- inline const Environment& environment() const noexcept { return _environment; }
+ ASMJIT_INLINE_NODEBUG const Environment& environment() const noexcept { return _environment; }
//! Returns the target architecture.
- inline Arch arch() const noexcept { return _environment.arch(); }
+ ASMJIT_INLINE_NODEBUG Arch arch() const noexcept { return _environment.arch(); }
//! Returns the target sub-architecture.
- inline SubArch subArch() const noexcept { return _environment.subArch(); }
+ ASMJIT_INLINE_NODEBUG SubArch subArch() const noexcept { return _environment.subArch(); }
+
+ //! Returns target CPU features.
+ ASMJIT_INLINE_NODEBUG const CpuFeatures& cpuFeatures() const noexcept { return _cpuFeatures; }
//! \}
};
diff --git a/3rdparty/asmjit/src/asmjit/core/type.h b/3rdparty/asmjit/src/asmjit/core/type.h
index 3754959e4c3..415fe0a421d 100644
--- a/3rdparty/asmjit/src/asmjit/core/type.h
+++ b/3rdparty/asmjit/src/asmjit/core/type.h
@@ -164,74 +164,98 @@ struct TypeData {
ASMJIT_VARAPI const TypeData _typeData;
//! Returns the scalar type of `typeId`.
-static inline TypeId scalarOf(TypeId typeId) noexcept { return _typeData.scalarOf[uint32_t(typeId)]; }
+static ASMJIT_INLINE_NODEBUG 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)]; }
+static ASMJIT_INLINE_NODEBUG 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 {
+static ASMJIT_INLINE_NODEBUG 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; }
+static ASMJIT_INLINE_NODEBUG 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); }
+static ASMJIT_INLINE_NODEBUG 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); }
+static ASMJIT_INLINE_NODEBUG 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); }
+static ASMJIT_INLINE_NODEBUG 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); }
+static ASMJIT_INLINE_NODEBUG 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; }
+static ASMJIT_INLINE_NODEBUG 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; }
+static ASMJIT_INLINE_NODEBUG 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; }
+static ASMJIT_INLINE_NODEBUG 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; }
+static ASMJIT_INLINE_NODEBUG 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; }
+static ASMJIT_INLINE_NODEBUG 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; }
+static ASMJIT_INLINE_NODEBUG 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; }
+static ASMJIT_INLINE_NODEBUG 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 ASMJIT_INLINE_NODEBUG 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 an 8-bit general purpose register representing either signed or unsigned 8-bit integer.
+static ASMJIT_INLINE_NODEBUG constexpr bool isGp8(TypeId typeId) noexcept { return isBetween(typeId, TypeId::kInt8, TypeId::kUInt8); }
+//! Tests whether a given type is a 16-bit general purpose register representing either signed or unsigned 16-bit integer
+static ASMJIT_INLINE_NODEBUG constexpr bool isGp16(TypeId typeId) noexcept { return isBetween(typeId, TypeId::kInt16, TypeId::kUInt16); }
+//! Tests whether a given type is a 32-bit general purpose register representing either signed or unsigned 32-bit integer
+static ASMJIT_INLINE_NODEBUG constexpr bool isGp32(TypeId typeId) noexcept { return isBetween(typeId, TypeId::kInt32, TypeId::kUInt32); }
+//! Tests whether a given type is a 64-bit general purpose register representing either signed or unsigned 64-bit integer
+static ASMJIT_INLINE_NODEBUG 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); }
+static ASMJIT_INLINE_NODEBUG 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; }
+static ASMJIT_INLINE_NODEBUG 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; }
+static ASMJIT_INLINE_NODEBUG 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); }
+static ASMJIT_INLINE_NODEBUG constexpr bool isFloat80(TypeId typeId) noexcept { return typeId == TypeId::kFloat80; }
+
+//! Tests whether a given type is a mask register of any size.
+static ASMJIT_INLINE_NODEBUG constexpr bool isMask(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kMaskStart, TypeId::_kMaskEnd); }
+//! Tests whether a given type is an 8-bit mask register.
+static ASMJIT_INLINE_NODEBUG constexpr bool isMask8(TypeId typeId) noexcept { return typeId == TypeId::kMask8; }
+//! Tests whether a given type is an 16-bit mask register.
+static ASMJIT_INLINE_NODEBUG constexpr bool isMask16(TypeId typeId) noexcept { return typeId == TypeId::kMask16; }
+//! Tests whether a given type is an 32-bit mask register.
+static ASMJIT_INLINE_NODEBUG constexpr bool isMask32(TypeId typeId) noexcept { return typeId == TypeId::kMask32; }
+//! Tests whether a given type is an 64-bit mask register.
+static ASMJIT_INLINE_NODEBUG constexpr bool isMask64(TypeId typeId) noexcept { return typeId == TypeId::kMask64; }
+
+//! Tests whether a given type is an MMX register.
+//!
+//! \note MMX functionality is in general deprecated on X86 architecture. AsmJit provides it just for completeness.
+static ASMJIT_INLINE_NODEBUG constexpr bool isMmx(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kMmxStart, TypeId::_kMmxEnd); }
+//! Tests whether a given type is an MMX register, which only uses the low 32 bits of data (only specific cases).
+//!
+//! \note MMX functionality is in general deprecated on X86 architecture. AsmJit provides it just for completeness.
+static ASMJIT_INLINE_NODEBUG constexpr bool isMmx32(TypeId typeId) noexcept { return typeId == TypeId::kMmx32; }
+//! Tests whether a given type is an MMX register, which uses 64 bits of data (default).
+//!
+//! \note MMX functionality is in general deprecated on X86 architecture. AsmJit provides it just for completeness.
+static ASMJIT_INLINE_NODEBUG constexpr bool isMmx64(TypeId typeId) noexcept { return typeId == TypeId::kMmx64; }
+
+//! Tests whether a given type is a vector register of any size.
+static ASMJIT_INLINE_NODEBUG constexpr bool isVec(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kVec32Start, TypeId::_kVec512End); }
+//! Tests whether a given type is a 32-bit or 32-bit view of a vector register.
+static ASMJIT_INLINE_NODEBUG constexpr bool isVec32(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kVec32Start, TypeId::_kVec32End); }
+//! Tests whether a given type is a 64-bit or 64-bit view of a vector register.
+static ASMJIT_INLINE_NODEBUG constexpr bool isVec64(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kVec64Start, TypeId::_kVec64End); }
+//! Tests whether a given type is a 128-bit or 128-bit view of a vector register.
+static ASMJIT_INLINE_NODEBUG constexpr bool isVec128(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kVec128Start, TypeId::_kVec128End); }
+//! Tests whether a given type is a 256-bit or 256-bit view of a vector register.
+static ASMJIT_INLINE_NODEBUG constexpr bool isVec256(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kVec256Start, TypeId::_kVec256End); }
+//! Tests whether a given type is a 512-bit or 512-bit view of a vector register.
+static ASMJIT_INLINE_NODEBUG constexpr bool isVec512(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kVec512Start, TypeId::_kVec512End); }
//! \cond
enum TypeCategory : uint32_t {
@@ -317,7 +341,7 @@ struct TypeIdOfT<T&> {
//! Returns a corresponding \ref TypeId of `T` type.
template<typename T>
-static inline constexpr TypeId typeIdOfT() noexcept { return TypeId(TypeIdOfT<T>::kTypeId); }
+static ASMJIT_INLINE_NODEBUG 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.
@@ -336,18 +360,18 @@ static inline constexpr TypeId typeIdOfT() noexcept { return TypeId(TypeIdOfT<T>
//! // The same, but by using TypeUtils::deabstract() function.
//! typeId = TypeUtils::deabstract(typeId, deabstractDelta);
//! ```
-static inline constexpr uint32_t deabstractDeltaOfSize(uint32_t registerSize) noexcept {
+static ASMJIT_INLINE_NODEBUG 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 {
+static ASMJIT_INLINE_NODEBUG constexpr TypeId deabstract(TypeId typeId, uint32_t deabstractDelta) noexcept {
return isAbstract(typeId) ? TypeId(uint32_t(typeId) + deabstractDelta) : typeId;
}
-static inline constexpr TypeId scalarToVector(TypeId scalarTypeId, TypeId vecStartId) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr TypeId scalarToVector(TypeId scalarTypeId, TypeId vecStartId) noexcept {
return TypeId(uint32_t(vecStartId) + uint32_t(scalarTypeId) - uint32_t(TypeId::kInt8));
}
diff --git a/3rdparty/asmjit/src/asmjit/core/virtmem.cpp b/3rdparty/asmjit/src/asmjit/core/virtmem.cpp
index 43766ef2cd2..743847746af 100644
--- a/3rdparty/asmjit/src/asmjit/core/virtmem.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/virtmem.cpp
@@ -6,7 +6,7 @@
#include "../core/api-build_p.h"
#ifndef ASMJIT_NO_JIT
-#include "../core/osutils.h"
+#include "../core/osutils_p.h"
#include "../core/string.h"
#include "../core/support.h"
#include "../core/virtmem.h"
@@ -19,9 +19,42 @@
#include <sys/types.h>
#include <unistd.h>
+ #if !ASMJIT_ARCH_X86
+ #include <sys/time.h> // required by gettimeofday()
+ #endif
+
// Linux has a `memfd_create` syscall that we would like to use, if available.
#if defined(__linux__)
#include <sys/syscall.h>
+ #include <sys/utsname.h>
+
+ #ifndef MAP_HUGETLB
+ #define MAP_HUGETLB 0x40000
+ #endif // MAP_HUGETLB
+
+ #ifndef MAP_HUGE_SHIFT
+ #define MAP_HUGE_SHIFT 26
+ #endif // MAP_HUGE_SHIFT
+
+ #if !defined(MFD_CLOEXEC)
+ #define MFD_CLOEXEC 0x0001u
+ #endif // MFD_CLOEXEC
+
+ #if !defined(MFD_NOEXEC_SEAL)
+ #define MFD_NOEXEC_SEAL 0x0008u
+ #endif // MFD_NOEXEC_SEAL
+
+ #if !defined(MFD_EXEC)
+ #define MFD_EXEC 0x0010u
+ #endif // MFD_EXEC
+
+ #ifndef MFD_HUGETLB
+ #define MFD_HUGETLB 0x0004
+ #endif // MFD_HUGETLB
+
+ #ifndef MFD_HUGE_SHIFT
+ #define MFD_HUGE_SHIFT 26
+ #endif // MFD_HUGE_SHIFT
#endif
// Apple recently introduced MAP_JIT flag, which we want to use.
@@ -42,25 +75,70 @@
#if !defined(MAP_ANONYMOUS)
#define MAP_ANONYMOUS MAP_ANON
#endif
+
+ // Android NDK doesn't provide `shm_open()` and `shm_unlink()`.
+ #if !defined(__BIONIC__) && !defined(ASMJIT_NO_SHM_OPEN)
+ #define ASMJIT_HAS_SHM_OPEN
+ #endif
+
+ #if defined(__APPLE__) || defined(__BIONIC__) || !defined(ASMJIT_HAS_SHM_OPEN)
+ #define ASMJIT_VM_SHM_DETECT 0
+ #else
+ #define ASMJIT_VM_SHM_DETECT 1
+ #endif
+
+ #if defined(__APPLE__) && TARGET_OS_OSX
+ #if ASMJIT_ARCH_X86 != 0
+ #define ASMJIT_ANONYMOUS_MEMORY_USE_MACH_VM_REMAP
+ #endif
+ #if ASMJIT_ARCH_ARM >= 64
+ #define ASMJIT_HAS_PTHREAD_JIT_WRITE_PROTECT_NP
+ #endif
+ #endif
+
+ #if defined(__APPLE__) && ASMJIT_ARCH_X86 == 0
+ #define ASMJIT_NO_DUAL_MAPPING
+ #endif
+
+ #if defined(__NetBSD__) && defined(MAP_REMAPDUP) && defined(PROT_MPROTECT)
+ #define ASMJIT_ANONYMOUS_MEMORY_USE_REMAPDUP
+ #endif
+
+ #if !defined(ASMJIT_ANONYMOUS_MEMORY_USE_REMAPDUP) && \
+ !defined(ASMJIT_ANONYMOUS_MEMORY_USE_MACH_VM_REMAP) && \
+ !defined(ASMJIT_NO_DUAL_MAPPING)
+ #define ASMJIT_ANONYMOUS_MEMORY_USE_FD
+ #endif
#endif
#include <atomic>
-#if defined(__APPLE__) || defined(__BIONIC__)
- #define ASMJIT_VM_SHM_DETECT 0
-#else
- #define ASMJIT_VM_SHM_DETECT 1
-#endif
+#if defined(ASMJIT_ANONYMOUS_MEMORY_USE_MACH_VM_REMAP)
+#include <mach/mach.h>
+#include <mach/mach_time.h>
+
+extern "C" {
-// Android NDK doesn't provide `shm_open()` and `shm_unlink()`.
-#if defined(__BIONIC__)
- #define ASMJIT_VM_SHM_AVAILABLE 0
+#ifdef mig_external
+mig_external
#else
- #define ASMJIT_VM_SHM_AVAILABLE 1
+extern
#endif
-
-#if defined(__APPLE__) && ASMJIT_ARCH_ARM >= 64
- #define ASMJIT_HAS_PTHREAD_JIT_WRITE_PROTECT_NP
+kern_return_t mach_vm_remap(
+ vm_map_t target_task,
+ mach_vm_address_t *target_address,
+ mach_vm_size_t size,
+ mach_vm_offset_t mask,
+ int flags,
+ vm_map_t src_task,
+ mach_vm_address_t src_address,
+ boolean_t copy,
+ vm_prot_t *cur_protection,
+ vm_prot_t *max_protection,
+ vm_inherit_t inheritance
+);
+
+} // {extern "C"}
#endif
ASMJIT_BEGIN_SUB_NAMESPACE(VirtMem)
@@ -68,7 +146,8 @@ ASMJIT_BEGIN_SUB_NAMESPACE(VirtMem)
// Virtual Memory Utilities
// ========================
-static const MemoryFlags dualMappingFilter[2] = {
+ASMJIT_MAYBE_UNUSED
+static const constexpr MemoryFlags dualMappingFilter[2] = {
MemoryFlags::kAccessWrite | MemoryFlags::kMMapMaxAccessWrite,
MemoryFlags::kAccessExecute | MemoryFlags::kMMapMaxAccessExecute
};
@@ -90,7 +169,7 @@ struct ScopedHandle {
HANDLE value;
};
-static void getVMInfo(Info& vmInfo) noexcept {
+static void detectVMInfo(Info& vmInfo) noexcept {
SYSTEM_INFO systemInfo;
::GetSystemInfo(&systemInfo);
@@ -98,6 +177,15 @@ static void getVMInfo(Info& vmInfo) noexcept {
vmInfo.pageGranularity = systemInfo.dwAllocationGranularity;
}
+static size_t detectLargePageSize() noexcept {
+ return ::GetLargePageMinimum();
+}
+
+static bool hasDualMappingSupport() noexcept {
+ // TODO: This assumption works on X86 platforms, this may not work on AArch64.
+ return true;
+}
+
// Returns windows-specific protectFlags from \ref MemoryFlags.
static DWORD protectFlagsFromMemoryFlags(MemoryFlags memoryFlags) noexcept {
DWORD protectFlags;
@@ -122,7 +210,12 @@ static DWORD desiredAccessFromMemoryFlags(MemoryFlags memoryFlags) noexcept {
}
static HardenedRuntimeFlags getHardenedRuntimeFlags() noexcept {
- return HardenedRuntimeFlags::kNone;
+ HardenedRuntimeFlags flags = HardenedRuntimeFlags::kNone;
+
+ if (hasDualMappingSupport())
+ flags |= HardenedRuntimeFlags::kDualMapping;
+
+ return flags;
}
Error alloc(void** p, size_t size, MemoryFlags memoryFlags) noexcept {
@@ -130,9 +223,23 @@ Error alloc(void** p, size_t size, MemoryFlags memoryFlags) noexcept {
if (size == 0)
return DebugUtils::errored(kErrorInvalidArgument);
+ DWORD allocationType = MEM_COMMIT | MEM_RESERVE;
DWORD protectFlags = protectFlagsFromMemoryFlags(memoryFlags);
- void* result = ::VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_RESERVE, protectFlags);
+ if (Support::test(memoryFlags, MemoryFlags::kMMapLargePages)) {
+ size_t lpSize = largePageSize();
+
+ // Does it make sense to call VirtualAlloc() if we failed to query large page size?
+ if (lpSize == 0)
+ return DebugUtils::errored(kErrorFeatureNotEnabled);
+
+ if (!Support::isAligned(size, lpSize))
+ return DebugUtils::errored(kErrorInvalidArgument);
+
+ allocationType |= MEM_LARGE_PAGES;
+ }
+
+ void* result = ::VirtualAlloc(nullptr, size, allocationType, protectFlags);
if (!result)
return DebugUtils::errored(kErrorOutOfMemory);
@@ -142,7 +249,9 @@ Error alloc(void** p, size_t size, MemoryFlags memoryFlags) noexcept {
Error release(void* p, size_t size) noexcept {
DebugUtils::unused(size);
- if (ASMJIT_UNLIKELY(!::VirtualFree(p, 0, MEM_RELEASE)))
+ // NOTE: If the `dwFreeType` parameter is MEM_RELEASE, `size` parameter must be zero.
+ constexpr DWORD dwFreeType = MEM_RELEASE;
+ if (ASMJIT_UNLIKELY(!::VirtualFree(p, 0, dwFreeType)))
return DebugUtils::errored(kErrorInvalidArgument);
return kErrorOk;
}
@@ -183,7 +292,7 @@ Error allocDualMapping(DualMapping* dm, size_t size, MemoryFlags memoryFlags) no
ptr[i] = ::MapViewOfFile(handle.value, desiredAccess, 0, 0, size);
if (ptr[i] == nullptr) {
- if (i == 0)
+ if (i == 1u)
::UnmapViewOfFile(ptr[0]);
return DebugUtils::errored(kErrorOutOfMemory);
}
@@ -214,26 +323,52 @@ Error releaseDualMapping(DualMapping* dm, size_t size) noexcept {
#endif
-// Virtual Memory [Posix]
-// ======================
+// Virtual Memory [Unix]
+// =====================
#if !defined(_WIN32)
-static void getVMInfo(Info& vmInfo) noexcept {
- uint32_t pageSize = uint32_t(::getpagesize());
+// Virtual Memory [Unix] - Utilities
+// =================================
- vmInfo.pageSize = pageSize;
- vmInfo.pageGranularity = Support::max<uint32_t>(pageSize, 65536);
-}
+#if defined(__linux__) || (defined(__APPLE__) && TARGET_OS_OSX)
+struct KernelVersion {
+ long ver[2];
-#if !defined(SHM_ANON)
-static const char* getTmpDir() noexcept {
- const char* tmpDir = getenv("TMPDIR");
- return tmpDir ? tmpDir : "/tmp";
+ inline long major() const noexcept { return ver[0]; }
+ inline long minor() const noexcept { return ver[1]; }
+
+ inline bool eq(long major, long minor) const noexcept { return ver[0] == major && ver[1] == minor; }
+ inline bool ge(long major, long minor) const noexcept { return ver[0] > major || (ver[0] == major && ver[1] >= minor); }
+};
+
+ASMJIT_MAYBE_UNUSED
+static KernelVersion getKernelVersion() noexcept {
+ KernelVersion out {};
+ struct utsname buf {};
+
+ uname(&buf);
+
+ size_t i = 0;
+ char* p = buf.release;
+
+ while (*p && i < 2u) {
+ uint8_t c = uint8_t(*p);
+ if (c >= uint8_t('0') && c <= uint8_t('9')) {
+ out.ver[i] = strtol(p, &p, 10);
+ i++;
+ continue;
+ }
+
+ p++;
+ }
+
+ return out;
}
-#endif
+#endif // getKernelVersion
// Translates libc errors specific to VirtualMemory mapping to `asmjit::Error`.
+ASMJIT_MAYBE_UNUSED
static Error asmjitErrorFromErrno(int e) noexcept {
switch (e) {
case EACCES:
@@ -256,16 +391,149 @@ static Error asmjitErrorFromErrno(int e) noexcept {
}
}
+ASMJIT_MAYBE_UNUSED
+static MemoryFlags maxAccessFlagsToRegularAccessFlags(MemoryFlags memoryFlags) noexcept {
+ static constexpr uint32_t kMaxProtShift = Support::ConstCTZ<uint32_t(MemoryFlags::kMMapMaxAccessRead)>::value;
+ return MemoryFlags(uint32_t(memoryFlags & MemoryFlags::kMMapMaxAccessRWX) >> kMaxProtShift);
+}
+
+ASMJIT_MAYBE_UNUSED
+static MemoryFlags regularAccessFlagsToMaxAccessFlags(MemoryFlags memoryFlags) noexcept {
+ static constexpr uint32_t kMaxProtShift = Support::ConstCTZ<uint32_t(MemoryFlags::kMMapMaxAccessRead)>::value;
+ return MemoryFlags(uint32_t(memoryFlags & MemoryFlags::kAccessRWX) << kMaxProtShift);
+}
+
+// Returns `mmap()` protection flags from \ref MemoryFlags.
+ASMJIT_MAYBE_UNUSED
+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;
+}
+
+// Returns maximum protection flags from `memoryFlags`.
+//
+// Uses:
+// - `PROT_MPROTECT()` on NetBSD.
+// - `PROT_MAX()` when available on other BSDs.
+ASMJIT_MAYBE_UNUSED
+static inline int mmMaxProtFromMemoryFlags(MemoryFlags memoryFlags) noexcept {
+ MemoryFlags acc = maxAccessFlagsToRegularAccessFlags(memoryFlags);
+ if (acc != MemoryFlags::kNone) {
+#if defined(__NetBSD__) && defined(PROT_MPROTECT)
+ return PROT_MPROTECT(mmProtFromMemoryFlags(acc));
+#elif defined(PROT_MAX)
+ return PROT_MAX(mmProtFromMemoryFlags(acc));
+#else
+ return 0;
+#endif
+ }
+
+ return 0;
+}
+
+static void detectVMInfo(Info& vmInfo) noexcept {
+ uint32_t pageSize = uint32_t(::getpagesize());
+
+ vmInfo.pageSize = pageSize;
+ vmInfo.pageGranularity = Support::max<uint32_t>(pageSize, 65536);
+}
+
+static size_t detectLargePageSize() noexcept {
+#if defined(__APPLE__) && defined(VM_FLAGS_SUPERPAGE_SIZE_2MB) && ASMJIT_ARCH_X86
+ return 2u * 1024u * 1024u;
+#elif defined(__FreeBSD__)
+ Support::Array<size_t, 2> pageSize;
+ // TODO: Does it return unsigned?
+ return (getpagesizes(pageSize.data(), 2) < 2) ? 0 : uint32_t(pageSize[1]);
+#elif defined(__linux__)
+ StringTmp<128> storage;
+ if (OSUtils::readFile("/sys/kernel/mm/transparent_hugepage/hpage_pmd_size", storage, 16) != kErrorOk || storage.empty())
+ return 0u;
+
+ // The first value should be the size of the page (hpage_pmd_size).
+ size_t largePageSize = 0;
+
+ const char* buf = storage.data();
+ size_t bufSize = storage.size();
+
+ for (size_t i = 0; i < bufSize; i++) {
+ uint32_t digit = uint32_t(uint8_t(buf[i]) - uint8_t('0'));
+ if (digit >= 10u)
+ break;
+ largePageSize = largePageSize * 10 + digit;
+ }
+
+ if (Support::isPowerOf2(largePageSize))
+ return largePageSize;
+ else
+ return 0u;
+#else
+ return 0u;
+#endif
+}
+
+// Virtual Memory [Posix] - Anonymous Memory
+// =========================================
+
+#if defined(ASMJIT_ANONYMOUS_MEMORY_USE_FD)
+
// 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 {
+// don't need the detection as we know it would always result in `AnonymousMemoryStrategy::kTmpDir`.
+enum class AnonymousMemoryStrategy : uint32_t {
kUnknown = 0,
kDevShm = 1,
kTmpDir = 2
};
+#if !defined(SHM_ANON)
+static const char* getTmpDir() noexcept {
+ const char* tmpDir = getenv("TMPDIR");
+ return tmpDir ? tmpDir : "/tmp";
+}
+#endif
+
+#if defined(__linux__) && defined(__NR_memfd_create)
+static uint32_t getMfdExecFlag() noexcept {
+ static std::atomic<uint32_t> cachedMfdExecSupported;
+ uint32_t val = cachedMfdExecSupported.load();
+
+ if (val == 0u) {
+ KernelVersion ver = getKernelVersion();
+ val = uint32_t(ver.ge(6, 3)) + 1u;
+ cachedMfdExecSupported.store(val);
+ }
+
+ return val == 2u ? uint32_t(MFD_EXEC) : uint32_t(0u);
+}
+#endif // __linux__ && __NR_memfd_create
+
+
+// It's not fully random, just to avoid collisions when opening TMP or SHM file.
+ASMJIT_MAYBE_UNUSED
+static uint64_t generateRandomBits(uintptr_t stackPtr, uint32_t attempt) noexcept {
+ static std::atomic<uint32_t> internalCounter;
+
+#if defined(__GNUC__) && ASMJIT_ARCH_X86
+ // Use RDTSC instruction to avoid gettimeofday() as we just need some "random" bits.
+ uint64_t mix = __builtin_ia32_rdtsc();
+#else
+ struct timeval tm {};
+ uint64_t mix = 1; // only used when gettimeofday() fails, which is unlikely.
+ if (gettimeofday(&tm, nullptr) == 0) {
+ mix = uint64_t(tm.tv_usec) ^ uint64_t(tm.tv_sec);
+ }
+#endif
+
+ uint64_t bits = (uint64_t(stackPtr) & 0x1010505000055590u) - mix * 773703683;
+ bits = (bits >> 33) ^ (bits << 7) ^ (attempt * 87178291199);
+ return bits + uint64_t(++internalCounter) * 10619863;
+}
+
class AnonymousMemory {
public:
enum FileType : uint32_t {
@@ -294,13 +562,17 @@ public:
#if defined(__linux__) && defined(__NR_memfd_create)
// Linux specific 'memfd_create' - if the syscall returns `ENOSYS` it means
// it's not available and we will never call it again (would be pointless).
+ //
+ // NOTE: There is also memfd_create() libc function in FreeBSD, but it internally
+ // uses `shm_open(SHM_ANON, ...)` so it's not needed to add support for it (it's
+ // not a syscall as in Linux).
// Zero initialized, if ever changed to '1' that would mean the syscall is not
- // available and we must use `shm_open()` and `shm_unlink()`.
+ // available and we must use `shm_open()` and `shm_unlink()` (or regular `open()`).
static volatile uint32_t memfd_create_not_supported;
if (!memfd_create_not_supported) {
- _fd = (int)syscall(__NR_memfd_create, "vmem", 0);
+ _fd = (int)syscall(__NR_memfd_create, "vmem", MFD_CLOEXEC | getMfdExecFlag());
if (ASMJIT_LIKELY(_fd >= 0))
return kErrorOk;
@@ -310,9 +582,9 @@ public:
else
return DebugUtils::errored(asmjitErrorFromErrno(e));
}
-#endif
+#endif // __linux__ && __NR_memfd_create
-#if defined(SHM_ANON)
+#if defined(ASMJIT_HAS_SHM_OPEN) && defined(SHM_ANON)
// Originally FreeBSD extension, apparently works in other BSDs too.
DebugUtils::unused(preferTmpOverDevShm);
_fd = ::shm_open(SHM_ANON, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
@@ -322,32 +594,26 @@ public:
else
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.
- static std::atomic<uint32_t> internalCounter;
- const char* kShmFormat = "/shm-id-%016llX";
-
+ // POSIX API. We have to generate somehow a unique name, so use `generateRandomBits()` helper. To prevent
+ // having file collisions we use `shm_open()` with flags that require creation of the file so we never open
+ // an existing shared memory.
+ static const char kShmFormat[] = "/shm-id-%016llX";
uint32_t kRetryCount = 100;
- uint64_t bits = ((uintptr_t)(void*)this) & 0x55555555u;
for (uint32_t i = 0; i < kRetryCount; i++) {
- bits -= uint64_t(OSUtils::getTickCount()) * 773703683;
- bits = ((bits >> 14) ^ (bits << 6)) + uint64_t(++internalCounter) * 10619863;
-
bool useTmp = !ASMJIT_VM_SHM_DETECT || preferTmpOverDevShm;
+ uint64_t bits = generateRandomBits((uintptr_t)this, i);
if (useTmp) {
_tmpName.assign(getTmpDir());
_tmpName.appendFormat(kShmFormat, (unsigned long long)bits);
- _fd = ::open(_tmpName.data(), O_RDWR | O_CREAT | O_EXCL, 0);
+ _fd = ASMJIT_FILE64_API(::open)(_tmpName.data(), O_RDWR | O_CREAT | O_EXCL, 0);
if (ASMJIT_LIKELY(_fd >= 0)) {
_fileType = kFileTypeTmp;
return kErrorOk;
}
}
-#if ASMJIT_VM_SHM_AVAILABLE
+#if defined(ASMJIT_HAS_SHM_OPEN)
else {
_tmpName.assignFormat(kShmFormat, (unsigned long long)bits);
_fd = ::shm_open(_tmpName.data(), O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
@@ -371,7 +637,7 @@ public:
FileType type = _fileType;
_fileType = kFileTypeNone;
-#if ASMJIT_VM_SHM_AVAILABLE
+#ifdef ASMJIT_HAS_SHM_OPEN
if (type == kFileTypeShm) {
::shm_unlink(_tmpName.data());
return;
@@ -393,31 +659,71 @@ public:
Error allocate(size_t size) noexcept {
// TODO: Improve this by using `posix_fallocate()` when available.
- if (ftruncate(_fd, off_t(size)) != 0)
+ if (ASMJIT_FILE64_API(ftruncate)(_fd, off_t(size)) != 0)
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 ASMJIT_VM_SHM_DETECT
+static Error detectAnonymousMemoryStrategy(AnonymousMemoryStrategy* strategyOut) noexcept {
+ AnonymousMemory anonMem;
+ Info vmInfo = info();
+
+ ASMJIT_PROPAGATE(anonMem.open(false));
+ ASMJIT_PROPAGATE(anonMem.allocate(vmInfo.pageSize));
+
+ void* ptr = mmap(nullptr, vmInfo.pageSize, PROT_READ | PROT_EXEC, MAP_SHARED, anonMem.fd(), 0);
+ if (ptr == MAP_FAILED) {
+ int e = errno;
+ if (e == EINVAL) {
+ *strategyOut = AnonymousMemoryStrategy::kTmpDir;
+ return kErrorOk;
+ }
+ return DebugUtils::errored(asmjitErrorFromErrno(e));
+ }
+ else {
+ munmap(ptr, vmInfo.pageSize);
+ *strategyOut = AnonymousMemoryStrategy::kDevShm;
+ return kErrorOk;
+ }
}
+#endif
-#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 inline bool hasHardenedRuntimeMacOS() noexcept {
-#if TARGET_OS_OSX && ASMJIT_ARCH_ARM >= 64
- // MacOS on AArch64 has always hardened runtime enabled.
+static Error getAnonymousMemoryStrategy(AnonymousMemoryStrategy* 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 std::atomic<uint32_t> cachedStrategy;
+
+ AnonymousMemoryStrategy strategy = static_cast<AnonymousMemoryStrategy>(cachedStrategy.load());
+ if (strategy == AnonymousMemoryStrategy::kUnknown) {
+ ASMJIT_PROPAGATE(detectAnonymousMemoryStrategy(&strategy));
+ cachedStrategy.store(static_cast<uint32_t>(strategy));
+ }
+
+ *strategyOut = strategy;
+ return kErrorOk;
+#else
+ *strategyOut = AnonymousMemoryStrategy::kTmpDir;
+ return kErrorOk;
+#endif
+}
+
+#endif // ASMJIT_ANONYMOUS_MEMORY_USE_FD
+
+// Virtual Memory [Posix] - Hardened Runtime & MAP_JIT
+// ===================================================
+
+// Detects whether the current process is hardened, which means that pages that have WRITE and EXECUTABLE flags
+// cannot be normally allocated. On OSX + AArch64 such allocation requires MAP_JIT flag, other platforms don't
+// support this combination.
+static bool hasHardenedRuntime() noexcept {
+#if defined(__APPLE__) && TARGET_OS_OSX && ASMJIT_ARCH_ARM >= 64
+ // OSX on AArch64 has always hardened runtime enabled.
return true;
#else
- static std::atomic<uint32_t> globalHardenedFlag;
+ static std::atomic<uint32_t> cachedHardenedFlag;
enum HardenedFlag : uint32_t {
kHardenedFlagUnknown = 0,
@@ -425,11 +731,11 @@ static inline bool hasHardenedRuntimeMacOS() noexcept {
kHardenedFlagEnabled = 2
};
- uint32_t flag = globalHardenedFlag.load();
+ uint32_t flag = cachedHardenedFlag.load();
if (flag == kHardenedFlagUnknown) {
- size_t pageSize = ::getpagesize();
+ size_t pageSize = size_t(::getpagesize());
+ void* ptr = mmap(nullptr, pageSize, PROT_READ | 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;
}
@@ -437,63 +743,49 @@ static inline bool hasHardenedRuntimeMacOS() noexcept {
flag = kHardenedFlagDisabled;
munmap(ptr, pageSize);
}
- globalHardenedFlag.store(flag);
+
+ cachedHardenedFlag.store(flag);
}
return flag == kHardenedFlagEnabled;
#endif
}
-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:
+// Detects whether MAP_JIT is available.
+static inline bool hasMapJitSupport() noexcept {
+#if defined(__APPLE__) && TARGET_OS_OSX && ASMJIT_ARCH_X86 == 0
+ // Apple platforms always use hardened runtime + MAP_JIT on non-x86 hardware:
// - 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.load();
- if (!ver) {
- struct utsname osname {};
- uname(&osname);
- ver = atoi(osname.release);
- globalVersion.store(ver);
+#elif defined(__APPLE__) && TARGET_OS_OSX
+ // MAP_JIT flag required to run unsigned JIT code is only supported by kernel version 10.14+ (Mojave).
+ static std::atomic<uint32_t> cachedMapJitSupport;
+ uint32_t val = cachedMapJitSupport.load();
+
+ if (val == 0u) {
+ KernelVersion ver = getKernelVersion();
+ val = uint32_t(ver.ge(18, 0)) + 1u;
+ cachedMapJitSupport.store(val);
}
- return ver >= 18;
-#else
- // Assume it's available.
- 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();
+ return val == 2u;
#else
+ // MAP_JIT is not available (it's only available on OSX).
return false;
#endif
}
-// 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.
+// Returns either MAP_JIT or 0 based on `memoryFlags` and the host operating system.
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 `memoryFlags`).
- bool useMapJit = Support::test(memoryFlags, MemoryFlags::kMMapEnableMapJit) || hasHardenedRuntime();
+ //
+ // MAP_JIT is not required when dual-mapping memory and is incompatible with MAP_SHARED, so it will not be
+ // added when the latter is enabled.
+ bool useMapJit = (Support::test(memoryFlags, MemoryFlags::kMMapEnableMapJit) || hasHardenedRuntime())
+ && !Support::test(memoryFlags, MemoryFlags::kMapShared);
if (useMapJit)
return hasMapJitSupport() ? int(MAP_JIT) : 0;
else
@@ -504,121 +796,252 @@ static inline int mmMapJitFromMemoryFlags(MemoryFlags memoryFlags) noexcept {
#endif
}
-// Returns BSD-specific `PROT_MAX()` flags.
-static inline int mmMaxProtFromMemoryFlags(MemoryFlags memoryFlags) noexcept {
-#if defined(PROT_MAX)
- 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(memoryFlags);
- return 0;
-#endif
-}
-
-#if ASMJIT_VM_SHM_DETECT
-static Error detectShmStrategy(ShmStrategy* strategyOut) noexcept {
- AnonymousMemory anonMem;
- Info vmInfo = info();
-
- ASMJIT_PROPAGATE(anonMem.open(false));
- ASMJIT_PROPAGATE(anonMem.allocate(vmInfo.pageSize));
-
- void* ptr = mmap(nullptr, vmInfo.pageSize, PROT_READ | PROT_EXEC, MAP_SHARED, anonMem.fd(), 0);
- if (ptr == MAP_FAILED) {
- int e = errno;
- if (e == EINVAL) {
- *strategyOut = ShmStrategy::kTmpDir;
- return kErrorOk;
- }
- return DebugUtils::errored(asmjitErrorFromErrno(e));
- }
- else {
- munmap(ptr, vmInfo.pageSize);
- *strategyOut = ShmStrategy::kDevShm;
- return kErrorOk;
- }
-}
-#endif
-
-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 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;
+static inline bool hasDualMappingSupport() noexcept {
+#if defined(ASMJIT_NO_DUAL_MAPPING)
+ return false;
#else
- *strategyOut = ShmStrategy::kTmpDir;
- return kErrorOk;
+ return true;
#endif
}
static HardenedRuntimeFlags getHardenedRuntimeFlags() noexcept {
- HardenedRuntimeFlags hrFlags = HardenedRuntimeFlags::kNone;
+ HardenedRuntimeFlags flags = HardenedRuntimeFlags::kNone;
if (hasHardenedRuntime())
- hrFlags |= HardenedRuntimeFlags::kEnabled;
+ flags |= HardenedRuntimeFlags::kEnabled;
if (hasMapJitSupport())
- hrFlags |= HardenedRuntimeFlags::kMapJit;
+ flags |= HardenedRuntimeFlags::kMapJit;
+
+ if (hasDualMappingSupport())
+ flags |= HardenedRuntimeFlags::kDualMapping;
- return hrFlags;
+ return flags;
}
-Error alloc(void** p, size_t size, MemoryFlags memoryFlags) noexcept {
+static Error mapMemory(void** p, size_t size, MemoryFlags memoryFlags, int fd = -1, off_t offset = 0) noexcept {
*p = nullptr;
if (size == 0)
return DebugUtils::errored(kErrorInvalidArgument);
int protection = mmProtFromMemoryFlags(memoryFlags) | mmMaxProtFromMemoryFlags(memoryFlags);
- int mmFlags = MAP_PRIVATE | MAP_ANONYMOUS | mmMapJitFromMemoryFlags(memoryFlags);
+ int mmFlags = mmMapJitFromMemoryFlags(memoryFlags);
+
+ mmFlags |= Support::test(memoryFlags, MemoryFlags::kMapShared) ? MAP_SHARED : MAP_PRIVATE;
+ if (fd == -1)
+ mmFlags |= MAP_ANONYMOUS;
- void* ptr = mmap(nullptr, size, protection, mmFlags, -1, 0);
+ bool useLargePages = Support::test(memoryFlags, VirtMem::MemoryFlags::kMMapLargePages);
+
+ if (useLargePages) {
+#if defined(__linux__)
+ size_t lpSize = largePageSize();
+ if (lpSize == 0)
+ return DebugUtils::errored(kErrorFeatureNotEnabled);
+
+ if (!Support::isAligned(size, lpSize))
+ return DebugUtils::errored(kErrorInvalidArgument);
+
+ unsigned lpSizeLog2 = Support::ctz(lpSize);
+ mmFlags |= int(unsigned(MAP_HUGETLB) | (lpSizeLog2 << MAP_HUGE_SHIFT));
+#else
+ return DebugUtils::errored(kErrorFeatureNotEnabled);
+#endif // __linux__
+ }
+
+ void* ptr = mmap(nullptr, size, protection, mmFlags, fd, offset);
if (ptr == MAP_FAILED)
- return DebugUtils::errored(kErrorOutOfMemory);
+ return DebugUtils::errored(asmjitErrorFromErrno(errno));
+
+#if defined(MADV_HUGEPAGE)
+ if (useLargePages) {
+ madvise(ptr, size, MADV_HUGEPAGE);
+ }
+#endif
*p = ptr;
return kErrorOk;
}
-Error release(void* p, size_t size) noexcept {
+static Error unmapMemory(void* p, size_t size) noexcept {
if (ASMJIT_UNLIKELY(munmap(p, size) != 0))
- return DebugUtils::errored(kErrorInvalidArgument);
+ return DebugUtils::errored(asmjitErrorFromErrno(errno));
return kErrorOk;
}
+Error alloc(void** p, size_t size, MemoryFlags memoryFlags) noexcept {
+ return mapMemory(p, size, memoryFlags);
+}
+
+Error release(void* p, size_t size) noexcept {
+ return unmapMemory(p, size);
+}
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);
+ return DebugUtils::errored(asmjitErrorFromErrno(errno));
}
-Error allocDualMapping(DualMapping* dm, size_t size, MemoryFlags memoryFlags) noexcept {
+// Virtual Memory [Posix] - Dual Mapping
+// =====================================
+
+#if !defined(ASMJIT_NO_DUAL_MAPPING)
+static Error unmapDualMapping(DualMapping* dm, size_t size) noexcept {
+ Error err1 = unmapMemory(dm->rx, size);
+ Error err2 = kErrorOk;
+
+ if (dm->rx != dm->rw)
+ err2 = unmapMemory(dm->rw, size);
+
+ // We can report only one error, so report the first...
+ if (err1 || err2)
+ return DebugUtils::errored(err1 ? err1 : err2);
+
dm->rx = nullptr;
dm->rw = nullptr;
+ return kErrorOk;
+}
+#endif // !ASMJIT_NO_DUAL_MAPPING
- if (off_t(size) <= 0)
- return DebugUtils::errored(size == 0 ? kErrorInvalidArgument : kErrorTooLarge);
+#if defined(ASMJIT_ANONYMOUS_MEMORY_USE_REMAPDUP)
+static Error allocDualMappingUsingRemapdup(DualMapping* dmOut, size_t size, MemoryFlags memoryFlags) noexcept {
+ MemoryFlags maxAccessFlags = regularAccessFlagsToMaxAccessFlags(memoryFlags);
+ MemoryFlags finalFlags = memoryFlags | maxAccessFlags | MemoryFlags::kMapShared;
+
+ MemoryFlags rxFlags = finalFlags & ~(MemoryFlags::kAccessWrite | MemoryFlags::kMMapMaxAccessWrite);
+ MemoryFlags rwFlags = finalFlags & ~(MemoryFlags::kAccessExecute);
+
+ // Allocate RW mapping.
+ DualMapping dm {};
+ ASMJIT_PROPAGATE(mapMemory(&dm.rw, size, rwFlags));
+
+ // Allocate RX mapping.
+ dm.rx = mremap(dm.rw, size, nullptr, size, MAP_REMAPDUP);
+ if (dm.rx == MAP_FAILED) {
+ int e = errno;
+ munmap(dm.rw, size);
+ return DebugUtils::errored(asmjitErrorFromErrno(e));
+ }
+
+ if (mprotect(dm.rx, size, mmProtFromMemoryFlags(rxFlags)) != 0) {
+ int e = errno;
+ unmapDualMapping(&dm, size);
+ return DebugUtils::errored(asmjitErrorFromErrno(e));
+ }
+
+ *dmOut = dm;
+ return kErrorOk;
+}
+#endif
+
+#if defined(ASMJIT_ANONYMOUS_MEMORY_USE_MACH_VM_REMAP)
+static Error asmjitErrorFromKernResult(kern_return_t result) noexcept {
+ switch (result) {
+ case KERN_PROTECTION_FAILURE:
+ return DebugUtils::errored(kErrorProtectionFailure);
+ case KERN_NO_SPACE:
+ return DebugUtils::errored(kErrorOutOfMemory);
+ case KERN_INVALID_ARGUMENT:
+ return DebugUtils::errored(kErrorInvalidArgument);
+ default:
+ return DebugUtils::errored(kErrorInvalidState);
+ }
+}
+
+static Error allocDualMappingUsingMachVmRemap(DualMapping* dmOut, size_t size, MemoryFlags memoryFlags) noexcept {
+ DualMapping dm {};
+
+ MemoryFlags mmapFlags = MemoryFlags::kAccessReadWrite | (memoryFlags & MemoryFlags::kMapShared);
+ ASMJIT_PROPAGATE(mapMemory(&dm.rx, size, mmapFlags));
+
+ vm_prot_t curProt;
+ vm_prot_t maxProt;
+
+ int rwProtectFlags = VM_PROT_READ | VM_PROT_WRITE;
+ int rxProtectFlags = VM_PROT_READ;
+
+ if (Support::test(memoryFlags, MemoryFlags::kAccessExecute))
+ rxProtectFlags |= VM_PROT_EXECUTE;
+
+ kern_return_t result {};
+ do {
+ vm_map_t task = mach_task_self();
+ mach_vm_address_t remappedAddr {};
+
+#if defined(VM_FLAGS_RANDOM_ADDR)
+ int remapFlags = VM_FLAGS_ANYWHERE | VM_FLAGS_RANDOM_ADDR;
+#else
+ int remapFlags = VM_FLAGS_ANYWHERE;
+#endif
+
+ // Try to remap the existing memory into a different address.
+ result = mach_vm_remap(
+ task, // target_task
+ &remappedAddr, // target_address
+ size, // size
+ 0, // mask
+ remapFlags, // flags
+ task, // src_task
+ (mach_vm_address_t)dm.rx, // src_address
+ false, // copy
+ &curProt, // cur_protection
+ &maxProt, // max_protection
+ VM_INHERIT_DEFAULT); // inheritance
+
+ if (result != KERN_SUCCESS)
+ break;
+
+ dm.rw = (void*)remappedAddr;
+
+ // Now, try to change permissions of both map regions into RW and RX. The vm_protect()
+ // API is used twice as we also want to set maximum permissions, so nobody would be
+ // allowed to change the RX region back to RW or RWX (if RWX is allowed).
+ uint32_t i;
+ for (i = 0; i < 2; i++) {
+ bool setMaximum = (i == 0);
+
+ result = vm_protect(
+ task, // target_task
+ (vm_address_t)dm.rx, // address
+ size, // size
+ setMaximum, // set_maximum
+ rxProtectFlags); // new_protection
+
+ if (result != KERN_SUCCESS)
+ break;
+
+ result = vm_protect(task, // target_task
+ (vm_address_t)dm.rw, // address
+ size, // size
+ setMaximum, // set_maximum
+ rwProtectFlags); // new_protection
+
+ if (result != KERN_SUCCESS)
+ break;
+ }
+ } while (0);
+
+ if (result != KERN_SUCCESS) {
+ unmapDualMapping(&dm, size);
+ return DebugUtils::errored(asmjitErrorFromKernResult(result));
+ }
+ *dmOut = dm;
+ return kErrorOk;
+}
+#endif // ASMJIT_ANONYMOUS_MEMORY_USE_MACH_VM_REMAP
+
+#if defined(ASMJIT_ANONYMOUS_MEMORY_USE_FD)
+static Error allocDualMappingUsingFile(DualMapping* dm, size_t size, MemoryFlags memoryFlags) noexcept {
bool preferTmpOverDevShm = Support::test(memoryFlags, MemoryFlags::kMappingPreferTmp);
if (!preferTmpOverDevShm) {
- ShmStrategy strategy;
- ASMJIT_PROPAGATE(getShmStrategy(&strategy));
- preferTmpOverDevShm = (strategy == ShmStrategy::kTmpDir);
+ AnonymousMemoryStrategy strategy;
+ ASMJIT_PROPAGATE(getAnonymousMemoryStrategy(&strategy));
+ preferTmpOverDevShm = (strategy == AnonymousMemoryStrategy::kTmpDir);
}
AnonymousMemory anonMem;
@@ -627,16 +1050,12 @@ Error allocDualMapping(DualMapping* dm, size_t size, MemoryFlags memoryFlags) no
void* ptr[2];
for (uint32_t i = 0; i < 2; i++) {
- 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) {
- // Get the error now before `munmap()` has a chance to clobber it.
- int e = errno;
+ MemoryFlags restrictedMemoryFlags = memoryFlags & ~dualMappingFilter[i];
+ Error err = mapMemory(&ptr[i], size, restrictedMemoryFlags | MemoryFlags::kMapShared, anonMem.fd(), 0);
+ if (err != kErrorOk) {
if (i == 1)
- munmap(ptr[0], size);
- return DebugUtils::errored(asmjitErrorFromErrno(e));
+ unmapMemory(ptr[0], size);
+ return err;
}
}
@@ -644,18 +1063,38 @@ Error allocDualMapping(DualMapping* dm, size_t size, MemoryFlags memoryFlags) no
dm->rw = ptr[1];
return kErrorOk;
}
+#endif // ASMJIT_ANONYMOUS_MEMORY_USE_FD
-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);
-
+Error allocDualMapping(DualMapping* dm, size_t size, MemoryFlags memoryFlags) noexcept {
dm->rx = nullptr;
dm->rw = nullptr;
- return kErrorOk;
+
+#if defined(ASMJIT_NO_DUAL_MAPPING)
+ DebugUtils::unused(size, memoryFlags);
+ return DebugUtils::errored(kErrorFeatureNotEnabled);
+#else
+ if (off_t(size) <= 0)
+ return DebugUtils::errored(size == 0 ? kErrorInvalidArgument : kErrorTooLarge);
+
+#if defined(ASMJIT_ANONYMOUS_MEMORY_USE_REMAPDUP)
+ return allocDualMappingUsingRemapdup(dm, size, memoryFlags);
+#elif defined(ASMJIT_ANONYMOUS_MEMORY_USE_MACH_VM_REMAP)
+ return allocDualMappingUsingMachVmRemap(dm, size, memoryFlags);
+#elif defined(ASMJIT_ANONYMOUS_MEMORY_USE_FD)
+ return allocDualMappingUsingFile(dm, size, memoryFlags);
+#else
+ #error "[asmjit] VirtMem::allocDualMapping() doesn't have implementation for the target OS or architecture"
+#endif
+#endif // ASMJIT_NO_DUAL_MAPPING
+}
+
+Error releaseDualMapping(DualMapping* dm, size_t size) noexcept {
+#if defined(ASMJIT_NO_DUAL_MAPPING)
+ DebugUtils::unused(dm, size);
+ return DebugUtils::errored(kErrorFeatureNotEnabled);
+#else
+ return unmapDualMapping(dm, size);
+#endif // ASMJIT_NO_DUAL_MAPPING
}
#endif
@@ -663,7 +1102,7 @@ Error releaseDualMapping(DualMapping* dm, size_t size) noexcept {
// ========================================
void flushInstructionCache(void* p, size_t size) noexcept {
-#if ASMJIT_ARCH_X86
+#if ASMJIT_ARCH_X86 || defined(__EMSCRIPTEN__)
// X86/X86_64 architecture doesn't require to do anything to flush instruction cache.
DebugUtils::unused(p, size);
#elif defined(__APPLE__)
@@ -676,7 +1115,7 @@ void flushInstructionCache(void* p, size_t size) noexcept {
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")
+ #pragma message("[asmjit] VirtMem::flushInstructionCache() doesn't have implementation for the target OS and compiler")
DebugUtils::unused(p, size);
#endif
}
@@ -690,7 +1129,7 @@ Info info() noexcept {
if (!vmInfoInitialized.load()) {
Info localMemInfo;
- getVMInfo(localMemInfo);
+ detectVMInfo(localMemInfo);
vmInfo = localMemInfo;
vmInfoInitialized.store(1u);
@@ -699,6 +1138,22 @@ Info info() noexcept {
return vmInfo;
}
+size_t largePageSize() noexcept {
+ static std::atomic<size_t> largePageSize;
+ static constexpr size_t kNotAvailable = 1;
+
+ size_t size = largePageSize.load();
+ if (ASMJIT_LIKELY(size > kNotAvailable))
+ return size;
+
+ if (size == kNotAvailable)
+ return 0;
+
+ size = detectLargePageSize();
+ largePageSize.store(size != 0 ? size : kNotAvailable);
+ return size;
+}
+
// Virtual Memory - Hardened Runtime Info
// ======================================
@@ -711,7 +1166,7 @@ HardenedRuntimeInfo hardenedRuntimeInfo() noexcept {
void protectJitMemory(ProtectJitAccess access) noexcept {
#if defined(ASMJIT_HAS_PTHREAD_JIT_WRITE_PROTECT_NP)
- pthread_jit_write_protect_np(static_cast<uint32_t>(access));
+ pthread_jit_write_protect_np(static_cast<int>(access));
#else
DebugUtils::unused(access);
#endif
@@ -719,4 +1174,33 @@ void protectJitMemory(ProtectJitAccess access) noexcept {
ASMJIT_END_SUB_NAMESPACE
-#endif
+// Virtual Memory - Tests
+// ======================
+
+#if defined(ASMJIT_TEST)
+ASMJIT_BEGIN_NAMESPACE
+
+UNIT(virt_mem) {
+ VirtMem::Info vmInfo = VirtMem::info();
+
+ INFO("VirtMem::info():");
+ INFO(" pageSize: %zu", size_t(vmInfo.pageSize));
+ INFO(" pageGranularity: %zu", size_t(vmInfo.pageGranularity));
+
+ INFO("VirtMem::largePageSize():");
+ INFO(" largePageSize: %zu", size_t(VirtMem::largePageSize()));
+
+ VirtMem::HardenedRuntimeInfo hardenedRtInfo = VirtMem::hardenedRuntimeInfo();
+ VirtMem::HardenedRuntimeFlags hardenedFlags = hardenedRtInfo.flags;
+
+ INFO("VirtMem::hardenedRuntimeInfo():");
+ INFO(" flags:");
+ INFO(" kEnabled: %s" , Support::test(hardenedFlags, VirtMem::HardenedRuntimeFlags::kEnabled ) ? "true" : "false");
+ INFO(" kMapJit: %s" , Support::test(hardenedFlags, VirtMem::HardenedRuntimeFlags::kMapJit ) ? "true" : "false");
+ INFO(" kDualMapping: %s", Support::test(hardenedFlags, VirtMem::HardenedRuntimeFlags::kDualMapping) ? "true" : "false");
+}
+
+ASMJIT_END_NAMESPACE
+#endif // ASMJIT_TEST
+
+#endif // !ASMJIT_NO_JIT
diff --git a/3rdparty/asmjit/src/asmjit/core/virtmem.h b/3rdparty/asmjit/src/asmjit/core/virtmem.h
index 50f09457eba..17996dcb07e 100644
--- a/3rdparty/asmjit/src/asmjit/core/virtmem.h
+++ b/3rdparty/asmjit/src/asmjit/core/virtmem.h
@@ -10,6 +10,7 @@
#ifndef ASMJIT_NO_JIT
#include "../core/globals.h"
+#include "../core/support.h"
ASMJIT_BEGIN_NAMESPACE
@@ -19,6 +20,21 @@ ASMJIT_BEGIN_NAMESPACE
//! Virtual memory management.
namespace VirtMem {
+//! Describes whether instruction cache should be flushed after a write operation.
+enum class CachePolicy : uint32_t {
+ //! Default policy.
+ //!
+ //! In some places this would mean `kFlushAfterWrite` and in some places it would mean `kNeverFlush`.
+ //! For example if it's known that an address has never been used before to execute code.
+ kDefault = 0,
+
+ //! Flush instruction cache after a write operation.
+ kFlushAfterWrite = 1,
+
+ //! Avoid flushing instruction cache after a write operation.
+ kNeverFlush = 2
+};
+
//! 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
@@ -36,6 +52,15 @@ struct Info {
//! Returns virtual memory information, see `VirtMem::Info` for more details.
ASMJIT_API Info info() noexcept;
+//! Returns the size of the smallest large page supported.
+//!
+//! AsmJit only uses the smallest large page at the moment as these are usually perfectly sized for executable
+//! memory allocation (standard size is 2MB, but different sizes are possible).
+//!
+//! Returns either the detected large page size or 0, if large page support is either not supported by AsmJit
+//! or not accessible to the process.
+ASMJIT_API size_t largePageSize() noexcept;
+
//! Virtual memory access and mmap-specific flags.
enum class MemoryFlags : uint32_t {
//! No flags.
@@ -50,52 +75,80 @@ enum class MemoryFlags : uint32_t {
//! Memory is executable.
kAccessExecute = 0x00000004u,
- //! A combination of \ref MemoryFlags::kAccessRead and \ref MemoryFlags::kAccessWrite.
+ //! A combination of \ref kAccessRead and \ref kAccessWrite.
kAccessReadWrite = kAccessRead | kAccessWrite,
- //! A combination of \ref MemoryFlags::kAccessRead, \ref MemoryFlags::kAccessWrite.
+ //! A combination of \ref kAccessRead, \ref kAccessWrite.
kAccessRW = kAccessRead | kAccessWrite,
- //! A combination of \ref MemoryFlags::kAccessRead and \ref MemoryFlags::kAccessExecute.
+ //! A combination of \ref kAccessRead and \ref kAccessExecute.
kAccessRX = kAccessRead | kAccessExecute,
- //! A combination of \ref MemoryFlags::kAccessRead, \ref MemoryFlags::kAccessWrite, and
- //! \ref MemoryFlags::kAccessExecute.
+ //! A combination of \ref kAccessRead, \ref kAccessWrite, and \ref 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 a MAC bundle.
//!
- //! \note This flag can only be used with \ref VirtMem::alloc().
+ //! This flag may be turned on by the allocator if there is no other way of allocating executable memory.
+ //!
+ //! \note This flag can only be used with \ref VirtMem::alloc(), `MAP_JIT` only works on OSX and not on iOS.
+ //! When a process uses `fork()` the child process has no access to the pages mapped with `MAP_JIT`.
kMMapEnableMapJit = 0x00000010u,
- //! Pass `PROT_MAX(PROT_READ)` to mmap() on platforms that support `PROT_MAX`.
+ //! Pass `PROT_MAX(PROT_READ)` or `PROT_MPROTECT(PROT_READ)` to `mmap()` on platforms that support it.
//!
- //! \note This flag can only be used with \ref VirtMem::alloc().
+ //! This flag allows to set a "maximum access" that the memory page can get during its lifetime. Use
+ //! \ref VirtMem::protect() to change the access flags.
+ //!
+ //! \note This flag can only be used with \ref VirtMem::alloc() and \ref VirtMem::allocDualMapping().
+ //! However \ref VirtMem::allocDualMapping() may automatically use this if \ref kAccessRead is used.
kMMapMaxAccessRead = 0x00000020u,
- //! Pass `PROT_MAX(PROT_WRITE)` to mmap() on platforms that support `PROT_MAX`.
+
+ //! Pass `PROT_MAX(PROT_WRITE)` or `PROT_MPROTECT(PROT_WRITE)` to `mmap()` on platforms that support it.
//!
- //! \note This flag can only be used with \ref VirtMem::alloc().
+ //! This flag allows to set a "maximum access" that the memory page can get during its lifetime. Use
+ //! \ref VirtMem::protect() to change the access flags.
+ //!
+ //! \note This flag can only be used with \ref VirtMem::alloc() and \ref VirtMem::allocDualMapping().
+ //! However \ref VirtMem::allocDualMapping() may automatically use this if \ref kAccessWrite is used.
kMMapMaxAccessWrite = 0x00000040u,
- //! Pass `PROT_MAX(PROT_EXEC)` to mmap() on platforms that support `PROT_MAX`.
+
+ //! Pass `PROT_MAX(PROT_EXEC)` or `PROT_MPROTECT(PROT_EXEC)` to `mmap()` on platforms that support it.
//!
- //! \note This flag can only be used with \ref VirtMem::alloc().
+ //! This flag allows to set a "maximum access" that the memory page can get during its lifetime. Use
+ //! \ref VirtMem::protect() to change the access flags.
+ //!
+ //! \note This flag can only be used with \ref VirtMem::alloc() and \ref VirtMem::allocDualMapping().
+ //! However \ref VirtMem::allocDualMapping() may automatically use this if \ref kAccessExecute is used.
kMMapMaxAccessExecute = 0x00000080u,
- //! A combination of \ref MemoryFlags::kMMapMaxAccessRead and \ref MemoryFlags::kMMapMaxAccessWrite.
+ //! A combination of \ref kMMapMaxAccessRead and \ref kMMapMaxAccessWrite.
kMMapMaxAccessReadWrite = kMMapMaxAccessRead | kMMapMaxAccessWrite,
- //! A combination of \ref MemoryFlags::kMMapMaxAccessRead and \ref MemoryFlags::kMMapMaxAccessWrite.
+ //! A combination of \ref kMMapMaxAccessRead and \ref kMMapMaxAccessWrite.
kMMapMaxAccessRW = kMMapMaxAccessRead | kMMapMaxAccessWrite,
- //! A combination of \ref MemoryFlags::kMMapMaxAccessRead and \ref MemoryFlags::kMMapMaxAccessExecute.
+ //! A combination of \ref kMMapMaxAccessRead and \ref kMMapMaxAccessExecute.
kMMapMaxAccessRX = kMMapMaxAccessRead | kMMapMaxAccessExecute,
- //! A combination of \ref MemoryFlags::kMMapMaxAccessRead, \ref MemoryFlags::kMMapMaxAccessWrite, \ref
- //! MemoryFlags::kMMapMaxAccessExecute.
+ //! A combination of \ref kMMapMaxAccessRead, \ref kMMapMaxAccessWrite, \ref kMMapMaxAccessExecute.
kMMapMaxAccessRWX = kMMapMaxAccessRead | kMMapMaxAccessWrite | kMMapMaxAccessExecute,
+ //! Use `MAP_SHARED` when calling mmap().
+ //!
+ //! \note In some cases `MAP_SHARED` may be set automatically. For example, some dual mapping implementations must
+ //! use `MAP_SHARED` instead of `MAP_PRIVATE` to ensure that the OS would not apply copy on write on RW page, which
+ //! would cause RX page not having the updated content.
+ kMapShared = 0x00000100u,
+
+ //! Request large memory mapped pages.
+ //!
+ //! \remarks If this option is used and large page(s) cannot be mapped, the allocation will fail. Fallback to
+ //! regular pages must be done by the user in this case. Higher level API such as \ref JitAllocator provides an
+ //! additional mechanism to allocate regular page(s) when large page(s) allocation fails.
+ kMMapLargePages = 0x00000200u,
+
//! 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
@@ -157,21 +210,37 @@ enum class HardenedRuntimeFlags : uint32_t {
//! 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()`
+ //! \note If the runtime is hardened it means that an operating system specific protection is used. For example
+ //! on Apple OSX 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
+ //! Read+Write+Execute can only be allocated with MAP_JIT flag (Apple specific, only available on Apple platforms).
+ kMapJit = 0x00000002u,
+
+ //! Read+Write+Execute can be allocated with dual mapping approach (one region with RW and the other with RX).
+ kDualMapping = 0x00000004u
};
ASMJIT_DEFINE_ENUM_FLAGS(HardenedRuntimeFlags)
//! Hardened runtime information.
struct HardenedRuntimeInfo {
+ //! \name Members
+ //! \{
+
//! Hardened runtime flags.
HardenedRuntimeFlags flags;
+
+ //! \}
+
+ //! \name Accessors
+ //! \{
+
+ //! Tests whether the hardened runtime `flag` is set.
+ ASMJIT_INLINE_NODEBUG bool hasFlag(HardenedRuntimeFlags flag) const noexcept { return Support::test(flags, flag); }
+
+ //! \}
};
//! Returns runtime features provided by the OS.
@@ -187,7 +256,7 @@ enum class ProtectJitAccess : uint32_t {
//! 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
+//! \note This feature is only available on Apple hardware (AArch64) at the moment 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:
@@ -212,24 +281,40 @@ ASMJIT_API void protectJitMemory(ProtectJitAccess access) noexcept;
//! in destructor. The purpose of this class is to make writing to JIT memory easier.
class ProtectJitReadWriteScope {
public:
+ ASMJIT_NONCOPYABLE(ProtectJitReadWriteScope)
+
+ //! \name Members
+ //! \{
+
void* _rxPtr;
size_t _size;
+ CachePolicy _policy;
+
+ //! \}
+
+ //! \name Construction & Destruction
+ //! \{
//! Makes the given memory block RW protected.
- ASMJIT_FORCE_INLINE ProtectJitReadWriteScope(void* rxPtr, size_t size) noexcept
+ ASMJIT_FORCE_INLINE ProtectJitReadWriteScope(
+ void* rxPtr,
+ size_t size,
+ CachePolicy policy = CachePolicy::kDefault) noexcept
: _rxPtr(rxPtr),
- _size(size) {
+ _size(size),
+ _policy(policy) {
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);
+
+ if (_policy != CachePolicy::kNeverFlush)
+ flushInstructionCache(_rxPtr, _size);
}
+
+ //! \}
};
} // VirtMem
diff --git a/3rdparty/asmjit/src/asmjit/core/zone.cpp b/3rdparty/asmjit/src/asmjit/core/zone.cpp
index d68e110b48c..e1948ebb0c9 100644
--- a/3rdparty/asmjit/src/asmjit/core/zone.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/zone.cpp
@@ -16,8 +16,8 @@ ASMJIT_BEGIN_NAMESPACE
// and should never be modified.
const Zone::Block Zone::_zeroBlock = { nullptr, nullptr, 0 };
-// Zone - Init & Reset
-// ===================
+// Zone - Initialization & Reset
+// =============================
void Zone::_init(size_t blockSize, size_t blockAlignment, const Support::Temporary* temporary) noexcept {
ASMJIT_ASSERT(blockSize >= kMinBlockSize);
@@ -215,8 +215,8 @@ static bool ZoneAllocator_hasDynamicBlock(ZoneAllocator* self, ZoneAllocator::Dy
}
#endif
-// ZoneAllocator - Init & Reset
-// ============================
+// ZoneAllocator - Initialization & Reset
+// ======================================
void ZoneAllocator::reset(Zone* zone) noexcept {
// Free dynamic blocks.
@@ -227,9 +227,9 @@ void ZoneAllocator::reset(Zone* zone) noexcept {
block = next;
}
- // Zero the entire class and initialize to the given `zone`.
- memset(this, 0, sizeof(*this));
_zone = zone;
+ memset(_slots, 0, sizeof(_slots));
+ _dynamicBlocks = nullptr;
}
// asmjit::ZoneAllocator - Alloc & Release
diff --git a/3rdparty/asmjit/src/asmjit/core/zone.h b/3rdparty/asmjit/src/asmjit/core/zone.h
index eaea252903e..b61a3d1292c 100644
--- a/3rdparty/asmjit/src/asmjit/core/zone.h
+++ b/3rdparty/asmjit/src/asmjit/core/zone.h
@@ -85,17 +85,17 @@ public:
//!
//! 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 {
+ ASMJIT_INLINE_NODEBUG explicit Zone(size_t blockSize, size_t blockAlignment = 1) noexcept {
_init(blockSize, blockAlignment, nullptr);
}
//! 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 {
+ ASMJIT_INLINE_NODEBUG 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 {
+ ASMJIT_INLINE_NODEBUG Zone(size_t blockSize, size_t blockAlignment, const Support::Temporary* temporary) noexcept {
_init(blockSize, blockAlignment, temporary);
}
@@ -118,7 +118,7 @@ public:
//!
//! 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_INLINE_NODEBUG ~Zone() noexcept { reset(ResetPolicy::kHard); }
ASMJIT_API void _init(size_t blockSize, size_t blockAlignment, const Support::Temporary* temporary) noexcept;
@@ -133,24 +133,24 @@ public:
//! \{
//! Tests whether this `Zone` is actually a `ZoneTmp` that uses temporary memory.
- inline bool isTemporary() const noexcept { return _isTemporary != 0; }
+ ASMJIT_INLINE_NODEBUG bool isTemporary() const noexcept { return _isTemporary != 0; }
//! Returns the default block size.
- inline size_t blockSize() const noexcept { return _blockSize; }
+ ASMJIT_INLINE_NODEBUG size_t blockSize() const noexcept { return _blockSize; }
//! Returns the default block alignment.
- inline size_t blockAlignment() const noexcept { return size_t(1) << _blockAlignmentShift; }
+ ASMJIT_INLINE_NODEBUG size_t blockAlignment() const noexcept { return size_t(1) << _blockAlignmentShift; }
//! Returns remaining size of the current block.
- inline size_t remainingSize() const noexcept { return (size_t)(_end - _ptr); }
+ ASMJIT_INLINE_NODEBUG 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.
template<typename T = uint8_t>
- inline T* ptr() noexcept { return reinterpret_cast<T*>(_ptr); }
+ ASMJIT_INLINE_NODEBUG 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>
- inline T* end() noexcept { return reinterpret_cast<T*>(_end); }
+ ASMJIT_INLINE_NODEBUG T* end() noexcept { return reinterpret_cast<T*>(_end); }
//! Sets the current zone pointer to `ptr` (must be within the current block).
template<typename T>
@@ -185,7 +185,7 @@ public:
}
//! Aligns the current pointer to `alignment`.
- inline void align(size_t alignment) noexcept {
+ ASMJIT_INLINE_NODEBUG void align(size_t alignment) noexcept {
_ptr = Support::min(Support::alignUp(_ptr, alignment), _end);
}
@@ -193,7 +193,7 @@ public:
//!
//! \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 {
+ ASMJIT_INLINE_NODEBUG Error ensure(size_t size) noexcept {
if (size <= remainingSize())
return kErrorOk;
else
@@ -322,7 +322,7 @@ public:
void* p = alloc(sizeof(T), alignof(T));
if (ASMJIT_UNLIKELY(!p))
return nullptr;
- return new(p) T();
+ return new(Support::PlacementNew{p}) T();
}
//! Like `new(std::nothrow) T(...)`, but allocated by `Zone`.
@@ -331,7 +331,7 @@ public:
void* p = alloc(sizeof(T), alignof(T));
if (ASMJIT_UNLIKELY(!p))
return nullptr;
- return new(p) T(std::forward<Args>(args)...);
+ return new(Support::PlacementNew{p}) T(std::forward<Args>(args)...);
}
//! \cond INTERNAL
@@ -430,11 +430,11 @@ public:
//! \{
//! Zone used to allocate memory that fits into slots.
- Zone* _zone;
+ Zone* _zone {};
//! Indexed slots containing released memory.
- Slot* _slots[kLoCount + kHiCount];
+ Slot* _slots[kLoCount + kHiCount] {};
//! Dynamic blocks for larger allocations (no slots).
- DynamicBlock* _dynamicBlocks;
+ DynamicBlock* _dynamicBlocks {};
//! \}
@@ -444,26 +444,22 @@ public:
//! Creates a new `ZoneAllocator`.
//!
//! \note To use it, you must first `init()` it.
- inline ZoneAllocator() noexcept {
- memset(this, 0, sizeof(*this));
- }
+ ASMJIT_INLINE_NODEBUG ZoneAllocator() noexcept {}
//! Creates a new `ZoneAllocator` initialized to use `zone`.
- inline explicit ZoneAllocator(Zone* zone) noexcept {
- memset(this, 0, sizeof(*this));
- _zone = zone;
- }
+ ASMJIT_INLINE_NODEBUG explicit ZoneAllocator(Zone* zone) noexcept
+ : _zone(zone) {}
//! Destroys the `ZoneAllocator`.
- inline ~ZoneAllocator() noexcept { reset(); }
+ ASMJIT_INLINE_NODEBUG ~ZoneAllocator() noexcept { reset(); }
//! Tests whether the `ZoneAllocator` is initialized (i.e. has `Zone`).
- inline bool isInitialized() const noexcept { return _zone != nullptr; }
+ ASMJIT_INLINE_NODEBUG bool isInitialized() const noexcept { return _zone != nullptr; }
//! Convenience function to initialize the `ZoneAllocator` with `zone`.
//!
//! It's the same as calling `reset(zone)`.
- inline void init(Zone* zone) noexcept { reset(zone); }
+ ASMJIT_INLINE_NODEBUG 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
@@ -476,7 +472,7 @@ public:
//! \{
//! Returns the assigned `Zone` of this allocator or null if this `ZoneAllocator` is not initialized.
- inline Zone* zone() const noexcept { return _zone; }
+ ASMJIT_INLINE_NODEBUG Zone* zone() const noexcept { return _zone; }
//! \}
@@ -577,7 +573,7 @@ public:
void* p = allocT<T>();
if (ASMJIT_UNLIKELY(!p))
return nullptr;
- return new(p) T();
+ return new(Support::PlacementNew{p}) T();
}
//! Like `new(std::nothrow) T(...)`, but allocated by `Zone`.
template<typename T, typename... Args>
@@ -585,7 +581,7 @@ public:
void* p = allocT<T>();
if (ASMJIT_UNLIKELY(!p))
return nullptr;
- return new(p) T(std::forward<Args>(args)...);
+ return new(Support::PlacementNew{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
diff --git a/3rdparty/asmjit/src/asmjit/core/zonehash.cpp b/3rdparty/asmjit/src/asmjit/core/zonehash.cpp
index 3778fbe2260..578b083680e 100644
--- a/3rdparty/asmjit/src/asmjit/core/zonehash.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/zonehash.cpp
@@ -288,8 +288,8 @@ UNIT(zone_hash) {
for (key = 0; key < count; key++) {
node = hashTable.get(MyKeyMatcher(key));
- EXPECT(node != nullptr);
- EXPECT(node->_key == key);
+ EXPECT_NOT_NULL(node);
+ EXPECT_EQ(node->_key, key);
}
{
@@ -298,11 +298,11 @@ UNIT(zone_hash) {
hashTable.remove(&allocator, node);
node = hashTable.get(MyKeyMatcher(count));
- EXPECT(node == nullptr);
+ EXPECT_NULL(node);
}
} while (count);
- EXPECT(hashTable.empty());
+ EXPECT_TRUE(hashTable.empty());
}
#endif
diff --git a/3rdparty/asmjit/src/asmjit/core/zonehash.h b/3rdparty/asmjit/src/asmjit/core/zonehash.h
index f332290b54d..d6cd2e31cb9 100644
--- a/3rdparty/asmjit/src/asmjit/core/zonehash.h
+++ b/3rdparty/asmjit/src/asmjit/core/zonehash.h
@@ -59,7 +59,7 @@ public:
//! \name Construction & Destruction
//! \{
- inline ZoneHashBase() noexcept {
+ ASMJIT_INLINE_NODEBUG ZoneHashBase() noexcept {
reset();
}
@@ -99,8 +99,8 @@ public:
//! \name Accessors
//! \{
- inline bool empty() const noexcept { return _size == 0; }
- inline size_t size() const noexcept { return _size; }
+ ASMJIT_INLINE_NODEBUG bool empty() const noexcept { return _size == 0; }
+ ASMJIT_INLINE_NODEBUG size_t size() const noexcept { return _size; }
//! \}
@@ -150,10 +150,10 @@ public:
//! \name Construction & Destruction
//! \{
- inline ZoneHash() noexcept
+ ASMJIT_INLINE_NODEBUG ZoneHash() noexcept
: ZoneHashBase() {}
- inline ZoneHash(ZoneHash&& other) noexcept
+ ASMJIT_INLINE_NODEBUG ZoneHash(ZoneHash&& other) noexcept
: ZoneHash(other) {}
//! \}
@@ -161,7 +161,7 @@ public:
//! \name Utilities
//! \{
- inline void swap(ZoneHash& other) noexcept { ZoneHashBase::_swap(other); }
+ ASMJIT_INLINE_NODEBUG void swap(ZoneHash& other) noexcept { ZoneHashBase::_swap(other); }
template<typename KeyT>
inline NodeT* get(const KeyT& key) const noexcept {
@@ -173,8 +173,8 @@ public:
return node;
}
- inline NodeT* insert(ZoneAllocator* allocator, NodeT* node) noexcept { return static_cast<NodeT*>(_insert(allocator, node)); }
- inline NodeT* remove(ZoneAllocator* allocator, NodeT* node) noexcept { return static_cast<NodeT*>(_remove(allocator, node)); }
+ ASMJIT_INLINE_NODEBUG NodeT* insert(ZoneAllocator* allocator, NodeT* node) noexcept { return static_cast<NodeT*>(_insert(allocator, node)); }
+ ASMJIT_INLINE_NODEBUG NodeT* remove(ZoneAllocator* allocator, NodeT* node) noexcept { return static_cast<NodeT*>(_remove(allocator, node)); }
//! \}
};
diff --git a/3rdparty/asmjit/src/asmjit/core/zonelist.cpp b/3rdparty/asmjit/src/asmjit/core/zonelist.cpp
index d4b311d4307..ff2c2cf1540 100644
--- a/3rdparty/asmjit/src/asmjit/core/zonelist.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/zonelist.cpp
@@ -27,136 +27,136 @@ UNIT(zone_list) {
INFO("Append / Unlink");
// []
- EXPECT(list.empty() == true);
+ EXPECT_TRUE(list.empty());
// [A]
list.append(a);
- EXPECT(list.empty() == false);
- EXPECT(list.first() == a);
- EXPECT(list.last() == a);
- EXPECT(a->prev() == nullptr);
- EXPECT(a->next() == nullptr);
+ EXPECT_FALSE(list.empty());
+ EXPECT_EQ(list.first(), a);
+ EXPECT_EQ(list.last(), a);
+ EXPECT_NULL(a->prev());
+ EXPECT_NULL(a->next());
// [A, B]
list.append(b);
- EXPECT(list.first() == a);
- EXPECT(list.last() == b);
- EXPECT(a->prev() == nullptr);
- EXPECT(a->next() == b);
- EXPECT(b->prev() == a);
- EXPECT(b->next() == nullptr);
+ EXPECT_EQ(list.first(), a);
+ EXPECT_EQ(list.last(), b);
+ EXPECT_NULL(a->prev());
+ EXPECT_EQ(a->next(), b);
+ EXPECT_EQ(b->prev(), a);
+ EXPECT_NULL(b->next());
// [A, B, C]
list.append(c);
- EXPECT(list.first() == a);
- EXPECT(list.last() == c);
- EXPECT(a->prev() == nullptr);
- EXPECT(a->next() == b);
- EXPECT(b->prev() == a);
- EXPECT(b->next() == c);
- EXPECT(c->prev() == b);
- EXPECT(c->next() == nullptr);
+ EXPECT_EQ(list.first(), a);
+ EXPECT_EQ(list.last(), c);
+ EXPECT_NULL(a->prev());
+ EXPECT_EQ(a->next(), b);
+ EXPECT_EQ(b->prev(), a);
+ EXPECT_EQ(b->next(), c);
+ EXPECT_EQ(c->prev(), b);
+ EXPECT_NULL(c->next());
// [B, C]
list.unlink(a);
- EXPECT(list.first() == b);
- EXPECT(list.last() == c);
- EXPECT(a->prev() == nullptr);
- EXPECT(a->next() == nullptr);
- EXPECT(b->prev() == nullptr);
- EXPECT(b->next() == c);
- EXPECT(c->prev() == b);
- EXPECT(c->next() == nullptr);
+ EXPECT_EQ(list.first(), b);
+ EXPECT_EQ(list.last(), c);
+ EXPECT_NULL(a->prev());
+ EXPECT_NULL(a->next());
+ EXPECT_NULL(b->prev());
+ EXPECT_EQ(b->next(), c);
+ EXPECT_EQ(c->prev(), b);
+ EXPECT_NULL(c->next());
// [B]
list.unlink(c);
- EXPECT(list.first() == b);
- EXPECT(list.last() == b);
- EXPECT(b->prev() == nullptr);
- EXPECT(b->next() == nullptr);
- EXPECT(c->prev() == nullptr);
- EXPECT(c->next() == nullptr);
+ EXPECT_EQ(list.first(), b);
+ EXPECT_EQ(list.last(), b);
+ EXPECT_NULL(b->prev());
+ EXPECT_NULL(b->next());
+ EXPECT_NULL(c->prev());
+ EXPECT_NULL(c->next());
// []
list.unlink(b);
- EXPECT(list.empty() == true);
- EXPECT(list.first() == nullptr);
- EXPECT(list.last() == nullptr);
- EXPECT(b->prev() == nullptr);
- EXPECT(b->next() == nullptr);
+ EXPECT_TRUE(list.empty());
+ EXPECT_NULL(list.first());
+ EXPECT_NULL(list.last());
+ EXPECT_NULL(b->prev());
+ EXPECT_NULL(b->next());
INFO("Prepend / Unlink");
// [A]
list.prepend(a);
- EXPECT(list.empty() == false);
- EXPECT(list.first() == a);
- EXPECT(list.last() == a);
- EXPECT(a->prev() == nullptr);
- EXPECT(a->next() == nullptr);
+ EXPECT_FALSE(list.empty());
+ EXPECT_EQ(list.first(), a);
+ EXPECT_EQ(list.last(), a);
+ EXPECT_NULL(a->prev());
+ EXPECT_NULL(a->next());
// [B, A]
list.prepend(b);
- EXPECT(list.first() == b);
- EXPECT(list.last() == a);
- EXPECT(b->prev() == nullptr);
- EXPECT(b->next() == a);
- EXPECT(a->prev() == b);
- EXPECT(a->next() == nullptr);
+ EXPECT_EQ(list.first(), b);
+ EXPECT_EQ(list.last(), a);
+ EXPECT_NULL(b->prev());
+ EXPECT_EQ(b->next(), a);
+ EXPECT_EQ(a->prev(), b);
+ EXPECT_NULL(a->next());
INFO("InsertAfter / InsertBefore");
// [B, A, C]
list.insertAfter(a, c);
- EXPECT(list.first() == b);
- EXPECT(list.last() == c);
- EXPECT(b->prev() == nullptr);
- EXPECT(b->next() == a);
- EXPECT(a->prev() == b);
- EXPECT(a->next() == c);
- EXPECT(c->prev() == a);
- EXPECT(c->next() == nullptr);
+ EXPECT_EQ(list.first(), b);
+ EXPECT_EQ(list.last(), c);
+ EXPECT_NULL(b->prev());
+ EXPECT_EQ(b->next(), a);
+ EXPECT_EQ(a->prev(), b);
+ EXPECT_EQ(a->next(), c);
+ EXPECT_EQ(c->prev(), a);
+ EXPECT_NULL(c->next());
// [B, D, A, C]
list.insertBefore(a, d);
- EXPECT(list.first() == b);
- EXPECT(list.last() == c);
- EXPECT(b->prev() == nullptr);
- EXPECT(b->next() == d);
- EXPECT(d->prev() == b);
- EXPECT(d->next() == a);
- EXPECT(a->prev() == d);
- EXPECT(a->next() == c);
- EXPECT(c->prev() == a);
- EXPECT(c->next() == nullptr);
+ EXPECT_EQ(list.first(), b);
+ EXPECT_EQ(list.last(), c);
+ EXPECT_NULL(b->prev());
+ EXPECT_EQ(b->next(), d);
+ EXPECT_EQ(d->prev(), b);
+ EXPECT_EQ(d->next(), a);
+ EXPECT_EQ(a->prev(), d);
+ EXPECT_EQ(a->next(), c);
+ EXPECT_EQ(c->prev(), a);
+ EXPECT_NULL(c->next());
INFO("PopFirst / Pop");
// [D, A, C]
- EXPECT(list.popFirst() == b);
- EXPECT(b->prev() == nullptr);
- EXPECT(b->next() == nullptr);
-
- EXPECT(list.first() == d);
- EXPECT(list.last() == c);
- EXPECT(d->prev() == nullptr);
- EXPECT(d->next() == a);
- EXPECT(a->prev() == d);
- EXPECT(a->next() == c);
- EXPECT(c->prev() == a);
- EXPECT(c->next() == nullptr);
+ EXPECT_EQ(list.popFirst(), b);
+ EXPECT_NULL(b->prev());
+ EXPECT_NULL(b->next());
+
+ EXPECT_EQ(list.first(), d);
+ EXPECT_EQ(list.last(), c);
+ EXPECT_NULL(d->prev());
+ EXPECT_EQ(d->next(), a);
+ EXPECT_EQ(a->prev(), d);
+ EXPECT_EQ(a->next(), c);
+ EXPECT_EQ(c->prev(), a);
+ EXPECT_NULL(c->next());
// [D, A]
- EXPECT(list.pop() == c);
- EXPECT(c->prev() == nullptr);
- EXPECT(c->next() == nullptr);
-
- EXPECT(list.first() == d);
- EXPECT(list.last() == a);
- EXPECT(d->prev() == nullptr);
- EXPECT(d->next() == a);
- EXPECT(a->prev() == d);
- EXPECT(a->next() == nullptr);
+ EXPECT_EQ(list.pop(), c);
+ EXPECT_NULL(c->prev());
+ EXPECT_NULL(c->next());
+
+ EXPECT_EQ(list.first(), d);
+ EXPECT_EQ(list.last(), a);
+ EXPECT_NULL(d->prev());
+ EXPECT_EQ(d->next(), a);
+ EXPECT_EQ(a->prev(), d);
+ EXPECT_NULL(a->next());
}
#endif
diff --git a/3rdparty/asmjit/src/asmjit/core/zonelist.h b/3rdparty/asmjit/src/asmjit/core/zonelist.h
index c5e00136589..8980240ef43 100644
--- a/3rdparty/asmjit/src/asmjit/core/zonelist.h
+++ b/3rdparty/asmjit/src/asmjit/core/zonelist.h
@@ -39,10 +39,10 @@ public:
//! \name Construction & Destruction
//! \{
- inline ZoneListNode() noexcept
+ ASMJIT_INLINE_NODEBUG ZoneListNode() noexcept
: _listNodes { nullptr, nullptr } {}
- inline ZoneListNode(ZoneListNode&& other) noexcept
+ ASMJIT_INLINE_NODEBUG ZoneListNode(ZoneListNode&& other) noexcept
: _listNodes { other._listNodes[0], other._listNodes[1] } {}
//! \}
@@ -50,11 +50,11 @@ public:
//! \name Accessors
//! \{
- inline bool hasPrev() const noexcept { return _listNodes[kNodeIndexPrev] != nullptr; }
- inline bool hasNext() const noexcept { return _listNodes[kNodeIndexNext] != nullptr; }
+ ASMJIT_INLINE_NODEBUG bool hasPrev() const noexcept { return _listNodes[kNodeIndexPrev] != nullptr; }
+ ASMJIT_INLINE_NODEBUG bool hasNext() const noexcept { return _listNodes[kNodeIndexNext] != nullptr; }
- inline NodeT* prev() const noexcept { return _listNodes[kNodeIndexPrev]; }
- inline NodeT* next() const noexcept { return _listNodes[kNodeIndexNext]; }
+ ASMJIT_INLINE_NODEBUG NodeT* prev() const noexcept { return _listNodes[kNodeIndexPrev]; }
+ ASMJIT_INLINE_NODEBUG NodeT* next() const noexcept { return _listNodes[kNodeIndexNext]; }
//! \}
};
@@ -78,20 +78,19 @@ public:
//! \name Members
//! \{
- NodeT* _nodes[2];
+ NodeT* _nodes[2] {};
//! \}
//! \name Construction & Destruction
//! \{
- inline ZoneList() noexcept
- : _nodes { nullptr, nullptr } {}
+ ASMJIT_INLINE_NODEBUG ZoneList() noexcept {}
- inline ZoneList(ZoneList&& other) noexcept
+ ASMJIT_INLINE_NODEBUG ZoneList(ZoneList&& other) noexcept
: _nodes { other._nodes[0], other._nodes[1] } {}
- inline void reset() noexcept {
+ ASMJIT_INLINE_NODEBUG void reset() noexcept {
_nodes[0] = nullptr;
_nodes[1] = nullptr;
}
@@ -101,16 +100,16 @@ public:
//! \name Accessors
//! \{
- inline bool empty() const noexcept { return _nodes[0] == nullptr; }
- inline NodeT* first() const noexcept { return _nodes[kNodeIndexFirst]; }
- inline NodeT* last() const noexcept { return _nodes[kNodeIndexLast]; }
+ ASMJIT_INLINE_NODEBUG bool empty() const noexcept { return _nodes[0] == nullptr; }
+ ASMJIT_INLINE_NODEBUG NodeT* first() const noexcept { return _nodes[kNodeIndexFirst]; }
+ ASMJIT_INLINE_NODEBUG NodeT* last() const noexcept { return _nodes[kNodeIndexLast]; }
//! \}
//! \name Utilities
//! \{
- inline void swap(ZoneList& other) noexcept {
+ ASMJIT_INLINE_NODEBUG void swap(ZoneList& other) noexcept {
std::swap(_nodes[0], other._nodes[0]);
std::swap(_nodes[1], other._nodes[1]);
}
@@ -144,11 +143,11 @@ public:
node->_listNodes[ dir] = next;
}
- inline void append(NodeT* node) noexcept { _addNode(node, kNodeIndexLast); }
- inline void prepend(NodeT* node) noexcept { _addNode(node, kNodeIndexFirst); }
+ ASMJIT_INLINE_NODEBUG void append(NodeT* node) noexcept { _addNode(node, kNodeIndexLast); }
+ ASMJIT_INLINE_NODEBUG void prepend(NodeT* node) noexcept { _addNode(node, kNodeIndexFirst); }
- 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); }
+ ASMJIT_INLINE_NODEBUG void insertAfter(NodeT* ref, NodeT* node) noexcept { _insertNode(ref, node, NodeT::kNodeIndexNext); }
+ ASMJIT_INLINE_NODEBUG 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/3rdparty/asmjit/src/asmjit/core/zonestack.cpp b/3rdparty/asmjit/src/asmjit/core/zonestack.cpp
index 77e6f202c7d..7d66670935b 100644
--- a/3rdparty/asmjit/src/asmjit/core/zonestack.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/zonestack.cpp
@@ -9,8 +9,8 @@
ASMJIT_BEGIN_NAMESPACE
-// ZoneStackBase - Init & Reset
-// ============================
+// ZoneStackBase - Initialization & Reset
+// ======================================
Error ZoneStackBase::_init(ZoneAllocator* allocator, size_t middleIndex) noexcept {
ZoneAllocator* oldAllocator = _allocator;
@@ -100,18 +100,24 @@ static void test_zone_stack(ZoneAllocator* allocator, const char* typeName) {
INFO("Testing ZoneStack<%s>", typeName);
INFO(" (%d items per one Block)", ZoneStack<T>::kNumBlockItems);
- EXPECT(stack.init(allocator) == kErrorOk);
- EXPECT(stack.empty(), "Stack must be empty after `init()`");
-
- EXPECT(stack.append(42) == kErrorOk);
- EXPECT(!stack.empty() , "Stack must not be empty after an item has been appended");
- EXPECT(stack.pop() == 42 , "Stack.pop() must return the item that has been appended last");
- EXPECT(stack.empty() , "Stack must be empty after the last item has been removed");
-
- EXPECT(stack.prepend(43) == kErrorOk);
- EXPECT(!stack.empty() , "Stack must not be empty after an item has been prepended");
- EXPECT(stack.popFirst() == 43, "Stack.popFirst() must return the item that has been prepended last");
- EXPECT(stack.empty() , "Stack must be empty after the last item has been removed");
+ EXPECT_EQ(stack.init(allocator), kErrorOk);
+ EXPECT_TRUE(stack.empty());
+
+ EXPECT_EQ(stack.append(42), kErrorOk);
+ EXPECT_FALSE(stack.empty())
+ .message("Stack must not be empty after an item has been appended");
+ EXPECT_EQ(stack.pop(), 42)
+ .message("Stack.pop() must return the item that has been appended last");
+ EXPECT_TRUE(stack.empty())
+ .message("Stack must be empty after the last item has been removed");
+
+ EXPECT_EQ(stack.prepend(43), kErrorOk);
+ EXPECT_FALSE(stack.empty())
+ .message("Stack must not be empty after an item has been prepended");
+ EXPECT_EQ(stack.popFirst(), 43)
+ .message("Stack.popFirst() must return the item that has been prepended last");
+ EXPECT_TRUE(stack.empty())
+ .message("Stack must be empty after the last item has been removed");
int i;
int iMin =-100000;
@@ -121,27 +127,31 @@ static void test_zone_stack(ZoneAllocator* allocator, const char* typeName) {
for (i = iMax; i >= 0; i--) stack.prepend(T(i));
for (i = 0; i <= iMax; i++) {
T item = stack.popFirst();
- EXPECT(i == item, "Item '%d' didn't match the item '%lld' popped", i, (long long)item);
+ EXPECT_EQ(i, item)
+ .message("Item '%d' didn't match the item '%lld' popped", i, (long long)item);
if (!stack.empty()) {
item = stack.popFirst();
- EXPECT(i + 1 == item, "Item '%d' didn't match the item '%lld' popped", i + 1, (long long)item);
+ EXPECT_EQ(i + 1, item)
+ .message("Item '%d' didn't match the item '%lld' popped", i + 1, (long long)item);
stack.prepend(item);
}
}
- EXPECT(stack.empty());
+ EXPECT_TRUE(stack.empty());
INFO("Validating append() & pop()");
for (i = 0; i <= iMax; i++) stack.append(T(i));
for (i = iMax; i >= 0; i--) {
T item = stack.pop();
- EXPECT(i == item, "Item '%d' didn't match the item '%lld' popped", i, (long long)item);
+ EXPECT_EQ(i, item)
+ .message("Item '%d' didn't match the item '%lld' popped", i, (long long)item);
if (!stack.empty()) {
item = stack.pop();
- EXPECT(i - 1 == item, "Item '%d' didn't match the item '%lld' popped", i - 1, (long long)item);
+ EXPECT_EQ(i - 1, item)
+ .message("Item '%d' didn't match the item '%lld' popped", i - 1, (long long)item);
stack.append(item);
}
}
- EXPECT(stack.empty());
+ EXPECT_TRUE(stack.empty());
INFO("Validating append()/prepend() & popFirst()");
for (i = 1; i <= iMax; i++) stack.append(T(i));
@@ -149,9 +159,9 @@ static void test_zone_stack(ZoneAllocator* allocator, const char* typeName) {
for (i = iMin; i <= iMax; i++) {
T item = stack.popFirst();
- EXPECT(i == item, "Item '%d' didn't match the item '%lld' popped", i, (long long)item);
+ EXPECT_EQ(i, item);
}
- EXPECT(stack.empty());
+ EXPECT_TRUE(stack.empty());
INFO("Validating append()/prepend() & pop()");
for (i = 0; i >= iMin; i--) stack.prepend(T(i));
@@ -159,9 +169,9 @@ static void test_zone_stack(ZoneAllocator* allocator, const char* typeName) {
for (i = iMax; i >= iMin; i--) {
T item = stack.pop();
- EXPECT(i == item, "Item '%d' didn't match the item '%lld' popped", i, (long long)item);
+ EXPECT_EQ(i, item);
}
- EXPECT(stack.empty());
+ EXPECT_TRUE(stack.empty());
}
UNIT(zone_stack) {
diff --git a/3rdparty/asmjit/src/asmjit/core/zonestack.h b/3rdparty/asmjit/src/asmjit/core/zonestack.h
index aea7b6868fa..16d5d09dbc1 100644
--- a/3rdparty/asmjit/src/asmjit/core/zonestack.h
+++ b/3rdparty/asmjit/src/asmjit/core/zonestack.h
@@ -44,31 +44,33 @@ public:
//! Pointer to the end of the array.
void* _end;
- inline bool empty() const noexcept { return _start == _end; }
- inline Block* prev() const noexcept { return _link[kBlockIndexPrev]; }
- inline Block* next() const noexcept { return _link[kBlockIndexNext]; }
+ ASMJIT_INLINE_NODEBUG bool empty() const noexcept { return _start == _end; }
+ ASMJIT_INLINE_NODEBUG Block* prev() const noexcept { return _link[kBlockIndexPrev]; }
+ ASMJIT_INLINE_NODEBUG Block* next() const noexcept { return _link[kBlockIndexNext]; }
- inline void setPrev(Block* block) noexcept { _link[kBlockIndexPrev] = block; }
- inline void setNext(Block* block) noexcept { _link[kBlockIndexNext] = block; }
+ ASMJIT_INLINE_NODEBUG void setPrev(Block* block) noexcept { _link[kBlockIndexPrev] = block; }
+ ASMJIT_INLINE_NODEBUG void setNext(Block* block) noexcept { _link[kBlockIndexNext] = block; }
template<typename T>
- inline T* start() const noexcept { return static_cast<T*>(_start); }
+ ASMJIT_INLINE_NODEBUG T* start() const noexcept { return static_cast<T*>(_start); }
template<typename T>
- inline void setStart(T* start) noexcept { _start = static_cast<void*>(start); }
+ ASMJIT_INLINE_NODEBUG void setStart(T* start) noexcept { _start = static_cast<void*>(start); }
template<typename T>
- inline T* end() const noexcept { return (T*)_end; }
+ ASMJIT_INLINE_NODEBUG T* end() const noexcept { return (T*)_end; }
template<typename T>
- inline void setEnd(T* end) noexcept { _end = (void*)end; }
+ ASMJIT_INLINE_NODEBUG void setEnd(T* end) noexcept { _end = (void*)end; }
template<typename T>
- inline T* data() const noexcept { return (T*)((uint8_t*)(this) + sizeof(Block)); }
+ ASMJIT_INLINE_NODEBUG const T* data() const noexcept { return (const T*)((const uint8_t*)(this) + sizeof(Block)); }
+ template<typename T>
+ ASMJIT_INLINE_NODEBUG T* data() noexcept { return (T*)((uint8_t*)(this) + sizeof(Block)); }
template<typename T>
- inline bool canPrepend() const noexcept { return _start > data<void>(); }
+ ASMJIT_INLINE_NODEBUG bool canPrepend() const noexcept { return _start > data<void>(); }
template<typename T>
- inline bool canAppend() const noexcept {
+ ASMJIT_INLINE_NODEBUG bool canAppend() const noexcept {
size_t kNumBlockItems = (kBlockSize - sizeof(Block)) / sizeof(T);
size_t kStartBlockIndex = sizeof(Block);
size_t kEndBlockIndex = kStartBlockIndex + kNumBlockItems * sizeof(T);
@@ -83,25 +85,21 @@ public:
//! \{
//! Allocator used to allocate data.
- ZoneAllocator* _allocator;
+ ZoneAllocator* _allocator {};
//! First and last blocks.
- Block* _block[2];
+ Block* _block[2] {};
//! \}
//! \name Construction & Destruction
//! \{
- inline ZoneStackBase() noexcept {
- _allocator = nullptr;
- _block[0] = nullptr;
- _block[1] = nullptr;
- }
- inline ~ZoneStackBase() noexcept { reset(); }
+ ASMJIT_INLINE_NODEBUG ZoneStackBase() noexcept {}
+ ASMJIT_INLINE_NODEBUG ~ZoneStackBase() noexcept { reset(); }
- inline bool isInitialized() const noexcept { return _allocator != nullptr; }
+ ASMJIT_INLINE_NODEBUG bool isInitialized() const noexcept { return _allocator != nullptr; }
ASMJIT_API Error _init(ZoneAllocator* allocator, size_t middleIndex) noexcept;
- inline Error reset() noexcept { return _init(nullptr, 0); }
+ ASMJIT_INLINE_NODEBUG Error reset() noexcept { return _init(nullptr, 0); }
//! \}
@@ -109,7 +107,7 @@ public:
//! \{
//! Returns `ZoneAllocator` attached to this container.
- inline ZoneAllocator* allocator() const noexcept { return _allocator; }
+ ASMJIT_INLINE_NODEBUG ZoneAllocator* allocator() const noexcept { return _allocator; }
inline bool empty() const noexcept {
ASMJIT_ASSERT(isInitialized());
diff --git a/3rdparty/asmjit/src/asmjit/core/zonestring.h b/3rdparty/asmjit/src/asmjit/core/zonestring.h
index 01f5bd89f6a..e62ac50f287 100644
--- a/3rdparty/asmjit/src/asmjit/core/zonestring.h
+++ b/3rdparty/asmjit/src/asmjit/core/zonestring.h
@@ -27,7 +27,7 @@ struct ZoneStringBase {
};
};
- inline void reset() noexcept {
+ ASMJIT_INLINE_NODEBUG void reset() noexcept {
_dummy = nullptr;
_external = nullptr;
}
@@ -83,8 +83,8 @@ public:
//! \name Construction & Destruction
//! \{
- inline ZoneString() noexcept { reset(); }
- inline void reset() noexcept { _base.reset(); }
+ ASMJIT_INLINE_NODEBUG ZoneString() noexcept { reset(); }
+ ASMJIT_INLINE_NODEBUG void reset() noexcept { _base.reset(); }
//! \}
@@ -92,21 +92,21 @@ public:
//! \{
//! Tests whether the string is empty.
- inline bool empty() const noexcept { return _base._size == 0; }
+ ASMJIT_INLINE_NODEBUG bool empty() const noexcept { return _base._size == 0; }
//! Returns the string data.
- inline const char* data() const noexcept { return _base._size <= kMaxEmbeddedSize ? _base._embedded : _base._external; }
+ ASMJIT_INLINE_NODEBUG const char* data() const noexcept { return _base._size <= kMaxEmbeddedSize ? _base._embedded : _base._external; }
//! Returns the string size.
- inline uint32_t size() const noexcept { return _base._size; }
+ ASMJIT_INLINE_NODEBUG uint32_t size() const noexcept { return _base._size; }
//! Tests whether the string is embedded (e.g. no dynamically allocated).
- inline bool isEmbedded() const noexcept { return _base._size <= kMaxEmbeddedSize; }
+ ASMJIT_INLINE_NODEBUG bool isEmbedded() const noexcept { return _base._size <= kMaxEmbeddedSize; }
//! 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.
- inline Error setData(Zone* zone, const char* data, size_t size) noexcept {
+ ASMJIT_INLINE_NODEBUG Error setData(Zone* zone, const char* data, size_t size) noexcept {
return _base.setData(zone, kMaxEmbeddedSize, data, size);
}
diff --git a/3rdparty/asmjit/src/asmjit/core/zonetree.cpp b/3rdparty/asmjit/src/asmjit/core/zonetree.cpp
index 8c42af8c02f..e8a0e111440 100644
--- a/3rdparty/asmjit/src/asmjit/core/zonetree.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/zonetree.cpp
@@ -19,7 +19,7 @@ struct ZoneRBUnit {
typedef ZoneTree<NodeT> Tree;
static void verifyTree(Tree& tree) noexcept {
- EXPECT(checkHeight(static_cast<NodeT*>(tree._root)) > 0);
+ EXPECT_GT(checkHeight(static_cast<NodeT*>(tree._root)), 0);
}
// Check whether the Red-Black tree is valid.
@@ -30,17 +30,16 @@ struct ZoneRBUnit {
NodeT* rn = node->right();
// Invalid tree.
- EXPECT(ln == nullptr || *ln < *node);
- EXPECT(rn == nullptr || *rn > *node);
+ EXPECT_TRUE(ln == nullptr || *ln < *node);
+ EXPECT_TRUE(rn == nullptr || *rn > *node);
// Red violation.
- EXPECT(!node->isRed() ||
- (!ZoneTreeNode::_isValidRed(ln) && !ZoneTreeNode::_isValidRed(rn)));
+ EXPECT_TRUE(!node->isRed() || (!ZoneTreeNode::_isValidRed(ln) && !ZoneTreeNode::_isValidRed(rn)));
// Black violation.
int lh = checkHeight(ln);
int rh = checkHeight(rn);
- EXPECT(!lh || !rh || lh == rh);
+ EXPECT_TRUE(!lh || !rh || lh == rh);
// Only count black links.
return (lh && rh) ? lh + !node->isRed() : 0;
@@ -83,8 +82,8 @@ UNIT(zone_rbtree) {
for (key = 0; key < count; key++) {
node = rbTree.get(key);
- EXPECT(node != nullptr);
- EXPECT(node->_key == key);
+ EXPECT_NOT_NULL(node);
+ EXPECT_EQ(node->_key, key);
}
node = rbTree.get(--count);
@@ -92,7 +91,7 @@ UNIT(zone_rbtree) {
ZoneRBUnit<MyRBNode>::verifyTree(rbTree);
} while (count);
- EXPECT(rbTree.empty());
+ EXPECT_TRUE(rbTree.empty());
}
#endif
diff --git a/3rdparty/asmjit/src/asmjit/core/zonetree.h b/3rdparty/asmjit/src/asmjit/core/zonetree.h
index c5dbc78f496..ffeb674cfe2 100644
--- a/3rdparty/asmjit/src/asmjit/core/zonetree.h
+++ b/3rdparty/asmjit/src/asmjit/core/zonetree.h
@@ -35,33 +35,32 @@ public:
//! \name Members
//! \{
- uintptr_t _rbNodeData[2];
+ uintptr_t _rbNodeData[2] {};
//! \}
//! \name Construction & Destruction
//! \{
- inline ZoneTreeNode() noexcept
- : _rbNodeData { 0, 0 } {}
+ ASMJIT_INLINE_NODEBUG ZoneTreeNode() noexcept {}
//! \}
//! \name Accessors
//! \{
- inline bool isRed() const noexcept { return static_cast<bool>(_rbNodeData[0] & kRedMask); }
+ ASMJIT_INLINE_NODEBUG bool isRed() const noexcept { return static_cast<bool>(_rbNodeData[0] & kRedMask); }
- inline bool hasChild(size_t i) const noexcept { return _rbNodeData[i] > kRedMask; }
- inline bool hasLeft() const noexcept { return _rbNodeData[0] > kRedMask; }
- inline bool hasRight() const noexcept { return _rbNodeData[1] != 0; }
+ ASMJIT_INLINE_NODEBUG bool hasChild(size_t i) const noexcept { return _rbNodeData[i] > kRedMask; }
+ ASMJIT_INLINE_NODEBUG bool hasLeft() const noexcept { return _rbNodeData[0] > kRedMask; }
+ ASMJIT_INLINE_NODEBUG bool hasRight() const noexcept { return _rbNodeData[1] != 0; }
template<typename T = ZoneTreeNode>
- inline T* child(size_t i) const noexcept { return static_cast<T*>(_getChild(i)); }
+ ASMJIT_INLINE_NODEBUG T* child(size_t i) const noexcept { return static_cast<T*>(_getChild(i)); }
template<typename T = ZoneTreeNode>
- inline T* left() const noexcept { return static_cast<T*>(_getLeft()); }
+ ASMJIT_INLINE_NODEBUG T* left() const noexcept { return static_cast<T*>(_getLeft()); }
template<typename T = ZoneTreeNode>
- inline T* right() const noexcept { return static_cast<T*>(_getRight()); }
+ ASMJIT_INLINE_NODEBUG T* right() const noexcept { return static_cast<T*>(_getRight()); }
//! \}
@@ -69,19 +68,19 @@ public:
//! \name Internal
//! \{
- inline ZoneTreeNode* _getChild(size_t i) const noexcept { return (ZoneTreeNode*)(_rbNodeData[i] & kPtrMask); }
- inline ZoneTreeNode* _getLeft() const noexcept { return (ZoneTreeNode*)(_rbNodeData[0] & kPtrMask); }
- inline ZoneTreeNode* _getRight() const noexcept { return (ZoneTreeNode*)(_rbNodeData[1]); }
+ ASMJIT_INLINE_NODEBUG ZoneTreeNode* _getChild(size_t i) const noexcept { return (ZoneTreeNode*)(_rbNodeData[i] & kPtrMask); }
+ ASMJIT_INLINE_NODEBUG ZoneTreeNode* _getLeft() const noexcept { return (ZoneTreeNode*)(_rbNodeData[0] & kPtrMask); }
+ ASMJIT_INLINE_NODEBUG ZoneTreeNode* _getRight() const noexcept { return (ZoneTreeNode*)(_rbNodeData[1]); }
- inline void _setChild(size_t i, ZoneTreeNode* node) noexcept { _rbNodeData[i] = (_rbNodeData[i] & kRedMask) | (uintptr_t)node; }
- inline void _setLeft(ZoneTreeNode* node) noexcept { _rbNodeData[0] = (_rbNodeData[0] & kRedMask) | (uintptr_t)node; }
- inline void _setRight(ZoneTreeNode* node) noexcept { _rbNodeData[1] = (uintptr_t)node; }
+ ASMJIT_INLINE_NODEBUG void _setChild(size_t i, ZoneTreeNode* node) noexcept { _rbNodeData[i] = (_rbNodeData[i] & kRedMask) | (uintptr_t)node; }
+ ASMJIT_INLINE_NODEBUG void _setLeft(ZoneTreeNode* node) noexcept { _rbNodeData[0] = (_rbNodeData[0] & kRedMask) | (uintptr_t)node; }
+ ASMJIT_INLINE_NODEBUG void _setRight(ZoneTreeNode* node) noexcept { _rbNodeData[1] = (uintptr_t)node; }
- inline void _makeRed() noexcept { _rbNodeData[0] |= kRedMask; }
- inline void _makeBlack() noexcept { _rbNodeData[0] &= kPtrMask; }
+ ASMJIT_INLINE_NODEBUG void _makeRed() noexcept { _rbNodeData[0] |= kRedMask; }
+ ASMJIT_INLINE_NODEBUG void _makeBlack() noexcept { _rbNodeData[0] &= kPtrMask; }
//! Tests whether the node is RED (RED node must be non-null and must have RED flag set).
- static inline bool _isValidRed(ZoneTreeNode* node) noexcept { return node && node->isRed(); }
+ static ASMJIT_INLINE_NODEBUG bool _isValidRed(ZoneTreeNode* node) noexcept { return node && node->isRed(); }
//! \}
//! \endcond
@@ -96,7 +95,7 @@ public:
//! \name Construction & Destruction
//! \{
- inline ZoneTreeNodeT() noexcept
+ ASMJIT_INLINE_NODEBUG ZoneTreeNodeT() noexcept
: ZoneTreeNode() {}
//! \}
@@ -104,9 +103,9 @@ public:
//! \name Accessors
//! \{
- inline NodeT* child(size_t i) const noexcept { return static_cast<NodeT*>(_getChild(i)); }
- inline NodeT* left() const noexcept { return static_cast<NodeT*>(_getLeft()); }
- inline NodeT* right() const noexcept { return static_cast<NodeT*>(_getRight()); }
+ ASMJIT_INLINE_NODEBUG NodeT* child(size_t i) const noexcept { return static_cast<NodeT*>(_getChild(i)); }
+ ASMJIT_INLINE_NODEBUG NodeT* left() const noexcept { return static_cast<NodeT*>(_getLeft()); }
+ ASMJIT_INLINE_NODEBUG NodeT* right() const noexcept { return static_cast<NodeT*>(_getRight()); }
//! \}
};
@@ -118,33 +117,30 @@ public:
ASMJIT_NONCOPYABLE(ZoneTree)
typedef NodeT Node;
- NodeT* _root;
+ NodeT* _root {};
//! \name Construction & Destruction
//! \{
- inline ZoneTree() noexcept
- : _root(nullptr) {}
-
- inline ZoneTree(ZoneTree&& other) noexcept
+ ASMJIT_INLINE_NODEBUG ZoneTree() noexcept {}
+ ASMJIT_INLINE_NODEBUG ZoneTree(ZoneTree&& other) noexcept
: _root(other._root) {}
-
- inline void reset() noexcept { _root = nullptr; }
+ ASMJIT_INLINE_NODEBUG void reset() noexcept { _root = nullptr; }
//! \}
//! \name Accessors
//! \{
- inline bool empty() const noexcept { return _root == nullptr; }
- inline NodeT* root() const noexcept { return static_cast<NodeT*>(_root); }
+ ASMJIT_INLINE_NODEBUG bool empty() const noexcept { return _root == nullptr; }
+ ASMJIT_INLINE_NODEBUG NodeT* root() const noexcept { return static_cast<NodeT*>(_root); }
//! \}
//! \name Utilities
//! \{
- inline void swap(ZoneTree& other) noexcept {
+ ASMJIT_INLINE_NODEBUG void swap(ZoneTree& other) noexcept {
std::swap(_root, other._root);
}
diff --git a/3rdparty/asmjit/src/asmjit/core/zonevector.cpp b/3rdparty/asmjit/src/asmjit/core/zonevector.cpp
index dfec5d5f795..b68e25abf65 100644
--- a/3rdparty/asmjit/src/asmjit/core/zonevector.cpp
+++ b/3rdparty/asmjit/src/asmjit/core/zonevector.cpp
@@ -13,8 +13,63 @@ ASMJIT_BEGIN_NAMESPACE
// ZoneVectorBase - Helpers
// ========================
+// ZoneVector is used as an array to hold short-lived data structures used during code generation. The growing
+// strategy is simple - use small capacity at the beginning (very good for ZoneAllocator) and then grow quicker
+// to prevent successive reallocations.
+static ASMJIT_FORCE_INLINE uint32_t ZoneVector_growCapacity(uint32_t current, uint32_t growMinimum, uint32_t sizeOfT) noexcept {
+ static constexpr size_t kGrowThreshold = Globals::kGrowThreshold;
+
+ size_t byteSize = size_t(current) * sizeOfT;
+ size_t minimumByteSize = size_t(growMinimum) * sizeOfT;
+
+ // This is more than exponential growth at the beginning.
+ if (byteSize < 32) {
+ byteSize = 32;
+ }
+ else if (byteSize < 128) {
+ byteSize = 128;
+ }
+ else if (byteSize < 512) {
+ byteSize = 512;
+ }
+
+ if (byteSize < minimumByteSize) {
+ // Exponential growth before we reach `kGrowThreshold`.
+ byteSize = Support::alignUpPowerOf2(minimumByteSize);
+
+ // Bail to `growMinimum` in case of overflow - most likely whatever that is happening afterwards would just fail.
+ if (byteSize < minimumByteSize) {
+ return growMinimum;
+ }
+
+ // Pretty much chunked growth advancing by `kGrowThreshold` after we exceed it.
+ // This should not be a common case, so we don't really have to optimize for it.
+ if (byteSize > kGrowThreshold) {
+ // Align to kGrowThreshold.
+ size_t remainder = minimumByteSize % kGrowThreshold;
+
+ byteSize = minimumByteSize + remainder;
+
+ // Bail to `growMinimum` in case of overflow - should never happen as it's unlikely we would hit this on a 32-bit
+ // machine (consecutive near 4GiB allocation is impossible, and this should never happen on 64-bit machine as we
+ // use 32-bit size & capacity, so overflow of 64 bit integer is not possible. Added just as an extreme measure.
+ if (byteSize < minimumByteSize)
+ return growMinimum;
+ }
+ }
+
+ size_t n = byteSize / sizeOfT;
+ return uint32_t(Support::min<size_t>(n, 0xFFFFFFFFu));
+}
+
+static ASMJIT_FORCE_INLINE bool ZoneVector_byteSizeIsSafe(size_t nBytes, uint32_t n) noexcept {
+ if (sizeof(uint32_t) < sizeof(size_t))
+ return true; // there is no problem when running on a 64-bit machine.
+ else
+ return nBytes >= size_t(n);
+};
+
Error ZoneVectorBase::_grow(ZoneAllocator* allocator, uint32_t sizeOfT, uint32_t n) noexcept {
- uint32_t threshold = Globals::kGrowThreshold / sizeOfT;
uint32_t capacity = _capacity;
uint32_t after = _size;
@@ -25,37 +80,16 @@ Error ZoneVectorBase::_grow(ZoneAllocator* allocator, uint32_t sizeOfT, uint32_t
if (capacity >= after)
return kErrorOk;
- // ZoneVector is used as an array to hold short-lived data structures used
- // during code generation. The growing strategy is simple - use small capacity
- // at the beginning (very good for ZoneAllocator) and then grow quicker to
- // prevent successive reallocations.
- if (capacity < 4)
- capacity = 4;
- else if (capacity < 8)
- capacity = 8;
- else if (capacity < 16)
- capacity = 16;
- else if (capacity < 64)
- capacity = 64;
- else if (capacity < 256)
- capacity = 256;
-
- while (capacity < after) {
- if (capacity < threshold)
- capacity *= 2;
- else
- capacity += threshold;
- }
-
- return _reserve(allocator, sizeOfT, capacity);
+ return _reserve(allocator, sizeOfT, ZoneVector_growCapacity(capacity, after, sizeOfT));
}
Error ZoneVectorBase::_reserve(ZoneAllocator* allocator, uint32_t sizeOfT, uint32_t n) noexcept {
uint32_t oldCapacity = _capacity;
- if (oldCapacity >= n) return kErrorOk;
+ if (oldCapacity >= n)
+ return kErrorOk;
- uint32_t nBytes = n * sizeOfT;
- if (ASMJIT_UNLIKELY(nBytes < n))
+ size_t nBytes = size_t(n) * sizeOfT;
+ if (ASMJIT_UNLIKELY(!ZoneVector_byteSizeIsSafe(nBytes, n)))
return DebugUtils::errored(kErrorOutOfMemory);
size_t allocatedBytes;
@@ -64,20 +98,28 @@ Error ZoneVectorBase::_reserve(ZoneAllocator* allocator, uint32_t sizeOfT, uint3
if (ASMJIT_UNLIKELY(!newData))
return DebugUtils::errored(kErrorOutOfMemory);
+ uint32_t newCapacity = uint32_t(allocatedBytes / sizeOfT);
+ ASMJIT_ASSERT(newCapacity >= n);
+
void* oldData = _data;
- if (_size)
+ if (oldData && _size) {
memcpy(newData, oldData, size_t(_size) * sizeOfT);
-
- if (oldData)
allocator->release(oldData, size_t(oldCapacity) * sizeOfT);
-
- _capacity = uint32_t(allocatedBytes / sizeOfT);
- ASMJIT_ASSERT(_capacity >= n);
+ }
_data = newData;
+ _capacity = newCapacity;
+
return kErrorOk;
}
+Error ZoneVectorBase::_growingReserve(ZoneAllocator* allocator, uint32_t sizeOfT, uint32_t n) noexcept {
+ uint32_t capacity = _capacity;
+ if (capacity >= n)
+ return kErrorOk;
+ return _reserve(allocator, sizeOfT, ZoneVector_growCapacity(capacity, n, sizeOfT));
+}
+
Error ZoneVectorBase::_resize(ZoneAllocator* allocator, uint32_t sizeOfT, uint32_t n) noexcept {
uint32_t size = _size;
@@ -266,34 +308,59 @@ Error ZoneBitVector::_append(ZoneAllocator* allocator, bool value) noexcept {
#if defined(ASMJIT_TEST)
template<typename T>
static void test_zone_vector(ZoneAllocator* allocator, const char* typeName) {
+ constexpr uint32_t kMiB = 1024 * 1024;
+
int i;
int kMax = 100000;
ZoneVector<T> vec;
INFO("ZoneVector<%s> basic tests", typeName);
- EXPECT(vec.append(allocator, 0) == kErrorOk);
- EXPECT(vec.empty() == false);
- EXPECT(vec.size() == 1);
- EXPECT(vec.capacity() >= 1);
- EXPECT(vec.indexOf(0) == 0);
- EXPECT(vec.indexOf(-11) == Globals::kNotFound);
+ EXPECT_EQ(vec.append(allocator, 0), kErrorOk);
+ EXPECT_FALSE(vec.empty());
+ EXPECT_EQ(vec.size(), 1u);
+ EXPECT_GE(vec.capacity(), 1u);
+ EXPECT_EQ(vec.indexOf(0), 0u);
+ EXPECT_EQ(vec.indexOf(-11), Globals::kNotFound);
vec.clear();
- EXPECT(vec.empty());
- EXPECT(vec.size() == 0);
- EXPECT(vec.indexOf(0) == Globals::kNotFound);
+ EXPECT_TRUE(vec.empty());
+ EXPECT_EQ(vec.size(), 0u);
+ EXPECT_EQ(vec.indexOf(0), Globals::kNotFound);
for (i = 0; i < kMax; i++) {
- EXPECT(vec.append(allocator, T(i)) == kErrorOk);
+ EXPECT_EQ(vec.append(allocator, T(i)), kErrorOk);
}
- EXPECT(vec.empty() == false);
- EXPECT(vec.size() == uint32_t(kMax));
- EXPECT(vec.indexOf(T(kMax - 1)) == uint32_t(kMax - 1));
+ EXPECT_FALSE(vec.empty());
+ EXPECT_EQ(vec.size(), uint32_t(kMax));
+ EXPECT_EQ(vec.indexOf(T(0)), uint32_t(0));
+ EXPECT_EQ(vec.indexOf(T(kMax - 1)), uint32_t(kMax - 1));
+
+ EXPECT_EQ(vec.begin()[0], 0);
+ EXPECT_EQ(vec.end()[-1], kMax - 1);
+
+ EXPECT_EQ(vec.rbegin()[0], kMax - 1);
+ EXPECT_EQ(vec.rend()[-1], 0);
- EXPECT(vec.rbegin()[0] == kMax - 1);
+ int64_t fsum = 0;
+ int64_t rsum = 0;
+
+ for (const T& item : vec) {
+ fsum += item;
+ }
+ for (auto it = vec.rbegin(); it != vec.rend(); ++it) {
+ rsum += *it;
+ }
+
+ EXPECT_EQ(fsum, rsum);
vec.release(allocator);
+
+ INFO("ZoneBitVector::growingReserve()");
+ for (uint32_t j = 0; j < 40 / sizeof(T); j += 8) {
+ EXPECT_EQ(vec.growingReserve(allocator, j * kMiB), kErrorOk);
+ EXPECT_GE(vec.capacity(), j * kMiB);
+ }
}
static void test_zone_bitvector(ZoneAllocator* allocator) {
@@ -303,31 +370,31 @@ static void test_zone_bitvector(ZoneAllocator* allocator) {
uint32_t kMaxCount = 100;
ZoneBitVector vec;
- EXPECT(vec.empty());
- EXPECT(vec.size() == 0);
+ EXPECT_TRUE(vec.empty());
+ EXPECT_EQ(vec.size(), 0u);
INFO("ZoneBitVector::resize()");
for (count = 1; count < kMaxCount; count++) {
vec.clear();
- EXPECT(vec.resize(allocator, count, false) == kErrorOk);
- EXPECT(vec.size() == count);
+ EXPECT_EQ(vec.resize(allocator, count, false), kErrorOk);
+ EXPECT_EQ(vec.size(), count);
for (i = 0; i < count; i++)
- EXPECT(vec.bitAt(i) == false);
+ EXPECT_FALSE(vec.bitAt(i));
vec.clear();
- EXPECT(vec.resize(allocator, count, true) == kErrorOk);
- EXPECT(vec.size() == count);
+ EXPECT_EQ(vec.resize(allocator, count, true), kErrorOk);
+ EXPECT_EQ(vec.size(), count);
for (i = 0; i < count; i++)
- EXPECT(vec.bitAt(i) == true);
+ EXPECT_TRUE(vec.bitAt(i));
}
INFO("ZoneBitVector::fillBits() / clearBits()");
for (count = 1; count < kMaxCount; count += 2) {
vec.clear();
- EXPECT(vec.resize(allocator, count) == kErrorOk);
- EXPECT(vec.size() == count);
+ EXPECT_EQ(vec.resize(allocator, count), kErrorOk);
+ EXPECT_EQ(vec.size(), count);
for (i = 0; i < (count + 1) / 2; i++) {
bool value = bool(i & 1);
@@ -338,7 +405,7 @@ static void test_zone_bitvector(ZoneAllocator* allocator) {
}
for (i = 0; i < count; i++) {
- EXPECT(vec.bitAt(i) == bool(i & 1));
+ EXPECT_EQ(vec.bitAt(i), bool(i & 1));
}
}
}
diff --git a/3rdparty/asmjit/src/asmjit/core/zonevector.h b/3rdparty/asmjit/src/asmjit/core/zonevector.h
index 447c08cb921..f38dca583a0 100644
--- a/3rdparty/asmjit/src/asmjit/core/zonevector.h
+++ b/3rdparty/asmjit/src/asmjit/core/zonevector.h
@@ -58,6 +58,7 @@ protected:
ASMJIT_API Error _grow(ZoneAllocator* allocator, uint32_t sizeOfT, uint32_t n) noexcept;
ASMJIT_API Error _resize(ZoneAllocator* allocator, uint32_t sizeOfT, uint32_t n) noexcept;
ASMJIT_API Error _reserve(ZoneAllocator* allocator, uint32_t sizeOfT, uint32_t n) noexcept;
+ ASMJIT_API Error _growingReserve(ZoneAllocator* allocator, uint32_t sizeOfT, uint32_t n) noexcept;
inline void _swap(ZoneVectorBase& other) noexcept {
std::swap(_data, other._data);
@@ -73,11 +74,11 @@ public:
//! \{
//! Tests whether the vector is empty.
- inline bool empty() const noexcept { return _size == 0; }
+ ASMJIT_INLINE_NODEBUG bool empty() const noexcept { return _size == 0; }
//! Returns the vector size.
- inline size_type size() const noexcept { return _size; }
+ ASMJIT_INLINE_NODEBUG size_type size() const noexcept { return _size; }
//! Returns the vector capacity.
- inline size_type capacity() const noexcept { return _capacity; }
+ ASMJIT_INLINE_NODEBUG size_type capacity() const noexcept { return _capacity; }
//! \}
@@ -85,16 +86,16 @@ public:
//! \{
//! Makes the vector empty (won't change the capacity or data pointer).
- inline void clear() noexcept { _size = 0; }
+ ASMJIT_INLINE_NODEBUG void clear() noexcept { _size = 0; }
//! Resets the vector data and set its `size` to zero.
- inline void reset() noexcept {
+ ASMJIT_INLINE_NODEBUG void reset() noexcept {
_data = nullptr;
_size = 0;
_capacity = 0;
}
//! Truncates the vector to at most `n` items.
- inline void truncate(size_type n) noexcept {
+ ASMJIT_INLINE_NODEBUG void truncate(size_type n) noexcept {
_size = Support::min(_size, n);
}
@@ -128,14 +129,14 @@ public:
typedef T* iterator;
typedef const T* const_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef Support::ArrayReverseIterator<T> reverse_iterator;
+ typedef Support::ArrayReverseIterator<const T> const_reverse_iterator;
//! \name Construction & Destruction
//! \{
- inline ZoneVector() noexcept : ZoneVectorBase() {}
- inline ZoneVector(ZoneVector&& other) noexcept : ZoneVector(other) {}
+ ASMJIT_INLINE_NODEBUG ZoneVector() noexcept : ZoneVectorBase() {}
+ ASMJIT_INLINE_NODEBUG ZoneVector(ZoneVector&& other) noexcept : ZoneVector(other) {}
//! \}
@@ -143,9 +144,9 @@ public:
//! \{
//! Returns vector data.
- inline T* data() noexcept { return static_cast<T*>(_data); }
+ ASMJIT_INLINE_NODEBUG T* data() noexcept { return static_cast<T*>(_data); }
//! Returns vector data (const)
- inline const T* data() const noexcept { return static_cast<const T*>(_data); }
+ ASMJIT_INLINE_NODEBUG const T* data() const noexcept { return static_cast<const T*>(_data); }
//! Returns item at the given index `i` (const).
inline const T& at(size_t i) const noexcept {
@@ -163,23 +164,23 @@ public:
//! \name STL Compatibility (Iterators)
//! \{
- inline iterator begin() noexcept { return iterator(data()); };
- inline const_iterator begin() const noexcept { return const_iterator(data()); };
+ ASMJIT_INLINE_NODEBUG iterator begin() noexcept { return iterator(data()); };
+ ASMJIT_INLINE_NODEBUG const_iterator begin() const noexcept { return const_iterator(data()); };
- inline iterator end() noexcept { return iterator(data() + _size); };
- inline const_iterator end() const noexcept { return const_iterator(data() + _size); };
+ ASMJIT_INLINE_NODEBUG iterator end() noexcept { return iterator(data() + _size); };
+ ASMJIT_INLINE_NODEBUG const_iterator end() const noexcept { return const_iterator(data() + _size); };
- inline reverse_iterator rbegin() noexcept { return reverse_iterator(end()); };
- inline const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); };
+ ASMJIT_INLINE_NODEBUG reverse_iterator rbegin() noexcept { return reverse_iterator(end()); };
+ ASMJIT_INLINE_NODEBUG const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); };
- inline reverse_iterator rend() noexcept { return reverse_iterator(begin()); };
- inline const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); };
+ ASMJIT_INLINE_NODEBUG reverse_iterator rend() noexcept { return reverse_iterator(begin()); };
+ ASMJIT_INLINE_NODEBUG const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); };
- inline const_iterator cbegin() const noexcept { return const_iterator(data()); };
- inline const_iterator cend() const noexcept { return const_iterator(data() + _size); };
+ ASMJIT_INLINE_NODEBUG const_iterator cbegin() const noexcept { return const_iterator(data()); };
+ ASMJIT_INLINE_NODEBUG const_iterator cend() const noexcept { return const_iterator(data() + _size); };
- inline const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); };
- inline const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); };
+ ASMJIT_INLINE_NODEBUG const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); };
+ ASMJIT_INLINE_NODEBUG const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); };
//! \}
@@ -194,8 +195,13 @@ public:
if (ASMJIT_UNLIKELY(_size == _capacity))
ASMJIT_PROPAGATE(grow(allocator, 1));
- ::memmove(static_cast<T*>(_data) + 1, _data, size_t(_size) * sizeof(T));
- memcpy(_data, &item, sizeof(T));
+ memmove(static_cast<void*>(static_cast<T*>(_data) + 1),
+ static_cast<const void*>(_data),
+ size_t(_size) * sizeof(T));
+
+ memcpy(static_cast<void*>(_data),
+ static_cast<const void*>(&item),
+ sizeof(T));
_size++;
return kErrorOk;
@@ -209,10 +215,15 @@ public:
ASMJIT_PROPAGATE(grow(allocator, 1));
T* dst = static_cast<T*>(_data) + index;
- ::memmove(dst + 1, dst, size_t(_size - index) * sizeof(T));
- memcpy(dst, &item, sizeof(T));
- _size++;
+ memmove(static_cast<void*>(dst + 1),
+ static_cast<const void*>(dst),
+ size_t(_size - index) * sizeof(T));
+
+ memcpy(static_cast<void*>(dst),
+ static_cast<const void*>(&item),
+ sizeof(T));
+ _size++;
return kErrorOk;
}
@@ -221,9 +232,11 @@ public:
if (ASMJIT_UNLIKELY(_size == _capacity))
ASMJIT_PROPAGATE(grow(allocator, 1));
- memcpy(static_cast<T*>(_data) + _size, &item, sizeof(T));
- _size++;
+ memcpy(static_cast<void*>(static_cast<T*>(_data) + _size),
+ static_cast<const void*>(&item),
+ sizeof(T));
+ _size++;
return kErrorOk;
}
@@ -234,7 +247,9 @@ public:
ASMJIT_PROPAGATE(grow(allocator, size));
if (size) {
- memcpy(static_cast<T*>(_data) + _size, other._data, size_t(size) * sizeof(T));
+ memcpy(static_cast<void*>(static_cast<T*>(_data) + _size),
+ static_cast<const void*>(other._data),
+ size_t(size) * sizeof(T));
_size += size;
}
@@ -249,10 +264,15 @@ public:
ASMJIT_ASSERT(_size < _capacity);
T* data = static_cast<T*>(_data);
- if (_size)
- ::memmove(data + 1, data, size_t(_size) * sizeof(T));
+ if (_size) {
+ memmove(static_cast<void*>(data + 1),
+ static_cast<const void*>(data),
+ size_t(_size) * sizeof(T));
+ }
- memcpy(data, &item, sizeof(T));
+ memcpy(static_cast<void*>(data),
+ static_cast<const void*>(&item),
+ sizeof(T));
_size++;
}
@@ -263,7 +283,9 @@ public:
ASMJIT_FORCE_INLINE void appendUnsafe(const T& item) noexcept {
ASMJIT_ASSERT(_size < _capacity);
- memcpy(static_cast<T*>(_data) + _size, &item, sizeof(T));
+ memcpy(static_cast<void*>(static_cast<T*>(_data) + _size),
+ static_cast<const void*>(&item),
+ sizeof(T));
_size++;
}
@@ -273,17 +295,26 @@ public:
ASMJIT_ASSERT(index <= _size);
T* dst = static_cast<T*>(_data) + index;
- ::memmove(dst + 1, dst, size_t(_size - index) * sizeof(T));
- memcpy(dst, &item, sizeof(T));
+ memmove(static_cast<void*>(dst + 1),
+ static_cast<const void*>(dst),
+ size_t(_size - index) * sizeof(T));
+
+ memcpy(static_cast<void*>(dst),
+ static_cast<const void*>(&item),
+ sizeof(T));
+
_size++;
}
+
//! Concatenates all items of `other` at the end of the vector.
ASMJIT_FORCE_INLINE void concatUnsafe(const ZoneVector<T>& other) noexcept {
uint32_t size = other._size;
ASMJIT_ASSERT(_capacity - _size >= size);
if (size) {
- memcpy(static_cast<T*>(_data) + _size, other._data, size_t(size) * sizeof(T));
+ memcpy(static_cast<void*>(static_cast<T*>(_data) + _size),
+ static_cast<const void*>(other._data),
+ size_t(size) * sizeof(T));
_size += size;
}
}
@@ -311,8 +342,11 @@ public:
T* data = static_cast<T*>(_data) + i;
size_t size = --_size - i;
- if (size)
- ::memmove(data, data + 1, size_t(size) * sizeof(T));
+ if (size) {
+ memmove(static_cast<void*>(data),
+ static_cast<const void*>(data + 1),
+ size_t(size) * sizeof(T));
+ }
}
//! Pops the last element from the vector and returns it.
@@ -344,9 +378,9 @@ public:
//!
//! \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); }
+ ASMJIT_INLINE_NODEBUG T& first() noexcept { return operator[](0); }
//! \overload
- inline const T& first() const noexcept { return operator[](0); }
+ ASMJIT_INLINE_NODEBUG const T& first() const noexcept { return operator[](0); }
//! Returns a reference to the last element of the vector.
//!
@@ -381,7 +415,21 @@ public:
//! Reallocates the internal array to fit at least `n` items.
inline Error reserve(ZoneAllocator* allocator, uint32_t n) noexcept {
- return n > _capacity ? ZoneVectorBase::_reserve(allocator, sizeof(T), n) : Error(kErrorOk);
+ if (ASMJIT_UNLIKELY(n > _capacity))
+ return ZoneVectorBase::_reserve(allocator, sizeof(T), n);
+ else
+ return Error(kErrorOk);
+ }
+
+ //! Reallocates the internal array to fit at least `n` items with growing semantics.
+ //!
+ //! If the vector is smaller than `n` the same growing calculations will be used as if N items were appended
+ //! to an empty vector, which means reserving additional space for more append operations that could follow.
+ inline Error growingReserve(ZoneAllocator* allocator, uint32_t n) noexcept {
+ if (ASMJIT_UNLIKELY(n > _capacity))
+ return ZoneVectorBase::_growingReserve(allocator, sizeof(T), n);
+ else
+ return Error(kErrorOk);
}
inline Error willGrow(ZoneAllocator* allocator, uint32_t n = 1) noexcept {
@@ -423,21 +471,21 @@ public:
//! \name Internal
//! \{
- static inline uint32_t _wordsPerBits(uint32_t nBits) noexcept {
+ static ASMJIT_INLINE_NODEBUG uint32_t _wordsPerBits(uint32_t nBits) noexcept {
return ((nBits + kBitWordSizeInBits - 1) / kBitWordSizeInBits);
}
- static inline void _zeroBits(BitWord* dst, uint32_t nBitWords) noexcept {
+ static ASMJIT_INLINE_NODEBUG void _zeroBits(BitWord* dst, uint32_t nBitWords) noexcept {
for (uint32_t i = 0; i < nBitWords; i++)
dst[i] = 0;
}
- static inline void _fillBits(BitWord* dst, uint32_t nBitWords) noexcept {
+ static ASMJIT_INLINE_NODEBUG void _fillBits(BitWord* dst, uint32_t nBitWords) noexcept {
for (uint32_t i = 0; i < nBitWords; i++)
dst[i] = ~BitWord(0);
}
- static inline void _copyBits(BitWord* dst, const BitWord* src, uint32_t nBitWords) noexcept {
+ static ASMJIT_INLINE_NODEBUG void _copyBits(BitWord* dst, const BitWord* src, uint32_t nBitWords) noexcept {
for (uint32_t i = 0; i < nBitWords; i++)
dst[i] = src[i];
}
@@ -448,9 +496,9 @@ public:
//! \name Construction & Destruction
//! \{
- inline ZoneBitVector() noexcept {}
+ ASMJIT_INLINE_NODEBUG ZoneBitVector() noexcept {}
- inline ZoneBitVector(ZoneBitVector&& other) noexcept
+ ASMJIT_INLINE_NODEBUG ZoneBitVector(ZoneBitVector&& other) noexcept
: _data(other._data),
_size(other._size),
_capacity(other._capacity) {}
@@ -460,8 +508,8 @@ public:
//! \name Overloaded Operators
//! \{
- inline bool operator==(const ZoneBitVector& other) const noexcept { return eq(other); }
- inline bool operator!=(const ZoneBitVector& other) const noexcept { return !eq(other); }
+ ASMJIT_INLINE_NODEBUG bool operator==(const ZoneBitVector& other) const noexcept { return equals(other); }
+ ASMJIT_INLINE_NODEBUG bool operator!=(const ZoneBitVector& other) const noexcept { return !equals(other); }
//! \}
@@ -469,44 +517,44 @@ public:
//! \{
//! Tests whether the bit-vector is empty (has no bits).
- inline bool empty() const noexcept { return _size == 0; }
+ ASMJIT_INLINE_NODEBUG bool empty() const noexcept { return _size == 0; }
//! Returns the size of this bit-vector (in bits).
- inline uint32_t size() const noexcept { return _size; }
+ ASMJIT_INLINE_NODEBUG uint32_t size() const noexcept { return _size; }
//! Returns the capacity of this bit-vector (in bits).
- inline uint32_t capacity() const noexcept { return _capacity; }
+ ASMJIT_INLINE_NODEBUG uint32_t capacity() const noexcept { return _capacity; }
//! Returns the size of the `BitWord[]` array in `BitWord` units.
- inline uint32_t sizeInBitWords() const noexcept { return _wordsPerBits(_size); }
+ ASMJIT_INLINE_NODEBUG uint32_t sizeInBitWords() const noexcept { return _wordsPerBits(_size); }
//! Returns the capacity of the `BitWord[]` array in `BitWord` units.
- inline uint32_t capacityInBitWords() const noexcept { return _wordsPerBits(_capacity); }
+ ASMJIT_INLINE_NODEBUG uint32_t capacityInBitWords() const noexcept { return _wordsPerBits(_capacity); }
- //! REturns bit-vector data as `BitWord[]`.
- inline BitWord* data() noexcept { return _data; }
+ //! Returns bit-vector data as `BitWord[]`.
+ ASMJIT_INLINE_NODEBUG BitWord* data() noexcept { return _data; }
//! \overload
- inline const BitWord* data() const noexcept { return _data; }
+ ASMJIT_INLINE_NODEBUG const BitWord* data() const noexcept { return _data; }
//! \}
//! \name Utilities
//! \{
- inline void swap(ZoneBitVector& other) noexcept {
+ ASMJIT_INLINE_NODEBUG void swap(ZoneBitVector& other) noexcept {
std::swap(_data, other._data);
std::swap(_size, other._size);
std::swap(_capacity, other._capacity);
}
- inline void clear() noexcept {
+ ASMJIT_INLINE_NODEBUG void clear() noexcept {
_size = 0;
}
- inline void reset() noexcept {
+ ASMJIT_INLINE_NODEBUG void reset() noexcept {
_data = nullptr;
_size = 0;
_capacity = 0;
}
- inline void truncate(uint32_t newSize) noexcept {
+ ASMJIT_INLINE_NODEBUG void truncate(uint32_t newSize) noexcept {
_size = Support::min(_size, newSize);
_clearUnusedBits();
}
@@ -628,7 +676,7 @@ public:
_data[idx] &= (BitWord(1) << bit) - 1u;
}
- ASMJIT_FORCE_INLINE bool eq(const ZoneBitVector& other) const noexcept {
+ ASMJIT_FORCE_INLINE bool equals(const ZoneBitVector& other) const noexcept {
if (_size != other._size)
return false;
@@ -642,18 +690,24 @@ public:
return true;
}
+#if !defined(ASMJIT_NO_DEPRECATED)
+ ASMJIT_DEPRECATED("Use ZoneVector::equals() instead")
+ ASMJIT_FORCE_INLINE bool eq(const ZoneBitVector& other) const noexcept { return equals(other); }
+#endif // !ASMJIT_NO_DEPRECATED
+
//! \}
//! \name Memory Management
//! \{
inline void release(ZoneAllocator* allocator) noexcept {
- if (!_data) return;
+ if (!_data)
+ return;
allocator->release(_data, _capacity / 8);
reset();
}
- inline Error resize(ZoneAllocator* allocator, uint32_t newSize, bool newBitsValue = false) noexcept {
+ ASMJIT_INLINE_NODEBUG Error resize(ZoneAllocator* allocator, uint32_t newSize, bool newBitsValue = false) noexcept {
return _resize(allocator, newSize, newSize, newBitsValue);
}
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86assembler.cpp b/3rdparty/asmjit/src/asmjit/x86/x86assembler.cpp
index f11fea00238..35c5502cc66 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86assembler.cpp
+++ b/3rdparty/asmjit/src/asmjit/x86/x86assembler.cpp
@@ -345,6 +345,10 @@ static ASMJIT_FORCE_INLINE uint32_t x86AltOpcodeOf(const InstDB::InstInfo* info)
return InstDB::_altOpcodeTable[info->_altOpcodeIndex];
}
+static ASMJIT_FORCE_INLINE bool x86IsMmxOrXmm(const Reg& reg) noexcept {
+ return reg.type() == RegType::kX86_Mm || reg.type() == RegType::kX86_Xmm;
+}
+
// x86::Assembler - X86BufferWriter
// ================================
@@ -493,11 +497,11 @@ static ASMJIT_FORCE_INLINE uint32_t x86GetMovAbsInstSize64Bit(uint32_t regSize,
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 !Support::test(options, InstOptions::kX86_ModMR | InstOptions::kX86_ModMR);
+ return !Support::test(options, InstOptions::kX86_ModMR | InstOptions::kX86_ModRM);
}
else {
// If the addressing type is REL or MOD R/M was specified then absolute mov won't be used.
- if (rmRel.addrType() == Mem::AddrType::kRel || Support::test(options, InstOptions::kX86_ModMR))
+ if (rmRel.addrType() == Mem::AddrType::kRel || Support::test(options, InstOptions::kX86_ModMR | InstOptions::kX86_ModRM))
return false;
int64_t addrValue = rmRel.offset();
@@ -529,8 +533,6 @@ static ASMJIT_FORCE_INLINE bool x86ShouldUseMovabs(Assembler* self, X86BufferWri
Assembler::Assembler(CodeHolder* code) noexcept : BaseAssembler() {
_archMask = (uint64_t(1) << uint32_t(Arch::kX86)) |
(uint64_t(1) << uint32_t(Arch::kX64)) ;
- assignEmitterFuncs(this);
-
if (code)
code->attach(this);
}
@@ -560,7 +562,7 @@ ASMJIT_FAVOR_SPEED Error Assembler::_emit(InstId instId, const Operand_& o0, con
const Operand_* rmRel; // Memory operand or operand that holds Label|Imm.
uint32_t rmInfo; // Memory operand's info based on x86MemInfo.
- uint32_t rbReg; // Memory base or modRM register.
+ uint32_t rbReg = 0; // Memory base or modRM register.
uint32_t rxReg; // Memory index register.
uint32_t opReg; // ModR/M opcode or register id.
@@ -610,7 +612,7 @@ ASMJIT_FAVOR_SPEED Error Assembler::_emit(InstId instId, const Operand_& o0, con
Operand_ opArray[Globals::kMaxOpCount];
EmitterUtils::opArrayFromEmitArgs(opArray, o0, o1, o2, opExt);
- err = _funcs.validate(arch(), BaseInst(instId, options, _extraReg), opArray, Globals::kMaxOpCount, ValidationFlags::kNone);
+ err = _funcs.validate(BaseInst(instId, options, _extraReg), opArray, Globals::kMaxOpCount, ValidationFlags::kNone);
if (ASMJIT_UNLIKELY(err))
goto Failed;
}
@@ -653,7 +655,6 @@ ASMJIT_FAVOR_SPEED Error Assembler::_emit(InstId instId, const Operand_& o0, con
// This sequence seems to be the fastest.
opcode = InstDB::_mainOpcodeTable[instInfo->_mainOpcodeIndex];
opReg = opcode.extractModO();
- rbReg = 0;
opcode |= instInfo->_mainOpcodeValue;
// Encoding Scope
@@ -740,11 +741,11 @@ ASMJIT_FAVOR_SPEED Error Assembler::_emit(InstId instId, const Operand_& o0, con
case InstDB::kEncodingX86M_NoMemSize:
if (o0.isReg())
- opcode.addPrefixBySize(o0.size());
+ opcode.addPrefixBySize(o0.x86RmSize());
goto CaseX86M_NoSize;
case InstDB::kEncodingX86M:
- opcode.addPrefixBySize(o0.size());
+ opcode.addPrefixBySize(o0.x86RmSize());
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingX86M_NoSize:
@@ -783,20 +784,20 @@ CaseX86M_GPB_MulDiv:
// [?DX:?AX] <- [?DX:?AX] div|mul r16|r32|r64
if (isign3 == ENC_OPS3(Reg, Reg, Reg)) {
- if (ASMJIT_UNLIKELY(o0.size() != o1.size()))
+ if (ASMJIT_UNLIKELY(o0.x86RmSize() != o1.x86RmSize()))
goto InvalidInstruction;
- opcode.addArithBySize(o0.size());
+ opcode.addArithBySize(o0.x86RmSize());
rbReg = o2.id();
goto EmitX86R;
}
// [?DX:?AX] <- [?DX:?AX] div|mul m16|m32|m64
if (isign3 == ENC_OPS3(Reg, Reg, Mem)) {
- if (ASMJIT_UNLIKELY(o0.size() != o1.size()))
+ if (ASMJIT_UNLIKELY(o0.x86RmSize() != o1.x86RmSize()))
goto InvalidInstruction;
- opcode.addArithBySize(o0.size());
+ opcode.addArithBySize(o0.x86RmSize());
rmRel = &o2;
goto EmitX86M;
}
@@ -808,10 +809,10 @@ CaseX86M_GPB_MulDiv:
case InstDB::kEncodingX86M_GPB:
if (isign3 == ENC_OPS1(Reg)) {
- opcode.addArithBySize(o0.size());
+ opcode.addArithBySize(o0.x86RmSize());
rbReg = o0.id();
- if (o0.size() != 1)
+ if (o0.x86RmSize() != 1)
goto EmitX86R;
FIXUP_GPB(o0, rbReg);
@@ -819,10 +820,10 @@ CaseX86M_GPB_MulDiv:
}
if (isign3 == ENC_OPS1(Mem)) {
- if (ASMJIT_UNLIKELY(o0.size() == 0))
+ if (ASMJIT_UNLIKELY(o0.x86RmSize() == 0))
goto AmbiguousOperandSize;
- opcode.addArithBySize(o0.size());
+ opcode.addArithBySize(o0.x86RmSize());
rmRel = &o0;
goto EmitX86M;
}
@@ -851,20 +852,20 @@ CaseX86M_GPB_MulDiv:
opReg = 0;
if (isign3 == ENC_OPS1(Reg)) {
- opcode.addPrefixBySize(o0.size());
+ opcode.addPrefixBySize(o0.x86RmSize());
rbReg = o0.id();
goto EmitX86R;
}
if (isign3 == ENC_OPS1(Mem)) {
- opcode.addPrefixBySize(o0.size());
+ opcode.addPrefixBySize(o0.x86RmSize());
rmRel = &o0;
goto EmitX86M;
}
// Two operand NOP instruction "0F 1F /r".
opReg = o1.id();
- opcode.addPrefixBySize(o1.size());
+ opcode.addPrefixBySize(o1.x86RmSize());
if (isign3 == ENC_OPS2(Reg, Reg)) {
rbReg = o0.id();
@@ -911,7 +912,7 @@ CaseX86M_GPB_MulDiv:
break;
case InstDB::kEncodingX86Rm:
- opcode.addPrefixBySize(o0.size());
+ opcode.addPrefixBySize(o0.x86RmSize());
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingX86Rm_NoSize:
@@ -934,10 +935,10 @@ CaseX86M_GPB_MulDiv:
opReg = o0.id();
rbReg = o1.id();
- if (o0.size() == 2)
+ if (o0.x86RmSize() == 2)
writer.emit8(0x66);
else
- opcode.addWBySize(o0.size());
+ opcode.addWBySize(o0.x86RmSize());
goto EmitX86R;
}
@@ -945,16 +946,16 @@ CaseX86M_GPB_MulDiv:
opReg = o0.id();
rmRel = &o1;
- if (o0.size() == 2)
+ if (o0.x86RmSize() == 2)
writer.emit8(0x66);
else
- opcode.addWBySize(o0.size());
+ opcode.addWBySize(o0.x86RmSize());
goto EmitX86M;
}
break;
case InstDB::kEncodingX86Mr:
- opcode.addPrefixBySize(o0.size());
+ opcode.addPrefixBySize(o1.x86RmSize());
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingX86Mr_NoSize:
@@ -973,15 +974,15 @@ CaseX86M_GPB_MulDiv:
case InstDB::kEncodingX86Arith:
if (isign3 == ENC_OPS2(Reg, Reg)) {
- opcode.addArithBySize(o0.size());
+ opcode.addArithBySize(o0.x86RmSize());
- if (o0.size() != o1.size())
+ if (o0.x86RmSize() != o1.x86RmSize())
goto OperandSizeMismatch;
rbReg = o0.id();
opReg = o1.id();
- if (o0.size() == 1) {
+ if (o0.x86RmSize() == 1) {
FIXUP_GPB(o0, rbReg);
FIXUP_GPB(o1, opReg);
}
@@ -991,19 +992,19 @@ CaseX86M_GPB_MulDiv:
goto EmitX86R;
// MOD/RM: Alternative encoding selected via instruction options.
- opcode += 2;
+ opcode += 2u;
std::swap(opReg, rbReg);
goto EmitX86R;
}
if (isign3 == ENC_OPS2(Reg, Mem)) {
- opcode += 2;
- opcode.addArithBySize(o0.size());
+ opcode += 2u;
+ opcode.addArithBySize(o0.x86RmSize());
opReg = o0.id();
rmRel = &o1;
- if (o0.size() != 1)
+ if (o0.x86RmSize() != 1)
goto EmitX86M;
FIXUP_GPB(o0, opReg);
@@ -1011,11 +1012,11 @@ CaseX86M_GPB_MulDiv:
}
if (isign3 == ENC_OPS2(Mem, Reg)) {
- opcode.addArithBySize(o1.size());
+ opcode.addArithBySize(o1.x86RmSize());
opReg = o1.id();
rmRel = &o0;
- if (o1.size() != 1)
+ if (o1.x86RmSize() != 1)
goto EmitX86M;
FIXUP_GPB(o1, opReg);
@@ -1026,7 +1027,7 @@ CaseX86M_GPB_MulDiv:
opcode = 0x80;
if (isign3 == ENC_OPS2(Reg, Imm)) {
- uint32_t size = o0.size();
+ uint32_t size = o0.x86RmSize();
rbReg = o0.id();
immValue = o1.as<Imm>().value();
@@ -1075,12 +1076,12 @@ CaseX86M_GPB_MulDiv:
goto EmitX86Op;
}
- opcode += size != 1 ? (immSize != 1 ? 1 : 3) : 0;
+ opcode += size != 1 ? (immSize != 1 ? 1u : 3u) : 0u;
goto EmitX86R;
}
if (isign3 == ENC_OPS2(Mem, Imm)) {
- uint32_t memSize = o0.size();
+ uint32_t memSize = o0.x86RmSize();
if (ASMJIT_UNLIKELY(memSize == 0))
goto AmbiguousOperandSize;
@@ -1095,7 +1096,7 @@ CaseX86M_GPB_MulDiv:
if (Support::isInt8(immValue) && !Support::test(options, InstOptions::kLongForm))
immSize = 1;
- opcode += memSize != 1 ? (immSize != 1 ? 1 : 3) : 0;
+ opcode += memSize != 1 ? (immSize != 1 ? 1u : 3u) : 0u;
opcode.addPrefixBySize(memSize);
rmRel = &o0;
@@ -1105,25 +1106,25 @@ CaseX86M_GPB_MulDiv:
case InstDB::kEncodingX86Bswap:
if (isign3 == ENC_OPS1(Reg)) {
- if (ASMJIT_UNLIKELY(o0.size() == 1))
+ if (ASMJIT_UNLIKELY(o0.x86RmSize() == 1))
goto InvalidInstruction;
opReg = o0.id();
- opcode.addPrefixBySize(o0.size());
+ opcode.addPrefixBySize(o0.x86RmSize());
goto EmitX86OpReg;
}
break;
case InstDB::kEncodingX86Bt:
if (isign3 == ENC_OPS2(Reg, Reg)) {
- opcode.addPrefixBySize(o1.size());
+ opcode.addPrefixBySize(o1.x86RmSize());
opReg = o1.id();
rbReg = o0.id();
goto EmitX86R;
}
if (isign3 == ENC_OPS2(Mem, Reg)) {
- opcode.addPrefixBySize(o1.size());
+ opcode.addPrefixBySize(o1.x86RmSize());
opReg = o1.id();
rmRel = &o0;
goto EmitX86M;
@@ -1134,7 +1135,7 @@ CaseX86M_GPB_MulDiv:
immSize = 1;
opcode = x86AltOpcodeOf(instInfo);
- opcode.addPrefixBySize(o0.size());
+ opcode.addPrefixBySize(o0.x86RmSize());
opReg = opcode.extractModO();
if (isign3 == ENC_OPS2(Reg, Imm)) {
@@ -1143,7 +1144,7 @@ CaseX86M_GPB_MulDiv:
}
if (isign3 == ENC_OPS2(Mem, Imm)) {
- if (ASMJIT_UNLIKELY(o0.size() == 0))
+ if (ASMJIT_UNLIKELY(o0.x86RmSize() == 0))
goto AmbiguousOperandSize;
rmRel = &o0;
@@ -1176,14 +1177,14 @@ CaseX86M_GPB_MulDiv:
}
if (isign3 == ENC_OPS2(Reg, Reg)) {
- if (o0.size() != o1.size())
+ if (o0.x86RmSize() != o1.x86RmSize())
goto OperandSizeMismatch;
- opcode.addArithBySize(o0.size());
+ opcode.addArithBySize(o0.x86RmSize());
rbReg = o0.id();
opReg = o1.id();
- if (o0.size() != 1)
+ if (o0.x86RmSize() != 1)
goto EmitX86R;
FIXUP_GPB(o0, rbReg);
@@ -1192,11 +1193,11 @@ CaseX86M_GPB_MulDiv:
}
if (isign3 == ENC_OPS2(Mem, Reg)) {
- opcode.addArithBySize(o1.size());
+ opcode.addArithBySize(o1.x86RmSize());
opReg = o1.id();
rmRel = &o0;
- if (o1.size() != 1)
+ if (o1.x86RmSize() != 1)
goto EmitX86M;
FIXUP_GPB(o1, opReg);
@@ -1225,18 +1226,18 @@ CaseX86M_GPB_MulDiv:
case InstDB::kEncodingX86Crc:
opReg = o0.id();
- opcode.addWBySize(o0.size());
+ opcode.addWBySize(o0.x86RmSize());
if (isign3 == ENC_OPS2(Reg, Reg)) {
rbReg = o1.id();
- if (o1.size() == 1) {
+ if (o1.x86RmSize() == 1) {
FIXUP_GPB(o1, rbReg);
goto EmitX86R;
}
else {
// This seems to be the only exception of encoding '66F2' prefix.
- if (o1.size() == 2) writer.emit8(0x66);
+ if (o1.x86RmSize() == 2) writer.emit8(0x66);
opcode.add(1);
goto EmitX86R;
@@ -1245,13 +1246,13 @@ CaseX86M_GPB_MulDiv:
if (isign3 == ENC_OPS2(Reg, Mem)) {
rmRel = &o1;
- if (o1.size() == 0)
+ if (o1.x86RmSize() == 0)
goto AmbiguousOperandSize;
// This seems to be the only exception of encoding '66F2' prefix.
- if (o1.size() == 2) writer.emit8(0x66);
+ if (o1.x86RmSize() == 2) writer.emit8(0x66);
- opcode += o1.size() != 1;
+ opcode += uint32_t(o1.x86RmSize() != 1u);
goto EmitX86M;
}
break;
@@ -1271,14 +1272,14 @@ CaseX86M_GPB_MulDiv:
// First process all forms distinct of `kEncodingX86M_OptB_MulDiv`.
if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
opcode = 0x6B;
- opcode.addPrefixBySize(o0.size());
+ opcode.addPrefixBySize(o0.x86RmSize());
immValue = o2.as<Imm>().value();
immSize = 1;
if (!Support::isInt8(immValue) || Support::test(options, InstOptions::kLongForm)) {
opcode -= 2;
- immSize = o0.size() == 2 ? 2 : 4;
+ immSize = o0.x86RmSize() == 2 ? 2 : 4;
}
opReg = o0.id();
@@ -1289,18 +1290,18 @@ CaseX86M_GPB_MulDiv:
if (isign3 == ENC_OPS3(Reg, Mem, Imm)) {
opcode = 0x6B;
- opcode.addPrefixBySize(o0.size());
+ opcode.addPrefixBySize(o0.x86RmSize());
immValue = o2.as<Imm>().value();
immSize = 1;
// Sign extend so isInt8 returns the right result.
- if (o0.size() == 4)
+ if (o0.x86RmSize() == 4)
immValue = x86SignExtendI32<int64_t>(immValue);
if (!Support::isInt8(immValue) || Support::test(options, InstOptions::kLongForm)) {
opcode -= 2;
- immSize = o0.size() == 2 ? 2 : 4;
+ immSize = o0.x86RmSize() == 2 ? 2 : 4;
}
opReg = o0.id();
@@ -1311,48 +1312,48 @@ CaseX86M_GPB_MulDiv:
if (isign3 == ENC_OPS2(Reg, Reg)) {
// Must be explicit 'ax, r8' form.
- if (o1.size() == 1)
+ if (o1.x86RmSize() == 1)
goto CaseX86M_GPB_MulDiv;
- if (o0.size() != o1.size())
+ if (o0.x86RmSize() != o1.x86RmSize())
goto OperandSizeMismatch;
opReg = o0.id();
rbReg = o1.id();
opcode = Opcode::k000F00 | 0xAF;
- opcode.addPrefixBySize(o0.size());
+ opcode.addPrefixBySize(o0.x86RmSize());
goto EmitX86R;
}
if (isign3 == ENC_OPS2(Reg, Mem)) {
// Must be explicit 'ax, m8' form.
- if (o1.size() == 1)
+ if (o1.x86RmSize() == 1)
goto CaseX86M_GPB_MulDiv;
opReg = o0.id();
rmRel = &o1;
opcode = Opcode::k000F00 | 0xAF;
- opcode.addPrefixBySize(o0.size());
+ opcode.addPrefixBySize(o0.x86RmSize());
goto EmitX86M;
}
// Shorthand to imul 'reg, reg, imm'.
if (isign3 == ENC_OPS2(Reg, Imm)) {
opcode = 0x6B;
- opcode.addPrefixBySize(o0.size());
+ opcode.addPrefixBySize(o0.x86RmSize());
immValue = o1.as<Imm>().value();
immSize = 1;
// Sign extend so isInt8 returns the right result.
- if (o0.size() == 4)
+ if (o0.x86RmSize() == 4)
immValue = x86SignExtendI32<int64_t>(immValue);
if (!Support::isInt8(immValue) || Support::test(options, InstOptions::kLongForm)) {
opcode -= 2;
- immSize = o0.size() == 2 ? 2 : 4;
+ immSize = o0.x86RmSize() == 2 ? 2 : 4;
}
opReg = rbReg = o0.id();
@@ -1370,8 +1371,8 @@ CaseX86M_GPB_MulDiv:
immValue = o1.as<Imm>().valueAs<uint8_t>();
immSize = 1;
- opcode = x86AltOpcodeOf(instInfo) + (o0.size() != 1);
- opcode.add66hBySize(o0.size());
+ opcode = x86AltOpcodeOf(instInfo) + (o0.x86RmSize() != 1);
+ opcode.add66hBySize(o0.x86RmSize());
goto EmitX86Op;
}
@@ -1379,8 +1380,8 @@ CaseX86M_GPB_MulDiv:
if (ASMJIT_UNLIKELY(o0.id() != Gp::kIdAx || o1.id() != Gp::kIdDx))
goto InvalidInstruction;
- opcode += o0.size() != 1;
- opcode.add66hBySize(o0.size());
+ opcode += uint32_t(o0.x86RmSize() != 1u);
+ opcode.add66hBySize(o0.x86RmSize());
goto EmitX86Op;
}
break;
@@ -1390,12 +1391,12 @@ CaseX86M_GPB_MulDiv:
if (ASMJIT_UNLIKELY(!x86IsImplicitMem(o0, Gp::kIdDi) || o1.id() != Gp::kIdDx))
goto InvalidInstruction;
- uint32_t size = o0.size();
+ uint32_t size = o0.x86RmSize();
if (ASMJIT_UNLIKELY(size == 0))
goto AmbiguousOperandSize;
rmRel = &o0;
- opcode += (size != 1);
+ opcode += uint32_t(size != 1u);
opcode.add66hBySize(size);
goto EmitX86OpImplicitMem;
@@ -1406,7 +1407,7 @@ CaseX86M_GPB_MulDiv:
if (isign3 == ENC_OPS1(Reg)) {
rbReg = o0.id();
- if (o0.size() == 1) {
+ if (o0.x86RmSize() == 1) {
FIXUP_GPB(o0, rbReg);
goto EmitX86R;
}
@@ -1414,19 +1415,19 @@ CaseX86M_GPB_MulDiv:
if (is32Bit()) {
// INC r16|r32 is only encodable in 32-bit mode (collides with REX).
opcode = x86AltOpcodeOf(instInfo) + (rbReg & 0x07);
- opcode.add66hBySize(o0.size());
+ opcode.add66hBySize(o0.x86RmSize());
goto EmitX86Op;
}
else {
- opcode.addArithBySize(o0.size());
+ opcode.addArithBySize(o0.x86RmSize());
goto EmitX86R;
}
}
if (isign3 == ENC_OPS1(Mem)) {
- if (!o0.size())
+ if (!o0.x86RmSize())
goto AmbiguousOperandSize;
- opcode.addArithBySize(o0.size());
+ opcode.addArithBySize(o0.x86RmSize());
rmRel = &o0;
goto EmitX86M;
}
@@ -1457,7 +1458,7 @@ CaseX86M_GPB_MulDiv:
if (ASMJIT_UNLIKELY(!Reg::isGp(o0, Gp::kIdCx)))
goto InvalidInstruction;
- writer.emitAddressOverride((is32Bit() && o0.size() == 2) || (is64Bit() && o0.size() == 4));
+ writer.emitAddressOverride((is32Bit() && o0.x86RmSize() == 2) || (is64Bit() && o0.x86RmSize() == 4));
rmRel = &o1;
}
@@ -1487,7 +1488,7 @@ CaseX86M_GPB_MulDiv:
case InstDB::kEncodingX86LcallLjmp:
if (isign3 == ENC_OPS1(Mem)) {
rmRel = &o0;
- uint32_t mSize = rmRel->size();
+ uint32_t mSize = rmRel->as<Mem>().size();
if (mSize == 0) {
mSize = registerSize();
}
@@ -1519,7 +1520,7 @@ CaseX86M_GPB_MulDiv:
case InstDB::kEncodingX86Lea:
if (isign3 == ENC_OPS2(Reg, Mem)) {
- opcode.addPrefixBySize(o0.size());
+ opcode.addPrefixBySize(o0.x86RmSize());
opReg = o0.id();
rmRel = &o1;
goto EmitX86M;
@@ -1540,8 +1541,8 @@ CaseX86M_GPB_MulDiv:
// GP <- GP
if (Reg::isGp(o1)) {
- uint32_t opSize = o0.size();
- if (opSize != o1.size())
+ uint32_t opSize = o0.x86RmSize();
+ if (opSize != o1.x86RmSize())
goto InvalidInstruction;
if (opSize == 1) {
@@ -1552,7 +1553,7 @@ CaseX86M_GPB_MulDiv:
if (!Support::test(options, InstOptions::kX86_ModRM))
goto EmitX86R;
- opcode += 2;
+ opcode += 2u;
std::swap(opReg, rbReg);
goto EmitX86R;
}
@@ -1563,7 +1564,7 @@ CaseX86M_GPB_MulDiv:
if (!Support::test(options, InstOptions::kX86_ModRM))
goto EmitX86R;
- opcode += 2;
+ opcode += 2u;
std::swap(opReg, rbReg);
goto EmitX86R;
}
@@ -1572,7 +1573,7 @@ CaseX86M_GPB_MulDiv:
// GP <- SReg
if (Reg::isSReg(o1)) {
opcode = 0x8C;
- opcode.addPrefixBySize(o0.size());
+ opcode.addPrefixBySize(o0.x86RmSize());
opReg--;
goto EmitX86R;
}
@@ -1606,7 +1607,7 @@ CaseX86M_GPB_MulDiv:
// SReg <- GP
if (Reg::isSReg(o0)) {
opcode = 0x8E;
- opcode.addPrefixBySize(o1.size());
+ opcode.addPrefixBySize(o1.x86RmSize());
opReg--;
goto EmitX86R;
}
@@ -1640,28 +1641,28 @@ CaseX86M_GPB_MulDiv:
// SReg <- Mem
if (Reg::isSReg(o0)) {
opcode = 0x8E;
- opcode.addPrefixBySize(o1.size());
+ opcode.addPrefixBySize(o1.x86RmSize());
opReg--;
goto EmitX86M;
}
// Reg <- Mem
else {
opcode = 0;
- opcode.addArithBySize(o0.size());
+ opcode.addArithBySize(o0.x86RmSize());
// Handle a special form of `mov al|ax|eax|rax, [ptr64]` that doesn't use MOD.
if (opReg == Gp::kIdAx && !rmRel->as<Mem>().hasBaseOrIndex()) {
- if (x86ShouldUseMovabs(this, writer, o0.size(), options, rmRel->as<Mem>())) {
- opcode += 0xA0;
+ if (x86ShouldUseMovabs(this, writer, o0.x86RmSize(), options, rmRel->as<Mem>())) {
+ opcode += 0xA0u;
immValue = rmRel->as<Mem>().offset();
goto EmitX86OpMovAbs;
}
}
- if (o0.size() == 1)
+ if (o0.x86RmSize() == 1)
FIXUP_GPB(o0, opReg);
- opcode += 0x8A;
+ opcode += 0x8Au;
goto EmitX86M;
}
}
@@ -1673,35 +1674,35 @@ CaseX86M_GPB_MulDiv:
// Mem <- SReg
if (Reg::isSReg(o1)) {
opcode = 0x8C;
- opcode.addPrefixBySize(o0.size());
+ opcode.addPrefixBySize(o0.x86RmSize());
opReg--;
goto EmitX86M;
}
// Mem <- Reg
else {
opcode = 0;
- opcode.addArithBySize(o1.size());
+ opcode.addArithBySize(o1.x86RmSize());
// Handle a special form of `mov [ptr64], al|ax|eax|rax` that doesn't use MOD.
if (opReg == Gp::kIdAx && !rmRel->as<Mem>().hasBaseOrIndex()) {
- if (x86ShouldUseMovabs(this, writer, o1.size(), options, rmRel->as<Mem>())) {
- opcode += 0xA2;
+ if (x86ShouldUseMovabs(this, writer, o1.x86RmSize(), options, rmRel->as<Mem>())) {
+ opcode += 0xA2u;
immValue = rmRel->as<Mem>().offset();
goto EmitX86OpMovAbs;
}
}
- if (o1.size() == 1)
+ if (o1.x86RmSize() == 1)
FIXUP_GPB(o1, opReg);
- opcode += 0x88;
+ opcode += 0x88u;
goto EmitX86M;
}
}
if (isign3 == ENC_OPS2(Reg, Imm)) {
opReg = o0.id();
- immSize = FastUInt8(o0.size());
+ immSize = FastUInt8(o0.x86RmSize());
if (immSize == 1) {
FIXUP_GPB(o0, opReg);
@@ -1739,7 +1740,7 @@ CaseX86M_GPB_MulDiv:
}
if (isign3 == ENC_OPS2(Mem, Imm)) {
- uint32_t memSize = o0.size();
+ uint32_t memSize = o0.x86RmSize();
if (ASMJIT_UNLIKELY(memSize == 0))
goto AmbiguousOperandSize;
@@ -1761,7 +1762,7 @@ CaseX86M_GPB_MulDiv:
rmRel = &o1;
opcode = 0xA0;
- opcode.addArithBySize(o0.size());
+ opcode.addArithBySize(o0.x86RmSize());
if (ASMJIT_UNLIKELY(!o0.as<Reg>().isGp()) || opReg != Gp::kIdAx)
goto InvalidInstruction;
@@ -1782,7 +1783,7 @@ CaseX86M_GPB_MulDiv:
rmRel = &o0;
opcode = 0xA2;
- opcode.addArithBySize(o1.size());
+ opcode.addArithBySize(o1.x86RmSize());
if (ASMJIT_UNLIKELY(!o1.as<Reg>().isGp()) || opReg != Gp::kIdAx)
goto InvalidInstruction;
@@ -1811,14 +1812,14 @@ CaseX86M_GPB_MulDiv:
break;
case InstDB::kEncodingX86MovsxMovzx:
- opcode.add(o1.size() != 1);
- opcode.addPrefixBySize(o0.size());
+ opcode.add(o1.x86RmSize() != 1);
+ opcode.addPrefixBySize(o0.x86RmSize());
if (isign3 == ENC_OPS2(Reg, Reg)) {
opReg = o0.id();
rbReg = o1.id();
- if (o1.size() != 1)
+ if (o1.x86RmSize() != 1)
goto EmitX86R;
FIXUP_GPB(o1, rbReg);
@@ -1864,8 +1865,8 @@ CaseX86M_GPB_MulDiv:
if (ASMJIT_UNLIKELY(o1.id() != Gp::kIdAx))
goto InvalidInstruction;
- opcode = x86AltOpcodeOf(instInfo) + (o1.size() != 1);
- opcode.add66hBySize(o1.size());
+ opcode = x86AltOpcodeOf(instInfo) + (o1.x86RmSize() != 1);
+ opcode.add66hBySize(o1.x86RmSize());
immValue = o0.as<Imm>().valueAs<uint8_t>();
immSize = 1;
@@ -1876,8 +1877,8 @@ CaseX86M_GPB_MulDiv:
if (ASMJIT_UNLIKELY(o0.id() != Gp::kIdDx || o1.id() != Gp::kIdAx))
goto InvalidInstruction;
- opcode.add(o1.size() != 1);
- opcode.add66hBySize(o1.size());
+ opcode.add(o1.x86RmSize() != 1);
+ opcode.add66hBySize(o1.x86RmSize());
goto EmitX86Op;
}
break;
@@ -1887,7 +1888,7 @@ CaseX86M_GPB_MulDiv:
if (ASMJIT_UNLIKELY(o0.id() != Gp::kIdDx || !x86IsImplicitMem(o1, Gp::kIdSi)))
goto InvalidInstruction;
- uint32_t size = o1.size();
+ uint32_t size = o1.x86RmSize();
if (ASMJIT_UNLIKELY(size == 0))
goto AmbiguousOperandSize;
@@ -1939,24 +1940,24 @@ CaseX86M_GPB_MulDiv:
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.
- if (ASMJIT_UNLIKELY(o0.size() < 2))
+ if (ASMJIT_UNLIKELY(o0.x86RmSize() < 2))
goto InvalidInstruction;
opcode = x86AltOpcodeOf(instInfo);
- opcode.add66hBySize(o0.size());
+ opcode.add66hBySize(o0.x86RmSize());
opReg = o0.id();
goto EmitX86OpReg;
}
}
if (isign3 == ENC_OPS1(Mem)) {
- if (ASMJIT_UNLIKELY(o0.size() == 0))
+ if (ASMJIT_UNLIKELY(o0.x86RmSize() == 0))
goto AmbiguousOperandSize;
- if (ASMJIT_UNLIKELY(o0.size() != 2 && o0.size() != registerSize()))
+ if (ASMJIT_UNLIKELY(o0.x86RmSize() != 2 && o0.x86RmSize() != registerSize()))
goto InvalidInstruction;
- opcode.add66hBySize(o0.size());
+ opcode.add66hBySize(o0.x86RmSize());
rmRel = &o0;
goto EmitX86M;
}
@@ -1985,17 +1986,17 @@ CaseX86PushPop_Gp:
case InstDB::kEncodingX86Rot:
if (o0.isReg()) {
- opcode.addArithBySize(o0.size());
+ opcode.addArithBySize(o0.x86RmSize());
rbReg = o0.id();
- if (o0.size() == 1)
+ if (o0.x86RmSize() == 1)
FIXUP_GPB(o0, rbReg);
if (isign3 == ENC_OPS2(Reg, Reg)) {
if (ASMJIT_UNLIKELY(o1.id() != Gp::kIdCx))
goto InvalidInstruction;
- opcode += 2;
+ opcode += 2u;
goto EmitX86R;
}
@@ -2012,15 +2013,15 @@ CaseX86PushPop_Gp:
}
}
else {
- if (ASMJIT_UNLIKELY(o0.size() == 0))
+ if (ASMJIT_UNLIKELY(o0.x86RmSize() == 0))
goto AmbiguousOperandSize;
- opcode.addArithBySize(o0.size());
+ opcode.addArithBySize(o0.x86RmSize());
if (isign3 == ENC_OPS2(Mem, Reg)) {
if (ASMJIT_UNLIKELY(o1.id() != Gp::kIdCx))
goto InvalidInstruction;
- opcode += 2;
+ opcode += 2u;
rmRel = &o0;
goto EmitX86M;
}
@@ -2055,7 +2056,7 @@ CaseX86PushPop_Gp:
case InstDB::kEncodingX86ShldShrd:
if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
- opcode.addPrefixBySize(o0.size());
+ opcode.addPrefixBySize(o0.x86RmSize());
opReg = o1.id();
rbReg = o0.id();
@@ -2065,7 +2066,7 @@ CaseX86PushPop_Gp:
}
if (isign3 == ENC_OPS3(Mem, Reg, Imm)) {
- opcode.addPrefixBySize(o1.size());
+ opcode.addPrefixBySize(o1.x86RmSize());
opReg = o1.id();
rmRel = &o0;
@@ -2081,7 +2082,7 @@ CaseX86PushPop_Gp:
if (ASMJIT_UNLIKELY(o2.id() != Gp::kIdCx))
goto InvalidInstruction;
- opcode.addPrefixBySize(o0.size());
+ opcode.addPrefixBySize(o0.x86RmSize());
opReg = o1.id();
rbReg = o0.id();
goto EmitX86R;
@@ -2091,7 +2092,7 @@ CaseX86PushPop_Gp:
if (ASMJIT_UNLIKELY(o2.id() != Gp::kIdCx))
goto InvalidInstruction;
- opcode.addPrefixBySize(o1.size());
+ opcode.addPrefixBySize(o1.x86RmSize());
opReg = o1.id();
rmRel = &o0;
goto EmitX86M;
@@ -2104,8 +2105,8 @@ CaseX86PushPop_Gp:
if (ASMJIT_UNLIKELY(rmRel->as<Mem>().offsetLo32() || !Reg::isGp(o0.as<Reg>(), Gp::kIdAx)))
goto InvalidInstruction;
- uint32_t size = o0.size();
- if (o1.hasSize() && ASMJIT_UNLIKELY(o1.size() != size))
+ uint32_t size = o0.x86RmSize();
+ if (o1.x86RmSize() != 0u && ASMJIT_UNLIKELY(o1.x86RmSize() != size))
goto OperandSizeMismatch;
opcode.addArithBySize(size);
@@ -2119,8 +2120,8 @@ CaseX86PushPop_Gp:
if (ASMJIT_UNLIKELY(rmRel->as<Mem>().offsetLo32() || !Reg::isGp(o1.as<Reg>(), Gp::kIdAx)))
goto InvalidInstruction;
- uint32_t size = o1.size();
- if (o0.hasSize() && ASMJIT_UNLIKELY(o0.size() != size))
+ uint32_t size = o1.x86RmSize();
+ if (o0.x86RmSize() != 0u && ASMJIT_UNLIKELY(o0.x86RmSize() != size))
goto OperandSizeMismatch;
opcode.addArithBySize(size);
@@ -2138,11 +2139,11 @@ CaseX86PushPop_Gp:
if (ASMJIT_UNLIKELY(o0.as<Mem>().hasOffset()))
goto InvalidInstruction;
- uint32_t size = o1.size();
+ uint32_t size = o1.x86RmSize();
if (ASMJIT_UNLIKELY(size == 0))
goto AmbiguousOperandSize;
- if (ASMJIT_UNLIKELY(o0.size() != size))
+ if (ASMJIT_UNLIKELY(o0.x86RmSize() != size))
goto OperandSizeMismatch;
opcode.addArithBySize(size);
@@ -2152,14 +2153,14 @@ CaseX86PushPop_Gp:
case InstDB::kEncodingX86Test:
if (isign3 == ENC_OPS2(Reg, Reg)) {
- if (o0.size() != o1.size())
+ if (o0.x86RmSize() != o1.x86RmSize())
goto OperandSizeMismatch;
- opcode.addArithBySize(o0.size());
+ opcode.addArithBySize(o0.x86RmSize());
rbReg = o0.id();
opReg = o1.id();
- if (o0.size() != 1)
+ if (o0.x86RmSize() != 1)
goto EmitX86R;
FIXUP_GPB(o0, rbReg);
@@ -2168,11 +2169,11 @@ CaseX86PushPop_Gp:
}
if (isign3 == ENC_OPS2(Mem, Reg)) {
- opcode.addArithBySize(o1.size());
+ opcode.addArithBySize(o1.x86RmSize());
opReg = o1.id();
rmRel = &o0;
- if (o1.size() != 1)
+ if (o1.x86RmSize() != 1)
goto EmitX86M;
FIXUP_GPB(o1, opReg);
@@ -2184,23 +2185,23 @@ CaseX86PushPop_Gp:
opReg = opcode.extractModO();
if (isign3 == ENC_OPS2(Reg, Imm)) {
- opcode.addArithBySize(o0.size());
+ opcode.addArithBySize(o0.x86RmSize());
rbReg = o0.id();
- if (o0.size() == 1) {
+ if (o0.x86RmSize() == 1) {
FIXUP_GPB(o0, rbReg);
immValue = o1.as<Imm>().valueAs<uint8_t>();
immSize = 1;
}
else {
immValue = o1.as<Imm>().value();
- immSize = FastUInt8(Support::min<uint32_t>(o0.size(), 4));
+ immSize = FastUInt8(Support::min<uint32_t>(o0.x86RmSize(), 4));
}
// Short form - AL, AX, EAX, RAX.
if (rbReg == 0 && !Support::test(options, InstOptions::kLongForm)) {
opcode &= Opcode::kPP_66 | Opcode::kW;
- opcode |= 0xA8 + (o0.size() != 1);
+ opcode |= 0xA8 + (o0.x86RmSize() != 1);
goto EmitX86Op;
}
@@ -2208,25 +2209,25 @@ CaseX86PushPop_Gp:
}
if (isign3 == ENC_OPS2(Mem, Imm)) {
- if (ASMJIT_UNLIKELY(o0.size() == 0))
+ if (ASMJIT_UNLIKELY(o0.x86RmSize() == 0))
goto AmbiguousOperandSize;
- opcode.addArithBySize(o0.size());
+ opcode.addArithBySize(o0.x86RmSize());
rmRel = &o0;
immValue = o1.as<Imm>().value();
- immSize = FastUInt8(Support::min<uint32_t>(o0.size(), 4));
+ immSize = FastUInt8(Support::min<uint32_t>(o0.x86RmSize(), 4));
goto EmitX86M;
}
break;
case InstDB::kEncodingX86Xchg:
if (isign3 == ENC_OPS2(Reg, Mem)) {
- opcode.addArithBySize(o0.size());
+ opcode.addArithBySize(o0.x86RmSize());
opReg = o0.id();
rmRel = &o1;
- if (o0.size() != 1)
+ if (o0.x86RmSize() != 1)
goto EmitX86M;
FIXUP_GPB(o0, opReg);
@@ -2239,8 +2240,8 @@ CaseX86PushPop_Gp:
rbReg = o0.id();
opReg = o1.id();
- uint32_t opSize = o0.size();
- if (opSize != o1.size())
+ uint32_t opSize = o0.x86RmSize();
+ if (opSize != o1.x86RmSize())
goto OperandSizeMismatch;
if (opSize == 1) {
@@ -2259,7 +2260,7 @@ CaseX86PushPop_Gp:
goto EmitX86OpReg;
}
else {
- // Encode 'xchg eax, eax' by by using a generic path.
+ // Encode 'xchg eax, eax' by using a generic path.
}
}
else if (!Support::test(options, InstOptions::kLongForm)) {
@@ -2278,11 +2279,11 @@ CaseX86PushPop_Gp:
}
if (isign3 == ENC_OPS2(Mem, Reg)) {
- opcode.addArithBySize(o1.size());
+ opcode.addArithBySize(o1.x86RmSize());
opReg = o1.id();
rmRel = &o0;
- if (o1.size() == 1) {
+ if (o1.x86RmSize() == 1) {
FIXUP_GPB(o1, opReg);
}
@@ -2356,7 +2357,7 @@ CaseFpuArith_Reg:
if (isign3 == ENC_OPS1(Mem)) {
CaseFpuArith_Mem:
// 0xD8/0xDC, depends on the size of the memory operand; opReg is valid.
- opcode = (o0.size() == 4) ? 0xD8 : 0xDC;
+ opcode = (o0.x86RmSize() == 4) ? 0xD8 : 0xDC;
// Clear compressed displacement before going to EmitX86M.
opcode &= ~uint32_t(Opcode::kCDSHL_Mask);
@@ -2385,16 +2386,16 @@ CaseFpuArith_Mem:
if (isign3 == ENC_OPS1(Mem)) {
rmRel = &o0;
- if (o0.size() == 4 && commonInfo->hasFlag(InstDB::InstFlags::kFpuM32)) {
+ if (o0.x86RmSize() == 4 && commonInfo->hasFlag(InstDB::InstFlags::kFpuM32)) {
goto EmitX86M;
}
- if (o0.size() == 8 && commonInfo->hasFlag(InstDB::InstFlags::kFpuM64)) {
- opcode += 4;
+ if (o0.x86RmSize() == 8 && commonInfo->hasFlag(InstDB::InstFlags::kFpuM64)) {
+ opcode += 4u;
goto EmitX86M;
}
- if (o0.size() == 10 && commonInfo->hasFlag(InstDB::InstFlags::kFpuM80)) {
+ if (o0.x86RmSize() == 10 && commonInfo->hasFlag(InstDB::InstFlags::kFpuM80)) {
opcode = x86AltOpcodeOf(instInfo);
opReg = opcode.extractModO();
goto EmitX86M;
@@ -2414,16 +2415,16 @@ CaseFpuArith_Mem:
opcode &= ~uint32_t(Opcode::kCDSHL_Mask);
rmRel = &o0;
- if (o0.size() == 2 && commonInfo->hasFlag(InstDB::InstFlags::kFpuM16)) {
- opcode += 4;
+ if (o0.x86RmSize() == 2 && commonInfo->hasFlag(InstDB::InstFlags::kFpuM16)) {
+ opcode += 4u;
goto EmitX86M;
}
- if (o0.size() == 4 && commonInfo->hasFlag(InstDB::InstFlags::kFpuM32)) {
+ if (o0.x86RmSize() == 4 && commonInfo->hasFlag(InstDB::InstFlags::kFpuM32)) {
goto EmitX86M;
}
- if (o0.size() == 8 && commonInfo->hasFlag(InstDB::InstFlags::kFpuM64)) {
+ if (o0.x86RmSize() == 8 && commonInfo->hasFlag(InstDB::InstFlags::kFpuM64)) {
opcode = x86AltOpcodeOf(instInfo) & ~uint32_t(Opcode::kCDSHL_Mask);
opReg = opcode.extractModO();
goto EmitX86M;
@@ -2433,7 +2434,7 @@ CaseFpuArith_Mem:
case InstDB::kEncodingFpuRDef:
if (isign3 == 0) {
- opcode += 1;
+ opcode += 1u;
goto EmitFpuOp;
}
ASMJIT_FALLTHROUGH;
@@ -2550,10 +2551,10 @@ CaseFpuArith_Mem:
case InstDB::kEncodingExtMovbe:
if (isign3 == ENC_OPS2(Reg, Mem)) {
- if (o0.size() == 1)
+ if (o0.x86RmSize() == 1)
goto InvalidInstruction;
- opcode.addPrefixBySize(o0.size());
+ opcode.addPrefixBySize(o0.x86RmSize());
opReg = o0.id();
rmRel = &o1;
goto EmitX86M;
@@ -2563,10 +2564,10 @@ CaseFpuArith_Mem:
opcode = x86AltOpcodeOf(instInfo);
if (isign3 == ENC_OPS2(Mem, Reg)) {
- if (o1.size() == 1)
+ if (o1.x86RmSize() == 1)
goto InvalidInstruction;
- opcode.addPrefixBySize(o1.size());
+ opcode.addPrefixBySize(o1.x86RmSize());
opReg = o1.id();
rmRel = &o0;
goto EmitX86M;
@@ -2575,37 +2576,41 @@ CaseFpuArith_Mem:
case InstDB::kEncodingExtMovd:
CaseExtMovd:
- opReg = o0.id();
- opcode.add66hIf(Reg::isXmm(o0));
+ if (x86IsMmxOrXmm(o0.as<Reg>())) {
+ opReg = o0.id();
+ opcode.add66hIf(Reg::isXmm(o0));
- // MM/XMM <- Gp
- if (isign3 == ENC_OPS2(Reg, Reg) && Reg::isGp(o1)) {
- rbReg = o1.id();
- goto EmitX86R;
- }
+ // MM/XMM <- Gp
+ if (isign3 == ENC_OPS2(Reg, Reg) && Reg::isGp(o1)) {
+ rbReg = o1.id();
+ goto EmitX86R;
+ }
- // MM/XMM <- Mem
- if (isign3 == ENC_OPS2(Reg, Mem)) {
- rmRel = &o1;
- goto EmitX86M;
+ // MM/XMM <- Mem
+ if (isign3 == ENC_OPS2(Reg, Mem)) {
+ rmRel = &o1;
+ goto EmitX86M;
+ }
}
// The following instructions use the secondary opcode.
- opcode &= Opcode::kW;
- opcode |= x86AltOpcodeOf(instInfo);
- opReg = o1.id();
- opcode.add66hIf(Reg::isXmm(o1));
+ if (x86IsMmxOrXmm(o1.as<Reg>())) {
+ opcode &= Opcode::kW;
+ opcode |= x86AltOpcodeOf(instInfo);
+ opReg = o1.id();
+ opcode.add66hIf(Reg::isXmm(o1));
- // GP <- MM/XMM
- if (isign3 == ENC_OPS2(Reg, Reg) && Reg::isGp(o0)) {
- rbReg = o0.id();
- goto EmitX86R;
- }
+ // GP <- MM/XMM
+ if (isign3 == ENC_OPS2(Reg, Reg) && Reg::isGp(o0)) {
+ rbReg = o0.id();
+ goto EmitX86R;
+ }
- // Mem <- MM/XMM
- if (isign3 == ENC_OPS2(Mem, Reg)) {
- rmRel = &o0;
- goto EmitX86M;
+ // Mem <- MM/XMM
+ if (isign3 == ENC_OPS2(Mem, Reg)) {
+ rmRel = &o0;
+ goto EmitX86M;
+ }
}
break;
@@ -2621,7 +2626,7 @@ CaseExtMovd:
if (!Support::test(options, InstOptions::kX86_ModMR))
goto EmitX86R;
- opcode += 0x10;
+ opcode += 0x10u;
std::swap(opReg, rbReg);
goto EmitX86R;
}
@@ -2692,7 +2697,7 @@ CaseExtMovd:
goto CaseExtRm;
case InstDB::kEncodingExtRm_Wx:
- opcode.addWIf(o1.size() == 8);
+ opcode.addWIf(o1.x86RmSize() == 8);
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingExtRm_Wx_GpqOnly:
@@ -2716,7 +2721,7 @@ CaseExtRm:
case InstDB::kEncodingExtRm_P:
if (isign3 == ENC_OPS2(Reg, Reg)) {
- opcode.add66hIf(Reg::isXmm(o0) | Reg::isXmm(o1));
+ opcode.add66hIf(unsigned(Reg::isXmm(o0)) | unsigned(Reg::isXmm(o1)));
opReg = o0.id();
rbReg = o1.id();
@@ -2760,7 +2765,7 @@ CaseExtRm:
case InstDB::kEncodingExtRmRi_P:
if (isign3 == ENC_OPS2(Reg, Reg)) {
- opcode.add66hIf(Reg::isXmm(o0) | Reg::isXmm(o1));
+ opcode.add66hIf(unsigned(Reg::isXmm(o0)) | unsigned(Reg::isXmm(o1)));
opReg = o0.id();
rbReg = o1.id();
@@ -2812,7 +2817,7 @@ CaseExtRm:
immSize = 1;
if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
- opcode.add66hIf(Reg::isXmm(o0) | Reg::isXmm(o1));
+ opcode.add66hIf(unsigned(Reg::isXmm(o0)) | unsigned(Reg::isXmm(o1)));
opReg = o0.id();
rbReg = o1.id();
@@ -2970,7 +2975,7 @@ CaseExtRm:
break;
case InstDB::kEncodingVexMr_Lx:
- opcode |= x86OpcodeLBySize(o0.size() | o1.size());
+ opcode |= x86OpcodeLBySize(o0.x86RmSize() | o1.x86RmSize());
if (isign3 == ENC_OPS2(Reg, Reg)) {
opReg = o1.id();
@@ -2987,7 +2992,7 @@ CaseExtRm:
case InstDB::kEncodingVexMr_VM:
if (isign3 == ENC_OPS2(Mem, Reg)) {
- opcode |= Support::max(x86OpcodeLByVMem(o0), x86OpcodeLBySize(o1.size()));
+ opcode |= Support::max(x86OpcodeLByVMem(o0), x86OpcodeLBySize(o1.x86RmSize()));
opReg = o1.id();
rmRel = &o0;
@@ -3010,8 +3015,17 @@ CaseExtRm:
goto CaseVexMri;
+ case InstDB::kEncodingVexMvr_Wx:
+ if (isign3 == ENC_OPS3(Mem, Reg, Reg)) {
+ opcode.addWIf(unsigned(Reg::isGpq(o1)));
+ opReg = x86PackRegAndVvvvv(o1.id(), o2.id());
+ rmRel = &o0;
+ goto EmitVexEvexM;
+ }
+ break;
+
case InstDB::kEncodingVexMri_Lx:
- opcode |= x86OpcodeLBySize(o0.size() | o1.size());
+ opcode |= x86OpcodeLBySize(o0.x86RmSize() | o1.x86RmSize());
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingVexMri:
@@ -3040,19 +3054,19 @@ CaseVexMri:
goto CaseVexRm;
case InstDB::kEncodingVexRm_Wx:
- opcode.addWIf(Reg::isGpq(o0) | Reg::isGpq(o1));
+ opcode.addWIf(unsigned(Reg::isGpq(o0)) | unsigned(Reg::isGpq(o1)));
goto CaseVexRm;
case InstDB::kEncodingVexRm_Lx_Narrow:
- if (o1.size())
- opcode |= x86OpcodeLBySize(o1.size());
- else if (o0.size() == 32)
+ if (o1.x86RmSize())
+ opcode |= x86OpcodeLBySize(o1.x86RmSize());
+ else if (o0.x86RmSize() == 32)
opcode |= Opcode::kLL_2;
goto CaseVexRm;
case InstDB::kEncodingVexRm_Lx_Bcst:
if (isign3 == ENC_OPS2(Reg, Reg) && Reg::isGp(o1.as<Reg>())) {
- opcode = x86AltOpcodeOf(instInfo) | x86OpcodeLBySize(o0.size() | o1.size());
+ opcode = x86AltOpcodeOf(instInfo) | x86OpcodeLBySize(o0.x86RmSize() | o1.x86RmSize());
opReg = o0.id();
rbReg = o1.id();
goto EmitVexEvexR;
@@ -3060,7 +3074,7 @@ CaseVexMri:
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingVexRm_Lx:
- opcode |= x86OpcodeLBySize(o0.size() | o1.size());
+ opcode |= x86OpcodeLBySize(o0.x86RmSize() | o1.x86RmSize());
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingVexRm:
@@ -3080,7 +3094,7 @@ CaseVexRm:
case InstDB::kEncodingVexRm_VM:
if (isign3 == ENC_OPS2(Reg, Mem)) {
- opcode |= Support::max(x86OpcodeLByVMem(o1), x86OpcodeLBySize(o0.size()));
+ opcode |= Support::max(x86OpcodeLByVMem(o1), x86OpcodeLBySize(o0.x86RmSize()));
opReg = o0.id();
rmRel = &o1;
goto EmitVexEvexM;
@@ -3110,11 +3124,11 @@ CaseVexRm:
}
case InstDB::kEncodingVexRmi_Wx:
- opcode.addWIf(Reg::isGpq(o0) | Reg::isGpq(o1));
+ opcode.addWIf(unsigned(Reg::isGpq(o0)) | unsigned(Reg::isGpq(o1)));
goto CaseVexRmi;
case InstDB::kEncodingVexRmi_Lx:
- opcode |= x86OpcodeLBySize(o0.size() | o1.size());
+ opcode |= x86OpcodeLBySize(o0.x86RmSize() | o1.x86RmSize());
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingVexRmi:
@@ -3159,7 +3173,7 @@ CaseVexRvm_R:
}
case InstDB::kEncodingVexRvm_Wx: {
- opcode.addWIf(Reg::isGpq(o0) | (o2.size() == 8));
+ opcode.addWIf(unsigned(Reg::isGpq(o0)) | unsigned((o2.x86RmSize() == 8)));
goto CaseVexRvm;
}
@@ -3169,7 +3183,7 @@ CaseVexRvm_R:
}
case InstDB::kEncodingVexRvm_Lx: {
- opcode |= x86OpcodeLBySize(o0.size() | o1.size());
+ opcode |= x86OpcodeLBySize(o0.x86RmSize() | o1.x86RmSize());
goto CaseVexRvm;
}
@@ -3183,7 +3197,7 @@ CaseVexRvm_R:
const Operand_& o3 = opExt[EmitterUtils::kOp3];
- opcode |= x86OpcodeLBySize(o2.size());
+ opcode |= x86OpcodeLBySize(o2.x86RmSize());
opReg = x86PackRegAndVvvvv(o0.id(), o2.id());
if (o3.isReg()) {
@@ -3200,7 +3214,7 @@ CaseVexRvm_R:
}
case InstDB::kEncodingVexRvmr_Lx: {
- opcode |= x86OpcodeLBySize(o0.size() | o1.size());
+ opcode |= x86OpcodeLBySize(o0.x86RmSize() | o1.x86RmSize());
ASMJIT_FALLTHROUGH;
}
@@ -3234,7 +3248,7 @@ CaseVexRvm_R:
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingVexRvmi_Lx:
- opcode |= x86OpcodeLBySize(o0.size() | o1.size());
+ opcode |= x86OpcodeLBySize(o0.x86RmSize() | o1.x86RmSize());
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingVexRvmi:
@@ -3261,7 +3275,7 @@ VexRvmi:
}
case InstDB::kEncodingVexRmv_Wx:
- opcode.addWIf(Reg::isGpq(o0) | Reg::isGpq(o2));
+ opcode.addWIf(unsigned(Reg::isGpq(o0)) | unsigned(Reg::isGpq(o2)));
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingVexRmv:
@@ -3281,7 +3295,7 @@ VexRvmi:
case InstDB::kEncodingVexRmvRm_VM:
if (isign3 == ENC_OPS2(Reg, Mem)) {
opcode = x86AltOpcodeOf(instInfo);
- opcode |= Support::max(x86OpcodeLByVMem(o1), x86OpcodeLBySize(o0.size()));
+ opcode |= Support::max(x86OpcodeLByVMem(o1), x86OpcodeLBySize(o0.x86RmSize()));
opReg = o0.id();
rmRel = &o1;
@@ -3291,7 +3305,7 @@ VexRvmi:
case InstDB::kEncodingVexRmv_VM:
if (isign3 == ENC_OPS3(Reg, Mem, Reg)) {
- opcode |= Support::max(x86OpcodeLByVMem(o1), x86OpcodeLBySize(o0.size() | o2.size()));
+ opcode |= Support::max(x86OpcodeLByVMem(o1), x86OpcodeLBySize(o0.x86RmSize() | o2.x86RmSize()));
opReg = x86PackRegAndVvvvv(o0.id(), o2.id());
rmRel = &o1;
@@ -3325,14 +3339,14 @@ VexRvmi:
if (isign3 == ENC_OPS2(Reg, Reg)) {
if (Reg::isGp(o0)) {
opcode = x86AltOpcodeOf(instInfo);
- opcode.addWBySize(o0.size());
+ opcode.addWBySize(o0.x86RmSize());
opReg = o1.id();
rbReg = o0.id();
goto EmitVexEvexR;
}
if (Reg::isGp(o1)) {
- opcode.addWBySize(o1.size());
+ opcode.addWBySize(o1.x86RmSize());
opReg = o0.id();
rbReg = o1.id();
goto EmitVexEvexR;
@@ -3376,7 +3390,7 @@ VexRvmi:
break;
case InstDB::kEncodingVexRmMr_Lx:
- opcode |= x86OpcodeLBySize(o0.size() | o1.size());
+ opcode |= x86OpcodeLBySize(o0.x86RmSize() | o1.x86RmSize());
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingVexRmMr:
@@ -3432,7 +3446,7 @@ VexRvmi:
break;
case InstDB::kEncodingVexRvmRmi_Lx:
- opcode |= x86OpcodeLBySize(o0.size() | o1.size());
+ opcode |= x86OpcodeLBySize(o0.x86RmSize() | o1.x86RmSize());
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingVexRvmRmi:
@@ -3544,7 +3558,7 @@ VexRvmi:
break;
case InstDB::kEncodingVexRvmMvr_Lx:
- opcode |= x86OpcodeLBySize(o0.size() | o1.size());
+ opcode |= x86OpcodeLBySize(o0.x86RmSize() | o1.x86RmSize());
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingVexRvmMvr:
@@ -3576,7 +3590,7 @@ VexRvmi:
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingVexRvmVmi_Lx:
- opcode |= x86OpcodeLBySize(o0.size() | o1.size());
+ opcode |= x86OpcodeLBySize(o0.x86RmSize() | o1.x86RmSize());
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingVexRvmVmi:
@@ -3614,7 +3628,7 @@ VexRvmi:
break;
case InstDB::kEncodingVexVm_Wx:
- opcode.addWIf(Reg::isGpq(o0) | Reg::isGpq(o1));
+ opcode.addWIf(unsigned(Reg::isGpq(o0)) | unsigned(Reg::isGpq(o1)));
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingVexVm:
@@ -3637,7 +3651,7 @@ VexRvmi:
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingVexVmi_Lx:
- opcode |= x86OpcodeLBySize(o0.size() | o1.size());
+ opcode |= x86OpcodeLBySize(o0.x86RmSize() | o1.x86RmSize());
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingVexVmi:
@@ -3659,13 +3673,13 @@ CaseVexVmi_AfterImm:
break;
case InstDB::kEncodingVexVmi4_Wx:
- opcode.addWIf(Reg::isGpq(o0) || o1.size() == 8);
+ opcode.addWIf(Reg::isGpq(o0) || o1.x86RmSize() == 8);
immValue = o2.as<Imm>().value();
immSize = 4;
goto CaseVexVmi_AfterImm;
case InstDB::kEncodingVexRvrmRvmr_Lx:
- opcode |= x86OpcodeLBySize(o0.size() | o1.size());
+ opcode |= x86OpcodeLBySize(o0.x86RmSize() | o1.x86RmSize());
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingVexRvrmRvmr: {
@@ -3710,7 +3724,7 @@ CaseVexVmi_AfterImm:
goto InvalidInstruction;
const uint32_t isign4 = isign3 + (uint32_t(o3.opType()) << 9);
- opcode |= x86OpcodeLBySize(o0.size() | o1.size() | o2.size() | o3.size());
+ opcode |= x86OpcodeLBySize(o0.x86RmSize() | o1.x86RmSize() | o2.x86RmSize() | o3.x86RmSize());
immValue = o4.as<Imm>().valueAs<uint8_t>() & 0x0F;
immSize = 1;
@@ -3766,7 +3780,7 @@ CaseVexVmi_AfterImm:
case InstDB::kEncodingFma4_Lx:
// It's fine to just check the first operand, second is just for sanity.
- opcode |= x86OpcodeLBySize(o0.size() | o1.size());
+ opcode |= x86OpcodeLBySize(o0.x86RmSize() | o1.x86RmSize());
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingFma4: {
@@ -4274,7 +4288,7 @@ EmitModSib_LabelRip_X86:
}
else {
// Non-bound label or label bound to a different section.
- relOffset = -4 - immSize;
+ relOffset = -4 - int32_t(immSize);
relSize = 4;
goto EmitRel;
}
@@ -4950,10 +4964,7 @@ EmitDone:
#endif
}
- resetExtraReg();
- resetInstOptions();
- resetInlineComment();
-
+ resetState();
writer.done(this);
return kErrorOk;
@@ -4987,9 +4998,7 @@ Failed:
#ifndef ASMJIT_NO_LOGGING
return EmitterUtils::logInstructionFailed(this, err, instId, options, o0, o1, o2, opExt);
#else
- resetExtraReg();
- resetInstOptions();
- resetInlineComment();
+ resetState();
return reportError(err);
#endif
}
@@ -5085,6 +5094,9 @@ Error Assembler::onAttach(CodeHolder* code) noexcept {
Arch arch = code->arch();
ASMJIT_PROPAGATE(Base::onAttach(code));
+ _instructionAlignment = uint8_t(1);
+ assignEmitterFuncs(this);
+
if (Environment::is32Bit(arch)) {
// 32 bit architecture - X86.
_forcedInstOptions |= InstOptions::kX86_InvalidRex;
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86assembler.h b/3rdparty/asmjit/src/asmjit/x86/x86assembler.h
index dbffae62895..dd980a72692 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86assembler.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86assembler.h
@@ -38,13 +38,14 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! JitRuntime rt; // Create a runtime specialized for JIT.
//! CodeHolder code; // Create a CodeHolder.
//!
-//! code.init(rt.environment()); // Initialize code to match the JIT environment.
+//! code.init(rt.environment(), // Initialize code to match the JIT environment.
+//! rt.cpuFeatures());
//! x86::Assembler a(&code); // Create and attach x86::Assembler to code.
//!
//! // Decide between 32-bit CDECL, WIN64, and SysV64 calling conventions:
//! // 32-BIT - passed all arguments by stack.
//! // WIN64 - passes first 4 arguments by RCX, RDX, R8, and R9.
-//! // UNIX64 - passes first 6 arguments by RDI, RSI, RCX, RDX, R8, and R9.
+//! // UNIX64 - passes first 6 arguments by RDI, RSI, RDX, RCX, R8, and R9.
//! x86::Gp arr, cnt;
//! x86::Gp sum = x86::eax; // Use EAX as 'sum' as it's a return register.
//!
@@ -100,7 +101,7 @@ 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,
-//! and SysV64 caling conventions and will work on most X86/X64 environments.
+//! and SysV64 calling 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.
@@ -131,7 +132,8 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! JitRuntime rt; // Create a runtime specialized for JIT.
//! CodeHolder code; // Create a CodeHolder.
//!
-//! code.init(rt.environment()); // Initialize code to match the JIT environment.
+//! code.init(rt.environment(), // Initialize code to match the JIT environment.
+//! rt.cpuFeatures());
//! x86::Assembler a(&code); // Create and attach x86::Assembler to code.
//!
//! // Enable strict validation.
@@ -149,7 +151,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! printf("Status: %s\n", DebugUtils::errorAsString(err));
//!
//! // Ambiguous operand size - the pointer requires size.
-//! err = a.inc(x86::ptr(x86::rax), 1);
+//! err = a.inc(x86::ptr(x86::rax));
//! printf("Status: %s\n", DebugUtils::errorAsString(err));
//!
//! return 0;
@@ -187,7 +189,8 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! JitRuntime rt; // Create a runtime specialized for JIT.
//! CodeHolder code; // Create a CodeHolder.
//!
-//! code.init(rt.environment()); // Initialize code to match the JIT environment.
+//! code.init(rt.environment(), // Initialize code to match the JIT environment.
+//! rt.cpuFeatures());
//! x86::Assembler a(&code); // Create and attach x86::Assembler to code.
//!
//! // Let's get these registers from x86::Assembler.
@@ -227,6 +230,9 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! targets easily. If you want to create a register of native size dynamically by specifying its id it's also possible:
//!
//! ```
+//! #include <asmjit/x86.h>
+//! using namespace asmjit;
+//!
//! void example(x86::Assembler& a) {
//! x86::Gp zax = a.gpz(x86::Gp::kIdAx);
//! x86::Gp zbx = a.gpz(x86::Gp::kIdBx);
@@ -281,21 +287,21 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! #include <asmjit/x86.h>
//! using namespace asmjit;
//!
-//! void embedData(x86::Assembler& a, const Label& L_Data) {
+//! void processData(x86::Assembler& a, const Label& L_Data) {
//! x86::Gp addr = a.zax(); // EAX or RAX.
//! x86::Gp val = x86::edi; // Where to store some value...
//!
//! // Approach 1 - Load the address to register through LEA. This approach
//! // is flexible as the address can be then manipulated, for
//! // example if you have a data array, which would need index.
-//! a.lea(addr, L_Data); // Loads the address of the label to EAX or RAX.
-//! a.mov(val, dword_ptr(addr));
+//! a.lea(addr, x86::ptr(L_Data));
+//! a.mov(val, x86::dword_ptr(addr));
//!
//! // Approach 2 - Load the data directly by using L_Data in address. It's
//! // worth noting that this doesn't work with indexes in X64
//! // mode. It will use absolute address in 32-bit mode and
//! // relative address (RIP) in 64-bit mode.
-//! a.mov(val, dword_ptr(L_Data));
+//! a.mov(val, x86::dword_ptr(L_Data));
//! }
//! ```
//!
@@ -346,7 +352,8 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! JitRuntime rt; // Create JIT Runtime.
//! CodeHolder code; // Create a CodeHolder.
//!
-//! code.init(rt.environment()); // Initialize code to match the JIT environment.
+//! code.init(rt.environment(), // Initialize code to match the JIT environment.
+//! rt.cpuFeatures());
//! x86::Assembler a(&code); // Create and attach x86::Assembler to code.
//!
//! // Decide which registers will be mapped to function arguments. Try changing
@@ -356,18 +363,19 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! x86::Gp src_a = a.zcx();
//! x86::Gp src_b = a.zdx();
//!
-//! X86::Xmm vec0 = x86::xmm0;
-//! X86::Xmm vec1 = x86::xmm1;
+//! x86::Xmm vec0 = x86::xmm0;
+//! x86::Xmm vec1 = x86::xmm1;
//!
//! // Create/initialize FuncDetail and FuncFrame.
//! FuncDetail func;
-//! func.init(FuncSignatureT<void, int*, const int*, const int*>(CallConvId::kHost));
+//! func.init(FuncSignature::build<void, int*, const int*, const int*>(),
+//! rt.environment());
//!
//! FuncFrame frame;
//! frame.init(func);
//!
//! // Make XMM0 and XMM1 dirty - RegGroup::kVec describes XMM|YMM|ZMM registers.
-//! frame.setDirtyRegs(RegGroup::kVec, IntUtils::mask(0, 1));
+//! frame.setDirtyRegs(RegGroup::kVec, Support::bitMask(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.
@@ -375,7 +383,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//!
//! FuncArgsAssignment args(&func); // Create arguments assignment context.
//! args.assignAll(dst, src_a, src_b);// Assign our registers to arguments.
-//! args.updateFrameInfo(frame); // Reflect our args in FuncFrame.
+//! args.updateFuncFrame(frame); // Reflect our args in FuncFrame.
//! frame.finalize(); // Finalize the FuncFrame (updates it).
//!
//! a.emitProlog(frame); // Emit function prolog.
@@ -453,7 +461,8 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! JitRuntime rt; // Create a runtime specialized for JIT.
//! CodeHolder code; // Create a CodeHolder.
//!
-//! code.init(rt.environment()); // Initialize code to match the JIT environment.
+//! code.init(rt.environment(), // Initialize code to match the JIT environment.
+//! rt.cpuFeatures());
//! x86::Assembler a(&code); // Create and attach x86::Assembler to code.
//!
//! // Let's get these registers from x86::Assembler.
@@ -532,16 +541,16 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//!
//! void prefixesExample(x86::Assembler& a) {
//! // Lock prefix for implementing atomics:
-//! // lock add dword ptr [dst], 1
-//! a.lock().add(x86::dword_ptr(dst), 1);
+//! // lock add dword ptr [rdi], 1
+//! a.lock().add(x86::dword_ptr(x86::rdi), 1);
//!
//! // Similarly, XAcquire/XRelease prefixes are also available:
-//! // xacquire add dword ptr [dst], 1
-//! a.xacquire().add(x86::dword_ptr(dst), 1);
+//! // xacquire add dword ptr [rdi], 1
+//! a.xacquire().add(x86::dword_ptr(x86::rdi), 1);
//!
//! // Rep prefix (see also repe/repz and repne/repnz):
-//! // rep movs byte ptr [dst], byte ptr [src]
-//! a.rep().movs(x86::byte_ptr(dst), x86::byte_ptr(src));
+//! // rep movs byte ptr [rdi], byte ptr [rsi]
+//! a.rep().movs(x86::byte_ptr(x86::rdi), x86::byte_ptr(x86::rsi));
//!
//! // Forcing REX prefix in 64-bit mode.
//! // rex mov eax, 1
@@ -605,12 +614,12 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! // -----------------
//! //
//! // - Broadcast data is part of memory operand.
-//! // - Use x86::Mem::_1toN(), which returns a new x86::Mem operand.
+//! // - Use x86::Mem::_1to2(), x86::Mem::_1to4(), etc..., which returns a new x86::Mem operand with broadcast.
//!
//! // vaddpd zmm0 {k1} {z}, zmm1, [rcx] {1to8}
-//! a.k(k1).z().vaddpd(zmm0, zmm1, x86::mem(rcx)._1to8());
+//! a.k(k1).z().vaddpd(zmm0, zmm1, x86::ptr(rcx)._1to8());
//!
-//! // Embedded Rounding & Suppress-All-Exceptoins
+//! // Embedded Rounding & Suppress-All-Exceptions
//! // -------------------------------------------
//! //
//! // - Rounding mode and {sae} are part of instruction options.
@@ -637,7 +646,7 @@ public:
//! \{
ASMJIT_API explicit Assembler(CodeHolder* code = nullptr) noexcept;
- ASMJIT_API virtual ~Assembler() noexcept;
+ ASMJIT_API ~Assembler() noexcept override;
//! \}
@@ -648,12 +657,13 @@ public:
// 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; }
+ ASMJIT_INLINE_NODEBUG uint32_t _addressOverrideMask() const noexcept { return _privateData; }
+ ASMJIT_INLINE_NODEBUG void _setAddressOverrideMask(uint32_t m) noexcept { _privateData = m; }
//! \}
//! \endcond
+ //! \cond INTERNAL
//! \name Emit
//! \{
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86builder.cpp b/3rdparty/asmjit/src/asmjit/x86/x86builder.cpp
index a27948b65d4..9f025a15bc0 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86builder.cpp
+++ b/3rdparty/asmjit/src/asmjit/x86/x86builder.cpp
@@ -18,8 +18,6 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
Builder::Builder(CodeHolder* code) noexcept : BaseBuilder() {
_archMask = (uint64_t(1) << uint32_t(Arch::kX86)) |
(uint64_t(1) << uint32_t(Arch::kX64)) ;
- assignEmitterFuncs(this);
-
if (code)
code->attach(this);
}
@@ -29,7 +27,12 @@ Builder::~Builder() noexcept {}
// =====================
Error Builder::onAttach(CodeHolder* code) noexcept {
- return Base::onAttach(code);
+ ASMJIT_PROPAGATE(Base::onAttach(code));
+
+ _instructionAlignment = uint8_t(1);
+ assignEmitterFuncs(this);
+
+ return kErrorOk;
}
Error Builder::onDetach(CodeHolder* code) noexcept {
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86builder.h b/3rdparty/asmjit/src/asmjit/x86/x86builder.h
index f3bb11a0ca2..194c1402f11 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86builder.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86builder.h
@@ -36,7 +36,9 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! // Small helper function to print the current content of `cb`.
//! static void dumpCode(BaseBuilder& builder, const char* phase) {
//! String sb;
-//! builder.dump(sb);
+//! formatOptions formatOptions {};
+//!
+//! Formatter::formatNodeList(sb, formatOptions, &builder);
//! printf("%s:\n%s\n", phase, sb.data());
//! }
//!
@@ -44,7 +46,8 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! JitRuntime rt; // Create JIT Runtime.
//! CodeHolder code; // Create a CodeHolder.
//!
-//! code.init(rt.environment()); // Initialize code to match the JIT environment.
+//! code.init(rt.environment(), // Initialize code to match the JIT environment.
+//! rt.cpuFeatures());
//! x86::Builder cb(&code); // Create and attach x86::Builder to `code`.
//!
//! // Decide which registers will be mapped to function arguments. Try changing registers
@@ -58,7 +61,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//!
//! // Create and initialize `FuncDetail`.
//! FuncDetail func;
-//! func.init(FuncSignatureT<void, int*, const int*, const int*>(CallConvId::kHost));
+//! func.init(FuncSignature::build<void, int*, const int*, const int*>());
//!
//! // Remember prolog insertion point.
//! BaseNode* prologInsertionPoint = cb.cursor();
@@ -323,7 +326,7 @@ public:
//! \{
ASMJIT_API explicit Builder(CodeHolder* code = nullptr) noexcept;
- ASMJIT_API virtual ~Builder() noexcept;
+ ASMJIT_API ~Builder() noexcept override;
//! \}
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86compiler.cpp b/3rdparty/asmjit/src/asmjit/x86/x86compiler.cpp
index 04d09807076..830600edabc 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86compiler.cpp
+++ b/3rdparty/asmjit/src/asmjit/x86/x86compiler.cpp
@@ -19,8 +19,6 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
Compiler::Compiler(CodeHolder* code) noexcept : BaseCompiler() {
_archMask = (uint64_t(1) << uint32_t(Arch::kX86)) |
(uint64_t(1) << uint32_t(Arch::kX64)) ;
- assignEmitterFuncs(this);
-
if (code)
code->attach(this);
}
@@ -38,6 +36,9 @@ Error Compiler::onAttach(CodeHolder* code) noexcept {
return err;
}
+ _instructionAlignment = uint8_t(1);
+ assignEmitterFuncs(this);
+
return kErrorOk;
}
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86compiler.h b/3rdparty/asmjit/src/asmjit/x86/x86compiler.h
index d89aea02519..b281e208879 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86compiler.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86compiler.h
@@ -35,31 +35,32 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! typedef int (*Func)(void);
//!
//! int main() {
-//! JitRuntime rt; // Runtime specialized for JIT code execution.
-//! CodeHolder code; // Holds code and relocation information.
+//! JitRuntime rt; // Runtime specialized for JIT code execution.
+//! CodeHolder code; // Holds code and relocation information.
//!
-//! code.init(rt.environment()); // Initialize code to match the JIT environment.
-//! x86::Compiler cc(&code); // Create and attach x86::Compiler to code.
+//! code.init(rt.environment(), // Initialize code to match the JIT environment.
+//! rt.cpuFeatures());
+//! x86::Compiler cc(&code); // Create and attach x86::Compiler to code.
//!
-//! cc.addFunc(FuncSignatureT<int>());// Begin a function of `int fn(void)` signature.
+//! cc.addFunc(FuncSignature::build<int>()); // Begin a function of `int fn(void)` signature.
//!
-//! x86::Gp vReg = cc.newGpd(); // Create a 32-bit general purpose register.
-//! cc.mov(vReg, 1); // Move one to our virtual register `vReg`.
-//! cc.ret(vReg); // Return `vReg` from the function.
+//! x86::Gp vReg = cc.newGpd(); // Create a 32-bit general purpose register.
+//! cc.mov(vReg, 1); // Move one to our virtual register `vReg`.
+//! cc.ret(vReg); // Return `vReg` from the function.
//!
-//! cc.endFunc(); // End of the function body.
-//! cc.finalize(); // Translate and assemble the whole 'cc' content.
+//! cc.endFunc(); // End of the function body.
+//! cc.finalize(); // Translate and assemble the whole 'cc' content.
//! // ----> x86::Compiler is no longer needed from here and can be destroyed <----
//!
//! Func fn;
-//! Error err = rt.add(&fn, &code); // Add the generated code to the runtime.
-//! if (err) return 1; // Handle a possible error returned by AsmJit.
+//! Error err = rt.add(&fn, &code); // Add the generated code to the runtime.
+//! if (err) return 1; // Handle a possible error returned by AsmJit.
//! // ----> CodeHolder is no longer needed from here and can be destroyed <----
//!
-//! int result = fn(); // Execute the generated code.
-//! printf("%d\n", result); // Print the resulting "1".
+//! int result = fn(); // Execute the generated code.
+//! printf("%d\n", result); // Print the resulting "1".
//!
-//! rt.release(fn); // Explicitly remove the function from the runtime.
+//! rt.release(fn); // Explicitly remove the function from the runtime.
//! return 0;
//! }
//! ```
@@ -79,48 +80,49 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! typedef void (*MemCpy32)(uint32_t* dst, const uint32_t* src, size_t count);
//!
//! int main() {
-//! JitRuntime rt; // Runtime specialized for JIT code execution.
-//! CodeHolder code; // Holds code and relocation information.
+//! JitRuntime rt; // Runtime specialized for JIT code execution.
+//! CodeHolder code; // Holds code and relocation information.
//!
-//! code.init(rt.environment()); // Initialize code to match the JIT environment.
-//! x86::Compiler cc(&code); // Create and attach x86::Compiler to code.
+//! code.init(rt.environment(), // Initialize code to match the JIT environment.
+//! rt.cpuFeatures());
+//! x86::Compiler cc(&code); // Create and attach x86::Compiler to code.
//!
-//! 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).
-//! size_t>()); // 3rd argument - size_t (machine reg-size).
+//! FuncNode* funcNode = cc.addFunc ( // Begin the function of the following signature:
+//! FuncSignature::build<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).
+//! size_t>()); // 3rd argument - size_t (machine reg-size).
//!
-//! Label L_Loop = cc.newLabel(); // Start of the loop.
-//! Label L_Exit = cc.newLabel(); // Used to exit early.
+//! Label L_Loop = cc.newLabel(); // Start of the loop.
+//! Label L_Exit = cc.newLabel(); // Used to exit early.
//!
-//! x86::Gp dst = cc.newIntPtr("dst");// Create `dst` register (destination pointer).
-//! x86::Gp src = cc.newIntPtr("src");// Create `src` register (source pointer).
-//! x86::Gp i = cc.newUIntPtr("i"); // Create `i` register (loop counter).
+//! x86::Gp dst = cc.newIntPtr("dst"); // Create `dst` register (destination pointer).
+//! x86::Gp src = cc.newIntPtr("src"); // Create `src` register (source pointer).
+//! x86::Gp i = cc.newUIntPtr("i"); // Create `i` register (loop counter).
//!
-//! funcNode->setArg(0, dst); // Assign `dst` argument.
-//! funcNode->setArg(1, src); // Assign `src` argument.
-//! funcNode->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.test(i, i); // Early exit if length is zero.
//! cc.jz(L_Exit);
//!
-//! cc.bind(L_Loop); // Bind the beginning of the loop here.
+//! cc.bind(L_Loop); // Bind the beginning of the loop here.
//!
-//! x86::Gp tmp = cc.newInt32("tmp"); // Copy a single dword (4 bytes).
-//! cc.mov(tmp, x86::dword_ptr(src)); // Load DWORD from [src] address.
-//! cc.mov(x86::dword_ptr(dst), tmp); // Store DWORD to [dst] address.
+//! x86::Gp tmp = cc.newInt32("tmp"); // Copy a single dword (4 bytes).
+//! cc.mov(tmp, x86::dword_ptr(src)); // Load DWORD from [src] address.
+//! cc.mov(x86::dword_ptr(dst), tmp); // Store DWORD to [dst] address.
//!
-//! cc.add(src, 4); // Increment `src`.
-//! cc.add(dst, 4); // Increment `dst`.
+//! cc.add(src, 4); // Increment `src`.
+//! cc.add(dst, 4); // Increment `dst`.
//!
-//! cc.dec(i); // Loop until `i` is non-zero.
+//! cc.dec(i); // Loop until `i` is non-zero.
//! cc.jnz(L_Loop);
//!
-//! cc.bind(L_Exit); // Label used by early exit.
-//! cc.endFunc(); // End of the function body.
+//! cc.bind(L_Exit); // Label used by early exit.
+//! cc.endFunc(); // End of the function body.
//!
-//! cc.finalize(); // Translate and assemble the whole 'cc' content.
+//! cc.finalize(); // Translate and assemble the whole 'cc' content.
//! // ----> x86::Compiler is no longer needed from here and can be destroyed <----
//!
//! // Add the generated code to the runtime.
@@ -161,13 +163,14 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! typedef void (*Func)(void*);
//!
//! int main() {
-//! JitRuntime rt; // Runtime specialized for JIT code execution.
-//! CodeHolder code; // Holds code and relocation information.
+//! JitRuntime rt; // Runtime specialized for JIT code execution.
+//! CodeHolder code; // Holds code and relocation information.
//!
-//! code.init(rt.environment()); // Initialize code to match the JIT environment.
-//! x86::Compiler cc(&code); // Create and attach x86::Compiler to code.
+//! code.init(rt.environment(), // Initialize code to match the JIT environment.
+//! rt.cpuFeatures());
+//! x86::Compiler cc(&code); // Create and attach x86::Compiler to code.
//!
-//! FuncNode* funcNode = cc.addFunc(FuncSignatureT<void, void*>());
+//! FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, void*>());
//!
//! // Use the following to enable AVX and/or AVX-512.
//! funcNode->frame().setAvxEnabled();
@@ -183,13 +186,13 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! cc.vpaddq(vreg, vreg, vreg);
//! cc.vmovdqu32(x86::ptr(addr), vreg);
//!
-//! cc.endFunc(); // End of the function body.
-//! cc.finalize(); // Translate and assemble the whole 'cc' content.
+//! cc.endFunc(); // End of the function body.
+//! cc.finalize(); // Translate and assemble the whole 'cc' content.
//! // ----> x86::Compiler is no longer needed from here and can be destroyed <----
//!
//! Func fn;
-//! Error err = rt.add(&fn, &code); // Add the generated code to the runtime.
-//! if (err) return 1; // Handle a possible error returned by AsmJit.
+//! Error err = rt.add(&fn, &code); // Add the generated code to the runtime.
+//! if (err) return 1; // Handle a possible error returned by AsmJit.
//! // ----> CodeHolder is no longer needed from here and can be destroyed <----
//!
//! // Execute the generated code and print some output.
@@ -197,7 +200,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! fn(data);
//! printf("%llu\n", (unsigned long long)data[0]);
//!
-//! rt.release(fn); // Explicitly remove the function from the runtime.
+//! rt.release(fn); // Explicitly remove the function from the runtime.
//! return 0;
//! }
//! ```
@@ -219,47 +222,48 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! typedef uint32_t (*Fibonacci)(uint32_t x);
//!
//! int main() {
-//! JitRuntime rt; // Runtime specialized for JIT code execution.
-//! CodeHolder code; // Holds code and relocation information.
+//! JitRuntime rt; // Runtime specialized for JIT code execution.
+//! CodeHolder code; // Holds code and relocation information.
//!
-//! code.init(rt.environment()); // Initialize code to match the JIT environment.
-//! x86::Compiler cc(&code); // Create and attach x86::Compiler to code.
+//! code.init(rt.environment(), // Initialize code to match the JIT environment.
+//! rt.cpuFeatures());
+//! x86::Compiler cc(&code); // Create and attach x86::Compiler to code.
//!
-//! FuncNode* funcNode = cc.addFunc( // Begin of the Fibonacci function, addFunc()
-//! FuncSignatureT<int, int>()); // Returns a pointer to the FuncNode node.
+//! FuncNode* funcNode = cc.addFunc( // Begin of the Fibonacci function, addFunc()
+//! FuncSignature::build<int, int>()); // Returns a pointer to the FuncNode node.
//!
-//! Label L_Exit = cc.newLabel() // Exit label.
-//! x86::Gp x = cc.newUInt32(); // Function x argument.
-//! x86::Gp y = cc.newUInt32(); // Temporary.
+//! Label L_Exit = cc.newLabel(); // Exit label.
+//! x86::Gp x = cc.newUInt32(); // Function x argument.
+//! x86::Gp y = cc.newUInt32(); // Temporary.
//!
//! funcNode->setArg(0, x);
//!
-//! cc.cmp(x, 3); // Return x if less than 3.
+//! cc.cmp(x, 3); // Return x if less than 3.
//! cc.jb(L_Exit);
//!
-//! cc.mov(y, x); // Make copy of the original x.
-//! cc.dec(x); // Decrease x.
+//! cc.mov(y, x); // Make copy of the original x.
+//! cc.dec(x); // Decrease x.
//!
-//! InvokeNode* invokeNode; // Function invocation:
-//! cc.invoke(&invokeNode, // - InvokeNode (output).
-//! funcNode->label(), // - Function address or Label.
-//! FuncSignatureT<int, int>()); // - Function signature.
+//! InvokeNode* invokeNode; // Function invocation:
+//! cc.invoke(&invokeNode, // - InvokeNode (output).
+//! funcNode->label(), // - Function address or Label.
+//! FuncSignature::build<int, int>()); // - Function signature.
//!
-//! invokeNode->setArg(0, x); // Assign x as the first argument.
-//! invokeNode->setRet(0, x); // Assign x as a return value as well.
+//! invokeNode->setArg(0, x); // Assign x as the first argument.
+//! invokeNode->setRet(0, x); // Assign x as a return value as well.
//!
-//! cc.add(x, y); // Combine the return value with y.
+//! cc.add(x, y); // Combine the return value with y.
//!
//! cc.bind(L_Exit);
-//! cc.ret(x); // Return x.
-//! cc.endFunc(); // End of the function body.
+//! cc.ret(x); // Return x.
+//! cc.endFunc(); // End of the function body.
//!
-//! cc.finalize(); // Translate and assemble the whole 'cc' content.
+//! cc.finalize(); // Translate and assemble the whole 'cc' content.
//! // ----> x86::Compiler is no longer needed from here and can be destroyed <----
//!
//! Fibonacci fib;
-//! Error err = rt.add(&fib, &code); // Add the generated code to the runtime.
-//! if (err) return 1; // Handle a possible error returned by AsmJit.
+//! Error err = rt.add(&fib, &code); // Add the generated code to the runtime.
+//! if (err) return 1; // Handle a possible error returned by AsmJit.
//! // ----> CodeHolder is no longer needed from here and can be destroyed <----
//!
//! // Test the generated code.
@@ -287,13 +291,14 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! typedef int (*Func)(void);
//!
//! int main() {
-//! JitRuntime rt; // Runtime specialized for JIT code execution.
-//! CodeHolder code; // Holds code and relocation information.
+//! JitRuntime rt; // Runtime specialized for JIT code execution.
+//! CodeHolder code; // Holds code and relocation information.
//!
-//! code.init(rt.environment()); // Initialize code to match the JIT environment.
-//! x86::Compiler cc(&code); // Create and attach x86::Compiler to code.
+//! code.init(rt.environment(), // Initialize code to match the JIT environment.
+//! rt.cpuFeatures());
+//! x86::Compiler cc(&code); // Create and attach x86::Compiler to code.
//!
-//! cc.addFunc(FuncSignatureT<int>());// Create a function that returns int.
+//! cc.addFunc(FuncSignature::build<int>()); // Create a function that returns int.
//!
//! x86::Gp p = cc.newIntPtr("p");
//! x86::Gp i = cc.newIntPtr("i");
@@ -301,9 +306,9 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! // Allocate 256 bytes on the stack aligned to 4 bytes.
//! x86::Mem stack = cc.newStack(256, 4);
//!
-//! x86::Mem stackIdx(stack); // Copy of stack with i added.
-//! stackIdx.setIndex(i); // stackIdx <- stack[i].
-//! stackIdx.setSize(1); // stackIdx <- byte ptr stack[i].
+//! x86::Mem stackIdx(stack); // Copy of stack with i added.
+//! stackIdx.setIndex(i); // stackIdx <- stack[i].
+//! stackIdx.setSize(1); // stackIdx <- byte ptr stack[i].
//!
//! // Load a stack address to `p`. This step is purely optional and shows
//! // that `lea` is useful to load a memory operands address (even absolute)
@@ -316,12 +321,12 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! Label L1 = cc.newLabel();
//! Label L2 = cc.newLabel();
//!
-//! cc.bind(L1); // First loop, fill the stack.
-//! cc.mov(stackIdx, i.r8()); // stack[i] = uint8_t(i).
+//! cc.bind(L1); // First loop, fill the stack.
+//! cc.mov(stackIdx, i.r8()); // stack[i] = uint8_t(i).
//!
-//! cc.inc(i); // i++;
-//! cc.cmp(i, 256); // if (i < 256)
-//! cc.jb(L1); // goto L1;
+//! cc.inc(i); // i++;
+//! cc.cmp(i, 256); // if (i < 256)
+//! cc.jb(L1); // goto L1;
//!
//! // Second loop, sum all bytes stored in `stack`.
//! x86::Gp sum = cc.newInt32("sum");
@@ -332,25 +337,25 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//!
//! cc.bind(L2);
//!
-//! cc.movzx(val, stackIdx); // val = uint32_t(stack[i]);
-//! cc.add(sum, val); // sum += val;
+//! cc.movzx(val, stackIdx); // val = uint32_t(stack[i]);
+//! cc.add(sum, val); // sum += val;
//!
-//! cc.inc(i); // i++;
-//! cc.cmp(i, 256); // if (i < 256)
-//! cc.jb(L2); // goto L2;
+//! cc.inc(i); // i++;
+//! cc.cmp(i, 256); // if (i < 256)
+//! cc.jb(L2); // goto L2;
//!
-//! cc.ret(sum); // Return the `sum` of all values.
-//! cc.endFunc(); // End of the function body.
+//! cc.ret(sum); // Return the `sum` of all values.
+//! cc.endFunc(); // End of the function body.
//!
-//! cc.finalize(); // Translate and assemble the whole 'cc' content.
+//! cc.finalize(); // Translate and assemble the whole 'cc' content.
//! // ----> x86::Compiler is no longer needed from here and can be destroyed <----
//!
//! Func func;
-//! Error err = rt.add(&func, &code); // Add the generated code to the runtime.
-//! if (err) return 1; // Handle a possible error returned by AsmJit.
+//! Error err = rt.add(&func, &code); // Add the generated code to the runtime.
+//! if (err) return 1; // Handle a possible error returned by AsmJit.
//! // ----> CodeHolder is no longer needed from here and can be destroyed <----
//!
-//! printf("Func() -> %d\n", func()); // Test the generated code.
+//! printf("Func() -> %d\n", func()); // Test the generated code.
//!
//! rt.release(func);
//! return 0;
@@ -375,7 +380,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! using namespace asmjit;
//!
//! static void exampleUseOfConstPool(x86::Compiler& cc) {
-//! cc.addFunc(FuncSignatureT<int>());
+//! cc.addFunc(FuncSignature::build<int>());
//!
//! x86::Gp v0 = cc.newGpd("v0");
//! x86::Gp v1 = cc.newGpd("v1");
@@ -409,7 +414,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! using namespace asmjit;
//!
//! static void exampleUseOfIndirectJump(x86::Compiler& cc) {
-//! FuncNode* funcNode = cc.addFunc(FuncSignatureT<float, float, float, uint32_t>(CallConvId::kHost));
+//! FuncNode* funcNode = cc.addFunc(FuncSignature::build<float, float, float, uint32_t>());
//!
//! // Function arguments
//! x86::Xmm a = cc.newXmmSs("a");
@@ -489,7 +494,7 @@ public:
//! \{
ASMJIT_API explicit Compiler(CodeHolder* code = nullptr) noexcept;
- ASMJIT_API virtual ~Compiler() noexcept;
+ ASMJIT_API ~Compiler() noexcept override;
//! \}
@@ -497,52 +502,52 @@ public:
//! \{
#ifndef ASMJIT_NO_LOGGING
-# define ASMJIT_NEW_REG_FMT(OUT, PARAM, FORMAT, ARGS) \
+# define ASMJIT_NEW_REG_FMT(OUT, PARAM, FORMAT, ARGS) \
_newRegFmt(&OUT, PARAM, FORMAT, ARGS)
#else
-# define ASMJIT_NEW_REG_FMT(OUT, PARAM, FORMAT, ARGS) \
- DebugUtils::unused(FORMAT); \
- DebugUtils::unused(std::forward<Args>(args)...); \
+# define ASMJIT_NEW_REG_FMT(OUT, PARAM, FORMAT, ARGS) \
+ DebugUtils::unused(FORMAT); \
+ DebugUtils::unused(std::forward<Args>(args)...); \
_newReg(&OUT, PARAM)
#endif
-#define ASMJIT_NEW_REG_CUSTOM(FUNC, REG) \
- inline REG FUNC(TypeId typeId) { \
- REG reg(Globals::NoInit); \
- _newReg(&reg, typeId); \
- return reg; \
- } \
- \
- template<typename... 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; \
+#define ASMJIT_NEW_REG_CUSTOM(FUNC, REG) \
+ ASMJIT_INLINE_NODEBUG REG FUNC(TypeId typeId) { \
+ REG reg(Globals::NoInit); \
+ _newReg(&reg, typeId); \
+ return reg; \
+ } \
+ \
+ template<typename... Args> \
+ ASMJIT_INLINE_NODEBUG 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; \
}
-#define ASMJIT_NEW_REG_TYPED(FUNC, REG, TYPE_ID) \
- inline REG FUNC() { \
- REG reg(Globals::NoInit); \
- _newReg(&reg, TYPE_ID); \
- return reg; \
- } \
- \
- template<typename... Args> \
- inline REG FUNC(const char* fmt, Args&&... args) { \
- REG reg(Globals::NoInit); \
- ASMJIT_NEW_REG_FMT(reg, TYPE_ID, fmt, std::forward<Args>(args)...); \
- return reg; \
+#define ASMJIT_NEW_REG_TYPED(FUNC, REG, TYPE_ID) \
+ ASMJIT_INLINE_NODEBUG REG FUNC() { \
+ REG reg(Globals::NoInit); \
+ _newReg(&reg, TYPE_ID); \
+ return reg; \
+ } \
+ \
+ template<typename... Args> \
+ ASMJIT_INLINE_NODEBUG REG FUNC(const char* fmt, Args&&... args) { \
+ REG reg(Globals::NoInit); \
+ ASMJIT_NEW_REG_FMT(reg, TYPE_ID, fmt, std::forward<Args>(args)...); \
+ return reg; \
}
template<typename RegT>
- inline RegT newSimilarReg(const RegT& ref) {
+ ASMJIT_INLINE_NODEBUG RegT newSimilarReg(const RegT& ref) {
RegT reg(Globals::NoInit);
- _newReg(reg, ref);
+ _newReg(&reg, ref);
return reg;
}
template<typename RegT, typename... Args>
- inline RegT newSimilarReg(const RegT& ref, const char* fmt, Args&&... args) {
+ ASMJIT_INLINE_NODEBUG RegT newSimilarReg(const RegT& ref, const char* fmt, Args&&... args) {
RegT reg(Globals::NoInit);
ASMJIT_NEW_REG_FMT(reg, ref, fmt, std::forward<Args>(args)...);
return reg;
@@ -596,7 +601,7 @@ public:
//! \{
//! Creates a new memory chunk allocated on the current function's stack.
- inline Mem newStack(uint32_t size, uint32_t alignment, const char* name = nullptr) {
+ ASMJIT_INLINE_NODEBUG Mem newStack(uint32_t size, uint32_t alignment, const char* name = nullptr) {
Mem m(Globals::NoInit);
_newStack(&m, size, alignment, name);
return m;
@@ -608,38 +613,38 @@ public:
//! \{
//! Put data to a constant-pool and get a memory reference to it.
- inline Mem newConst(ConstPoolScope scope, const void* data, size_t size) {
+ ASMJIT_INLINE_NODEBUG 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(ConstPoolScope scope, uint8_t val) noexcept { return newConst(scope, &val, 1); }
+ ASMJIT_INLINE_NODEBUG Mem newByteConst(ConstPoolScope scope, uint8_t val) noexcept { return newConst(scope, &val, 1); }
//! Put a WORD `val` to a constant-pool.
- inline Mem newWordConst(ConstPoolScope scope, uint16_t val) noexcept { return newConst(scope, &val, 2); }
+ ASMJIT_INLINE_NODEBUG Mem newWordConst(ConstPoolScope scope, uint16_t val) noexcept { return newConst(scope, &val, 2); }
//! Put a DWORD `val` to a constant-pool.
- inline Mem newDWordConst(ConstPoolScope scope, uint32_t val) noexcept { return newConst(scope, &val, 4); }
+ ASMJIT_INLINE_NODEBUG Mem newDWordConst(ConstPoolScope scope, uint32_t val) noexcept { return newConst(scope, &val, 4); }
//! Put a QWORD `val` to a constant-pool.
- inline Mem newQWordConst(ConstPoolScope scope, uint64_t val) noexcept { return newConst(scope, &val, 8); }
+ ASMJIT_INLINE_NODEBUG Mem newQWordConst(ConstPoolScope scope, uint64_t val) noexcept { return newConst(scope, &val, 8); }
//! Put a WORD `val` to a constant-pool.
- inline Mem newInt16Const(ConstPoolScope scope, int16_t val) noexcept { return newConst(scope, &val, 2); }
+ ASMJIT_INLINE_NODEBUG Mem newInt16Const(ConstPoolScope scope, int16_t val) noexcept { return newConst(scope, &val, 2); }
//! Put a WORD `val` to a constant-pool.
- inline Mem newUInt16Const(ConstPoolScope scope, uint16_t val) noexcept { return newConst(scope, &val, 2); }
+ ASMJIT_INLINE_NODEBUG Mem newUInt16Const(ConstPoolScope scope, uint16_t val) noexcept { return newConst(scope, &val, 2); }
//! Put a DWORD `val` to a constant-pool.
- inline Mem newInt32Const(ConstPoolScope scope, int32_t val) noexcept { return newConst(scope, &val, 4); }
+ ASMJIT_INLINE_NODEBUG Mem newInt32Const(ConstPoolScope scope, int32_t val) noexcept { return newConst(scope, &val, 4); }
//! Put a DWORD `val` to a constant-pool.
- inline Mem newUInt32Const(ConstPoolScope scope, uint32_t val) noexcept { return newConst(scope, &val, 4); }
+ ASMJIT_INLINE_NODEBUG Mem newUInt32Const(ConstPoolScope scope, uint32_t val) noexcept { return newConst(scope, &val, 4); }
//! Put a QWORD `val` to a constant-pool.
- inline Mem newInt64Const(ConstPoolScope scope, int64_t val) noexcept { return newConst(scope, &val, 8); }
+ ASMJIT_INLINE_NODEBUG Mem newInt64Const(ConstPoolScope scope, int64_t val) noexcept { return newConst(scope, &val, 8); }
//! Put a QWORD `val` to a constant-pool.
- inline Mem newUInt64Const(ConstPoolScope scope, uint64_t val) noexcept { return newConst(scope, &val, 8); }
+ ASMJIT_INLINE_NODEBUG 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(ConstPoolScope scope, float val) noexcept { return newConst(scope, &val, 4); }
+ ASMJIT_INLINE_NODEBUG Mem newFloatConst(ConstPoolScope scope, float val) noexcept { return newConst(scope, &val, 4); }
//! Put a DP-FP `val` to a constant-pool.
- inline Mem newDoubleConst(ConstPoolScope scope, double val) noexcept { return newConst(scope, &val, 8); }
+ ASMJIT_INLINE_NODEBUG Mem newDoubleConst(ConstPoolScope scope, double val) noexcept { return newConst(scope, &val, 8); }
//! \}
@@ -647,9 +652,9 @@ public:
//! \{
//! Force the compiler to not follow the conditional or unconditional jump.
- inline Compiler& unfollow() noexcept { addInstOptions(InstOptions::kUnfollow); return *this; }
+ ASMJIT_INLINE_NODEBUG Compiler& unfollow() noexcept { addInstOptions(InstOptions::kUnfollow); return *this; }
//! Tell the compiler that the destination variable will be overwritten.
- inline Compiler& overwrite() noexcept { addInstOptions(InstOptions::kOverwrite); return *this; }
+ ASMJIT_INLINE_NODEBUG Compiler& overwrite() noexcept { addInstOptions(InstOptions::kOverwrite); return *this; }
//! \}
@@ -657,7 +662,7 @@ public:
//! \{
//! Invoke a function call without `target` type enforcement.
- inline Error invoke_(InvokeNode** out, const Operand_& target, const FuncSignature& signature) {
+ ASMJIT_INLINE_NODEBUG Error invoke_(InvokeNode** out, const Operand_& target, const FuncSignature& signature) {
return addInvokeNode(out, Inst::kIdCall, target, signature);
}
@@ -666,22 +671,22 @@ public:
//! 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); }
+ ASMJIT_INLINE_NODEBUG Error invoke(InvokeNode** out, const Gp& target, const FuncSignature& signature) { return invoke_(out, target, signature); }
//! \overload
- inline Error invoke(InvokeNode** out, const Mem& target, const FuncSignature& signature) { return invoke_(out, target, signature); }
+ ASMJIT_INLINE_NODEBUG Error invoke(InvokeNode** out, const Mem& target, const FuncSignature& signature) { return invoke_(out, target, signature); }
//! \overload
- inline Error invoke(InvokeNode** out, const Label& target, const FuncSignature& signature) { return invoke_(out, target, signature); }
+ ASMJIT_INLINE_NODEBUG Error invoke(InvokeNode** out, const Label& target, const FuncSignature& signature) { return invoke_(out, target, signature); }
//! \overload
- inline Error invoke(InvokeNode** out, const Imm& target, const FuncSignature& signature) { return invoke_(out, target, signature); }
+ ASMJIT_INLINE_NODEBUG Error invoke(InvokeNode** out, const Imm& target, const FuncSignature& signature) { return invoke_(out, target, signature); }
//! \overload
- inline Error invoke(InvokeNode** out, uint64_t target, const FuncSignature& signature) { return invoke_(out, Imm(int64_t(target)), signature); }
+ ASMJIT_INLINE_NODEBUG Error invoke(InvokeNode** out, uint64_t target, const FuncSignature& signature) { return invoke_(out, Imm(int64_t(target)), signature); }
//! Return from function.
- inline Error ret() { return addRet(Operand(), Operand()); }
+ ASMJIT_INLINE_NODEBUG Error ret() { return addRet(Operand(), Operand()); }
//! \overload
- inline Error ret(const BaseReg& o0) { return addRet(o0, Operand()); }
+ ASMJIT_INLINE_NODEBUG Error ret(const BaseReg& o0) { return addRet(o0, Operand()); }
//! \overload
- inline Error ret(const BaseReg& o0, const BaseReg& o1) { return addRet(o0, o1); }
+ ASMJIT_INLINE_NODEBUG Error ret(const BaseReg& o0, const BaseReg& o1) { return addRet(o0, o1); }
//! \}
@@ -691,9 +696,9 @@ public:
using EmitterExplicitT<Compiler>::jmp;
//! Adds a jump to the given `target` with the provided jump `annotation`.
- inline Error jmp(const BaseReg& target, JumpAnnotation* annotation) { return emitAnnotatedJump(Inst::kIdJmp, target, annotation); }
+ ASMJIT_INLINE_NODEBUG Error jmp(const BaseReg& target, JumpAnnotation* annotation) { return emitAnnotatedJump(Inst::kIdJmp, target, annotation); }
//! \overload
- inline Error jmp(const BaseMem& target, JumpAnnotation* annotation) { return emitAnnotatedJump(Inst::kIdJmp, target, annotation); }
+ ASMJIT_INLINE_NODEBUG Error jmp(const BaseMem& target, JumpAnnotation* annotation) { return emitAnnotatedJump(Inst::kIdJmp, target, annotation); }
//! \}
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86emithelper.cpp b/3rdparty/asmjit/src/asmjit/x86/x86emithelper.cpp
index b541c048b04..9cd1db68423 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86emithelper.cpp
+++ b/3rdparty/asmjit/src/asmjit/x86/x86emithelper.cpp
@@ -22,6 +22,18 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
// x86::EmitHelper - Utilities
// ===========================
+static constexpr OperandSignature regSizeToGpSignature[8 + 1] = {
+ OperandSignature{0},
+ OperandSignature{RegTraits<RegType::kX86_GpbLo>::kSignature},
+ OperandSignature{RegTraits<RegType::kX86_Gpw>::kSignature},
+ OperandSignature{0},
+ OperandSignature{RegTraits<RegType::kX86_Gpd>::kSignature},
+ OperandSignature{0},
+ OperandSignature{0},
+ OperandSignature{0},
+ OperandSignature{RegTraits<RegType::kX86_Gpq>::kSignature}
+};
+
static inline uint32_t getXmmMovInst(const FuncFrame& frame) {
bool avx = frame.isAvxEnabled();
bool aligned = frame.hasAlignedVecSR();
@@ -70,8 +82,8 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitRegMove(
// 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()); }
+ if (dst.isMem()) { memFlags |= kDstMem; dst.as<Mem>().setSize(src.as<Mem>().size()); }
+ if (src.isMem()) { memFlags |= kSrcMem; src.as<Mem>().setSize(dst.as<Mem>().size()); }
switch (typeId) {
case TypeId::kInt8:
@@ -182,41 +194,42 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitArgMove(
// Not a real loop, just 'break' is nicer than 'goto'.
for (;;) {
if (TypeUtils::isInt(dstTypeId)) {
+ // Sign extend.
if (TypeUtils::isInt(srcTypeId)) {
- instId = Inst::kIdMovsx;
uint32_t castOp = makeCastOp(dstTypeId, srcTypeId);
- // Sign extend by using 'movsx'.
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 (castOp == makeCastOp(TypeId::kInt64, TypeId::kInt32))
+ castOp == makeCastOp(TypeId::kInt32, TypeId::kInt16) ||
+ castOp == makeCastOp(TypeId::kInt64, TypeId::kInt16) ||
+ castOp == makeCastOp(TypeId::kInt64, TypeId::kInt32)) {
+ // Sign extend by using 'movsx' or 'movsxd'.
+ instId =
+ castOp == makeCastOp(TypeId::kInt64, TypeId::kInt32)
+ ? Inst::kIdMovsxd
+ : Inst::kIdMovsx;
+
+ dst.setSignature(regSizeToGpSignature[dstSize]);
+ if (src.isReg())
+ src.setSignature(regSizeToGpSignature[srcSize]);
break;
+ }
}
+ // Zero extend.
if (TypeUtils::isInt(srcTypeId) || src_.isMem()) {
+ uint32_t movSize = Support::min(srcSize, dstSize);
+ if (movSize <= 4)
+ dstSize = 4;
+
// Zero extend by using 'movzx' or 'mov'.
- if (dstSize <= 4 && srcSize < 4) {
- instId = Inst::kIdMovzx;
- 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.
- instId = Inst::kIdMov;
- srcSize = Support::min(srcSize, dstSize);
-
- dst.setSignature(srcSize == 4 ? Reg::signatureOfT<RegType::kX86_Gpd>()
- : Reg::signatureOfT<RegType::kX86_Gpq>());
- if (src.isReg())
- src.setSignature(dst.signature());
- }
+ instId = movSize < 4 ? Inst::kIdMovzx : Inst::kIdMov;
+ srcSize = Support::min(srcSize, movSize);
+
+ dst.setSignature(regSizeToGpSignature[dstSize]);
+ if (src.isReg())
+ src.setSignature(regSizeToGpSignature[srcSize]);
break;
}
@@ -394,25 +407,29 @@ Error EmitHelper::emitRegSwap(
// x86::EmitHelper - Emit Prolog & Epilog
// ======================================
-static inline void X86Internal_setupSaveRestoreInfo(RegGroup group, const FuncFrame& frame, Reg& xReg, uint32_t& xInst, uint32_t& xSize) noexcept {
+static inline Error X86Internal_setupSaveRestoreInfo(RegGroup group, const FuncFrame& frame, Reg& xReg, uint32_t& xInst, uint32_t& xSize) noexcept {
switch (group) {
case RegGroup::kVec:
xReg = xmm(0);
xInst = getXmmMovInst(frame);
xSize = xReg.size();
- break;
+ return kErrorOk;
+
case RegGroup::kX86_K:
xReg = k(0);
xInst = Inst::kIdKmovq;
xSize = xReg.size();
- break;
+ return kErrorOk;
+
case RegGroup::kX86_MM:
xReg = mm(0);
xInst = Inst::kIdMovq;
xSize = xReg.size();
- break;
+ return kErrorOk;
+
default:
- break;
+ // This would be a bug in AsmJit if hit.
+ return DebugUtils::errored(kErrorInvalidState);
}
}
@@ -425,6 +442,12 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitProlog(const FuncFrame& frame) {
Gp gpReg = zsp; // General purpose register (temporary).
Gp saReg = zsp; // Stack-arguments base pointer.
+ // Emit: 'endbr32' or 'endbr64' (indirect branch protection).
+ if (frame.hasIndirectBranchProtection()) {
+ InstId instId = emitter->is32Bit() ? Inst::kIdEndbr32 : Inst::kIdEndbr64;
+ ASMJIT_PROPAGATE(emitter->emit(instId));
+ }
+
// Emit: 'push zbp'
// 'mov zbp, zsp'.
if (frame.hasPreservedFP()) {
@@ -473,16 +496,15 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitProlog(const FuncFrame& frame) {
// Emit 'movxxx [zsp + X], {[x|y|z]mm, k}'.
{
- Reg xReg;
Mem xBase = ptr(zsp, int32_t(frame.extraRegSaveOffset()));
- uint32_t xInst;
- uint32_t xSize;
-
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);
+ Reg xReg;
+ uint32_t xInst = 0;
+ uint32_t xSize = 0;
+ ASMJIT_PROPAGATE(X86Internal_setupSaveRestoreInfo(group, frame, xReg, xInst, xSize));
do {
xReg.setId(it.next());
ASMJIT_PROPAGATE(emitter->emit(xInst, xBase, xReg));
@@ -514,16 +536,15 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitEpilog(const FuncFrame& frame) {
// Emit 'movxxx {[x|y|z]mm, k}, [zsp + X]'.
{
- Reg xReg;
Mem xBase = ptr(zsp, int32_t(frame.extraRegSaveOffset()));
- uint32_t xInst;
- uint32_t xSize;
-
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);
+ Reg xReg;
+ uint32_t xInst;
+ uint32_t xSize;
+ ASMJIT_PROPAGATE(X86Internal_setupSaveRestoreInfo(group, frame, xReg, xInst, xSize));
do {
xReg.setId(it.next());
ASMJIT_PROPAGATE(emitter->emit(xInst, xReg, xBase));
@@ -610,7 +631,7 @@ void assignEmitterFuncs(BaseEmitter* emitter) {
#endif
#ifndef ASMJIT_NO_VALIDATION
- emitter->_funcs.validate = InstInternal::validate;
+ emitter->_funcs.validate = emitter->is32Bit() ? InstInternal::validateX86 : InstInternal::validateX64;
#endif
}
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86emithelper_p.h b/3rdparty/asmjit/src/asmjit/x86/x86emithelper_p.h
index e71d9afe7db..e09d084a097 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86emithelper_p.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86emithelper_p.h
@@ -19,7 +19,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! \addtogroup asmjit_x86
//! \{
-static inline RegType vecTypeIdToRegType(TypeId typeId) noexcept {
+static ASMJIT_INLINE_NODEBUG 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;
}
@@ -29,7 +29,7 @@ public:
bool _avxEnabled;
bool _avx512Enabled;
- inline explicit EmitHelper(BaseEmitter* emitter = nullptr, bool avxEnabled = false, bool avx512Enabled = false) noexcept
+ ASMJIT_INLINE_NODEBUG explicit EmitHelper(BaseEmitter* emitter = nullptr, bool avxEnabled = false, bool avx512Enabled = false) noexcept
: BaseEmitHelper(emitter),
_avxEnabled(avxEnabled || avx512Enabled),
_avx512Enabled(avx512Enabled) {}
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86emitter.h b/3rdparty/asmjit/src/asmjit/x86/x86emitter.h
index 1f85dec4fd9..60881d3ff93 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86emitter.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86emitter.h
@@ -139,16 +139,18 @@ struct EmitterExplicitT {
// 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); }
+ ASMJIT_ATTRIBUTE_NO_SANITIZE_UNDEF ASMJIT_INLINE_NODEBUG This* _emitter() noexcept { return static_cast<This*>(this); }
+ ASMJIT_ATTRIBUTE_NO_SANITIZE_UNDEF ASMJIT_INLINE_NODEBUG const This* _emitter() const noexcept { return static_cast<const This*>(this); }
//! \endcond
//! \name Native Registers
//! \{
- //! Returns either GPD or GPQ register of the given `id` depending on the emitter's architecture.
+ //! Returns either 32-bit or 64-bit GP register of the given `id` depending on the emitter's architecture.
inline Gp gpz(uint32_t id) const noexcept { return Gp(_emitter()->_gpSignature, id); }
+ //! Clones the given `reg` to either 32-bit or 64-bit GP register depending on the emitter's architecture.
+ inline Gp gpz(const Gp& reg) const noexcept { return Gp(_emitter()->_gpSignature, reg.id()); }
inline Gp zax() const noexcept { return Gp(_emitter()->_gpSignature, Gp::kIdAx); }
inline Gp zcx() const noexcept { return Gp(_emitter()->_gpSignature, Gp::kIdCx); }
@@ -471,7 +473,6 @@ public:
ASMJIT_INST_3x(idiv, Idiv, Gp, Gp, Mem) // ANY [EXPLICIT] xDX[Rem]:xAX[Quot] <- xDX:xAX / m16|m32|m64
ASMJIT_INST_2x(imul, Imul, Gp, Gp) // ANY [EXPLICIT] AX <- AL * r8 | ra <- ra * rb
ASMJIT_INST_2x(imul, Imul, Gp, Mem) // ANY [EXPLICIT] AX <- AL * m8 | ra <- ra * m16|m32|m64
- ASMJIT_INST_2x(imul, Imul, Gp, Imm) // ANY
ASMJIT_INST_3x(imul, Imul, Gp, Gp, Imm) // ANY
ASMJIT_INST_3x(imul, Imul, Gp, Mem, Imm) // ANY
ASMJIT_INST_3x(imul, Imul, Gp, Gp, Gp) // ANY [EXPLICIT] xDX:xAX <- xAX * r16|r32|r64
@@ -633,6 +634,14 @@ public:
//! \}
+ //! \name Core Instructions (Aliases)
+ //! \{
+
+ //! The `imul(Gp, Imm)` instruction is an alias of `imul(Gp, Gp, Imm)` instruction.
+ inline Error imul(const Gp& o0, const Imm& o1) { return _emitter()->_emitI(Inst::kIdImul, o0, o0, o1); }
+
+ //! \}
+
//! \name Deprecated 32-bit Instructions
//! \{
@@ -657,7 +666,6 @@ public:
//! \{
// NOTE: For some reason Doxygen is messed up here and thinks we are in cond.
- //! \endcond
ASMJIT_INST_2x(in, In, Gp_ZAX, Imm) // ANY
ASMJIT_INST_2x(in, In, Gp_ZAX, Gp_DX) // ANY
@@ -679,14 +687,6 @@ public:
//! \}
- //! \name LAHF/SAHF Instructions
- //! \{
-
- ASMJIT_INST_1x(lahf, Lahf, Gp_AH) // LAHFSAHF [EXPLICIT] AH <- EFL
- ASMJIT_INST_1x(sahf, Sahf, Gp_AH) // LAHFSAHF [EXPLICIT] EFL <- AH
-
- //! \}
-
//! \name ADX Instructions
//! \{
@@ -697,13 +697,18 @@ public:
//! \}
- //! \name LZCNT/POPCNT Instructions
+ //! \name CPUID Instruction
//! \{
- ASMJIT_INST_2x(lzcnt, Lzcnt, Gp, Gp) // LZCNT
- ASMJIT_INST_2x(lzcnt, Lzcnt, Gp, Mem) // LZCNT
- ASMJIT_INST_2x(popcnt, Popcnt, Gp, Gp) // POPCNT
- ASMJIT_INST_2x(popcnt, Popcnt, Gp, Mem) // POPCNT
+ ASMJIT_INST_4x(cpuid, Cpuid, Gp_EAX, Gp_EBX, Gp_ECX, Gp_EDX) // I486 [EXPLICIT] EAX:EBX:ECX:EDX <- CPUID[EAX:ECX]
+
+ //! \}
+
+ //! \name LAHF/SAHF Instructions
+ //! \{
+
+ ASMJIT_INST_1x(lahf, Lahf, Gp_AH) // LAHFSAHF [EXPLICIT] AH <- EFL
+ ASMJIT_INST_1x(sahf, Sahf, Gp_AH) // LAHFSAHF [EXPLICIT] EFL <- AH
//! \}
@@ -747,27 +752,36 @@ public:
//! \}
- //! \name TBM Instructions
+ //! \name CMPCCXADD Instructions
//! \{
- ASMJIT_INST_2x(blcfill, Blcfill, Gp, Gp) // TBM
- ASMJIT_INST_2x(blcfill, Blcfill, Gp, Mem) // TBM
- ASMJIT_INST_2x(blci, Blci, Gp, Gp) // TBM
- ASMJIT_INST_2x(blci, Blci, Gp, Mem) // TBM
- ASMJIT_INST_2x(blcic, Blcic, Gp, Gp) // TBM
- ASMJIT_INST_2x(blcic, Blcic, Gp, Mem) // TBM
- ASMJIT_INST_2x(blcmsk, Blcmsk, Gp, Gp) // TBM
- ASMJIT_INST_2x(blcmsk, Blcmsk, Gp, Mem) // TBM
- ASMJIT_INST_2x(blcs, Blcs, Gp, Gp) // TBM
- ASMJIT_INST_2x(blcs, Blcs, Gp, Mem) // TBM
- ASMJIT_INST_2x(blsfill, Blsfill, Gp, Gp) // TBM
- ASMJIT_INST_2x(blsfill, Blsfill, Gp, Mem) // TBM
- ASMJIT_INST_2x(blsic, Blsic, Gp, Gp) // TBM
- ASMJIT_INST_2x(blsic, Blsic, Gp, Mem) // TBM
- ASMJIT_INST_2x(t1mskc, T1mskc, Gp, Gp) // TBM
- ASMJIT_INST_2x(t1mskc, T1mskc, Gp, Mem) // TBM
- ASMJIT_INST_2x(tzmsk, Tzmsk, Gp, Gp) // TBM
- ASMJIT_INST_2x(tzmsk, Tzmsk, Gp, Mem) // TBM
+ ASMJIT_INST_3x(cmpbexadd, Cmpbexadd, Mem, Gp, Gp)
+ ASMJIT_INST_3x(cmpbxadd, Cmpbxadd, Mem, Gp, Gp)
+ ASMJIT_INST_3x(cmplexadd, Cmplexadd, Mem, Gp, Gp)
+ ASMJIT_INST_3x(cmplxadd, Cmplxadd, Mem, Gp, Gp)
+ ASMJIT_INST_3x(cmpnbexadd, Cmpnbexadd, Mem, Gp, Gp)
+ ASMJIT_INST_3x(cmpnbxadd, Cmpnbxadd, Mem, Gp, Gp)
+ ASMJIT_INST_3x(cmpnlexadd, Cmpnlexadd, Mem, Gp, Gp)
+ ASMJIT_INST_3x(cmpnlxadd, Cmpnlxadd, Mem, Gp, Gp)
+ ASMJIT_INST_3x(cmpnoxadd, Cmpnoxadd, Mem, Gp, Gp)
+ ASMJIT_INST_3x(cmpnpxadd, Cmpnpxadd, Mem, Gp, Gp)
+ ASMJIT_INST_3x(cmpnsxadd, Cmpnsxadd, Mem, Gp, Gp)
+ ASMJIT_INST_3x(cmpnzxadd, Cmpnzxadd, Mem, Gp, Gp)
+ ASMJIT_INST_3x(cmpoxadd, Cmpoxadd, Mem, Gp, Gp)
+ ASMJIT_INST_3x(cmppxadd, Cmppxadd, Mem, Gp, Gp)
+ ASMJIT_INST_3x(cmpsxadd, Cmpsxadd, Mem, Gp, Gp)
+ ASMJIT_INST_3x(cmpzxadd, Cmpzxadd, Mem, Gp, Gp)
+
+ //! \}
+
+ //! \name CacheLine Instructions
+ //! \{
+
+ ASMJIT_INST_1x(cldemote, Cldemote, Mem) // CLDEMOTE
+ ASMJIT_INST_1x(clflush, Clflush, Mem) // CLFLUSH
+ ASMJIT_INST_1x(clflushopt, Clflushopt, Mem) // CLFLUSH_OPT
+ ASMJIT_INST_1x(clwb, Clwb, Mem) // CLWB
+ ASMJIT_INST_1x(clzero, Clzero, DS_ZAX) // CLZERO [EXPLICIT]
//! \}
@@ -779,6 +793,23 @@ public:
//! \}
+ //! \name FENCE Instructions (SSE and SSE2)
+ //! \{
+
+ ASMJIT_INST_0x(lfence, Lfence) // SSE2
+ ASMJIT_INST_0x(mfence, Mfence) // SSE2
+ ASMJIT_INST_0x(sfence, Sfence) // SSE
+
+ //! \}
+
+ //! \name LZCNT Instructions
+ //! \{
+
+ ASMJIT_INST_2x(lzcnt, Lzcnt, Gp, Gp) // LZCNT
+ ASMJIT_INST_2x(lzcnt, Lzcnt, Gp, Mem) // LZCNT
+
+ //! \}
+
//! \name MOVBE Instructions
//! \{
@@ -803,12 +834,11 @@ public:
//! \}
- //! \name FENCE Instructions (SSE and SSE2)
+ //! \name POPCNT Instructions
//! \{
- ASMJIT_INST_0x(lfence, Lfence) // SSE2
- ASMJIT_INST_0x(mfence, Mfence) // SSE2
- ASMJIT_INST_0x(sfence, Sfence) // SSE
+ ASMJIT_INST_2x(popcnt, Popcnt, Gp, Gp) // POPCNT
+ ASMJIT_INST_2x(popcnt, Popcnt, Gp, Mem) // POPCNT
//! \}
@@ -825,28 +855,21 @@ public:
//! \}
- //! \name CPUID Instruction
- //! \{
-
- ASMJIT_INST_4x(cpuid, Cpuid, Gp_EAX, Gp_EBX, Gp_ECX, Gp_EDX) // I486 [EXPLICIT] EAX:EBX:ECX:EDX <- CPUID[EAX:ECX]
-
- //! \}
-
- //! \name CacheLine Instructions
+ //! \name PREFETCHI Instructions
//! \{
- ASMJIT_INST_1x(cldemote, Cldemote, Mem) // CLDEMOTE
- ASMJIT_INST_1x(clflush, Clflush, Mem) // CLFLUSH
- ASMJIT_INST_1x(clflushopt, Clflushopt, Mem) // CLFLUSH_OPT
- ASMJIT_INST_1x(clwb, Clwb, Mem) // CLWB
- ASMJIT_INST_1x(clzero, Clzero, DS_ZAX) // CLZERO [EXPLICIT]
+ ASMJIT_INST_1x(prefetchit0, Prefetchit0, Mem)
+ ASMJIT_INST_1x(prefetchit1, Prefetchit1, Mem)
//! \}
- //! \name SERIALIZE Instruction
+ //! \name RAO_INT Instructions
//! \{
- ASMJIT_INST_0x(serialize, Serialize) // SERIALIZE
+ ASMJIT_INST_2x(aadd, Aadd, Mem, Gp)
+ ASMJIT_INST_2x(aand, Aand, Mem, Gp)
+ ASMJIT_INST_2x(aor, Aor, Mem, Gp)
+ ASMJIT_INST_2x(axor, Axor, Mem, Gp)
//! \}
@@ -873,6 +896,37 @@ public:
//! \}
+ //! \name SERIALIZE Instruction
+ //! \{
+
+ ASMJIT_INST_0x(serialize, Serialize) // SERIALIZE
+
+ //! \}
+
+ //! \name TBM Instructions
+ //! \{
+
+ ASMJIT_INST_2x(blcfill, Blcfill, Gp, Gp) // TBM
+ ASMJIT_INST_2x(blcfill, Blcfill, Gp, Mem) // TBM
+ ASMJIT_INST_2x(blci, Blci, Gp, Gp) // TBM
+ ASMJIT_INST_2x(blci, Blci, Gp, Mem) // TBM
+ ASMJIT_INST_2x(blcic, Blcic, Gp, Gp) // TBM
+ ASMJIT_INST_2x(blcic, Blcic, Gp, Mem) // TBM
+ ASMJIT_INST_2x(blcmsk, Blcmsk, Gp, Gp) // TBM
+ ASMJIT_INST_2x(blcmsk, Blcmsk, Gp, Mem) // TBM
+ ASMJIT_INST_2x(blcs, Blcs, Gp, Gp) // TBM
+ ASMJIT_INST_2x(blcs, Blcs, Gp, Mem) // TBM
+ ASMJIT_INST_2x(blsfill, Blsfill, Gp, Gp) // TBM
+ ASMJIT_INST_2x(blsfill, Blsfill, Gp, Mem) // TBM
+ ASMJIT_INST_2x(blsic, Blsic, Gp, Gp) // TBM
+ ASMJIT_INST_2x(blsic, Blsic, Gp, Mem) // TBM
+ ASMJIT_INST_2x(t1mskc, T1mskc, Gp, Gp) // TBM
+ ASMJIT_INST_2x(t1mskc, T1mskc, Gp, Mem) // TBM
+ ASMJIT_INST_2x(tzmsk, Tzmsk, Gp, Gp) // TBM
+ ASMJIT_INST_2x(tzmsk, Tzmsk, Gp, Mem) // TBM
+
+ //! \}
+
//! \name Other User-Mode Instructions
//! \{
@@ -1122,6 +1176,14 @@ public:
//! \}
+ //! \name INVLPGB Instructions
+ //! \{
+
+ ASMJIT_INST_3x(invlpgb, Invlpgb, Gp_EAX, Gp_EDX, Gp_ECX)
+ ASMJIT_INST_0x(tlbsync, Tlbsync)
+
+ //! \}
+
//! \name MONITOR Instructions (Privileged)
//! \{
@@ -1172,6 +1234,7 @@ public:
ASMJIT_INST_0x(vmresume, Vmresume) // VMX
ASMJIT_INST_2x(vmwrite, Vmwrite, Gp, Mem) // VMX
ASMJIT_INST_2x(vmwrite, Vmwrite, Gp, Gp) // VMX
+ ASMJIT_INST_0x(vmxoff, Vmxoff) // VMX
ASMJIT_INST_1x(vmxon, Vmxon, Mem) // VMX
//! \}
@@ -1188,6 +1251,13 @@ public:
//! \}
+ //! \name SEV_ES Instructions
+ //! \{
+
+ ASMJIT_INST_0x(vmgexit, Vmgexit)
+
+ //! \}
+
//! \name FPU Instructions
//! \{
@@ -2092,9 +2162,6 @@ public:
//! \name GFNI Instructions
//! \{
- // NOTE: For some reason Doxygen is messed up here and thinks we are in cond.
- //! \endcond
-
ASMJIT_INST_3x(gf2p8affineinvqb, Gf2p8affineinvqb, Xmm, Xmm, Imm) // GFNI
ASMJIT_INST_3x(gf2p8affineinvqb, Gf2p8affineinvqb, Xmm, Mem, Imm) // GFNI
ASMJIT_INST_3x(gf2p8affineqb, Gf2p8affineqb, Xmm, Xmm, Imm) // GFNI
@@ -2762,7 +2829,7 @@ public:
ASMJIT_INST_3x(vpand, Vpand, Vec, Vec, Mem) // AVX+
ASMJIT_INST_3x(vpandd, Vpandd, Vec, Vec, Vec) // AVX512_F{kz|b32}
ASMJIT_INST_3x(vpandd, Vpandd, Vec, Vec, Mem) // AVX512_F{kz|b32}
- ASMJIT_INST_3x(vpandn, Vpandn, Vec, Vec, Vec) // AV+
+ ASMJIT_INST_3x(vpandn, Vpandn, Vec, Vec, Vec) // AVX+
ASMJIT_INST_3x(vpandn, Vpandn, Vec, Vec, Mem) // AVX+
ASMJIT_INST_3x(vpandnd, Vpandnd, Vec, Vec, Vec) // AVX512_F{kz|b32}
ASMJIT_INST_3x(vpandnd, Vpandnd, Vec, Vec, Mem) // AVX512_F{kz|b32}
@@ -3121,7 +3188,7 @@ public:
ASMJIT_INST_2x(vpopcntq, Vpopcntq, Vec, Mem) // AVX512_VPOPCNTDQ{kz|b64}
ASMJIT_INST_2x(vpopcntw, Vpopcntw, Vec, Vec) // AVX512_BITALG{kz|b32}
ASMJIT_INST_2x(vpopcntw, Vpopcntw, Vec, Mem) // AVX512_BITALG{kz|b32}
- ASMJIT_INST_3x(vpor, Vpor, Vec, Vec, Vec) // AV+
+ ASMJIT_INST_3x(vpor, Vpor, Vec, Vec, Vec) // AVX+
ASMJIT_INST_3x(vpor, Vpor, Vec, Vec, Mem) // AVX+
ASMJIT_INST_3x(vpord, Vpord, Vec, Vec, Vec) // AVX512_F{kz|b32}
ASMJIT_INST_3x(vpord, Vpord, Vec, Vec, Mem) // AVX512_F{kz|b32}
@@ -3659,6 +3726,83 @@ public:
//! \}
+ //! \name AVX_NE_CONVERT Instructions
+ //! \{
+
+ ASMJIT_INST_2x(vbcstnebf162ps, Vbcstnebf162ps, Vec, Mem)
+ ASMJIT_INST_2x(vbcstnesh2ps, Vbcstnesh2ps, Vec, Mem)
+ ASMJIT_INST_2x(vcvtneebf162ps, Vcvtneebf162ps, Vec, Mem)
+ ASMJIT_INST_2x(vcvtneeph2ps, Vcvtneeph2ps, Vec, Mem)
+ ASMJIT_INST_2x(vcvtneobf162ps, Vcvtneobf162ps, Vec, Mem)
+ ASMJIT_INST_2x(vcvtneoph2ps, Vcvtneoph2ps, Vec, Mem)
+
+ //! \}
+
+ //! \name AVX_VNNI_INT8 Instructions
+ //! \{
+
+ ASMJIT_INST_3x(vpdpbssd, Vpdpbssd, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vpdpbssd, Vpdpbssd, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vpdpbssds, Vpdpbssds, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vpdpbssds, Vpdpbssds, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vpdpbsud, Vpdpbsud, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vpdpbsud, Vpdpbsud, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vpdpbsuds, Vpdpbsuds, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vpdpbsuds, Vpdpbsuds, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vpdpbuud, Vpdpbuud, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vpdpbuud, Vpdpbuud, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vpdpbuuds, Vpdpbuuds, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vpdpbuuds, Vpdpbuuds, Vec, Vec, Mem)
+
+ //! \}
+
+ //! \name AVX_VNNI_INT16 Instructions
+ //! \{
+
+ ASMJIT_INST_3x(vpdpwsud, Vpdpwsud, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vpdpwsud, Vpdpwsud, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vpdpwsuds, Vpdpwsuds, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vpdpwsuds, Vpdpwsuds, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vpdpwusd, Vpdpwusd, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vpdpwusd, Vpdpwusd, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vpdpwusds, Vpdpwusds, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vpdpwusds, Vpdpwusds, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vpdpwuud, Vpdpwuud, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vpdpwuud, Vpdpwuud, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vpdpwuuds, Vpdpwuuds, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vpdpwuuds, Vpdpwuuds, Vec, Vec, Mem)
+
+ //! \}
+
+ //! \name AVX+SHA512 Instructions
+ //! \{
+ ASMJIT_INST_2x(vsha512msg1, Vsha512msg1, Vec, Vec)
+ ASMJIT_INST_2x(vsha512msg2, Vsha512msg2, Vec, Vec)
+ ASMJIT_INST_3x(vsha512rnds2, Vsha512rnds2, Vec, Vec, Vec)
+ //! \}
+
+ //! \name AVX+SM3 Instructions
+ //! \{
+
+ ASMJIT_INST_3x(vsm3msg1, Vsm3msg1, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vsm3msg1, Vsm3msg1, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vsm3msg2, Vsm3msg2, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vsm3msg2, Vsm3msg2, Vec, Vec, Mem)
+ ASMJIT_INST_4x(vsm3rnds2, Vsm3rnds2, Vec, Vec, Vec, Imm)
+ ASMJIT_INST_4x(vsm3rnds2, Vsm3rnds2, Vec, Vec, Mem, Imm)
+
+ //! \}
+
+ //! \name AVX+SM4 Instructions
+ //! \{
+
+ ASMJIT_INST_3x(vsm4key4, Vsm4key4, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vsm4key4, Vsm4key4, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vsm4rnds4, Vsm4rnds4, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vsm4rnds4, Vsm4rnds4, Vec, Vec, Mem)
+
+ //! \}
+
//! \name AVX512_FP16 Instructions
//! \{
@@ -3880,22 +4024,48 @@ public:
//! \}
- //! \name AMX Instructions
+ //! \name AMX_TILE Instructions
//! \{
- ASMJIT_INST_1x(ldtilecfg, Ldtilecfg, Mem) // AMX_TILE
- ASMJIT_INST_1x(sttilecfg, Sttilecfg, Mem) // AMX_TILE
- ASMJIT_INST_2x(tileloadd, Tileloadd, Tmm, Mem) // AMX_TILE
- ASMJIT_INST_2x(tileloaddt1, Tileloaddt1, Tmm, Mem) // AMX_TILE
- ASMJIT_INST_0x(tilerelease, Tilerelease) // AMX_TILE
- ASMJIT_INST_2x(tilestored, Tilestored, Mem, Tmm) // AMX_TILE
- ASMJIT_INST_1x(tilezero, Tilezero, Tmm) // AMX_TILE
+ ASMJIT_INST_1x(ldtilecfg, Ldtilecfg, Mem)
+ ASMJIT_INST_1x(sttilecfg, Sttilecfg, Mem)
+ ASMJIT_INST_2x(tileloadd, Tileloadd, Tmm, Mem)
+ ASMJIT_INST_2x(tileloaddt1, Tileloaddt1, Tmm, Mem)
+ ASMJIT_INST_0x(tilerelease, Tilerelease)
+ ASMJIT_INST_2x(tilestored, Tilestored, Mem, Tmm)
+ ASMJIT_INST_1x(tilezero, Tilezero, Tmm)
- ASMJIT_INST_3x(tdpbf16ps, Tdpbf16ps, Tmm, Tmm, Tmm) // AMX_BF16
- ASMJIT_INST_3x(tdpbssd, Tdpbssd, Tmm, Tmm, Tmm) // AMX_INT8
- ASMJIT_INST_3x(tdpbsud, Tdpbsud, Tmm, Tmm, Tmm) // AMX_INT8
- ASMJIT_INST_3x(tdpbusd, Tdpbusd, Tmm, Tmm, Tmm) // AMX_INT8
- ASMJIT_INST_3x(tdpbuud, Tdpbuud, Tmm, Tmm, Tmm) // AMX_INT8
+ //! \}
+
+ //! \name AMX_BF16 Instructions
+ //! \{
+
+ ASMJIT_INST_3x(tdpbf16ps, Tdpbf16ps, Tmm, Tmm, Tmm)
+
+ //! \}
+
+ //! \name AMX_COMPLEX Instructions
+ //! \{
+
+ ASMJIT_INST_3x(tcmmimfp16ps, Tcmmimfp16ps, Tmm, Tmm, Tmm)
+ ASMJIT_INST_3x(tcmmrlfp16ps, Tcmmrlfp16ps, Tmm, Tmm, Tmm)
+
+ //! \}
+
+ //! \name AMX_FP16 Instructions
+ //! \{
+
+ ASMJIT_INST_3x(tdpfp16ps, Tdpfp16ps, Tmm, Tmm, Tmm)
+
+ //! \}
+
+ //! \name AMX_INT8 Instructions
+ //! \{
+
+ ASMJIT_INST_3x(tdpbssd, Tdpbssd, Tmm, Tmm, Tmm)
+ ASMJIT_INST_3x(tdpbsud, Tdpbsud, Tmm, Tmm, Tmm)
+ ASMJIT_INST_3x(tdpbusd, Tdpbusd, Tmm, Tmm, Tmm)
+ ASMJIT_INST_3x(tdpbuud, Tdpbuud, Tmm, Tmm, Tmm)
//! \}
};
@@ -4167,6 +4337,16 @@ struct EmitterImplicitT : public EmitterExplicitT<This> {
//! \}
+ //! \name SEAM Instructions
+ //! \{
+
+ ASMJIT_INST_0x(seamcall, Seamcall)
+ ASMJIT_INST_0x(seamops, Seamops)
+ ASMJIT_INST_0x(seamret, Seamret)
+ ASMJIT_INST_0x(tdcall, Tdcall)
+
+ //! \}
+
//! \name Privileged Instructions
//! \{
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86formatter.cpp b/3rdparty/asmjit/src/asmjit/x86/x86formatter.cpp
index d62dd18b638..67b38dfa779 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86formatter.cpp
+++ b/3rdparty/asmjit/src/asmjit/x86/x86formatter.cpp
@@ -4,7 +4,7 @@
// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
-#ifndef ASMJIT_NO_LOGGING
+#if !defined(ASMJIT_NO_X86) && !defined(ASMJIT_NO_LOGGING)
#include "../core/cpuinfo.h"
#include "../core/misc_p.h"
@@ -95,6 +95,24 @@ struct RegFormatInfo_T {
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,
+
+ kRegCount = X == uint32_t(RegType::kX86_GpbLo) ? 32 :
+ X == uint32_t(RegType::kX86_GpbHi) ? 4 :
+ X == uint32_t(RegType::kX86_Gpw ) ? 32 :
+ X == uint32_t(RegType::kX86_Gpd ) ? 32 :
+ X == uint32_t(RegType::kX86_Gpq ) ? 32 :
+ X == uint32_t(RegType::kX86_Xmm ) ? 32 :
+ X == uint32_t(RegType::kX86_Ymm ) ? 32 :
+ X == uint32_t(RegType::kX86_Zmm ) ? 32 :
+ X == uint32_t(RegType::kX86_Mm ) ? 8 :
+ X == uint32_t(RegType::kX86_KReg ) ? 8 :
+ X == uint32_t(RegType::kX86_SReg ) ? 7 :
+ X == uint32_t(RegType::kX86_CReg ) ? 16 :
+ X == uint32_t(RegType::kX86_DReg ) ? 16 :
+ X == uint32_t(RegType::kX86_St ) ? 8 :
+ X == uint32_t(RegType::kX86_Bnd ) ? 4 :
+ X == uint32_t(RegType::kX86_Tmm ) ? 8 :
X == uint32_t(RegType::kX86_Rip ) ? 1 : 0
};
};
@@ -104,7 +122,7 @@ struct RegFormatInfo_T {
}
#define ASMJIT_REG_NAME_ENTRY(TYPE) { \
- RegTraits<RegType(TYPE)>::kCount, \
+ RegFormatInfo_T<TYPE>::kRegCount, \
RegFormatInfo_T<TYPE>::kFormatIndex, \
RegFormatInfo_T<TYPE>::kSpecialIndex, \
RegFormatInfo_T<TYPE>::kSpecialCount \
@@ -198,8 +216,11 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
"AESNI\0"
"ALTMOVCR8\0"
"AMX_BF16\0"
+ "AMX_COMPLEX\0"
+ "AMX_FP16\0"
"AMX_INT8\0"
"AMX_TILE\0"
+ "APX_F\0"
"AVX\0"
"AVX2\0"
"AVX512_4FMAPS\0"
@@ -207,30 +228,36 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
"AVX512_BF16\0"
"AVX512_BITALG\0"
"AVX512_BW\0"
- "AVX512_CDI\0"
+ "AVX512_CD\0"
"AVX512_DQ\0"
- "AVX512_ERI\0"
+ "AVX512_ER\0"
"AVX512_F\0"
"AVX512_FP16\0"
"AVX512_IFMA\0"
- "AVX512_PFI\0"
+ "AVX512_PF\0"
"AVX512_VBMI\0"
"AVX512_VBMI2\0"
"AVX512_VL\0"
"AVX512_VNNI\0"
"AVX512_VP2INTERSECT\0"
"AVX512_VPOPCNTDQ\0"
+ "AVX_IFMA\0"
+ "AVX_NE_CONVERT\0"
"AVX_VNNI\0"
+ "AVX_VNNI_INT16\0"
+ "AVX_VNNI_INT8\0"
"BMI\0"
"BMI2\0"
"CET_IBT\0"
"CET_SS\0"
+ "CET_SSS\0"
"CLDEMOTE\0"
"CLFLUSH\0"
"CLFLUSHOPT\0"
"CLWB\0"
"CLZERO\0"
"CMOV\0"
+ "CMPCCXADD\0"
"CMPXCHG16B\0"
"CMPXCHG8B\0"
"ENCLV\0"
@@ -241,14 +268,20 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
"FMA4\0"
"FPU\0"
"FSGSBASE\0"
+ "FSRM\0"
+ "FSRC\0"
+ "FSRS\0"
"FXSR\0"
"FXSROPT\0"
+ "FZRM\0"
"GEODE\0"
"GFNI\0"
"HLE\0"
"HRESET\0"
"I486\0"
+ "INVLPGB\0"
"LAHFSAHF\0"
+ "LAM\0"
"LWP\0"
"LZCNT\0"
"MCOMMIT\0"
@@ -261,15 +294,19 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
"MOVDIRI\0"
"MPX\0"
"MSR\0"
+ "MSRLIST\0"
"MSSE\0"
"OSXSAVE\0"
"OSPKE\0"
"PCLMULQDQ\0"
"PCONFIG\0"
"POPCNT\0"
+ "PREFETCHI\0"
"PREFETCHW\0"
"PREFETCHWT1\0"
"PTWRITE\0"
+ "RAO_INT\0"
+ "RMPQUERY\0"
"RDPID\0"
"RDPRU\0"
"RDRAND\0"
@@ -277,13 +314,20 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
"RDTSC\0"
"RDTSCP\0"
"RTM\0"
+ "SEAM\0"
"SERIALIZE\0"
+ "SEV\0"
+ "SEV_ES\0"
+ "SEV_SNP\0"
"SHA\0"
+ "SHA512\0"
"SKINIT\0"
+ "SM3\0"
+ "SM4\0"
"SMAP\0"
+ "SME\0"
"SMEP\0"
"SMX\0"
- "SNP\0"
"SSE\0"
"SSE2\0"
"SSE3\0"
@@ -293,6 +337,7 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
"SSSE3\0"
"SVM\0"
"TBM\0"
+ "TSE\0"
"TSX\0"
"TSXLDTRK\0"
"UINTR\0"
@@ -301,6 +346,7 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
"VPCLMULQDQ\0"
"WAITPKG\0"
"WBNOINVD\0"
+ "WRMSRNS\0"
"XOP\0"
"XSAVE\0"
"XSAVEC\0"
@@ -309,14 +355,16 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
"<Unknown>\0";
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, 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
+ 0, 5, 8, 11, 17, 24, 28, 34, 44, 53, 65, 74, 83, 92, 98, 102, 107, 121, 135,
+ 147, 161, 171, 181, 191, 201, 210, 222, 234, 244, 256, 269, 279, 291, 311,
+ 328, 337, 352, 361, 376, 390, 394, 399, 407, 414, 422, 431, 439, 450, 455,
+ 462, 467, 477, 488, 498, 504, 511, 516, 521, 525, 530, 534, 543, 548, 553,
+ 558, 563, 571, 576, 582, 587, 591, 598, 603, 611, 620, 624, 628, 634, 642,
+ 646, 651, 659, 668, 674, 684, 692, 696, 700, 708, 713, 721, 727, 737, 745,
+ 752, 762, 772, 784, 792, 800, 809, 815, 821, 828, 835, 841, 848, 852, 857,
+ 867, 871, 878, 886, 890, 897, 904, 908, 912, 917, 921, 926, 930, 934, 939,
+ 944, 951, 958, 964, 970, 974, 978, 982, 986, 995, 1001, 1006, 1010, 1021,
+ 1029, 1038, 1046, 1050, 1056, 1063, 1072, 1079
};
// @EnumStringEnd@
@@ -344,7 +392,10 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatRegister(String& sb, FormatFlag
else
ASMJIT_PROPAGATE(sb.appendFormat("%%%u", unsigned(Operand::virtIdToIndex(id))));
- if (vReg->type() != type && uint32_t(type) <= uint32_t(RegType::kMaxValue) && Support::test(formatFlags, FormatFlags::kRegCasts)) {
+ bool formatType = (Support::test(formatFlags, FormatFlags::kRegType)) ||
+ (Support::test(formatFlags, FormatFlags::kRegCasts) && vReg->type() != type);
+
+ if (formatType && uint32_t(type) <= uint32_t(RegType::kMaxValue)) {
const RegFormatInfo::TypeEntry& typeEntry = info.typeEntries[size_t(type)];
if (typeEntry.index)
ASMJIT_PROPAGATE(sb.appendFormat("@%s", info.typeStrings + typeEntry.index));
@@ -481,8 +532,8 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatOperand(
// =====================================================
static constexpr char kImmCharStart = '{';
-static constexpr char kImmCharEnd = '}';
-static constexpr char kImmCharOr = '|';
+static constexpr char kImmCharEnd = '}';
+static constexpr char kImmCharOr = '|';
struct ImmBits {
enum Mode : uint32_t {
@@ -496,29 +547,29 @@ struct ImmBits {
char text[48 - 3];
};
-ASMJIT_FAVOR_SIZE static Error FormatterInternal_formatImmShuf(String& sb, uint32_t u8, uint32_t bits, uint32_t count) noexcept {
+ASMJIT_FAVOR_SIZE static Error FormatterInternal_formatImmShuf(String& sb, uint32_t imm8, uint32_t bits, uint32_t count) noexcept {
uint32_t mask = (1 << bits) - 1;
+ uint32_t lastPredicateShift = bits * (count - 1u);
- for (uint32_t i = 0; i < count; i++, u8 >>= bits) {
- uint32_t value = u8 & mask;
+ for (uint32_t i = 0; i < count; i++, imm8 <<= bits) {
+ uint32_t index = (imm8 >> lastPredicateShift) & mask;
ASMJIT_PROPAGATE(sb.append(i == 0 ? kImmCharStart : kImmCharOr));
- ASMJIT_PROPAGATE(sb.appendUInt(value));
+ ASMJIT_PROPAGATE(sb.appendUInt(index));
}
- if (kImmCharEnd)
- ASMJIT_PROPAGATE(sb.append(kImmCharEnd));
+ ASMJIT_PROPAGATE(sb.append(kImmCharEnd));
return kErrorOk;
}
-ASMJIT_FAVOR_SIZE static Error FormatterInternal_formatImmBits(String& sb, uint32_t u8, const ImmBits* bits, uint32_t count) noexcept {
+ASMJIT_FAVOR_SIZE static Error FormatterInternal_formatImmBits(String& sb, uint32_t imm8, const ImmBits* bits, uint32_t count) noexcept {
uint32_t n = 0;
char buf[64];
for (uint32_t i = 0; i < count; i++) {
const ImmBits& spec = bits[i];
- uint32_t value = (u8 & uint32_t(spec.mask)) >> spec.shift;
+ uint32_t value = (imm8 & uint32_t(spec.mask)) >> spec.shift;
const char* str = nullptr;
switch (spec.mode) {
@@ -542,26 +593,23 @@ ASMJIT_FAVOR_SIZE static Error FormatterInternal_formatImmBits(String& sb, uint3
ASMJIT_PROPAGATE(sb.append(str));
}
- if (n && kImmCharEnd)
+ if (n)
ASMJIT_PROPAGATE(sb.append(kImmCharEnd));
return kErrorOk;
}
-ASMJIT_FAVOR_SIZE static Error FormatterInternal_formatImmText(String& sb, uint32_t u8, uint32_t bits, uint32_t advance, const char* text, uint32_t count = 1) noexcept {
+ASMJIT_FAVOR_SIZE static Error FormatterInternal_formatImmText(String& sb, uint32_t imm8, uint32_t bits, uint32_t advance, const char* text, uint32_t count = 1) noexcept {
uint32_t mask = (1u << bits) - 1;
uint32_t pos = 0;
- for (uint32_t i = 0; i < count; i++, u8 >>= bits, pos += advance) {
- uint32_t value = (u8 & mask) + pos;
+ for (uint32_t i = 0; i < count; i++, imm8 >>= bits, pos += advance) {
+ uint32_t value = (imm8 & mask) + pos;
ASMJIT_PROPAGATE(sb.append(i == 0 ? kImmCharStart : kImmCharOr));
ASMJIT_PROPAGATE(sb.append(Support::findPackedString(text, value)));
}
- if (kImmCharEnd)
- ASMJIT_PROPAGATE(sb.append(kImmCharEnd));
-
- return kErrorOk;
+ return sb.append(kImmCharEnd);
}
ASMJIT_FAVOR_SIZE static Error FormatterInternal_explainConst(
@@ -583,8 +631,8 @@ ASMJIT_FAVOR_SIZE static Error FormatterInternal_explainConst(
static const char vpcmpx[] = "EQ\0" "LT\0" "LE\0" "FALSE\0" "NEQ\0" "GE\0" "GT\0" "TRUE\0";
static const char vpcomx[] = "LT\0" "LE\0" "GT\0" "GE\0" "EQ\0" "NEQ\0" "FALSE\0" "TRUE\0";
- static const char vshufpd[] = "A0\0A1\0B0\0B1\0A2\0A3\0B2\0B3\0A4\0A5\0B4\0B5\0A6\0A7\0B6\0B7\0";
- static const char vshufps[] = "A0\0A1\0A2\0A3\0A0\0A1\0A2\0A3\0B0\0B1\0B2\0B3\0B0\0B1\0B2\0B3\0";
+ static const char vshufpd[] = "A0\0" "A1\0" "B0\0" "B1\0" "A2\0" "A3\0" "B2\0" "B3\0" "A4\0" "A5\0" "B4\0" "B5\0" "A6\0" "A7\0" "B6\0" "B7\0";
+ static const char vshufps[] = "A0\0" "A1\0" "A2\0" "A3\0" "A0\0" "A1\0" "A2\0" "A3\0" "B0\0" "B1\0" "B2\0" "B3\0" "B0\0" "B1\0" "B2\0" "B3\0";
static const ImmBits vfpclassxx[] = {
{ 0x07u, 0, ImmBits::kModeLookup, "QNAN\0" "+0\0" "-0\0" "+INF\0" "-INF\0" "DENORMAL\0" "-FINITE\0" "SNAN\0" }
@@ -608,25 +656,25 @@ ASMJIT_FAVOR_SIZE static Error FormatterInternal_explainConst(
};
static const ImmBits vmpsadbw[] = {
- { 0x04u, 2, ImmBits::kModeLookup, "BLK1[0]\0" "BLK1[1]\0" },
- { 0x03u, 0, ImmBits::kModeLookup, "BLK2[0]\0" "BLK2[1]\0" "BLK2[2]\0" "BLK2[3]\0" },
{ 0x40u, 6, ImmBits::kModeLookup, "BLK1[4]\0" "BLK1[5]\0" },
- { 0x30u, 4, ImmBits::kModeLookup, "BLK2[4]\0" "BLK2[5]\0" "BLK2[6]\0" "BLK2[7]\0" }
+ { 0x30u, 4, ImmBits::kModeLookup, "BLK2[4]\0" "BLK2[5]\0" "BLK2[6]\0" "BLK2[7]\0" },
+ { 0x04u, 2, ImmBits::kModeLookup, "BLK1[0]\0" "BLK1[1]\0" },
+ { 0x03u, 0, ImmBits::kModeLookup, "BLK2[0]\0" "BLK2[1]\0" "BLK2[2]\0" "BLK2[3]\0" }
};
static const ImmBits vpclmulqdq[] = {
- { 0x01u, 0, ImmBits::kModeLookup, "LQ\0" "HQ\0" },
- { 0x10u, 4, ImmBits::kModeLookup, "LQ\0" "HQ\0" }
+ { 0x10u, 4, ImmBits::kModeLookup, "LQ\0" "HQ\0" },
+ { 0x01u, 0, ImmBits::kModeLookup, "LQ\0" "HQ\0" }
};
static const ImmBits vperm2x128[] = {
- { 0x0Bu, 0, ImmBits::kModeLookup, "A0\0" "A1\0" "B0\0" "B1\0" "\0" "\0" "\0" "\0" "0\0" "0\0" "0\0" "0\0" },
- { 0xB0u, 4, ImmBits::kModeLookup, "A0\0" "A1\0" "B0\0" "B1\0" "\0" "\0" "\0" "\0" "0\0" "0\0" "0\0" "0\0" }
+ { 0xB0u, 4, ImmBits::kModeLookup, "A0\0" "A1\0" "B0\0" "B1\0" "\0" "\0" "\0" "\0" "0\0" "0\0" "0\0" "0\0" },
+ { 0x0Bu, 0, ImmBits::kModeLookup, "A0\0" "A1\0" "B0\0" "B1\0" "\0" "\0" "\0" "\0" "0\0" "0\0" "0\0" "0\0" }
};
static const ImmBits vrangexx[] = {
- { 0x03u, 0, ImmBits::kModeLookup, "MIN\0" "MAX\0" "MIN_ABS\0" "MAX_ABS\0" },
- { 0x0Cu, 2, ImmBits::kModeLookup, "SIGN_A\0" "SIGN_B\0" "SIGN_0\0" "SIGN_1\0" }
+ { 0x0Cu, 2, ImmBits::kModeLookup, "SIGN_A\0" "SIGN_B\0" "SIGN_0\0" "SIGN_1\0" },
+ { 0x03u, 0, ImmBits::kModeLookup, "MIN\0" "MAX\0" "MIN_ABS\0" "MAX_ABS\0" }
};
static const ImmBits vreducexx_vrndscalexx[] = {
@@ -881,7 +929,7 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatInstruction(
}
}
- ASMJIT_PROPAGATE(InstInternal::instIdToString(arch, instId, sb));
+ ASMJIT_PROPAGATE(InstInternal::instIdToString(instId, sb));
}
else {
ASMJIT_PROPAGATE(sb.appendFormat("[InstId=#%u]", unsigned(instId)));
@@ -898,7 +946,7 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatInstruction(
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());
+ vecSize = Support::max<uint32_t>(vecSize, operands[j].as<Reg>().size());
ASMJIT_PROPAGATE(FormatterInternal_explainConst(sb, formatFlags, instId, vecSize, op.as<Imm>()));
}
@@ -941,4 +989,4 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatInstruction(
ASMJIT_END_SUB_NAMESPACE
-#endif // !ASMJIT_NO_LOGGING
+#endif // !ASMJIT_NO_X86 && !ASMJIT_NO_LOGGING
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86func.cpp b/3rdparty/asmjit/src/asmjit/x86/x86func.cpp
index bba9eef148c..ac73aff8bdd 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86func.cpp
+++ b/3rdparty/asmjit/src/asmjit/x86/x86func.cpp
@@ -14,7 +14,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
namespace FuncInternal {
-static inline bool shouldThreatAsCDeclIn64BitMode(CallConvId ccId) noexcept {
+static inline bool shouldTreatAsCDeclIn64BitMode(CallConvId ccId) noexcept {
return ccId == CallConvId::kCDecl ||
ccId == CallConvId::kStdCall ||
ccId == CallConvId::kThisCall ||
@@ -143,7 +143,7 @@ ASMJIT_FAVOR_SIZE Error initCallConv(CallConv& cc, CallConvId ccId, const Enviro
// 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))
+ if (shouldTreatAsCDeclIn64BitMode(ccId))
ccId = winABI ? CallConvId::kX64Windows : CallConvId::kX64SystemV;
switch (ccId) {
@@ -327,7 +327,8 @@ ASMJIT_FAVOR_SIZE Error initFuncDetail(FuncDetail& func, const FuncSignature& si
}
switch (cc.strategy()) {
- case CallConvStrategy::kDefault: {
+ case CallConvStrategy::kDefault:
+ default: {
uint32_t gpzPos = 0;
uint32_t vecPos = 0;
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86globals.h b/3rdparty/asmjit/src/asmjit/x86/x86globals.h
index 803c813ac53..21ed41e87d1 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86globals.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86globals.h
@@ -53,20 +53,23 @@ enum class CondCode : uint8_t {
kNLE = 0x0Fu, //!< ZF==0 & SF==OF (signed > )
kZero = kZ, //!< Zero flag.
- kNotZero = kNZ, //!< Non-zero flag.
+ kNotZero = kNZ, //!< Not zero.
+
+ kEqual = kE, //!< `a == b` (equal).
+ kNotEqual = kNE, //!< `a != b` (not equal).
+
+ kCarry = kC, //!< Carry flag.
+ kNotCarry = kNC, //!< Not carry.
kSign = kS, //!< Sign flag.
- kNotSign = kNS, //!< No sign flag.
+ kNotSign = kNS, //!< Not sign.
kNegative = kS, //!< Sign flag.
- kPositive = kNS, //!< No sign flag.
+ kPositive = kNS, //!< Not sign.
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).
@@ -77,6 +80,9 @@ enum class CondCode : uint8_t {
kUnsignedGT = kA, //!< `a > b` (unsigned).
kUnsignedGE = kAE, //!< `a >= b` (unsigned).
+ kBTZero = kNC, //!< Tested bit is zero.
+ kBTNotZero = kC, //!< Tested bit is non-zero.
+
kParityEven = kP, //!< Even parity flag.
kParityOdd = kPO, //!< Odd parity flag.
@@ -105,9 +111,9 @@ static constexpr CondCode _reverseCondTable[] = {
//! \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)]; }
+static ASMJIT_INLINE_NODEBUG 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); }
+static ASMJIT_INLINE_NODEBUG constexpr CondCode negateCond(CondCode cond) noexcept { return CondCode(uint8_t(cond) ^ 1u); }
//! Instruction.
//!
@@ -119,7 +125,9 @@ namespace Inst {
kIdNone = 0, //!< Invalid instruction id.
kIdAaa, //!< Instruction 'aaa' (X86).
kIdAad, //!< Instruction 'aad' (X86).
+ kIdAadd, //!< Instruction 'aadd' {RAO_INT}.
kIdAam, //!< Instruction 'aam' (X86).
+ kIdAand, //!< Instruction 'aand' {RAO_INT}.
kIdAas, //!< Instruction 'aas' (X86).
kIdAdc, //!< Instruction 'adc'.
kIdAdcx, //!< Instruction 'adcx' {ADX}.
@@ -143,7 +151,9 @@ namespace Inst {
kIdAndnps, //!< Instruction 'andnps' {SSE}.
kIdAndpd, //!< Instruction 'andpd' {SSE2}.
kIdAndps, //!< Instruction 'andps' {SSE}.
+ kIdAor, //!< Instruction 'aor' {RAO_INT}.
kIdArpl, //!< Instruction 'arpl' (X86).
+ kIdAxor, //!< Instruction 'axor' {RAO_INT}.
kIdBextr, //!< Instruction 'bextr' {BMI}.
kIdBlcfill, //!< Instruction 'blcfill' {TBM}.
kIdBlci, //!< Instruction 'blci' {TBM}.
@@ -224,14 +234,30 @@ namespace Inst {
kIdCmovs, //!< Instruction 'cmovs' {CMOV}.
kIdCmovz, //!< Instruction 'cmovz' {CMOV}.
kIdCmp, //!< Instruction 'cmp'.
+ kIdCmpbexadd, //!< Instruction 'cmpbexadd' {CMPCCXADD}.
+ kIdCmpbxadd, //!< Instruction 'cmpbxadd' {CMPCCXADD}.
+ kIdCmplexadd, //!< Instruction 'cmplexadd' {CMPCCXADD}.
+ kIdCmplxadd, //!< Instruction 'cmplxadd' {CMPCCXADD}.
+ kIdCmpnbexadd, //!< Instruction 'cmpnbexadd' {CMPCCXADD}.
+ kIdCmpnbxadd, //!< Instruction 'cmpnbxadd' {CMPCCXADD}.
+ kIdCmpnlexadd, //!< Instruction 'cmpnlexadd' {CMPCCXADD}.
+ kIdCmpnlxadd, //!< Instruction 'cmpnlxadd' {CMPCCXADD}.
+ kIdCmpnoxadd, //!< Instruction 'cmpnoxadd' {CMPCCXADD}.
+ kIdCmpnpxadd, //!< Instruction 'cmpnpxadd' {CMPCCXADD}.
+ kIdCmpnsxadd, //!< Instruction 'cmpnsxadd' {CMPCCXADD}.
+ kIdCmpnzxadd, //!< Instruction 'cmpnzxadd' {CMPCCXADD}.
+ kIdCmpoxadd, //!< Instruction 'cmpoxadd' {CMPCCXADD}.
kIdCmppd, //!< Instruction 'cmppd' {SSE2}.
kIdCmpps, //!< Instruction 'cmpps' {SSE}.
+ kIdCmppxadd, //!< Instruction 'cmppxadd' {CMPCCXADD}.
kIdCmps, //!< Instruction 'cmps'.
kIdCmpsd, //!< Instruction 'cmpsd' {SSE2}.
kIdCmpss, //!< Instruction 'cmpss' {SSE}.
+ kIdCmpsxadd, //!< Instruction 'cmpsxadd' {CMPCCXADD}.
kIdCmpxchg, //!< Instruction 'cmpxchg' {I486}.
kIdCmpxchg16b, //!< Instruction 'cmpxchg16b' {CMPXCHG16B} (X64).
kIdCmpxchg8b, //!< Instruction 'cmpxchg8b' {CMPXCHG8B}.
+ kIdCmpzxadd, //!< Instruction 'cmpzxadd' {CMPCCXADD}.
kIdComisd, //!< Instruction 'comisd' {SSE2}.
kIdComiss, //!< Instruction 'comiss' {SSE}.
kIdCpuid, //!< Instruction 'cpuid' {I486}.
@@ -279,104 +305,104 @@ namespace Inst {
kIdEnter, //!< Instruction 'enter'.
kIdExtractps, //!< Instruction 'extractps' {SSE4_1}.
kIdExtrq, //!< Instruction 'extrq' {SSE4A}.
- kIdF2xm1, //!< Instruction 'f2xm1'.
- kIdFabs, //!< Instruction 'fabs'.
- kIdFadd, //!< Instruction 'fadd'.
- kIdFaddp, //!< Instruction 'faddp'.
- kIdFbld, //!< Instruction 'fbld'.
- kIdFbstp, //!< Instruction 'fbstp'.
- kIdFchs, //!< Instruction 'fchs'.
- kIdFclex, //!< Instruction 'fclex'.
- kIdFcmovb, //!< Instruction 'fcmovb' {CMOV}.
- kIdFcmovbe, //!< Instruction 'fcmovbe' {CMOV}.
- kIdFcmove, //!< Instruction 'fcmove' {CMOV}.
- kIdFcmovnb, //!< Instruction 'fcmovnb' {CMOV}.
- kIdFcmovnbe, //!< Instruction 'fcmovnbe' {CMOV}.
- kIdFcmovne, //!< Instruction 'fcmovne' {CMOV}.
- kIdFcmovnu, //!< Instruction 'fcmovnu' {CMOV}.
- kIdFcmovu, //!< Instruction 'fcmovu' {CMOV}.
- kIdFcom, //!< Instruction 'fcom'.
- kIdFcomi, //!< Instruction 'fcomi'.
- kIdFcomip, //!< Instruction 'fcomip'.
- kIdFcomp, //!< Instruction 'fcomp'.
- kIdFcompp, //!< Instruction 'fcompp'.
- kIdFcos, //!< Instruction 'fcos'.
- kIdFdecstp, //!< Instruction 'fdecstp'.
- kIdFdiv, //!< Instruction 'fdiv'.
- kIdFdivp, //!< Instruction 'fdivp'.
- kIdFdivr, //!< Instruction 'fdivr'.
- kIdFdivrp, //!< Instruction 'fdivrp'.
+ kIdF2xm1, //!< Instruction 'f2xm1' {FPU}.
+ kIdFabs, //!< Instruction 'fabs' {FPU}.
+ kIdFadd, //!< Instruction 'fadd' {FPU}.
+ kIdFaddp, //!< Instruction 'faddp' {FPU}.
+ kIdFbld, //!< Instruction 'fbld' {FPU}.
+ kIdFbstp, //!< Instruction 'fbstp' {FPU}.
+ kIdFchs, //!< Instruction 'fchs' {FPU}.
+ kIdFclex, //!< Instruction 'fclex' {FPU}.
+ kIdFcmovb, //!< Instruction 'fcmovb' {CMOV|FPU}.
+ kIdFcmovbe, //!< Instruction 'fcmovbe' {CMOV|FPU}.
+ kIdFcmove, //!< Instruction 'fcmove' {CMOV|FPU}.
+ kIdFcmovnb, //!< Instruction 'fcmovnb' {CMOV|FPU}.
+ kIdFcmovnbe, //!< Instruction 'fcmovnbe' {CMOV|FPU}.
+ kIdFcmovne, //!< Instruction 'fcmovne' {CMOV|FPU}.
+ kIdFcmovnu, //!< Instruction 'fcmovnu' {CMOV|FPU}.
+ kIdFcmovu, //!< Instruction 'fcmovu' {CMOV|FPU}.
+ kIdFcom, //!< Instruction 'fcom' {FPU}.
+ kIdFcomi, //!< Instruction 'fcomi' {FPU}.
+ kIdFcomip, //!< Instruction 'fcomip' {FPU}.
+ kIdFcomp, //!< Instruction 'fcomp' {FPU}.
+ kIdFcompp, //!< Instruction 'fcompp' {FPU}.
+ kIdFcos, //!< Instruction 'fcos' {FPU}.
+ kIdFdecstp, //!< Instruction 'fdecstp' {FPU}.
+ kIdFdiv, //!< Instruction 'fdiv' {FPU}.
+ kIdFdivp, //!< Instruction 'fdivp' {FPU}.
+ kIdFdivr, //!< Instruction 'fdivr' {FPU}.
+ kIdFdivrp, //!< Instruction 'fdivrp' {FPU}.
kIdFemms, //!< Instruction 'femms' {3DNOW}.
- kIdFfree, //!< Instruction 'ffree'.
- kIdFiadd, //!< Instruction 'fiadd'.
- kIdFicom, //!< Instruction 'ficom'.
- kIdFicomp, //!< Instruction 'ficomp'.
- kIdFidiv, //!< Instruction 'fidiv'.
- kIdFidivr, //!< Instruction 'fidivr'.
- kIdFild, //!< Instruction 'fild'.
- kIdFimul, //!< Instruction 'fimul'.
- kIdFincstp, //!< Instruction 'fincstp'.
- kIdFinit, //!< Instruction 'finit'.
- kIdFist, //!< Instruction 'fist'.
- kIdFistp, //!< Instruction 'fistp'.
- kIdFisttp, //!< Instruction 'fisttp' {SSE3}.
- kIdFisub, //!< Instruction 'fisub'.
- kIdFisubr, //!< Instruction 'fisubr'.
- kIdFld, //!< Instruction 'fld'.
- kIdFld1, //!< Instruction 'fld1'.
- kIdFldcw, //!< Instruction 'fldcw'.
- kIdFldenv, //!< Instruction 'fldenv'.
- kIdFldl2e, //!< Instruction 'fldl2e'.
- kIdFldl2t, //!< Instruction 'fldl2t'.
- kIdFldlg2, //!< Instruction 'fldlg2'.
- kIdFldln2, //!< Instruction 'fldln2'.
- kIdFldpi, //!< Instruction 'fldpi'.
- kIdFldz, //!< Instruction 'fldz'.
- kIdFmul, //!< Instruction 'fmul'.
- kIdFmulp, //!< Instruction 'fmulp'.
- kIdFnclex, //!< Instruction 'fnclex'.
- kIdFninit, //!< Instruction 'fninit'.
- kIdFnop, //!< Instruction 'fnop'.
- kIdFnsave, //!< Instruction 'fnsave'.
- kIdFnstcw, //!< Instruction 'fnstcw'.
- kIdFnstenv, //!< Instruction 'fnstenv'.
- kIdFnstsw, //!< Instruction 'fnstsw'.
- kIdFpatan, //!< Instruction 'fpatan'.
- kIdFprem, //!< Instruction 'fprem'.
- kIdFprem1, //!< Instruction 'fprem1'.
- kIdFptan, //!< Instruction 'fptan'.
- kIdFrndint, //!< Instruction 'frndint'.
- kIdFrstor, //!< Instruction 'frstor'.
- kIdFsave, //!< Instruction 'fsave'.
- kIdFscale, //!< Instruction 'fscale'.
- kIdFsin, //!< Instruction 'fsin'.
- kIdFsincos, //!< Instruction 'fsincos'.
- kIdFsqrt, //!< Instruction 'fsqrt'.
- kIdFst, //!< Instruction 'fst'.
- kIdFstcw, //!< Instruction 'fstcw'.
- kIdFstenv, //!< Instruction 'fstenv'.
- kIdFstp, //!< Instruction 'fstp'.
- kIdFstsw, //!< Instruction 'fstsw'.
- kIdFsub, //!< Instruction 'fsub'.
- kIdFsubp, //!< Instruction 'fsubp'.
- kIdFsubr, //!< Instruction 'fsubr'.
- kIdFsubrp, //!< Instruction 'fsubrp'.
- kIdFtst, //!< Instruction 'ftst'.
- kIdFucom, //!< Instruction 'fucom'.
- kIdFucomi, //!< Instruction 'fucomi'.
- kIdFucomip, //!< Instruction 'fucomip'.
- kIdFucomp, //!< Instruction 'fucomp'.
- kIdFucompp, //!< Instruction 'fucompp'.
- kIdFwait, //!< Instruction 'fwait'.
- kIdFxam, //!< Instruction 'fxam'.
- kIdFxch, //!< Instruction 'fxch'.
+ kIdFfree, //!< Instruction 'ffree' {FPU}.
+ kIdFiadd, //!< Instruction 'fiadd' {FPU}.
+ kIdFicom, //!< Instruction 'ficom' {FPU}.
+ kIdFicomp, //!< Instruction 'ficomp' {FPU}.
+ kIdFidiv, //!< Instruction 'fidiv' {FPU}.
+ kIdFidivr, //!< Instruction 'fidivr' {FPU}.
+ kIdFild, //!< Instruction 'fild' {FPU}.
+ kIdFimul, //!< Instruction 'fimul' {FPU}.
+ kIdFincstp, //!< Instruction 'fincstp' {FPU}.
+ kIdFinit, //!< Instruction 'finit' {FPU}.
+ kIdFist, //!< Instruction 'fist' {FPU}.
+ kIdFistp, //!< Instruction 'fistp' {FPU}.
+ kIdFisttp, //!< Instruction 'fisttp' {SSE3|FPU}.
+ kIdFisub, //!< Instruction 'fisub' {FPU}.
+ kIdFisubr, //!< Instruction 'fisubr' {FPU}.
+ kIdFld, //!< Instruction 'fld' {FPU}.
+ kIdFld1, //!< Instruction 'fld1' {FPU}.
+ kIdFldcw, //!< Instruction 'fldcw' {FPU}.
+ kIdFldenv, //!< Instruction 'fldenv' {FPU}.
+ kIdFldl2e, //!< Instruction 'fldl2e' {FPU}.
+ kIdFldl2t, //!< Instruction 'fldl2t' {FPU}.
+ kIdFldlg2, //!< Instruction 'fldlg2' {FPU}.
+ kIdFldln2, //!< Instruction 'fldln2' {FPU}.
+ kIdFldpi, //!< Instruction 'fldpi' {FPU}.
+ kIdFldz, //!< Instruction 'fldz' {FPU}.
+ kIdFmul, //!< Instruction 'fmul' {FPU}.
+ kIdFmulp, //!< Instruction 'fmulp' {FPU}.
+ kIdFnclex, //!< Instruction 'fnclex' {FPU}.
+ kIdFninit, //!< Instruction 'fninit' {FPU}.
+ kIdFnop, //!< Instruction 'fnop' {FPU}.
+ kIdFnsave, //!< Instruction 'fnsave' {FPU}.
+ kIdFnstcw, //!< Instruction 'fnstcw' {FPU}.
+ kIdFnstenv, //!< Instruction 'fnstenv' {FPU}.
+ kIdFnstsw, //!< Instruction 'fnstsw' {FPU}.
+ kIdFpatan, //!< Instruction 'fpatan' {FPU}.
+ kIdFprem, //!< Instruction 'fprem' {FPU}.
+ kIdFprem1, //!< Instruction 'fprem1' {FPU}.
+ kIdFptan, //!< Instruction 'fptan' {FPU}.
+ kIdFrndint, //!< Instruction 'frndint' {FPU}.
+ kIdFrstor, //!< Instruction 'frstor' {FPU}.
+ kIdFsave, //!< Instruction 'fsave' {FPU}.
+ kIdFscale, //!< Instruction 'fscale' {FPU}.
+ kIdFsin, //!< Instruction 'fsin' {FPU}.
+ kIdFsincos, //!< Instruction 'fsincos' {FPU}.
+ kIdFsqrt, //!< Instruction 'fsqrt' {FPU}.
+ kIdFst, //!< Instruction 'fst' {FPU}.
+ kIdFstcw, //!< Instruction 'fstcw' {FPU}.
+ kIdFstenv, //!< Instruction 'fstenv' {FPU}.
+ kIdFstp, //!< Instruction 'fstp' {FPU}.
+ kIdFstsw, //!< Instruction 'fstsw' {FPU}.
+ kIdFsub, //!< Instruction 'fsub' {FPU}.
+ kIdFsubp, //!< Instruction 'fsubp' {FPU}.
+ kIdFsubr, //!< Instruction 'fsubr' {FPU}.
+ kIdFsubrp, //!< Instruction 'fsubrp' {FPU}.
+ kIdFtst, //!< Instruction 'ftst' {FPU}.
+ kIdFucom, //!< Instruction 'fucom' {FPU}.
+ kIdFucomi, //!< Instruction 'fucomi' {FPU}.
+ kIdFucomip, //!< Instruction 'fucomip' {FPU}.
+ kIdFucomp, //!< Instruction 'fucomp' {FPU}.
+ kIdFucompp, //!< Instruction 'fucompp' {FPU}.
+ kIdFwait, //!< Instruction 'fwait' {FPU}.
+ kIdFxam, //!< Instruction 'fxam' {FPU}.
+ kIdFxch, //!< Instruction 'fxch' {FPU}.
kIdFxrstor, //!< Instruction 'fxrstor' {FXSR}.
kIdFxrstor64, //!< Instruction 'fxrstor64' {FXSR} (X64).
kIdFxsave, //!< Instruction 'fxsave' {FXSR}.
kIdFxsave64, //!< Instruction 'fxsave64' {FXSR} (X64).
- kIdFxtract, //!< Instruction 'fxtract'.
- kIdFyl2x, //!< Instruction 'fyl2x'.
- kIdFyl2xp1, //!< Instruction 'fyl2xp1'.
+ kIdFxtract, //!< Instruction 'fxtract' {FPU}.
+ kIdFyl2x, //!< Instruction 'fyl2x' {FPU}.
+ kIdFyl2xp1, //!< Instruction 'fyl2xp1' {FPU}.
kIdGetsec, //!< Instruction 'getsec' {SMX}.
kIdGf2p8affineinvqb, //!< Instruction 'gf2p8affineinvqb' {GFNI}.
kIdGf2p8affineqb, //!< Instruction 'gf2p8affineqb' {GFNI}.
@@ -403,6 +429,7 @@ namespace Inst {
kIdInvept, //!< Instruction 'invept' {VMX}.
kIdInvlpg, //!< Instruction 'invlpg' {I486}.
kIdInvlpga, //!< Instruction 'invlpga' {SVM}.
+ kIdInvlpgb, //!< Instruction 'invlpgb' {INVLPGB}.
kIdInvpcid, //!< Instruction 'invpcid' {I486}.
kIdInvvpid, //!< Instruction 'invvpid' {VMX}.
kIdIret, //!< Instruction 'iret'.
@@ -535,7 +562,7 @@ namespace Inst {
kIdMonitor, //!< Instruction 'monitor' {MONITOR}.
kIdMonitorx, //!< Instruction 'monitorx' {MONITORX}.
kIdMov, //!< Instruction 'mov'.
- kIdMovabs, //!< Instruction 'movabs' (X64).
+ kIdMovabs, //!< Instruction 'movabs'.
kIdMovapd, //!< Instruction 'movapd' {SSE2}.
kIdMovaps, //!< Instruction 'movaps' {SSE}.
kIdMovbe, //!< Instruction 'movbe' {MOVBE}.
@@ -606,7 +633,7 @@ namespace Inst {
kIdPaddusb, //!< Instruction 'paddusb' {MMX|SSE2}.
kIdPaddusw, //!< Instruction 'paddusw' {MMX|SSE2}.
kIdPaddw, //!< Instruction 'paddw' {MMX|SSE2}.
- kIdPalignr, //!< Instruction 'palignr' {SSE3}.
+ kIdPalignr, //!< Instruction 'palignr' {SSSE3}.
kIdPand, //!< Instruction 'pand' {MMX|SSE2}.
kIdPandn, //!< Instruction 'pandn' {MMX|SSE2}.
kIdPause, //!< Instruction 'pause'.
@@ -713,10 +740,12 @@ namespace Inst {
kIdPopfq, //!< Instruction 'popfq' (X64).
kIdPor, //!< Instruction 'por' {MMX|SSE2}.
kIdPrefetch, //!< Instruction 'prefetch' {3DNOW}.
- kIdPrefetchnta, //!< Instruction 'prefetchnta' {MMX2}.
- kIdPrefetcht0, //!< Instruction 'prefetcht0' {MMX2}.
- kIdPrefetcht1, //!< Instruction 'prefetcht1' {MMX2}.
- kIdPrefetcht2, //!< Instruction 'prefetcht2' {MMX2}.
+ kIdPrefetchit0, //!< Instruction 'prefetchit0' {PREFETCHI} (X64).
+ kIdPrefetchit1, //!< Instruction 'prefetchit1' {PREFETCHI} (X64).
+ kIdPrefetchnta, //!< Instruction 'prefetchnta' {SSE}.
+ kIdPrefetcht0, //!< Instruction 'prefetcht0' {SSE}.
+ kIdPrefetcht1, //!< Instruction 'prefetcht1' {SSE}.
+ kIdPrefetcht2, //!< Instruction 'prefetcht2' {SSE}.
kIdPrefetchw, //!< Instruction 'prefetchw' {PREFETCHW}.
kIdPrefetchwt1, //!< Instruction 'prefetchwt1' {PREFETCHWT1}.
kIdPsadbw, //!< Instruction 'psadbw' {MMX2|SSE2}.
@@ -732,7 +761,7 @@ namespace Inst {
kIdPslldq, //!< Instruction 'pslldq' {SSE2}.
kIdPsllq, //!< Instruction 'psllq' {MMX|SSE2}.
kIdPsllw, //!< Instruction 'psllw' {MMX|SSE2}.
- kIdPsmash, //!< Instruction 'psmash' {SNP} (X64).
+ kIdPsmash, //!< Instruction 'psmash' {SEV_SNP} (X64).
kIdPsrad, //!< Instruction 'psrad' {MMX|SSE2}.
kIdPsraw, //!< Instruction 'psraw' {MMX|SSE2}.
kIdPsrld, //!< Instruction 'psrld' {MMX|SSE2}.
@@ -764,7 +793,7 @@ namespace Inst {
kIdPushf, //!< Instruction 'pushf'.
kIdPushfd, //!< Instruction 'pushfd' (X86).
kIdPushfq, //!< Instruction 'pushfq' (X64).
- kIdPvalidate, //!< Instruction 'pvalidate' {SNP}.
+ kIdPvalidate, //!< Instruction 'pvalidate' {SEV_SNP}.
kIdPxor, //!< Instruction 'pxor' {MMX|SSE2}.
kIdRcl, //!< Instruction 'rcl'.
kIdRcpps, //!< Instruction 'rcpps' {SSE}.
@@ -785,8 +814,8 @@ namespace Inst {
kIdRdtscp, //!< Instruction 'rdtscp' {RDTSCP}.
kIdRet, //!< Instruction 'ret'.
kIdRetf, //!< Instruction 'retf'.
- kIdRmpadjust, //!< Instruction 'rmpadjust' {SNP} (X64).
- kIdRmpupdate, //!< Instruction 'rmpupdate' {SNP} (X64).
+ kIdRmpadjust, //!< Instruction 'rmpadjust' {SEV_SNP} (X64).
+ kIdRmpupdate, //!< Instruction 'rmpupdate' {SEV_SNP} (X64).
kIdRol, //!< Instruction 'rol'.
kIdRor, //!< Instruction 'ror'.
kIdRorx, //!< Instruction 'rorx' {BMI2}.
@@ -805,6 +834,9 @@ namespace Inst {
kIdSaveprevssp, //!< Instruction 'saveprevssp' {CET_SS}.
kIdSbb, //!< Instruction 'sbb'.
kIdScas, //!< Instruction 'scas'.
+ kIdSeamcall, //!< Instruction 'seamcall' {SEAM}.
+ kIdSeamops, //!< Instruction 'seamops' {SEAM}.
+ kIdSeamret, //!< Instruction 'seamret' {SEAM}.
kIdSenduipi, //!< Instruction 'senduipi' {UINTR} (X64).
kIdSerialize, //!< Instruction 'serialize' {SERIALIZE}.
kIdSeta, //!< Instruction 'seta'.
@@ -838,7 +870,7 @@ namespace Inst {
kIdSets, //!< Instruction 'sets'.
kIdSetssbsy, //!< Instruction 'setssbsy' {CET_SS}.
kIdSetz, //!< Instruction 'setz'.
- kIdSfence, //!< Instruction 'sfence' {MMX2}.
+ kIdSfence, //!< Instruction 'sfence' {SSE}.
kIdSgdt, //!< Instruction 'sgdt'.
kIdSha1msg1, //!< Instruction 'sha1msg1' {SHA}.
kIdSha1msg2, //!< Instruction 'sha1msg2' {SHA}.
@@ -883,15 +915,19 @@ namespace Inst {
kIdSyscall, //!< Instruction 'syscall' (X64).
kIdSysenter, //!< Instruction 'sysenter'.
kIdSysexit, //!< Instruction 'sysexit'.
- kIdSysexitq, //!< Instruction 'sysexitq'.
+ kIdSysexitq, //!< Instruction 'sysexitq' (X64).
kIdSysret, //!< Instruction 'sysret' (X64).
kIdSysretq, //!< Instruction 'sysretq' (X64).
kIdT1mskc, //!< Instruction 't1mskc' {TBM}.
+ kIdTcmmimfp16ps, //!< Instruction 'tcmmimfp16ps' {AMX_COMPLEX} (X64).
+ kIdTcmmrlfp16ps, //!< Instruction 'tcmmrlfp16ps' {AMX_COMPLEX} (X64).
+ kIdTdcall, //!< Instruction 'tdcall' {SEAM}.
kIdTdpbf16ps, //!< Instruction 'tdpbf16ps' {AMX_BF16} (X64).
kIdTdpbssd, //!< Instruction 'tdpbssd' {AMX_INT8} (X64).
kIdTdpbsud, //!< Instruction 'tdpbsud' {AMX_INT8} (X64).
kIdTdpbusd, //!< Instruction 'tdpbusd' {AMX_INT8} (X64).
kIdTdpbuud, //!< Instruction 'tdpbuud' {AMX_INT8} (X64).
+ kIdTdpfp16ps, //!< Instruction 'tdpfp16ps' {AMX_FP16} (X64).
kIdTest, //!< Instruction 'test'.
kIdTestui, //!< Instruction 'testui' {UINTR} (X64).
kIdTileloadd, //!< Instruction 'tileloadd' {AMX_TILE} (X64).
@@ -899,6 +935,7 @@ namespace Inst {
kIdTilerelease, //!< Instruction 'tilerelease' {AMX_TILE} (X64).
kIdTilestored, //!< Instruction 'tilestored' {AMX_TILE} (X64).
kIdTilezero, //!< Instruction 'tilezero' {AMX_TILE} (X64).
+ kIdTlbsync, //!< Instruction 'tlbsync' {INVLPGB}.
kIdTpause, //!< Instruction 'tpause' {WAITPKG}.
kIdTzcnt, //!< Instruction 'tzcnt' {BMI}.
kIdTzmsk, //!< Instruction 'tzmsk' {TBM}.
@@ -938,6 +975,8 @@ namespace Inst {
kIdVandnps, //!< Instruction 'vandnps' {AVX|AVX512_DQ+VL}.
kIdVandpd, //!< Instruction 'vandpd' {AVX|AVX512_DQ+VL}.
kIdVandps, //!< Instruction 'vandps' {AVX|AVX512_DQ+VL}.
+ kIdVbcstnebf162ps, //!< Instruction 'vbcstnebf162ps' {AVX_NE_CONVERT}.
+ kIdVbcstnesh2ps, //!< Instruction 'vbcstnesh2ps' {AVX_NE_CONVERT}.
kIdVblendmpd, //!< Instruction 'vblendmpd' {AVX512_F+VL}.
kIdVblendmps, //!< Instruction 'vblendmps' {AVX512_F+VL}.
kIdVblendpd, //!< Instruction 'vblendpd' {AVX}.
@@ -973,7 +1012,11 @@ namespace Inst {
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}.
+ kIdVcvtneebf162ps, //!< Instruction 'vcvtneebf162ps' {AVX_NE_CONVERT}.
+ kIdVcvtneeph2ps, //!< Instruction 'vcvtneeph2ps' {AVX_NE_CONVERT}.
+ kIdVcvtneobf162ps, //!< Instruction 'vcvtneobf162ps' {AVX_NE_CONVERT}.
+ kIdVcvtneoph2ps, //!< Instruction 'vcvtneoph2ps' {AVX_NE_CONVERT}.
+ kIdVcvtneps2bf16, //!< Instruction 'vcvtneps2bf16' {AVX_NE_CONVERT|AVX512_BF16+VL}.
kIdVcvtpd2dq, //!< Instruction 'vcvtpd2dq' {AVX|AVX512_F+VL}.
kIdVcvtpd2ph, //!< Instruction 'vcvtpd2ph' {AVX512_FP16+VL}.
kIdVcvtpd2ps, //!< Instruction 'vcvtpd2ps' {AVX|AVX512_F+VL}.
@@ -1057,8 +1100,8 @@ namespace Inst {
kIdVdpps, //!< Instruction 'vdpps' {AVX}.
kIdVerr, //!< Instruction 'verr'.
kIdVerw, //!< Instruction 'verw'.
- kIdVexp2pd, //!< Instruction 'vexp2pd' {AVX512_ERI}.
- kIdVexp2ps, //!< Instruction 'vexp2ps' {AVX512_ERI}.
+ kIdVexp2pd, //!< Instruction 'vexp2pd' {AVX512_ER}.
+ kIdVexp2ps, //!< Instruction 'vexp2ps' {AVX512_ER}.
kIdVexpandpd, //!< Instruction 'vexpandpd' {AVX512_F+VL}.
kIdVexpandps, //!< Instruction 'vexpandps' {AVX512_F+VL}.
kIdVextractf128, //!< Instruction 'vextractf128' {AVX}.
@@ -1073,9 +1116,9 @@ namespace Inst {
kIdVextracti64x4, //!< Instruction 'vextracti64x4' {AVX512_F}.
kIdVextractps, //!< Instruction 'vextractps' {AVX|AVX512_F}.
kIdVfcmaddcph, //!< Instruction 'vfcmaddcph' {AVX512_FP16+VL}.
- kIdVfcmaddcsh, //!< Instruction 'vfcmaddcsh' {AVX512_FP16+VL}.
+ kIdVfcmaddcsh, //!< Instruction 'vfcmaddcsh' {AVX512_FP16}.
kIdVfcmulcph, //!< Instruction 'vfcmulcph' {AVX512_FP16+VL}.
- kIdVfcmulcsh, //!< Instruction 'vfcmulcsh' {AVX512_FP16+VL}.
+ kIdVfcmulcsh, //!< Instruction 'vfcmulcsh' {AVX512_FP16}.
kIdVfixupimmpd, //!< Instruction 'vfixupimmpd' {AVX512_F+VL}.
kIdVfixupimmps, //!< Instruction 'vfixupimmps' {AVX512_F+VL}.
kIdVfixupimmsd, //!< Instruction 'vfixupimmsd' {AVX512_F}.
@@ -1099,7 +1142,7 @@ namespace Inst {
kIdVfmadd231sh, //!< Instruction 'vfmadd231sh' {AVX512_FP16}.
kIdVfmadd231ss, //!< Instruction 'vfmadd231ss' {FMA|AVX512_F}.
kIdVfmaddcph, //!< Instruction 'vfmaddcph' {AVX512_FP16+VL}.
- kIdVfmaddcsh, //!< Instruction 'vfmaddcsh' {AVX512_FP16+VL}.
+ kIdVfmaddcsh, //!< Instruction 'vfmaddcsh' {AVX512_FP16}.
kIdVfmaddpd, //!< Instruction 'vfmaddpd' {FMA4}.
kIdVfmaddps, //!< Instruction 'vfmaddps' {FMA4}.
kIdVfmaddsd, //!< Instruction 'vfmaddsd' {FMA4}.
@@ -1206,14 +1249,14 @@ namespace Inst {
kIdVfrczss, //!< Instruction 'vfrczss' {XOP}.
kIdVgatherdpd, //!< Instruction 'vgatherdpd' {AVX2|AVX512_F+VL}.
kIdVgatherdps, //!< Instruction 'vgatherdps' {AVX2|AVX512_F+VL}.
- kIdVgatherpf0dpd, //!< Instruction 'vgatherpf0dpd' {AVX512_PFI}.
- kIdVgatherpf0dps, //!< Instruction 'vgatherpf0dps' {AVX512_PFI}.
- kIdVgatherpf0qpd, //!< Instruction 'vgatherpf0qpd' {AVX512_PFI}.
- kIdVgatherpf0qps, //!< Instruction 'vgatherpf0qps' {AVX512_PFI}.
- kIdVgatherpf1dpd, //!< Instruction 'vgatherpf1dpd' {AVX512_PFI}.
- kIdVgatherpf1dps, //!< Instruction 'vgatherpf1dps' {AVX512_PFI}.
- kIdVgatherpf1qpd, //!< Instruction 'vgatherpf1qpd' {AVX512_PFI}.
- kIdVgatherpf1qps, //!< Instruction 'vgatherpf1qps' {AVX512_PFI}.
+ kIdVgatherpf0dpd, //!< Instruction 'vgatherpf0dpd' {AVX512_PF}.
+ kIdVgatherpf0dps, //!< Instruction 'vgatherpf0dps' {AVX512_PF}.
+ kIdVgatherpf0qpd, //!< Instruction 'vgatherpf0qpd' {AVX512_PF}.
+ kIdVgatherpf0qps, //!< Instruction 'vgatherpf0qps' {AVX512_PF}.
+ kIdVgatherpf1dpd, //!< Instruction 'vgatherpf1dpd' {AVX512_PF}.
+ kIdVgatherpf1dps, //!< Instruction 'vgatherpf1dps' {AVX512_PF}.
+ kIdVgatherpf1qpd, //!< Instruction 'vgatherpf1qpd' {AVX512_PF}.
+ kIdVgatherpf1qps, //!< Instruction 'vgatherpf1qps' {AVX512_PF}.
kIdVgatherqpd, //!< Instruction 'vgatherqpd' {AVX2|AVX512_F+VL}.
kIdVgatherqps, //!< Instruction 'vgatherqps' {AVX2|AVX512_F+VL}.
kIdVgetexppd, //!< Instruction 'vgetexppd' {AVX512_F+VL}.
@@ -1254,18 +1297,19 @@ namespace Inst {
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}.
+ kIdVmaxsd, //!< Instruction 'vmaxsd' {AVX|AVX512_F}.
kIdVmaxsh, //!< Instruction 'vmaxsh' {AVX512_FP16}.
- kIdVmaxss, //!< Instruction 'vmaxss' {AVX|AVX512_F+VL}.
+ kIdVmaxss, //!< Instruction 'vmaxss' {AVX|AVX512_F}.
kIdVmcall, //!< Instruction 'vmcall' {VMX}.
kIdVmclear, //!< Instruction 'vmclear' {VMX}.
kIdVmfunc, //!< Instruction 'vmfunc' {VMX}.
+ kIdVmgexit, //!< Instruction 'vmgexit' {SEV_ES}.
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}.
+ kIdVminsd, //!< Instruction 'vminsd' {AVX|AVX512_F}.
kIdVminsh, //!< Instruction 'vminsh' {AVX512_FP16}.
- kIdVminss, //!< Instruction 'vminss' {AVX|AVX512_F+VL}.
+ kIdVminss, //!< Instruction 'vminss' {AVX|AVX512_F}.
kIdVmlaunch, //!< Instruction 'vmlaunch' {VMX}.
kIdVmload, //!< Instruction 'vmload' {SVM}.
kIdVmmcall, //!< Instruction 'vmmcall' {SVM}.
@@ -1316,11 +1360,12 @@ namespace Inst {
kIdVmulsh, //!< Instruction 'vmulsh' {AVX512_FP16}.
kIdVmulss, //!< Instruction 'vmulss' {AVX|AVX512_F}.
kIdVmwrite, //!< Instruction 'vmwrite' {VMX}.
+ kIdVmxoff, //!< Instruction 'vmxoff' {VMX}.
kIdVmxon, //!< Instruction 'vmxon' {VMX}.
kIdVorpd, //!< Instruction 'vorpd' {AVX|AVX512_DQ+VL}.
kIdVorps, //!< Instruction 'vorps' {AVX|AVX512_DQ+VL}.
- kIdVp2intersectd, //!< Instruction 'vp2intersectd' {AVX512_VP2INTERSECT}.
- kIdVp2intersectq, //!< Instruction 'vp2intersectq' {AVX512_VP2INTERSECT}.
+ kIdVp2intersectd, //!< Instruction 'vp2intersectd' {AVX512_VP2INTERSECT+VL}.
+ kIdVp2intersectq, //!< Instruction 'vp2intersectq' {AVX512_VP2INTERSECT+VL}.
kIdVp4dpwssd, //!< Instruction 'vp4dpwssd' {AVX512_4VNNIW}.
kIdVp4dpwssds, //!< Instruction 'vp4dpwssds' {AVX512_4VNNIW}.
kIdVpabsb, //!< Instruction 'vpabsb' {AVX|AVX2|AVX512_BW+VL}.
@@ -1357,8 +1402,8 @@ namespace Inst {
kIdVpblendw, //!< Instruction 'vpblendw' {AVX|AVX2}.
kIdVpbroadcastb, //!< Instruction 'vpbroadcastb' {AVX2|AVX512_BW+VL}.
kIdVpbroadcastd, //!< Instruction 'vpbroadcastd' {AVX2|AVX512_F+VL}.
- kIdVpbroadcastmb2q, //!< Instruction 'vpbroadcastmb2q' {AVX512_CDI+VL}.
- kIdVpbroadcastmw2d, //!< Instruction 'vpbroadcastmw2d' {AVX512_CDI+VL}.
+ kIdVpbroadcastmb2q, //!< Instruction 'vpbroadcastmb2q' {AVX512_CD+VL}.
+ kIdVpbroadcastmw2d, //!< Instruction 'vpbroadcastmw2d' {AVX512_CD+VL}.
kIdVpbroadcastq, //!< Instruction 'vpbroadcastq' {AVX2|AVX512_F+VL}.
kIdVpbroadcastw, //!< Instruction 'vpbroadcastw' {AVX2|AVX512_BW+VL}.
kIdVpclmulqdq, //!< Instruction 'vpclmulqdq' {AVX|AVX512_F+VL & PCLMULQDQ|VPCLMULQDQ}.
@@ -1395,12 +1440,24 @@ namespace Inst {
kIdVpcomuq, //!< Instruction 'vpcomuq' {XOP}.
kIdVpcomuw, //!< Instruction 'vpcomuw' {XOP}.
kIdVpcomw, //!< Instruction 'vpcomw' {XOP}.
- kIdVpconflictd, //!< Instruction 'vpconflictd' {AVX512_CDI+VL}.
- kIdVpconflictq, //!< Instruction 'vpconflictq' {AVX512_CDI+VL}.
+ kIdVpconflictd, //!< Instruction 'vpconflictd' {AVX512_CD+VL}.
+ kIdVpconflictq, //!< Instruction 'vpconflictq' {AVX512_CD+VL}.
+ kIdVpdpbssd, //!< Instruction 'vpdpbssd' {AVX_VNNI_INT8}.
+ kIdVpdpbssds, //!< Instruction 'vpdpbssds' {AVX_VNNI_INT8}.
+ kIdVpdpbsud, //!< Instruction 'vpdpbsud' {AVX_VNNI_INT8}.
+ kIdVpdpbsuds, //!< Instruction 'vpdpbsuds' {AVX_VNNI_INT8}.
kIdVpdpbusd, //!< Instruction 'vpdpbusd' {AVX_VNNI|AVX512_VNNI+VL}.
kIdVpdpbusds, //!< Instruction 'vpdpbusds' {AVX_VNNI|AVX512_VNNI+VL}.
+ kIdVpdpbuud, //!< Instruction 'vpdpbuud' {AVX_VNNI_INT8}.
+ kIdVpdpbuuds, //!< Instruction 'vpdpbuuds' {AVX_VNNI_INT8}.
kIdVpdpwssd, //!< Instruction 'vpdpwssd' {AVX_VNNI|AVX512_VNNI+VL}.
kIdVpdpwssds, //!< Instruction 'vpdpwssds' {AVX_VNNI|AVX512_VNNI+VL}.
+ kIdVpdpwsud, //!< Instruction 'vpdpwsud' {AVX_VNNI_INT16}.
+ kIdVpdpwsuds, //!< Instruction 'vpdpwsuds' {AVX_VNNI_INT16}.
+ kIdVpdpwusd, //!< Instruction 'vpdpwusd' {AVX_VNNI_INT16}.
+ kIdVpdpwusds, //!< Instruction 'vpdpwusds' {AVX_VNNI_INT16}.
+ kIdVpdpwuud, //!< Instruction 'vpdpwuud' {AVX_VNNI_INT16}.
+ kIdVpdpwuuds, //!< Instruction 'vpdpwuuds' {AVX_VNNI_INT16}.
kIdVperm2f128, //!< Instruction 'vperm2f128' {AVX}.
kIdVperm2i128, //!< Instruction 'vperm2i128' {AVX2}.
kIdVpermb, //!< Instruction 'vpermb' {AVX512_VBMI+VL}.
@@ -1463,8 +1520,8 @@ namespace Inst {
kIdVpinsrd, //!< Instruction 'vpinsrd' {AVX|AVX512_DQ}.
kIdVpinsrq, //!< Instruction 'vpinsrq' {AVX|AVX512_DQ} (X64).
kIdVpinsrw, //!< Instruction 'vpinsrw' {AVX|AVX512_BW}.
- kIdVplzcntd, //!< Instruction 'vplzcntd' {AVX512_CDI+VL}.
- kIdVplzcntq, //!< Instruction 'vplzcntq' {AVX512_CDI+VL}.
+ kIdVplzcntd, //!< Instruction 'vplzcntd' {AVX512_CD+VL}.
+ kIdVplzcntq, //!< Instruction 'vplzcntq' {AVX512_CD+VL}.
kIdVpmacsdd, //!< Instruction 'vpmacsdd' {XOP}.
kIdVpmacsdqh, //!< Instruction 'vpmacsdqh' {XOP}.
kIdVpmacsdql, //!< Instruction 'vpmacsdql' {XOP}.
@@ -1477,8 +1534,8 @@ namespace Inst {
kIdVpmacsww, //!< Instruction 'vpmacsww' {XOP}.
kIdVpmadcsswd, //!< Instruction 'vpmadcsswd' {XOP}.
kIdVpmadcswd, //!< Instruction 'vpmadcswd' {XOP}.
- kIdVpmadd52huq, //!< Instruction 'vpmadd52huq' {AVX512_IFMA+VL}.
- kIdVpmadd52luq, //!< Instruction 'vpmadd52luq' {AVX512_IFMA+VL}.
+ kIdVpmadd52huq, //!< Instruction 'vpmadd52huq' {AVX_IFMA|AVX512_IFMA+VL}.
+ kIdVpmadd52luq, //!< Instruction 'vpmadd52luq' {AVX_IFMA|AVX512_IFMA+VL}.
kIdVpmaddubsw, //!< Instruction 'vpmaddubsw' {AVX|AVX2|AVX512_BW+VL}.
kIdVpmaddwd, //!< Instruction 'vpmaddwd' {AVX|AVX2|AVX512_BW+VL}.
kIdVpmaskmovd, //!< Instruction 'vpmaskmovd' {AVX2}.
@@ -1658,10 +1715,10 @@ namespace Inst {
kIdVrcp14ps, //!< Instruction 'vrcp14ps' {AVX512_F+VL}.
kIdVrcp14sd, //!< Instruction 'vrcp14sd' {AVX512_F}.
kIdVrcp14ss, //!< Instruction 'vrcp14ss' {AVX512_F}.
- kIdVrcp28pd, //!< Instruction 'vrcp28pd' {AVX512_ERI}.
- kIdVrcp28ps, //!< Instruction 'vrcp28ps' {AVX512_ERI}.
- kIdVrcp28sd, //!< Instruction 'vrcp28sd' {AVX512_ERI}.
- kIdVrcp28ss, //!< Instruction 'vrcp28ss' {AVX512_ERI}.
+ kIdVrcp28pd, //!< Instruction 'vrcp28pd' {AVX512_ER}.
+ kIdVrcp28ps, //!< Instruction 'vrcp28ps' {AVX512_ER}.
+ kIdVrcp28sd, //!< Instruction 'vrcp28sd' {AVX512_ER}.
+ kIdVrcp28ss, //!< Instruction 'vrcp28ss' {AVX512_ER}.
kIdVrcpph, //!< Instruction 'vrcpph' {AVX512_FP16}.
kIdVrcpps, //!< Instruction 'vrcpps' {AVX}.
kIdVrcpsh, //!< Instruction 'vrcpsh' {AVX512_FP16}.
@@ -1686,10 +1743,10 @@ namespace Inst {
kIdVrsqrt14ps, //!< Instruction 'vrsqrt14ps' {AVX512_F+VL}.
kIdVrsqrt14sd, //!< Instruction 'vrsqrt14sd' {AVX512_F}.
kIdVrsqrt14ss, //!< Instruction 'vrsqrt14ss' {AVX512_F}.
- kIdVrsqrt28pd, //!< Instruction 'vrsqrt28pd' {AVX512_ERI}.
- kIdVrsqrt28ps, //!< Instruction 'vrsqrt28ps' {AVX512_ERI}.
- kIdVrsqrt28sd, //!< Instruction 'vrsqrt28sd' {AVX512_ERI}.
- kIdVrsqrt28ss, //!< Instruction 'vrsqrt28ss' {AVX512_ERI}.
+ kIdVrsqrt28pd, //!< Instruction 'vrsqrt28pd' {AVX512_ER}.
+ kIdVrsqrt28ps, //!< Instruction 'vrsqrt28ps' {AVX512_ER}.
+ kIdVrsqrt28sd, //!< Instruction 'vrsqrt28sd' {AVX512_ER}.
+ kIdVrsqrt28ss, //!< Instruction 'vrsqrt28ss' {AVX512_ER}.
kIdVrsqrtph, //!< Instruction 'vrsqrtph' {AVX512_FP16+VL}.
kIdVrsqrtps, //!< Instruction 'vrsqrtps' {AVX}.
kIdVrsqrtsh, //!< Instruction 'vrsqrtsh' {AVX512_FP16}.
@@ -1702,22 +1759,30 @@ namespace Inst {
kIdVscalefss, //!< Instruction 'vscalefss' {AVX512_F}.
kIdVscatterdpd, //!< Instruction 'vscatterdpd' {AVX512_F+VL}.
kIdVscatterdps, //!< Instruction 'vscatterdps' {AVX512_F+VL}.
- kIdVscatterpf0dpd, //!< Instruction 'vscatterpf0dpd' {AVX512_PFI}.
- kIdVscatterpf0dps, //!< Instruction 'vscatterpf0dps' {AVX512_PFI}.
- kIdVscatterpf0qpd, //!< Instruction 'vscatterpf0qpd' {AVX512_PFI}.
- kIdVscatterpf0qps, //!< Instruction 'vscatterpf0qps' {AVX512_PFI}.
- kIdVscatterpf1dpd, //!< Instruction 'vscatterpf1dpd' {AVX512_PFI}.
- kIdVscatterpf1dps, //!< Instruction 'vscatterpf1dps' {AVX512_PFI}.
- kIdVscatterpf1qpd, //!< Instruction 'vscatterpf1qpd' {AVX512_PFI}.
- kIdVscatterpf1qps, //!< Instruction 'vscatterpf1qps' {AVX512_PFI}.
+ kIdVscatterpf0dpd, //!< Instruction 'vscatterpf0dpd' {AVX512_PF}.
+ kIdVscatterpf0dps, //!< Instruction 'vscatterpf0dps' {AVX512_PF}.
+ kIdVscatterpf0qpd, //!< Instruction 'vscatterpf0qpd' {AVX512_PF}.
+ kIdVscatterpf0qps, //!< Instruction 'vscatterpf0qps' {AVX512_PF}.
+ kIdVscatterpf1dpd, //!< Instruction 'vscatterpf1dpd' {AVX512_PF}.
+ kIdVscatterpf1dps, //!< Instruction 'vscatterpf1dps' {AVX512_PF}.
+ kIdVscatterpf1qpd, //!< Instruction 'vscatterpf1qpd' {AVX512_PF}.
+ kIdVscatterpf1qps, //!< Instruction 'vscatterpf1qps' {AVX512_PF}.
kIdVscatterqpd, //!< Instruction 'vscatterqpd' {AVX512_F+VL}.
kIdVscatterqps, //!< Instruction 'vscatterqps' {AVX512_F+VL}.
+ kIdVsha512msg1, //!< Instruction 'vsha512msg1' {AVX & SHA512}.
+ kIdVsha512msg2, //!< Instruction 'vsha512msg2' {AVX & SHA512}.
+ kIdVsha512rnds2, //!< Instruction 'vsha512rnds2' {AVX & SHA512}.
kIdVshuff32x4, //!< Instruction 'vshuff32x4' {AVX512_F+VL}.
kIdVshuff64x2, //!< Instruction 'vshuff64x2' {AVX512_F+VL}.
kIdVshufi32x4, //!< Instruction 'vshufi32x4' {AVX512_F+VL}.
kIdVshufi64x2, //!< Instruction 'vshufi64x2' {AVX512_F+VL}.
kIdVshufpd, //!< Instruction 'vshufpd' {AVX|AVX512_F+VL}.
kIdVshufps, //!< Instruction 'vshufps' {AVX|AVX512_F+VL}.
+ kIdVsm3msg1, //!< Instruction 'vsm3msg1' {AVX & SM3}.
+ kIdVsm3msg2, //!< Instruction 'vsm3msg2' {AVX & SM3}.
+ kIdVsm3rnds2, //!< Instruction 'vsm3rnds2' {AVX & SM3}.
+ kIdVsm4key4, //!< Instruction 'vsm4key4' {AVX & SM4}.
+ kIdVsm4rnds4, //!< Instruction 'vsm4rnds4' {AVX & SM4}.
kIdVsqrtpd, //!< Instruction 'vsqrtpd' {AVX|AVX512_F+VL}.
kIdVsqrtph, //!< Instruction 'vsqrtph' {AVX512_FP16+VL}.
kIdVsqrtps, //!< Instruction 'vsqrtps' {AVX|AVX512_F+VL}.
@@ -1744,7 +1809,7 @@ namespace Inst {
kIdVxorps, //!< Instruction 'vxorps' {AVX|AVX512_DQ+VL}.
kIdVzeroall, //!< Instruction 'vzeroall' {AVX}.
kIdVzeroupper, //!< Instruction 'vzeroupper' {AVX}.
- kIdWbinvd, //!< Instruction 'wbinvd'.
+ kIdWbinvd, //!< Instruction 'wbinvd' {I486}.
kIdWbnoinvd, //!< Instruction 'wbnoinvd' {WBNOINVD}.
kIdWrfsbase, //!< Instruction 'wrfsbase' {FSGSBASE} (X64).
kIdWrgsbase, //!< Instruction 'wrgsbase' {FSGSBASE} (X64).
@@ -1784,7 +1849,7 @@ namespace Inst {
};
//! Tests whether the `instId` is defined.
- static inline constexpr bool isDefinedId(InstId instId) noexcept { return instId < _kIdCount; }
+ static ASMJIT_INLINE_NODEBUG constexpr bool isDefinedId(InstId instId) noexcept { return instId < _kIdCount; }
//! \cond
#define ASMJIT_INST_FROM_COND(ID) \
@@ -1801,11 +1866,11 @@ namespace Inst {
//! \endcond
//! Translates a condition code `cond` to a `jcc` instruction id.
- static constexpr InstId jccFromCond(CondCode cond) noexcept { return _jccTable[uint8_t(cond)]; }
+ static ASMJIT_INLINE_NODEBUG constexpr InstId jccFromCond(CondCode cond) noexcept { return _jccTable[uint8_t(cond)]; }
//! Translates a condition code `cond` to a `setcc` instruction id.
- static constexpr InstId setccFromCond(CondCode cond) noexcept { return _setccTable[uint8_t(cond)]; }
+ static ASMJIT_INLINE_NODEBUG constexpr InstId setccFromCond(CondCode cond) noexcept { return _setccTable[uint8_t(cond)]; }
//! Translates a condition code `cond` to a `cmovcc` instruction id.
- static constexpr InstId cmovccFromCond(CondCode cond) noexcept { return _cmovccTable[uint8_t(cond)]; }
+ static ASMJIT_INLINE_NODEBUG constexpr InstId cmovccFromCond(CondCode cond) noexcept { return _cmovccTable[uint8_t(cond)]; }
} // {Inst}
//! FPU status word bits.
@@ -1933,7 +1998,7 @@ enum class RoundImm : uint8_t {
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).
+ kSuppress = 0x08u //!< Suppress exceptions (avoids inexact exception, if set).
};
ASMJIT_DEFINE_ENUM_FLAGS(RoundImm)
@@ -2085,7 +2150,7 @@ enum class VReduceImm : uint8_t {
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 {
+static ASMJIT_INLINE_NODEBUG constexpr VReduceImm vReduceImm(VReduceImm flags, uint32_t fixedPointLength) noexcept {
return flags | VReduceImm(fixedPointLength << 4);
}
@@ -2120,7 +2185,7 @@ enum class TLogImm : uint8_t {
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 {
+static ASMJIT_INLINE_NODEBUG 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) |
@@ -2132,7 +2197,7 @@ static inline constexpr TLogImm tLogFromBits(uint8_t b000, uint8_t b001, uint8_t
}
//! 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); }
+static ASMJIT_INLINE_NODEBUG constexpr TLogImm fLogIfElse(TLogImm condition, TLogImm a, TLogImm b) noexcept { return (condition & a) | (~condition & b); }
//! Creates a shuffle immediate value that be used with SSE/AVX/AVX-512 instructions to shuffle 2 elements in a vector.
//!
@@ -2141,7 +2206,7 @@ static inline constexpr TLogImm fLogIfElse(TLogImm condition, TLogImm a, TLogImm
//!
//! 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 {
+static ASMJIT_INLINE_NODEBUG constexpr uint32_t shuffleImm(uint32_t a, uint32_t b) noexcept {
return (a << 1) | b;
}
@@ -2158,7 +2223,7 @@ static inline constexpr uint32_t shuffleImm(uint32_t a, uint32_t b) noexcept {
//! - `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 {
+static ASMJIT_INLINE_NODEBUG 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/3rdparty/asmjit/src/asmjit/x86/x86instapi.cpp b/3rdparty/asmjit/src/asmjit/x86/x86instapi.cpp
index 3857cc12127..fc17b5cdaea 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86instapi.cpp
+++ b/3rdparty/asmjit/src/asmjit/x86/x86instapi.cpp
@@ -3,30 +3,12 @@
// 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
-// static tables within this file. Perform the following steps to regenerate
-// all tables enclosed by ${...}:
-//
-// 1. Install node.js environment <https://nodejs.org>
-// 2. Go to asmjit/tools directory
-// 3. Get the latest asmdb from <https://github.com/asmjit/asmdb> and
-// copy/link the `asmdb` directory to `asmjit/tools/asmdb`.
-// 4. Execute `node tablegen-x86.js`
-//
-// Instruction encoding and opcodes were added to the `x86inst.cpp` database
-// manually in the past and they are not updated by the script as it became
-// tricky. However, everything else is updated including instruction operands
-// and tables required to validate them, instruction read/write information
-// (including registers and flags), and all indexes to all tables.
-// ----------------------------------------------------------------------------
-
#include "../core/api-build_p.h"
#if !defined(ASMJIT_NO_X86)
#include "../core/cpuinfo.h"
+#include "../core/instdb_p.h"
#include "../core/misc_p.h"
-#include "../core/support.h"
#include "../x86/x86instapi_p.h"
#include "../x86/x86instdb_p.h"
#include "../x86/x86opcode_p.h"
@@ -34,63 +16,21 @@
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
+namespace InstInternal {
+
// x86::InstInternal - Text
// ========================
#ifndef ASMJIT_NO_TEXT
-Error InstInternal::instIdToString(Arch arch, InstId instId, String& output) noexcept {
- DebugUtils::unused(arch);
-
+Error instIdToString(InstId instId, String& output) noexcept {
if (ASMJIT_UNLIKELY(!Inst::isDefinedId(instId)))
return DebugUtils::errored(kErrorInvalidInstruction);
- const InstDB::InstInfo& info = InstDB::infoById(instId);
- return output.append(InstDB::_nameData + info._nameDataIndex);
+ return InstNameUtils::decode(output, InstDB::_instNameIndexTable[instId], InstDB::_instNameStringTable);
}
-InstId InstInternal::stringToInstId(Arch arch, const char* s, size_t len) noexcept {
- DebugUtils::unused(arch);
-
- if (ASMJIT_UNLIKELY(!s))
- return Inst::kIdNone;
-
- if (len == SIZE_MAX)
- len = strlen(s);
-
- if (ASMJIT_UNLIKELY(len == 0 || len > InstDB::kMaxNameSize))
- return Inst::kIdNone;
-
- uint32_t prefix = uint32_t(s[0]) - 'a';
- if (ASMJIT_UNLIKELY(prefix > 'z' - 'a'))
- return Inst::kIdNone;
-
- uint32_t index = InstDB::instNameIndex[prefix].start;
- if (ASMJIT_UNLIKELY(!index))
- return Inst::kIdNone;
-
- const char* nameData = InstDB::_nameData;
- const InstDB::InstInfo* table = InstDB::_instInfoTable;
-
- const InstDB::InstInfo* base = table + index;
- const InstDB::InstInfo* end = table + InstDB::instNameIndex[prefix].end;
-
- for (size_t lim = (size_t)(end - base); lim != 0; lim >>= 1) {
- const InstDB::InstInfo* cur = base + (lim >> 1);
- int result = Support::cmpInstName(nameData + cur[0]._nameDataIndex, s, len);
-
- if (result < 0) {
- base = cur + 1;
- lim--;
- continue;
- }
-
- if (result > 0)
- continue;
-
- return InstId((size_t)(cur - table));
- }
-
- return Inst::kIdNone;
+InstId stringToInstId(const char* s, size_t len) noexcept {
+ return InstNameUtils::find(s, len, InstDB::instNameIndex, InstDB::_instNameIndexTable, InstDB::_instNameStringTable);
}
#endif // !ASMJIT_NO_TEXT
@@ -184,7 +124,7 @@ static const X86ValidationData _x64ValidationData = {
#undef REG_MASK_FROM_REG_TYPE_X86
static ASMJIT_FORCE_INLINE bool x86IsZmmOrM512(const Operand_& op) noexcept {
- return Reg::isZmm(op) || (op.isMem() && op.size() == 64);
+ return Reg::isZmm(op) || (op.isMem() && op.x86RmSize() == 64);
}
static ASMJIT_FORCE_INLINE bool x86CheckOSig(const InstDB::OpSignature& op, const InstDB::OpSignature& ref, bool& immOutOfRange) noexcept {
@@ -216,20 +156,11 @@ static ASMJIT_FORCE_INLINE bool x86CheckOSig(const InstDB::OpSignature& op, cons
return true;
}
-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 == Arch::kX86)
- vd = &_x86ValidationData;
- else
- vd = &_x64ValidationData;
-
+static ASMJIT_FAVOR_SIZE Error validate(InstDB::Mode mode, const BaseInst& inst, const Operand_* operands, size_t opCount, ValidationFlags validationFlags) noexcept {
uint32_t i;
- InstDB::Mode mode = InstDB::modeFromArch(arch);
// Get the instruction data.
+ const X86ValidationData* vd = (mode == InstDB::Mode::kX86) ? &_x86ValidationData : &_x64ValidationData;
InstId instId = inst.id();
InstOptions options = inst.options();
@@ -717,6 +648,15 @@ Next:
return kErrorOk;
}
+
+Error validateX86(const BaseInst& inst, const Operand_* operands, size_t opCount, ValidationFlags validationFlags) noexcept {
+ return validate(InstDB::Mode::kX86, inst, operands, opCount, validationFlags);
+}
+
+Error validateX64(const BaseInst& inst, const Operand_* operands, size_t opCount, ValidationFlags validationFlags) noexcept {
+ return validate(InstDB::Mode::kX64, inst, operands, opCount, validationFlags);
+}
+
#endif // !ASMJIT_NO_VALIDATION
// x86::InstInternal - QueryRWInfo
@@ -785,7 +725,7 @@ static ASMJIT_FORCE_INLINE bool hasSameRegType(const BaseReg* regs, size_t opCou
return true;
}
-Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, InstRWInfo* out) noexcept {
+Error 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));
@@ -827,7 +767,7 @@ Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_*
constexpr OpRWFlags RegPhys = OpRWFlags::kRegPhysId;
constexpr OpRWFlags MibRead = OpRWFlags::kMemBaseRead | OpRWFlags::kMemIndexRead;
- if (instRwInfo.category == InstDB::RWInfo::kCategoryGeneric) {
+ if (instRwInfo.category <= uint32_t(InstDB::RWInfo::kCategoryGenericEx)) {
uint32_t i;
uint32_t rmOpsMask = 0;
uint32_t rmMaxSize = 0;
@@ -852,8 +792,8 @@ Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_*
uint64_t rByteMask = rwOpData.rByteMask;
uint64_t wByteMask = rwOpData.wByteMask;
- if (op.isRead() && !rByteMask) rByteMask = Support::lsbMask<uint64_t>(srcOp.size());
- if (op.isWrite() && !wByteMask) wByteMask = Support::lsbMask<uint64_t>(srcOp.size());
+ if (op.isRead() && !rByteMask) rByteMask = Support::lsbMask<uint64_t>(srcOp.x86RmSize());
+ if (op.isWrite() && !wByteMask) wByteMask = Support::lsbMask<uint64_t>(srcOp.x86RmSize());
op._readByteMask = rByteMask;
op._writeByteMask = wByteMask;
@@ -876,7 +816,7 @@ Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_*
}
// Aggregate values required to calculate valid Reg/M info.
- rmMaxSize = Support::max(rmMaxSize, srcOp.size());
+ rmMaxSize = Support::max(rmMaxSize, srcOp.x86RmSize());
rmOpsMask |= Support::bitMask<uint32_t>(i);
}
else {
@@ -919,8 +859,8 @@ Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_*
}
}
- rmOpsMask &= instRmInfo.rmOpsMask;
- if (rmOpsMask) {
+ rmOpsMask &= uint32_t(instRmInfo.rmOpsMask);
+ if (rmOpsMask && !inst.hasOption(InstOptions::kX86_ER)) {
Support::BitWordIterator<uint32_t> it(rmOpsMask);
do {
i = it.next();
@@ -933,7 +873,7 @@ Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_*
op.setRmSize(instRmInfo.fixedSize);
break;
case InstDB::RWInfoRm::kCategoryConsistent:
- op.setRmSize(operands[i].size());
+ op.setRmSize(operands[i].x86RmSize());
break;
case InstDB::RWInfoRm::kCategoryHalf:
op.setRmSize(rmMaxSize / 2u);
@@ -948,6 +888,27 @@ Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_*
} while (it.hasNext());
}
+ // Special cases per instruction.
+ if (instRwInfo.category == InstDB::RWInfo::kCategoryGenericEx) {
+ switch (inst.id()) {
+ case Inst::kIdVpternlogd:
+ case Inst::kIdVpternlogq: {
+ if (opCount == 4 && operands[3].isImm()) {
+ uint32_t predicate = operands[3].as<Imm>().valueAs<uint8_t>();
+
+ if ((predicate >> 4) == (predicate & 0xF)) {
+ out->_operands[0].clearOpFlags(OpRWFlags::kRead);
+ out->_operands[0].setReadByteMask(0);
+ }
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
return rwHandleAVX512(inst, commonInfo, out);
}
@@ -966,8 +927,8 @@ Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_*
const Reg& o1 = operands[1].as<Reg>();
if (o0.isGp() && o1.isGp()) {
- out->_operands[0].reset(W | RegM, operands[0].size());
- out->_operands[1].reset(R | RegM, operands[1].size());
+ out->_operands[0].reset(W | RegM, operands[0].x86RmSize());
+ out->_operands[1].reset(R | RegM, operands[1].x86RmSize());
rwZeroExtendGp(out->_operands[0], operands[0].as<Gp>(), nativeGpSize);
out->_instFlags |= InstRWFlags::kMovOp;
@@ -1114,14 +1075,14 @@ Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_*
if (opCount == 2) {
if (operands[0].isReg() && operands[1].isImm()) {
- out->_operands[0].reset(X, operands[0].size());
+ out->_operands[0].reset(X, operands[0].as<Reg>().size());
out->_operands[1].reset();
rwZeroExtendGp(out->_operands[0], operands[0].as<Gp>(), nativeGpSize);
return kErrorOk;
}
- if (Reg::isGpw(operands[0]) && operands[1].size() == 1) {
+ if (Reg::isGpw(operands[0]) && operands[1].x86RmSize() == 1) {
// imul ax, r8/m8 <- AX = AL * r8/m8
out->_operands[0].reset(X | RegPhys, 2, Gp::kIdAx);
out->_operands[0].setReadByteMask(Support::lsbMask<uint64_t>(1));
@@ -1129,8 +1090,8 @@ Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_*
}
else {
// imul r?, r?/m?
- out->_operands[0].reset(X, operands[0].size());
- out->_operands[1].reset(R | RegM, operands[0].size());
+ out->_operands[0].reset(X, operands[0].as<Gp>().size());
+ out->_operands[1].reset(R | RegM, operands[0].as<Gp>().size());
rwZeroExtendGp(out->_operands[0], operands[0].as<Gp>(), nativeGpSize);
}
@@ -1141,8 +1102,8 @@ Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_*
if (opCount == 3) {
if (operands[2].isImm()) {
- out->_operands[0].reset(W, operands[0].size());
- out->_operands[1].reset(R | RegM, operands[1].size());
+ out->_operands[0].reset(W, operands[0].x86RmSize());
+ out->_operands[1].reset(R | RegM, operands[1].x86RmSize());
out->_operands[2].reset();
rwZeroExtendGp(out->_operands[0], operands[0].as<Gp>(), nativeGpSize);
@@ -1151,9 +1112,9 @@ Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_*
return kErrorOk;
}
else {
- out->_operands[0].reset(W | RegPhys, operands[0].size(), Gp::kIdDx);
- out->_operands[1].reset(X | RegPhys, operands[1].size(), Gp::kIdAx);
- out->_operands[2].reset(R | RegM, operands[2].size());
+ out->_operands[0].reset(W | RegPhys, operands[0].x86RmSize(), Gp::kIdDx);
+ out->_operands[1].reset(X | RegPhys, operands[1].x86RmSize(), Gp::kIdAx);
+ out->_operands[2].reset(R | RegM, operands[2].x86RmSize());
rwZeroExtendGp(out->_operands[0], operands[0].as<Gp>(), nativeGpSize);
rwZeroExtendGp(out->_operands[1], operands[1].as<Gp>(), nativeGpSize);
@@ -1230,18 +1191,18 @@ Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_*
// Special case for 'vmaskmovpd|vmaskmovps|vpmaskmovd|vpmaskmovq' instructions.
if (opCount == 3) {
if (BaseReg::isVec(operands[0]) && BaseReg::isVec(operands[1]) && operands[2].isMem()) {
- out->_operands[0].reset(W, operands[0].size());
- out->_operands[1].reset(R, operands[1].size());
- out->_operands[2].reset(R | MibRead, operands[1].size());
+ out->_operands[0].reset(W, operands[0].x86RmSize());
+ out->_operands[1].reset(R, operands[1].x86RmSize());
+ out->_operands[2].reset(R | MibRead, operands[1].x86RmSize());
rwZeroExtendAvxVec(out->_operands[0], operands[0].as<Vec>());
return kErrorOk;
}
if (operands[0].isMem() && BaseReg::isVec(operands[1]) && BaseReg::isVec(operands[2])) {
- out->_operands[0].reset(X | MibRead, operands[1].size());
- out->_operands[1].reset(R, operands[1].size());
- out->_operands[2].reset(R, operands[2].size());
+ out->_operands[0].reset(X | MibRead, operands[1].x86RmSize());
+ out->_operands[1].reset(R, operands[1].x86RmSize());
+ out->_operands[2].reset(R, operands[2].x86RmSize());
return kErrorOk;
}
}
@@ -1254,7 +1215,7 @@ Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_*
// operand, respectively.
if (opCount == 2) {
if (BaseReg::isVec(operands[0]) && BaseReg::isVec(operands[1])) {
- uint32_t o0Size = operands[0].size();
+ uint32_t o0Size = operands[0].x86RmSize();
uint32_t o1Size = o0Size == 16 ? 8 : o0Size;
out->_operands[0].reset(W, o0Size);
@@ -1266,7 +1227,7 @@ Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_*
}
if (BaseReg::isVec(operands[0]) && operands[1].isMem()) {
- uint32_t o0Size = operands[0].size();
+ uint32_t o0Size = operands[0].x86RmSize();
uint32_t o1Size = o0Size == 16 ? 8 : o0Size;
out->_operands[0].reset(W, o0Size);
@@ -1286,7 +1247,7 @@ Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_*
if (BaseReg::isGp(operands[0]) && BaseReg::isVec(operands[1])) {
out->_operands[0].reset(W, 1);
out->_operands[0].setExtendByteMask(Support::lsbMask<uint32_t>(nativeGpSize - 1) << 1);
- out->_operands[1].reset(R, operands[1].size());
+ out->_operands[1].reset(R, operands[1].x86RmSize());
return kErrorOk;
}
}
@@ -1324,7 +1285,7 @@ Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_*
}
if (operands[0].isReg() && operands[1].isReg()) {
- uint32_t size1 = operands[1].size();
+ uint32_t size1 = operands[1].x86RmSize();
uint32_t size0 = size1 >> shift;
out->_operands[0].reset(W, size0);
@@ -1351,16 +1312,20 @@ Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_*
}
if (operands[0].isReg() && operands[1].isMem()) {
- uint32_t size1 = operands[1].size() ? operands[1].size() : uint32_t(16);
+ uint32_t size1 = operands[1].x86RmSize() ? operands[1].x86RmSize() : uint32_t(16);
uint32_t size0 = size1 >> shift;
out->_operands[0].reset(W, size0);
out->_operands[1].reset(R | MibRead, size1);
+
+ if (BaseReg::isVec(operands[0]))
+ rwZeroExtendAvxVec(out->_operands[0], operands[0].as<Vec>());
+
return kErrorOk;
}
if (operands[0].isMem() && operands[1].isReg()) {
- uint32_t size1 = operands[1].size();
+ uint32_t size1 = operands[1].x86RmSize();
uint32_t size0 = size1 >> shift;
out->_operands[0].reset(W | MibRead, size0);
@@ -1401,12 +1366,15 @@ Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_*
out->_operands[2].reset();
}
- uint32_t size0 = operands[0].size();
+ uint32_t size0 = operands[0].x86RmSize();
uint32_t size1 = size0 >> shift;
out->_operands[0].reset(W, size0);
out->_operands[1].reset(R, size1);
+ if (BaseReg::isVec(operands[0]))
+ rwZeroExtendAvxVec(out->_operands[0], operands[0].as<Vec>());
+
if (operands[0].isReg() && operands[1].isReg()) {
if (instRmInfo.rmOpsMask & 0x1) {
out->_operands[0].addOpFlags(RegM);
@@ -1481,7 +1449,9 @@ static inline uint32_t InstInternal_usesAvx512(InstOptions instOptions, const Re
return hasEvex | hasKMask | hasKOrZmm;
}
-Error InstInternal::queryFeatures(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, CpuFeatures* out) noexcept {
+Error queryFeatures(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, CpuFeatures* out) noexcept {
+ typedef CpuFeatures::X86 Ext;
+
// Only called when `arch` matches X86 family.
DebugUtils::unused(arch);
ASMJIT_ASSERT(Environment::isFamilyX86(arch));
@@ -1514,19 +1484,19 @@ Error InstInternal::queryFeatures(Arch arch, const BaseInst& inst, const Operand
RegAnalysis regAnalysis = InstInternal_regAnalysis(operands, opCount);
// Handle MMX vs SSE overlap.
- if (out->has(CpuFeatures::X86::kMMX) || out->has(CpuFeatures::X86::kMMX2)) {
+ if (out->has(Ext::kMMX) || out->has(Ext::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 (out->has(Ext::kSSE) || out->has(Ext::kSSE2)) {
if (!regAnalysis.hasRegType(RegType::kX86_Xmm)) {
// The instruction doesn't use XMM register(s), thus it's MMX/MMX2 only.
- out->remove(CpuFeatures::X86::kSSE);
- out->remove(CpuFeatures::X86::kSSE2);
- out->remove(CpuFeatures::X86::kSSE4_1);
+ out->remove(Ext::kSSE);
+ out->remove(Ext::kSSE2);
+ out->remove(Ext::kSSE4_1);
}
else {
- out->remove(CpuFeatures::X86::kMMX);
- out->remove(CpuFeatures::X86::kMMX2);
+ out->remove(Ext::kMMX);
+ out->remove(Ext::kMMX2);
}
// Special case: PEXTRW instruction is MMX/SSE2 instruction. However, MMX/SSE version cannot access memory
@@ -1535,30 +1505,30 @@ Error InstInternal::queryFeatures(Arch arch, const BaseInst& inst, const Operand
// 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(CpuFeatures::X86::kSSE2);
+ out->remove(Ext::kSSE2);
else
- out->remove(CpuFeatures::X86::kSSE4_1);
+ out->remove(Ext::kSSE4_1);
}
}
}
// Handle PCLMULQDQ vs VPCLMULQDQ.
- if (out->has(CpuFeatures::X86::kVPCLMULQDQ)) {
+ if (out->has(Ext::kVPCLMULQDQ)) {
if (regAnalysis.hasRegType(RegType::kX86_Zmm) || Support::test(options, InstOptions::kX86_Evex)) {
// AVX512_F & VPCLMULQDQ.
- out->remove(CpuFeatures::X86::kAVX, CpuFeatures::X86::kPCLMULQDQ);
+ out->remove(Ext::kAVX, Ext::kPCLMULQDQ);
}
else if (regAnalysis.hasRegType(RegType::kX86_Ymm)) {
- out->remove(CpuFeatures::X86::kAVX512_F, CpuFeatures::X86::kAVX512_VL);
+ out->remove(Ext::kAVX512_F, Ext::kAVX512_VL);
}
else {
// AVX & PCLMULQDQ.
- out->remove(CpuFeatures::X86::kAVX512_F, CpuFeatures::X86::kAVX512_VL, CpuFeatures::X86::kVPCLMULQDQ);
+ out->remove(Ext::kAVX512_F, Ext::kAVX512_VL, Ext::kVPCLMULQDQ);
}
}
// Handle AVX vs AVX2 overlap.
- if (out->has(CpuFeatures::X86::kAVX) && out->has(CpuFeatures::X86::kAVX2)) {
+ if (out->has(Ext::kAVX) && out->has(Ext::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.
@@ -1575,157 +1545,287 @@ Error InstInternal::queryFeatures(Arch arch, const BaseInst& inst, const Operand
}
if (isAVX2)
- out->remove(CpuFeatures::X86::kAVX);
+ out->remove(Ext::kAVX);
else
- out->remove(CpuFeatures::X86::kAVX2);
+ out->remove(Ext::kAVX2);
}
- // Handle AVX|AVX2|FMA|F16C vs AVX512 overlap.
- 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(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.
- case Inst::kIdVpslldq:
- case Inst::kIdVpsrldq:
- mustUseEvex = opCount >= 2 && operands[1].isMem();
- break;
+ // Handle AVX vs AVX512 overlap.
+ //
+ // In general, non-AVX encoding is preferred, however, AVX encoded instructions that were initially provided
+ // as AVX-512 instructions must naturally prefer AVX-512 encoding, as that was the first one provided.
+ if (out->hasAny(Ext::kAVX,
+ Ext::kAVX_IFMA,
+ Ext::kAVX_NE_CONVERT,
+ Ext::kAVX_VNNI,
+ Ext::kAVX2,
+ Ext::kF16C,
+ Ext::kFMA)
+ &&
+ out->hasAny(Ext::kAVX512_BF16,
+ Ext::kAVX512_BW,
+ Ext::kAVX512_DQ,
+ Ext::kAVX512_F,
+ Ext::kAVX512_IFMA,
+ Ext::kAVX512_VNNI)) {
+
+ uint32_t useEvex = InstInternal_usesAvx512(options, inst.extraReg(), regAnalysis) | regAnalysis.highVecUsed;
+ switch (instId) {
+ // Special case: VPBROADCAST[B|D|Q|W] only supports r32/r64 with EVEX prefix.
+ case Inst::kIdVpbroadcastb:
+ case Inst::kIdVpbroadcastd:
+ case Inst::kIdVpbroadcastq:
+ case Inst::kIdVpbroadcastw:
+ useEvex |= uint32_t(opCount >= 2 && x86::Reg::isGp(operands[1]));
+ break;
- // Special case: VPBROADCAST[B|D|Q|W] only supports r32/r64 with EVEX prefix.
- case Inst::kIdVpbroadcastb:
- case Inst::kIdVpbroadcastd:
- case Inst::kIdVpbroadcastq:
- case Inst::kIdVpbroadcastw:
- mustUseEvex = opCount >= 2 && x86::Reg::isGp(operands[1]);
- break;
+ case Inst::kIdVcvtpd2dq:
+ case Inst::kIdVcvtpd2ps:
+ case Inst::kIdVcvttpd2dq:
+ useEvex |= uint32_t(opCount >= 2 && Reg::isYmm(operands[0]));
+ break;
- // Special case: VPERMPD - AVX2 vs AVX512-F case.
- case Inst::kIdVpermpd:
- mustUseEvex = opCount >= 3 && !operands[2].isImm();
- break;
+ case Inst::kIdVgatherdpd:
+ case Inst::kIdVgatherdps:
+ case Inst::kIdVgatherqpd:
+ case Inst::kIdVgatherqps:
+ case Inst::kIdVpgatherdd:
+ case Inst::kIdVpgatherdq:
+ case Inst::kIdVpgatherqd:
+ case Inst::kIdVpgatherqq:
+ useEvex |= uint32_t(opCount == 2);
+ break;
- // Special case: VPERMQ - AVX2 vs AVX512-F case.
- case Inst::kIdVpermq:
- mustUseEvex = opCount >= 3 && (operands[1].isMem() || !operands[2].isImm());
- break;
- }
+ // Special case: These 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::kIdVpslld:
+ case Inst::kIdVpsllq:
+ case Inst::kIdVpsllw:
+ case Inst::kIdVpsrad:
+ case Inst::kIdVpsraq:
+ case Inst::kIdVpsraw:
+ case Inst::kIdVpsrld:
+ case Inst::kIdVpsrldq:
+ case Inst::kIdVpsrlq:
+ case Inst::kIdVpsrlw:
+ useEvex |= uint32_t(opCount >= 2 && operands[1].isMem());
+ break;
- if (!(usesAvx512 | mustUseEvex | regAnalysis.highVecUsed))
- out->remove(CpuFeatures::X86::kAVX512_F, CpuFeatures::X86::kAVX512_BW, CpuFeatures::X86::kAVX512_DQ, CpuFeatures::X86::kAVX512_VL);
- else
- out->remove(CpuFeatures::X86::kAVX, CpuFeatures::X86::kAVX2, CpuFeatures::X86::kFMA, CpuFeatures::X86::kF16C);
- }
- }
+ // Special case: VPERMPD - AVX2 vs AVX512-F case.
+ case Inst::kIdVpermpd:
+ useEvex |= uint32_t(opCount >= 3 && !operands[2].isImm());
+ break;
- // Handle AVX_VNNI vs AVX512_VNNI overlap.
- 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);
+ // Special case: VPERMQ - AVX2 vs AVX512-F case.
+ case Inst::kIdVpermq:
+ useEvex |= uint32_t(opCount >= 3 && (operands[1].isMem() || !operands[2].isImm()));
+ break;
+ }
- if (!usesAvx512 && Support::test(options, InstOptions::kX86_Vex | InstOptions::kX86_Vex3))
- out->remove(CpuFeatures::X86::kAVX512_VNNI, CpuFeatures::X86::kAVX512_VL);
- else
- out->remove(CpuFeatures::X86::kAVX_VNNI);
+ if (instInfo.commonInfo().preferEvex() && !Support::test(options, InstOptions::kX86_Vex | InstOptions::kX86_Vex3))
+ useEvex = 1;
+
+ if (useEvex) {
+ out->remove(Ext::kAVX,
+ Ext::kAVX_IFMA,
+ Ext::kAVX_NE_CONVERT,
+ Ext::kAVX_VNNI,
+ Ext::kAVX2,
+ Ext::kF16C,
+ Ext::kFMA);
+ }
+ else {
+ out->remove(Ext::kAVX512_BF16,
+ Ext::kAVX512_BW,
+ Ext::kAVX512_DQ,
+ Ext::kAVX512_F,
+ Ext::kAVX512_IFMA,
+ Ext::kAVX512_VL,
+ Ext::kAVX512_VNNI);
+ }
}
// Clear AVX512_VL if ZMM register is used.
if (regAnalysis.hasRegType(RegType::kX86_Zmm))
- out->remove(CpuFeatures::X86::kAVX512_VL);
+ out->remove(Ext::kAVX512_VL);
}
return kErrorOk;
}
#endif // !ASMJIT_NO_INTROSPECTION
+} // {InstInternal}
+
// x86::InstInternal - Tests
// =========================
#if defined(ASMJIT_TEST)
+#ifndef ASMJIT_NO_TEXT
UNIT(x86_inst_api_text) {
// All known instructions should be matched.
INFO("Matching all X86 instructions");
for (uint32_t a = 1; a < Inst::_kIdCount; a++) {
StringTmp<128> aName;
- EXPECT(InstInternal::instIdToString(Arch::kX86, a, aName) == kErrorOk,
- "Failed to get the name of instruction #%u", a);
+ EXPECT_EQ(InstInternal::instIdToString(a, aName), kErrorOk)
+ .message("Failed to get the name of instruction #%u", a);
- uint32_t b = InstInternal::stringToInstId(Arch::kX86, aName.data(), aName.size());
+ uint32_t b = InstInternal::stringToInstId(aName.data(), aName.size());
StringTmp<128> bName;
- InstInternal::instIdToString(Arch::kX86, b, bName);
+ InstInternal::instIdToString(b, bName);
+ EXPECT_EQ(a, b)
+ .message("Instructions do not match \"%s\" (#%u) != \"%s\" (#%u)", aName.data(), a, bName.data(), b);
+ }
+}
+#endif // !ASMJIT_NO_TEXT
+
+#ifndef ASMJIT_NO_INTROSPECTION
+template<typename... Args>
+static Error queryFeaturesInline(CpuFeatures* out, Arch arch, BaseInst inst, Args&&... args) {
+ Operand_ opArray[] = { std::forward<Args>(args)... };
+ return InstInternal::queryFeatures(arch, inst, opArray, sizeof...(args), out);
+}
+
+UNIT(x86_inst_api_cpu_features) {
+ INFO("Verifying whether SSE2+ features are reported correctly for legacy instructions");
+ {
+ CpuFeatures f;
+
+ queryFeaturesInline(&f, Arch::kX64, BaseInst(Inst::kIdPaddd), xmm1, xmm2);
+ EXPECT_TRUE(f.x86().hasSSE2());
+
+ queryFeaturesInline(&f, Arch::kX64, BaseInst(Inst::kIdAddsubpd), xmm1, xmm2);
+ EXPECT_TRUE(f.x86().hasSSE3());
- EXPECT(a == b,
- "Instructions do not match \"%s\" (#%u) != \"%s\" (#%u)", aName.data(), a, bName.data(), b);
+ queryFeaturesInline(&f, Arch::kX64, BaseInst(Inst::kIdPshufb), xmm1, xmm2);
+ EXPECT_TRUE(f.x86().hasSSSE3());
+
+ queryFeaturesInline(&f, Arch::kX64, BaseInst(Inst::kIdBlendpd), xmm1, xmm2, Imm(1));
+ EXPECT_TRUE(f.x86().hasSSE4_1());
+
+ queryFeaturesInline(&f, Arch::kX64, BaseInst(Inst::kIdCrc32), eax, al);
+ EXPECT_TRUE(f.x86().hasSSE4_2());
+ }
+
+ INFO("Verifying whether AVX+ features are reported correctly for AVX instructions");
+ {
+ CpuFeatures f;
+
+ queryFeaturesInline(&f, Arch::kX64, BaseInst(Inst::kIdVpaddd), xmm1, xmm2, xmm3);
+ EXPECT_TRUE(f.x86().hasAVX());
+
+ queryFeaturesInline(&f, Arch::kX64, BaseInst(Inst::kIdVpaddd), ymm1, ymm2, ymm3);
+ EXPECT_TRUE(f.x86().hasAVX2());
+
+ queryFeaturesInline(&f, Arch::kX64, BaseInst(Inst::kIdVaddsubpd), xmm1, xmm2, xmm3);
+ EXPECT_TRUE(f.x86().hasAVX());
+
+ queryFeaturesInline(&f, Arch::kX64, BaseInst(Inst::kIdVaddsubpd), ymm1, ymm2, ymm3);
+ EXPECT_TRUE(f.x86().hasAVX());
+
+ queryFeaturesInline(&f, Arch::kX64, BaseInst(Inst::kIdVpshufb), xmm1, xmm2, xmm3);
+ EXPECT_TRUE(f.x86().hasAVX());
+
+ queryFeaturesInline(&f, Arch::kX64, BaseInst(Inst::kIdVpshufb), ymm1, ymm2, ymm3);
+ EXPECT_TRUE(f.x86().hasAVX2());
+
+ queryFeaturesInline(&f, Arch::kX64, BaseInst(Inst::kIdVblendpd), xmm1, xmm2, xmm3, Imm(1));
+ EXPECT_TRUE(f.x86().hasAVX());
+
+ queryFeaturesInline(&f, Arch::kX64, BaseInst(Inst::kIdVblendpd), ymm1, ymm2, ymm3, Imm(1));
+ EXPECT_TRUE(f.x86().hasAVX());
+
+ queryFeaturesInline(&f, Arch::kX64, BaseInst(Inst::kIdVpunpcklbw), xmm1, xmm2, xmm3);
+ EXPECT_TRUE(f.x86().hasAVX());
+
+ queryFeaturesInline(&f, Arch::kX64, BaseInst(Inst::kIdVpunpcklbw), ymm1, ymm2, ymm3);
+ EXPECT_TRUE(f.x86().hasAVX2());
+ }
+
+ INFO("Verifying whether AVX2 / AVX512 features are reported correctly for vpgatherxx instructions");
+ {
+ CpuFeatures f;
+
+ queryFeaturesInline(&f, Arch::kX64, BaseInst(Inst::kIdVpgatherdd), xmm1, ptr(rax, xmm2), xmm3);
+ EXPECT_TRUE(f.x86().hasAVX2());
+ EXPECT_FALSE(f.x86().hasAVX512_F());
+
+ // NOTE: This instruction is unencodable, but sometimes this signature is used to check the support (without the {k}).
+ queryFeaturesInline(&f, Arch::kX64, BaseInst(Inst::kIdVpgatherdd), xmm1, ptr(rax, xmm2));
+ EXPECT_FALSE(f.x86().hasAVX2());
+ EXPECT_TRUE(f.x86().hasAVX512_F());
+
+ queryFeaturesInline(&f, Arch::kX64, BaseInst(Inst::kIdVpgatherdd, InstOptions::kNone, k1), xmm1, ptr(rax, xmm2));
+ EXPECT_FALSE(f.x86().hasAVX2());
+ EXPECT_TRUE(f.x86().hasAVX512_F());
}
}
+#endif // !ASMJIT_NO_INTROSPECTION
+#ifndef ASMJIT_NO_INTROSPECTION
template<typename... Args>
-static Error queryRWInfoSimple(InstRWInfo* out, Arch arch, InstId instId, InstOptions options, Args&&... args) {
- BaseInst inst(instId);
- inst.addOptions(options);
+static Error queryRWInfoInline(InstRWInfo* out, Arch arch, BaseInst inst, Args&&... args) {
Operand_ opArray[] = { std::forward<Args>(args)... };
return InstInternal::queryRWInfo(arch, inst, opArray, sizeof...(args), out);
}
-UNIT(x86_inst_api_rm_feature) {
+UNIT(x86_inst_api_rm_features) {
INFO("Verifying whether RM/feature is reported correctly for PEXTRW instruction");
{
InstRWInfo rwi;
- queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdPextrw, InstOptions::kNone, eax, mm1, imm(1));
- EXPECT(rwi.rmFeature() == 0);
+ queryRWInfoInline(&rwi, Arch::kX64, BaseInst(Inst::kIdPextrw), eax, mm1, imm(1));
+ EXPECT_EQ(rwi.rmFeature(), 0u);
- queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdPextrw, InstOptions::kNone, eax, xmm1, imm(1));
- EXPECT(rwi.rmFeature() == CpuFeatures::X86::kSSE4_1);
+ queryRWInfoInline(&rwi, Arch::kX64, BaseInst(Inst::kIdPextrw), eax, xmm1, imm(1));
+ EXPECT_EQ(rwi.rmFeature(), CpuFeatures::X86::kSSE4_1);
}
INFO("Verifying whether RM/feature is reported correctly for AVX512 shift instructions");
{
InstRWInfo rwi;
- queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpslld, InstOptions::kNone, xmm1, xmm2, imm(8));
- EXPECT(rwi.rmFeature() == CpuFeatures::X86::kAVX512_F);
+ queryRWInfoInline(&rwi, Arch::kX64, BaseInst(Inst::kIdVpslld), xmm1, xmm2, imm(8));
+ EXPECT_EQ(rwi.rmFeature(), CpuFeatures::X86::kAVX512_F);
- queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsllq, InstOptions::kNone, ymm1, ymm2, imm(8));
- EXPECT(rwi.rmFeature() == CpuFeatures::X86::kAVX512_F);
+ queryRWInfoInline(&rwi, Arch::kX64, BaseInst(Inst::kIdVpsllq), ymm1, ymm2, imm(8));
+ EXPECT_EQ(rwi.rmFeature(), CpuFeatures::X86::kAVX512_F);
- queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsrad, InstOptions::kNone, xmm1, xmm2, imm(8));
- EXPECT(rwi.rmFeature() == CpuFeatures::X86::kAVX512_F);
+ queryRWInfoInline(&rwi, Arch::kX64, BaseInst(Inst::kIdVpsrad), xmm1, xmm2, imm(8));
+ EXPECT_EQ(rwi.rmFeature(), CpuFeatures::X86::kAVX512_F);
- queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsrld, InstOptions::kNone, ymm1, ymm2, imm(8));
- EXPECT(rwi.rmFeature() == CpuFeatures::X86::kAVX512_F);
+ queryRWInfoInline(&rwi, Arch::kX64, BaseInst(Inst::kIdVpsrld), ymm1, ymm2, imm(8));
+ EXPECT_EQ(rwi.rmFeature(), CpuFeatures::X86::kAVX512_F);
- queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsrlq, InstOptions::kNone, xmm1, xmm2, imm(8));
- EXPECT(rwi.rmFeature() == CpuFeatures::X86::kAVX512_F);
+ queryRWInfoInline(&rwi, Arch::kX64, BaseInst(Inst::kIdVpsrlq), xmm1, xmm2, imm(8));
+ EXPECT_EQ(rwi.rmFeature(), CpuFeatures::X86::kAVX512_F);
- queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpslldq, InstOptions::kNone, xmm1, xmm2, imm(8));
- EXPECT(rwi.rmFeature() == CpuFeatures::X86::kAVX512_BW);
+ queryRWInfoInline(&rwi, Arch::kX64, BaseInst(Inst::kIdVpslldq), xmm1, xmm2, imm(8));
+ EXPECT_EQ(rwi.rmFeature(), CpuFeatures::X86::kAVX512_BW);
- queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsllw, InstOptions::kNone, ymm1, ymm2, imm(8));
- EXPECT(rwi.rmFeature() == CpuFeatures::X86::kAVX512_BW);
+ queryRWInfoInline(&rwi, Arch::kX64, BaseInst(Inst::kIdVpsllw), ymm1, ymm2, imm(8));
+ EXPECT_EQ(rwi.rmFeature(), CpuFeatures::X86::kAVX512_BW);
- queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsraw, InstOptions::kNone, xmm1, xmm2, imm(8));
- EXPECT(rwi.rmFeature() == CpuFeatures::X86::kAVX512_BW);
+ queryRWInfoInline(&rwi, Arch::kX64, BaseInst(Inst::kIdVpsraw), xmm1, xmm2, imm(8));
+ EXPECT_EQ(rwi.rmFeature(), CpuFeatures::X86::kAVX512_BW);
- queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsrldq, InstOptions::kNone, ymm1, ymm2, imm(8));
- EXPECT(rwi.rmFeature() == CpuFeatures::X86::kAVX512_BW);
+ queryRWInfoInline(&rwi, Arch::kX64, BaseInst(Inst::kIdVpsrldq), ymm1, ymm2, imm(8));
+ EXPECT_EQ(rwi.rmFeature(), CpuFeatures::X86::kAVX512_BW);
- queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsrlw, InstOptions::kNone, xmm1, xmm2, imm(8));
- EXPECT(rwi.rmFeature() == CpuFeatures::X86::kAVX512_BW);
+ queryRWInfoInline(&rwi, Arch::kX64, BaseInst(Inst::kIdVpsrlw), xmm1, xmm2, imm(8));
+ EXPECT_EQ(rwi.rmFeature(), CpuFeatures::X86::kAVX512_BW);
- queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpslld, InstOptions::kNone, xmm1, xmm2, xmm3);
- EXPECT(rwi.rmFeature() == 0);
+ queryRWInfoInline(&rwi, Arch::kX64, BaseInst(Inst::kIdVpslld), xmm1, xmm2, xmm3);
+ EXPECT_EQ(rwi.rmFeature(), 0u);
- queryRWInfoSimple(&rwi, Arch::kX64, Inst::kIdVpsllw, InstOptions::kNone, xmm1, xmm2, xmm3);
- EXPECT(rwi.rmFeature() == 0);
+ queryRWInfoInline(&rwi, Arch::kX64, BaseInst(Inst::kIdVpsllw), xmm1, xmm2, xmm3);
+ EXPECT_EQ(rwi.rmFeature(), 0u);
}
}
-#endif
+#endif // !ASMJIT_NO_INTROSPECTION
+
+#endif // ASMJIT_TEST
ASMJIT_END_SUB_NAMESPACE
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86instapi_p.h b/3rdparty/asmjit/src/asmjit/x86/x86instapi_p.h
index 56f7fb928f2..e0866ea702e 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86instapi_p.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86instapi_p.h
@@ -18,12 +18,13 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
namespace InstInternal {
#ifndef ASMJIT_NO_TEXT
-Error ASMJIT_CDECL instIdToString(Arch arch, InstId instId, String& output) noexcept;
-InstId ASMJIT_CDECL stringToInstId(Arch arch, const char* s, size_t len) noexcept;
+Error ASMJIT_CDECL instIdToString(InstId instId, String& output) noexcept;
+InstId ASMJIT_CDECL stringToInstId(const char* s, size_t len) noexcept;
#endif // !ASMJIT_NO_TEXT
#ifndef ASMJIT_NO_VALIDATION
-Error ASMJIT_CDECL validate(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, ValidationFlags validationFlags) noexcept;
+Error ASMJIT_CDECL validateX86(const BaseInst& inst, const Operand_* operands, size_t opCount, ValidationFlags validationFlags) noexcept;
+Error ASMJIT_CDECL validateX64(const BaseInst& inst, const Operand_* operands, size_t opCount, ValidationFlags validationFlags) noexcept;
#endif // !ASMJIT_NO_VALIDATION
#ifndef ASMJIT_NO_INTROSPECTION
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86instdb.cpp b/3rdparty/asmjit/src/asmjit/x86/x86instdb.cpp
index ee22526c348..c31ce91019a 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86instdb.cpp
+++ b/3rdparty/asmjit/src/asmjit/x86/x86instdb.cpp
@@ -3,24 +3,6 @@
// 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
-// static tables within this file. Perform the following steps to regenerate
-// all tables enclosed by ${...}:
-//
-// 1. Install node.js environment <https://nodejs.org>
-// 2. Go to asmjit/tools directory
-// 3. Get the latest asmdb from <https://github.com/asmjit/asmdb> and
-// copy/link the `asmdb` directory to `asmjit/tools/asmdb`.
-// 4. Execute `node tablegen-x86.js`
-//
-// Instruction encoding and opcodes were added to the `x86inst.cpp` database
-// manually in the past and they are not updated by the script as it became
-// tricky. However, everything else is updated including instruction operands
-// and tables required to validate them, instruction read/write information
-// (including registers and flags), and all indexes to all tables.
-// ----------------------------------------------------------------------------
-
#include "../core/api-build_p.h"
#if !defined(ASMJIT_NO_X86)
@@ -47,17 +29,9 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
#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
-// APIs can use `_nameDataIndex` it's much safer if it's zero if it's not defined.
-#ifndef ASMJIT_NO_TEXT
- #define NAME_DATA_INDEX(Index) Index
-#else
- #define NAME_DATA_INDEX(Index) 0
-#endif
-
// Defines an X86 instruction.
-#define INST(id, encoding, opcode0, opcode1, mainOpcodeIndex, altOpcodeIndex, nameDataIndex, commomInfoIndex, additionalInfoIndex) { \
- uint32_t(NAME_DATA_INDEX(nameDataIndex)), \
+#define INST(id, encoding, opcode0, opcode1, mainOpcodeIndex, altOpcodeIndex, commomInfoIndex, additionalInfoIndex) { \
+ uint32_t(0), \
uint32_t(commomInfoIndex), \
uint32_t(additionalInfoIndex), \
uint8_t(InstDB::kEncoding##encoding), \
@@ -67,1674 +41,1733 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
}
const InstDB::InstInfo InstDB::_instInfoTable[] = {
- /*--------------------+--------------------+------------------+--------+------------------+--------+----+----+------+----+----+
- | Instruction | Instruction | Main Opcode | EVEX |Alternative Opcode| EVEX |Op0X|Op1X|Name-X|IdxA|IdxB|
- | Id & Name | Encoding | (pp+mmm|op/o|L|w|W|N|TT.)|--(pp+mmm|op/o|L|w|W|N|TT.)| (auto-generated) |
- +---------------------+--------------------+---------+----+-+-+-+-+----+---------+----+-+-+-+-+----+----+----+------+----+---*/
+ /*--------------------+--------------------+------------------+--------+------------------+--------+----+----+----+----+
+ | Instruction | Instruction | Main Opcode | EVEX |Alternative Opcode| EVEX |Op0X|Op1X|IdxA|IdxB|
+ | Id & Name | Encoding | (pp+mmm|op/o|L|w|W|N|TT.)|--(pp+mmm|op/o|L|w|W|N|TT.)| (auto-generated) |
+ +---------------------+--------------------+---------+----+-+-+-+-+----+---------+----+-+-+-+-+----+----+----+----+---*/
// ${InstInfo:Begin}
- INST(None , None , 0 , 0 , 0 , 0 , 0 , 0 , 0 ), // #0
- INST(Aaa , X86Op_xAX , O(000000,37,_,_,_,_,_,_ ), 0 , 0 , 0 , 1 , 1 , 1 ), // #1
- INST(Aad , X86I_xAX , O(000000,D5,_,_,_,_,_,_ ), 0 , 0 , 0 , 5 , 2 , 1 ), // #2
- INST(Aam , X86I_xAX , O(000000,D4,_,_,_,_,_,_ ), 0 , 0 , 0 , 9 , 2 , 1 ), // #3
- INST(Aas , X86Op_xAX , O(000000,3F,_,_,_,_,_,_ ), 0 , 0 , 0 , 13 , 1 , 1 ), // #4
- 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 , 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 , 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 , 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 , 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
- INST(Blci , VexVm_Wx , V(XOP_M9,02,6,0,x,_,_,_ ), 0 , 12 , 0 , 50 , 14 , 11 ), // #30
- 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 , 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
- INST(Blsmsk , VexVm_Wx , V(000F38,F3,2,0,x,_,_,_ ), 0 , 17 , 0 , 92 , 14 , 9 ), // #41
- INST(Blsr , VexVm_Wx , V(000F38,F3,1,0,x,_,_,_ ), 0 , 18 , 0 , 99 , 14 , 9 ), // #42
- INST(Bndcl , X86Rm , O(F30F00,1A,_,_,_,_,_,_ ), 0 , 6 , 0 , 104 , 16 , 13 ), // #43
- INST(Bndcn , X86Rm , O(F20F00,1B,_,_,_,_,_,_ ), 0 , 5 , 0 , 110 , 16 , 13 ), // #44
- INST(Bndcu , X86Rm , O(F20F00,1A,_,_,_,_,_,_ ), 0 , 5 , 0 , 116 , 16 , 13 ), // #45
- INST(Bndldx , X86Rm , O(000F00,1A,_,_,_,_,_,_ ), 0 , 4 , 0 , 122 , 17 , 13 ), // #46
- INST(Bndmk , X86Rm , O(F30F00,1B,_,_,_,_,_,_ ), 0 , 6 , 0 , 129 , 18 , 13 ), // #47
- INST(Bndmov , X86Bndmov , O(660F00,1A,_,_,_,_,_,_ ), O(660F00,1B,_,_,_,_,_,_ ), 3 , 1 , 135 , 19 , 13 ), // #48
- INST(Bndstx , X86Mr , O(000F00,1B,_,_,_,_,_,_ ), 0 , 4 , 0 , 142 , 20 , 13 ), // #49
- INST(Bound , X86Rm , O(000000,62,_,_,_,_,_,_ ), 0 , 0 , 0 , 149 , 21 , 0 ), // #50
- INST(Bsf , X86Rm , O(000F00,BC,_,_,x,_,_,_ ), 0 , 4 , 0 , 155 , 22 , 1 ), // #51
- INST(Bsr , X86Rm , O(000F00,BD,_,_,x,_,_,_ ), 0 , 4 , 0 , 159 , 22 , 1 ), // #52
- INST(Bswap , X86Bswap , O(000F00,C8,_,_,x,_,_,_ ), 0 , 4 , 0 , 163 , 23 , 0 ), // #53
- INST(Bt , X86Bt , O(000F00,A3,_,_,x,_,_,_ ), O(000F00,BA,4,_,x,_,_,_ ), 4 , 2 , 169 , 24 , 14 ), // #54
- INST(Btc , X86Bt , O(000F00,BB,_,_,x,_,_,_ ), O(000F00,BA,7,_,x,_,_,_ ), 4 , 3 , 172 , 25 , 14 ), // #55
- INST(Btr , X86Bt , O(000F00,B3,_,_,x,_,_,_ ), O(000F00,BA,6,_,x,_,_,_ ), 4 , 4 , 176 , 25 , 14 ), // #56
- INST(Bts , X86Bt , O(000F00,AB,_,_,x,_,_,_ ), O(000F00,BA,5,_,x,_,_,_ ), 4 , 5 , 180 , 25 , 14 ), // #57
- INST(Bzhi , VexRmv_Wx , V(000F38,F5,_,0,x,_,_,_ ), 0 , 10 , 0 , 184 , 13 , 15 ), // #58
- INST(Call , X86Call , O(000000,FF,2,_,_,_,_,_ ), 0 , 1 , 0 , 3038 , 26 , 1 ), // #59
- INST(Cbw , X86Op_xAX , O(660000,98,_,_,_,_,_,_ ), 0 , 19 , 0 , 189 , 27 , 0 ), // #60
- INST(Cdq , X86Op_xDX_xAX , O(000000,99,_,_,_,_,_,_ ), 0 , 0 , 0 , 193 , 28 , 0 ), // #61
- INST(Cdqe , X86Op_xAX , O(000000,98,_,_,1,_,_,_ ), 0 , 20 , 0 , 197 , 29 , 0 ), // #62
- INST(Clac , X86Op , O(000F01,CA,_,_,_,_,_,_ ), 0 , 21 , 0 , 202 , 30 , 16 ), // #63
- INST(Clc , X86Op , O(000000,F8,_,_,_,_,_,_ ), 0 , 0 , 0 , 207 , 30 , 17 ), // #64
- INST(Cld , X86Op , O(000000,FC,_,_,_,_,_,_ ), 0 , 0 , 0 , 211 , 30 , 18 ), // #65
- INST(Cldemote , X86M_Only , O(000F00,1C,0,_,_,_,_,_ ), 0 , 4 , 0 , 215 , 31 , 19 ), // #66
- INST(Clflush , X86M_Only , O(000F00,AE,7,_,_,_,_,_ ), 0 , 22 , 0 , 224 , 31 , 20 ), // #67
- INST(Clflushopt , X86M_Only , O(660F00,AE,7,_,_,_,_,_ ), 0 , 23 , 0 , 232 , 31 , 21 ), // #68
- INST(Clgi , X86Op , O(000F01,DD,_,_,_,_,_,_ ), 0 , 21 , 0 , 243 , 30 , 22 ), // #69
- INST(Cli , X86Op , O(000000,FA,_,_,_,_,_,_ ), 0 , 0 , 0 , 248 , 30 , 23 ), // #70
- INST(Clrssbsy , X86M_Only , O(F30F00,AE,6,_,_,_,_,_ ), 0 , 24 , 0 , 252 , 32 , 24 ), // #71
- INST(Clts , X86Op , O(000F00,06,_,_,_,_,_,_ ), 0 , 4 , 0 , 261 , 30 , 0 ), // #72
- INST(Clui , X86Op , O(F30F01,EE,_,_,_,_,_,_ ), 0 , 25 , 0 , 266 , 33 , 25 ), // #73
- INST(Clwb , X86M_Only , O(660F00,AE,6,_,_,_,_,_ ), 0 , 26 , 0 , 271 , 31 , 26 ), // #74
- INST(Clzero , X86Op_MemZAX , O(000F01,FC,_,_,_,_,_,_ ), 0 , 21 , 0 , 276 , 34 , 27 ), // #75
- INST(Cmc , X86Op , O(000000,F5,_,_,_,_,_,_ ), 0 , 0 , 0 , 283 , 30 , 28 ), // #76
- INST(Cmova , X86Rm , O(000F00,47,_,_,x,_,_,_ ), 0 , 4 , 0 , 287 , 22 , 29 ), // #77
- INST(Cmovae , X86Rm , O(000F00,43,_,_,x,_,_,_ ), 0 , 4 , 0 , 293 , 22 , 30 ), // #78
- INST(Cmovb , X86Rm , O(000F00,42,_,_,x,_,_,_ ), 0 , 4 , 0 , 648 , 22 , 30 ), // #79
- INST(Cmovbe , X86Rm , O(000F00,46,_,_,x,_,_,_ ), 0 , 4 , 0 , 655 , 22 , 29 ), // #80
- INST(Cmovc , X86Rm , O(000F00,42,_,_,x,_,_,_ ), 0 , 4 , 0 , 300 , 22 , 30 ), // #81
- INST(Cmove , X86Rm , O(000F00,44,_,_,x,_,_,_ ), 0 , 4 , 0 , 663 , 22 , 31 ), // #82
- INST(Cmovg , X86Rm , O(000F00,4F,_,_,x,_,_,_ ), 0 , 4 , 0 , 306 , 22 , 32 ), // #83
- INST(Cmovge , X86Rm , O(000F00,4D,_,_,x,_,_,_ ), 0 , 4 , 0 , 312 , 22 , 33 ), // #84
- INST(Cmovl , X86Rm , O(000F00,4C,_,_,x,_,_,_ ), 0 , 4 , 0 , 319 , 22 , 33 ), // #85
- INST(Cmovle , X86Rm , O(000F00,4E,_,_,x,_,_,_ ), 0 , 4 , 0 , 325 , 22 , 32 ), // #86
- INST(Cmovna , X86Rm , O(000F00,46,_,_,x,_,_,_ ), 0 , 4 , 0 , 332 , 22 , 29 ), // #87
- INST(Cmovnae , X86Rm , O(000F00,42,_,_,x,_,_,_ ), 0 , 4 , 0 , 339 , 22 , 30 ), // #88
- INST(Cmovnb , X86Rm , O(000F00,43,_,_,x,_,_,_ ), 0 , 4 , 0 , 670 , 22 , 30 ), // #89
- INST(Cmovnbe , X86Rm , O(000F00,47,_,_,x,_,_,_ ), 0 , 4 , 0 , 678 , 22 , 29 ), // #90
- INST(Cmovnc , X86Rm , O(000F00,43,_,_,x,_,_,_ ), 0 , 4 , 0 , 347 , 22 , 30 ), // #91
- INST(Cmovne , X86Rm , O(000F00,45,_,_,x,_,_,_ ), 0 , 4 , 0 , 687 , 22 , 31 ), // #92
- INST(Cmovng , X86Rm , O(000F00,4E,_,_,x,_,_,_ ), 0 , 4 , 0 , 354 , 22 , 32 ), // #93
- INST(Cmovnge , X86Rm , O(000F00,4C,_,_,x,_,_,_ ), 0 , 4 , 0 , 361 , 22 , 33 ), // #94
- INST(Cmovnl , X86Rm , O(000F00,4D,_,_,x,_,_,_ ), 0 , 4 , 0 , 369 , 22 , 33 ), // #95
- INST(Cmovnle , X86Rm , O(000F00,4F,_,_,x,_,_,_ ), 0 , 4 , 0 , 376 , 22 , 32 ), // #96
- INST(Cmovno , X86Rm , O(000F00,41,_,_,x,_,_,_ ), 0 , 4 , 0 , 384 , 22 , 34 ), // #97
- INST(Cmovnp , X86Rm , O(000F00,4B,_,_,x,_,_,_ ), 0 , 4 , 0 , 391 , 22 , 35 ), // #98
- INST(Cmovns , X86Rm , O(000F00,49,_,_,x,_,_,_ ), 0 , 4 , 0 , 398 , 22 , 36 ), // #99
- INST(Cmovnz , X86Rm , O(000F00,45,_,_,x,_,_,_ ), 0 , 4 , 0 , 405 , 22 , 31 ), // #100
- INST(Cmovo , X86Rm , O(000F00,40,_,_,x,_,_,_ ), 0 , 4 , 0 , 412 , 22 , 34 ), // #101
- INST(Cmovp , X86Rm , O(000F00,4A,_,_,x,_,_,_ ), 0 , 4 , 0 , 418 , 22 , 35 ), // #102
- INST(Cmovpe , X86Rm , O(000F00,4A,_,_,x,_,_,_ ), 0 , 4 , 0 , 424 , 22 , 35 ), // #103
- INST(Cmovpo , X86Rm , O(000F00,4B,_,_,x,_,_,_ ), 0 , 4 , 0 , 431 , 22 , 35 ), // #104
- 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 , 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 , 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 , 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 , 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 , 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 , 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 , 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 , 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 , 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 , 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 , 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 , 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
- INST(Faddp , FpuRDef , O_FPU(00,DEC0,_) , 0 , 37 , 0 , 619 , 61 , 0 ), // #166
- INST(Fbld , X86M_Only , O_FPU(00,00DF,4) , 0 , 38 , 0 , 625 , 62 , 0 ), // #167
- INST(Fbstp , X86M_Only , O_FPU(00,00DF,6) , 0 , 39 , 0 , 630 , 62 , 0 ), // #168
- INST(Fchs , FpuOp , O_FPU(00,D9E0,_) , 0 , 35 , 0 , 636 , 30 , 0 ), // #169
- INST(Fclex , FpuOp , O_FPU(9B,DBE2,_) , 0 , 40 , 0 , 641 , 30 , 0 ), // #170
- INST(Fcmovb , FpuR , O_FPU(00,DAC0,_) , 0 , 41 , 0 , 647 , 63 , 30 ), // #171
- INST(Fcmovbe , FpuR , O_FPU(00,DAD0,_) , 0 , 41 , 0 , 654 , 63 , 29 ), // #172
- INST(Fcmove , FpuR , O_FPU(00,DAC8,_) , 0 , 41 , 0 , 662 , 63 , 31 ), // #173
- INST(Fcmovnb , FpuR , O_FPU(00,DBC0,_) , 0 , 42 , 0 , 669 , 63 , 30 ), // #174
- INST(Fcmovnbe , FpuR , O_FPU(00,DBD0,_) , 0 , 42 , 0 , 677 , 63 , 29 ), // #175
- INST(Fcmovne , FpuR , O_FPU(00,DBC8,_) , 0 , 42 , 0 , 686 , 63 , 31 ), // #176
- INST(Fcmovnu , FpuR , O_FPU(00,DBD8,_) , 0 , 42 , 0 , 694 , 63 , 35 ), // #177
- INST(Fcmovu , FpuR , O_FPU(00,DAD8,_) , 0 , 41 , 0 , 702 , 63 , 35 ), // #178
- INST(Fcom , FpuCom , O_FPU(00,D0D0,2) , 0 , 43 , 0 , 709 , 64 , 0 ), // #179
- INST(Fcomi , FpuR , O_FPU(00,DBF0,_) , 0 , 42 , 0 , 714 , 63 , 50 ), // #180
- INST(Fcomip , FpuR , O_FPU(00,DFF0,_) , 0 , 44 , 0 , 720 , 63 , 50 ), // #181
- INST(Fcomp , FpuCom , O_FPU(00,D8D8,3) , 0 , 45 , 0 , 727 , 64 , 0 ), // #182
- INST(Fcompp , FpuOp , O_FPU(00,DED9,_) , 0 , 37 , 0 , 733 , 30 , 0 ), // #183
- INST(Fcos , FpuOp , O_FPU(00,D9FF,_) , 0 , 35 , 0 , 740 , 30 , 0 ), // #184
- INST(Fdecstp , FpuOp , O_FPU(00,D9F6,_) , 0 , 35 , 0 , 745 , 30 , 0 ), // #185
- INST(Fdiv , FpuArith , O_FPU(00,F0F8,6) , 0 , 46 , 0 , 753 , 60 , 0 ), // #186
- INST(Fdivp , FpuRDef , O_FPU(00,DEF8,_) , 0 , 37 , 0 , 758 , 61 , 0 ), // #187
- INST(Fdivr , FpuArith , O_FPU(00,F8F0,7) , 0 , 47 , 0 , 764 , 60 , 0 ), // #188
- INST(Fdivrp , FpuRDef , O_FPU(00,DEF0,_) , 0 , 37 , 0 , 770 , 61 , 0 ), // #189
- INST(Femms , X86Op , O(000F00,0E,_,_,_,_,_,_ ), 0 , 4 , 0 , 777 , 30 , 51 ), // #190
- INST(Ffree , FpuR , O_FPU(00,DDC0,_) , 0 , 48 , 0 , 783 , 63 , 0 ), // #191
- INST(Fiadd , FpuM , O_FPU(00,00DA,0) , 0 , 49 , 0 , 789 , 65 , 0 ), // #192
- INST(Ficom , FpuM , O_FPU(00,00DA,2) , 0 , 50 , 0 , 795 , 65 , 0 ), // #193
- INST(Ficomp , FpuM , O_FPU(00,00DA,3) , 0 , 51 , 0 , 801 , 65 , 0 ), // #194
- INST(Fidiv , FpuM , O_FPU(00,00DA,6) , 0 , 39 , 0 , 808 , 65 , 0 ), // #195
- INST(Fidivr , FpuM , O_FPU(00,00DA,7) , 0 , 52 , 0 , 814 , 65 , 0 ), // #196
- INST(Fild , FpuM , O_FPU(00,00DB,0) , O_FPU(00,00DF,5) , 49 , 8 , 821 , 66 , 0 ), // #197
- INST(Fimul , FpuM , O_FPU(00,00DA,1) , 0 , 53 , 0 , 826 , 65 , 0 ), // #198
- INST(Fincstp , FpuOp , O_FPU(00,D9F7,_) , 0 , 35 , 0 , 832 , 30 , 0 ), // #199
- INST(Finit , FpuOp , O_FPU(9B,DBE3,_) , 0 , 40 , 0 , 840 , 30 , 0 ), // #200
- INST(Fist , FpuM , O_FPU(00,00DB,2) , 0 , 50 , 0 , 846 , 65 , 0 ), // #201
- INST(Fistp , FpuM , O_FPU(00,00DB,3) , O_FPU(00,00DF,7) , 51 , 9 , 851 , 66 , 0 ), // #202
- INST(Fisttp , FpuM , O_FPU(00,00DB,1) , O_FPU(00,00DD,1) , 53 , 10 , 857 , 66 , 6 ), // #203
- INST(Fisub , FpuM , O_FPU(00,00DA,4) , 0 , 38 , 0 , 864 , 65 , 0 ), // #204
- INST(Fisubr , FpuM , O_FPU(00,00DA,5) , 0 , 54 , 0 , 870 , 65 , 0 ), // #205
- INST(Fld , FpuFldFst , O_FPU(00,00D9,0) , O_FPU(00,00DB,5) , 49 , 11 , 877 , 67 , 0 ), // #206
- INST(Fld1 , FpuOp , O_FPU(00,D9E8,_) , 0 , 35 , 0 , 881 , 30 , 0 ), // #207
- INST(Fldcw , X86M_Only , O_FPU(00,00D9,5) , 0 , 54 , 0 , 886 , 68 , 0 ), // #208
- INST(Fldenv , X86M_Only , O_FPU(00,00D9,4) , 0 , 38 , 0 , 892 , 69 , 0 ), // #209
- INST(Fldl2e , FpuOp , O_FPU(00,D9EA,_) , 0 , 35 , 0 , 899 , 30 , 0 ), // #210
- INST(Fldl2t , FpuOp , O_FPU(00,D9E9,_) , 0 , 35 , 0 , 906 , 30 , 0 ), // #211
- INST(Fldlg2 , FpuOp , O_FPU(00,D9EC,_) , 0 , 35 , 0 , 913 , 30 , 0 ), // #212
- INST(Fldln2 , FpuOp , O_FPU(00,D9ED,_) , 0 , 35 , 0 , 920 , 30 , 0 ), // #213
- INST(Fldpi , FpuOp , O_FPU(00,D9EB,_) , 0 , 35 , 0 , 927 , 30 , 0 ), // #214
- INST(Fldz , FpuOp , O_FPU(00,D9EE,_) , 0 , 35 , 0 , 933 , 30 , 0 ), // #215
- INST(Fmul , FpuArith , O_FPU(00,C8C8,1) , 0 , 55 , 0 , 2163 , 60 , 0 ), // #216
- INST(Fmulp , FpuRDef , O_FPU(00,DEC8,_) , 0 , 37 , 0 , 938 , 61 , 0 ), // #217
- INST(Fnclex , FpuOp , O_FPU(00,DBE2,_) , 0 , 42 , 0 , 944 , 30 , 0 ), // #218
- INST(Fninit , FpuOp , O_FPU(00,DBE3,_) , 0 , 42 , 0 , 951 , 30 , 0 ), // #219
- INST(Fnop , FpuOp , O_FPU(00,D9D0,_) , 0 , 35 , 0 , 958 , 30 , 0 ), // #220
- INST(Fnsave , X86M_Only , O_FPU(00,00DD,6) , 0 , 39 , 0 , 963 , 69 , 0 ), // #221
- INST(Fnstcw , X86M_Only , O_FPU(00,00D9,7) , 0 , 52 , 0 , 970 , 68 , 0 ), // #222
- INST(Fnstenv , X86M_Only , O_FPU(00,00D9,6) , 0 , 39 , 0 , 977 , 69 , 0 ), // #223
- INST(Fnstsw , FpuStsw , O_FPU(00,00DD,7) , O_FPU(00,DFE0,_) , 52 , 12 , 985 , 70 , 0 ), // #224
- INST(Fpatan , FpuOp , O_FPU(00,D9F3,_) , 0 , 35 , 0 , 992 , 30 , 0 ), // #225
- INST(Fprem , FpuOp , O_FPU(00,D9F8,_) , 0 , 35 , 0 , 999 , 30 , 0 ), // #226
- INST(Fprem1 , FpuOp , O_FPU(00,D9F5,_) , 0 , 35 , 0 , 1005 , 30 , 0 ), // #227
- INST(Fptan , FpuOp , O_FPU(00,D9F2,_) , 0 , 35 , 0 , 1012 , 30 , 0 ), // #228
- INST(Frndint , FpuOp , O_FPU(00,D9FC,_) , 0 , 35 , 0 , 1018 , 30 , 0 ), // #229
- INST(Frstor , X86M_Only , O_FPU(00,00DD,4) , 0 , 38 , 0 , 1026 , 69 , 0 ), // #230
- INST(Fsave , X86M_Only , O_FPU(9B,00DD,6) , 0 , 56 , 0 , 1033 , 69 , 0 ), // #231
- INST(Fscale , FpuOp , O_FPU(00,D9FD,_) , 0 , 35 , 0 , 1039 , 30 , 0 ), // #232
- INST(Fsin , FpuOp , O_FPU(00,D9FE,_) , 0 , 35 , 0 , 1046 , 30 , 0 ), // #233
- INST(Fsincos , FpuOp , O_FPU(00,D9FB,_) , 0 , 35 , 0 , 1051 , 30 , 0 ), // #234
- INST(Fsqrt , FpuOp , O_FPU(00,D9FA,_) , 0 , 35 , 0 , 1059 , 30 , 0 ), // #235
- INST(Fst , FpuFldFst , O_FPU(00,00D9,2) , 0 , 50 , 0 , 1065 , 71 , 0 ), // #236
- INST(Fstcw , X86M_Only , O_FPU(9B,00D9,7) , 0 , 57 , 0 , 1069 , 68 , 0 ), // #237
- INST(Fstenv , X86M_Only , O_FPU(9B,00D9,6) , 0 , 56 , 0 , 1075 , 69 , 0 ), // #238
- INST(Fstp , FpuFldFst , O_FPU(00,00D9,3) , O(000000,DB,7,_,_,_,_,_ ), 51 , 13 , 1082 , 67 , 0 ), // #239
- INST(Fstsw , FpuStsw , O_FPU(9B,00DD,7) , O_FPU(9B,DFE0,_) , 57 , 14 , 1087 , 70 , 0 ), // #240
- INST(Fsub , FpuArith , O_FPU(00,E0E8,4) , 0 , 58 , 0 , 2241 , 60 , 0 ), // #241
- INST(Fsubp , FpuRDef , O_FPU(00,DEE8,_) , 0 , 37 , 0 , 1093 , 61 , 0 ), // #242
- INST(Fsubr , FpuArith , O_FPU(00,E8E0,5) , 0 , 59 , 0 , 2247 , 60 , 0 ), // #243
- INST(Fsubrp , FpuRDef , O_FPU(00,DEE0,_) , 0 , 37 , 0 , 1099 , 61 , 0 ), // #244
- INST(Ftst , FpuOp , O_FPU(00,D9E4,_) , 0 , 35 , 0 , 1106 , 30 , 0 ), // #245
- INST(Fucom , FpuRDef , O_FPU(00,DDE0,_) , 0 , 48 , 0 , 1111 , 61 , 0 ), // #246
- INST(Fucomi , FpuR , O_FPU(00,DBE8,_) , 0 , 42 , 0 , 1117 , 63 , 50 ), // #247
- 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 , 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 , 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 , 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 , 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 , 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 , 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 , 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 , 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
- INST(Invpcid , X86Rm_NoSize , O(660F38,82,_,_,_,_,_,_ ), 0 , 2 , 0 , 1297 , 82 , 43 ), // #287
- INST(Invvpid , X86Rm_NoSize , O(660F38,81,_,_,_,_,_,_ ), 0 , 2 , 0 , 1305 , 82 , 58 ), // #288
- INST(Iret , X86Op , O(660000,CF,_,_,_,_,_,_ ), 0 , 19 , 0 , 3226 , 84 , 1 ), // #289
- INST(Iretd , X86Op , O(000000,CF,_,_,_,_,_,_ ), 0 , 0 , 0 , 1313 , 84 , 1 ), // #290
- INST(Iretq , X86Op , O(000000,CF,_,_,1,_,_,_ ), 0 , 20 , 0 , 1319 , 85 , 1 ), // #291
- INST(Ja , X86Jcc , O(000F00,87,_,_,_,_,_,_ ), O(000000,77,_,_,_,_,_,_ ), 4 , 18 , 1325 , 86 , 59 ), // #292
- INST(Jae , X86Jcc , O(000F00,83,_,_,_,_,_,_ ), O(000000,73,_,_,_,_,_,_ ), 4 , 19 , 1328 , 86 , 60 ), // #293
- INST(Jb , X86Jcc , O(000F00,82,_,_,_,_,_,_ ), O(000000,72,_,_,_,_,_,_ ), 4 , 20 , 1332 , 86 , 60 ), // #294
- INST(Jbe , X86Jcc , O(000F00,86,_,_,_,_,_,_ ), O(000000,76,_,_,_,_,_,_ ), 4 , 21 , 1335 , 86 , 59 ), // #295
- INST(Jc , X86Jcc , O(000F00,82,_,_,_,_,_,_ ), O(000000,72,_,_,_,_,_,_ ), 4 , 20 , 1339 , 86 , 60 ), // #296
- INST(Je , X86Jcc , O(000F00,84,_,_,_,_,_,_ ), O(000000,74,_,_,_,_,_,_ ), 4 , 22 , 1342 , 86 , 61 ), // #297
- INST(Jecxz , X86JecxzLoop , 0 , O(000000,E3,_,_,_,_,_,_ ), 0 , 23 , 1345 , 87 , 0 ), // #298
- INST(Jg , X86Jcc , O(000F00,8F,_,_,_,_,_,_ ), O(000000,7F,_,_,_,_,_,_ ), 4 , 24 , 1351 , 86 , 62 ), // #299
- INST(Jge , X86Jcc , O(000F00,8D,_,_,_,_,_,_ ), O(000000,7D,_,_,_,_,_,_ ), 4 , 25 , 1354 , 86 , 63 ), // #300
- INST(Jl , X86Jcc , O(000F00,8C,_,_,_,_,_,_ ), O(000000,7C,_,_,_,_,_,_ ), 4 , 26 , 1358 , 86 , 63 ), // #301
- INST(Jle , X86Jcc , O(000F00,8E,_,_,_,_,_,_ ), O(000000,7E,_,_,_,_,_,_ ), 4 , 27 , 1361 , 86 , 62 ), // #302
- INST(Jmp , X86Jmp , O(000000,FF,4,_,_,_,_,_ ), O(000000,EB,_,_,_,_,_,_ ), 9 , 28 , 1861 , 88 , 0 ), // #303
- INST(Jna , X86Jcc , O(000F00,86,_,_,_,_,_,_ ), O(000000,76,_,_,_,_,_,_ ), 4 , 21 , 1365 , 86 , 59 ), // #304
- INST(Jnae , X86Jcc , O(000F00,82,_,_,_,_,_,_ ), O(000000,72,_,_,_,_,_,_ ), 4 , 20 , 1369 , 86 , 60 ), // #305
- INST(Jnb , X86Jcc , O(000F00,83,_,_,_,_,_,_ ), O(000000,73,_,_,_,_,_,_ ), 4 , 19 , 1374 , 86 , 60 ), // #306
- INST(Jnbe , X86Jcc , O(000F00,87,_,_,_,_,_,_ ), O(000000,77,_,_,_,_,_,_ ), 4 , 18 , 1378 , 86 , 59 ), // #307
- INST(Jnc , X86Jcc , O(000F00,83,_,_,_,_,_,_ ), O(000000,73,_,_,_,_,_,_ ), 4 , 19 , 1383 , 86 , 60 ), // #308
- INST(Jne , X86Jcc , O(000F00,85,_,_,_,_,_,_ ), O(000000,75,_,_,_,_,_,_ ), 4 , 29 , 1387 , 86 , 61 ), // #309
- INST(Jng , X86Jcc , O(000F00,8E,_,_,_,_,_,_ ), O(000000,7E,_,_,_,_,_,_ ), 4 , 27 , 1391 , 86 , 62 ), // #310
- INST(Jnge , X86Jcc , O(000F00,8C,_,_,_,_,_,_ ), O(000000,7C,_,_,_,_,_,_ ), 4 , 26 , 1395 , 86 , 63 ), // #311
- INST(Jnl , X86Jcc , O(000F00,8D,_,_,_,_,_,_ ), O(000000,7D,_,_,_,_,_,_ ), 4 , 25 , 1400 , 86 , 63 ), // #312
- INST(Jnle , X86Jcc , O(000F00,8F,_,_,_,_,_,_ ), O(000000,7F,_,_,_,_,_,_ ), 4 , 24 , 1404 , 86 , 62 ), // #313
- INST(Jno , X86Jcc , O(000F00,81,_,_,_,_,_,_ ), O(000000,71,_,_,_,_,_,_ ), 4 , 30 , 1409 , 86 , 57 ), // #314
- INST(Jnp , X86Jcc , O(000F00,8B,_,_,_,_,_,_ ), O(000000,7B,_,_,_,_,_,_ ), 4 , 31 , 1413 , 86 , 64 ), // #315
- INST(Jns , X86Jcc , O(000F00,89,_,_,_,_,_,_ ), O(000000,79,_,_,_,_,_,_ ), 4 , 32 , 1417 , 86 , 65 ), // #316
- INST(Jnz , X86Jcc , O(000F00,85,_,_,_,_,_,_ ), O(000000,75,_,_,_,_,_,_ ), 4 , 29 , 1421 , 86 , 61 ), // #317
- INST(Jo , X86Jcc , O(000F00,80,_,_,_,_,_,_ ), O(000000,70,_,_,_,_,_,_ ), 4 , 33 , 1425 , 86 , 57 ), // #318
- INST(Jp , X86Jcc , O(000F00,8A,_,_,_,_,_,_ ), O(000000,7A,_,_,_,_,_,_ ), 4 , 34 , 1428 , 86 , 64 ), // #319
- INST(Jpe , X86Jcc , O(000F00,8A,_,_,_,_,_,_ ), O(000000,7A,_,_,_,_,_,_ ), 4 , 34 , 1431 , 86 , 64 ), // #320
- 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 , 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 , 69 ), // #336
- INST(Kmovd , VexKmov , V(660F00,90,_,0,1,_,_,_ ), V(F20F00,92,_,0,0,_,_,_ ), 70 , 37 , 9105 , 91 , 70 ), // #337
- INST(Kmovq , VexKmov , V(000F00,90,_,0,1,_,_,_ ), V(F20F00,92,_,0,1,_,_,_ ), 71 , 38 , 9116 , 92 , 70 ), // #338
- INST(Kmovw , VexKmov , V(000F00,90,_,0,0,_,_,_ ), V(000F00,92,_,0,0,_,_,_ ), 72 , 39 , 1527 , 93 , 71 ), // #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 , 72 ), // #347
- INST(Kortestd , VexRm , V(660F00,98,_,0,1,_,_,_ ), 0 , 70 , 0 , 1581 , 94 , 73 ), // #348
- INST(Kortestq , VexRm , V(000F00,98,_,0,1,_,_,_ ), 0 , 71 , 0 , 1590 , 94 , 73 ), // #349
- INST(Kortestw , VexRm , V(000F00,98,_,0,0,_,_,_ ), 0 , 72 , 0 , 1599 , 94 , 74 ), // #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 , 72 ), // #360
- INST(Ktestd , VexRm , V(660F00,99,_,0,1,_,_,_ ), 0 , 70 , 0 , 1692 , 94 , 73 ), // #361
- INST(Ktestq , VexRm , V(000F00,99,_,0,1,_,_,_ ), 0 , 71 , 0 , 1699 , 94 , 73 ), // #362
- INST(Ktestw , VexRm , V(000F00,99,_,0,0,_,_,_ ), 0 , 72 , 0 , 1706 , 94 , 72 ), // #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 , 75 ), // #375
- INST(Lar , X86Rm , O(000F00,02,_,_,_,_,_,_ ), 0 , 4 , 0 , 1797 , 98 , 10 ), // #376
- 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, 76 ), // #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 , 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 , 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 , 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, 77 ), // #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, 78 ), // #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 , 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, 77 ), // #401
- INST(Lwpval , VexVmi4_Wx , V(XOP_MA,12,1,0,x,_,_,_ ), 0 , 82 , 0 , 1920 , 112, 77 ), // #402
- INST(Lzcnt , X86Rm_Raw66H , O(F30F00,BD,_,_,x,_,_,_ ), 0 , 6 , 0 , 1927 , 22 , 79 ), // #403
- 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, 80 ), // #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 , 81 ), // #410
- 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, 82 ), // #416
- INST(Monitorx , X86Op , O(000F01,FA,_,_,_,_,_,_ ), 0 , 21 , 0 , 1948 , 115, 83 ), // #417
- INST(Mov , X86Mov , 0 , 0 , 0 , 0 , 138 , 116, 84 ), // #418
- INST(Movabs , X86Movabs , 0 , 0 , 0 , 0 , 1957 , 117, 0 ), // #419
- INST(Movapd , ExtMov , O(660F00,28,_,_,_,_,_,_ ), O(660F00,29,_,_,_,_,_,_ ), 3 , 45 , 7183 , 118, 85 ), // #420
- INST(Movaps , ExtMov , O(000F00,28,_,_,_,_,_,_ ), O(000F00,29,_,_,_,_,_,_ ), 4 , 46 , 7191 , 118, 86 ), // #421
- INST(Movbe , ExtMovbe , O(000F38,F0,_,_,x,_,_,_ ), O(000F38,F1,_,_,x,_,_,_ ), 83 , 47 , 656 , 119, 87 ), // #422
- INST(Movd , ExtMovd , O(000F00,6E,_,_,_,_,_,_ ), O(000F00,7E,_,_,_,_,_,_ ), 4 , 48 , 9106 , 120, 88 ), // #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, 89 ), // #425
- INST(Movdiri , X86MovntiMovdiri , O(000F38,F9,_,_,_,_,_,_ ), 0 , 83 , 0 , 1974 , 122, 90 ), // #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 , 7214 , 118, 85 ), // #428
- INST(Movdqu , ExtMov , O(F30F00,6F,_,_,_,_,_,_ ), O(F30F00,7F,_,_,_,_,_,_ ), 6 , 50 , 7023 , 118, 85 ), // #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 , 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, 80 ), // #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 , 48 , 9117 , 131, 91 ), // #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, 78 ), // #448
- INST(Movsd , ExtMov , O(F20F00,10,_,_,_,_,_,_ ), O(F20F00,11,_,_,_,_,_,_ ), 5 , 61 , 7402 , 134, 85 ), // #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, 86 ), // #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 , 63 , 7443 , 118, 85 ), // #455
- INST(Movups , ExtMov , O(000F00,10,_,_,_,_,_,_ ), O(000F00,11,_,_,_,_,_,_ ), 4 , 64 , 7451 , 118, 86 ), // #456
- INST(Movzx , X86MovsxMovzx , O(000F00,B6,_,_,x,_,_,_ ), 0 , 4 , 0 , 2041 , 136, 0 ), // #457
- 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 , 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, 92 ), // #464
- INST(Mwait , X86Op , O(000F01,C9,_,_,_,_,_,_ ), 0 , 21 , 0 , 3241 , 139, 82 ), // #465
- INST(Mwaitx , X86Op , O(000F01,FB,_,_,_,_,_,_ ), 0 , 21 , 0 , 2052 , 140, 83 ), // #466
- 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 , 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 , 83 , 0 , 7636 , 146, 93 ), // #475
- INST(Pabsd , ExtRm_P , O(000F38,1E,_,_,_,_,_,_ ), 0 , 83 , 0 , 7643 , 146, 93 ), // #476
- INST(Pabsw , ExtRm_P , O(000F38,1D,_,_,_,_,_,_ ), 0 , 83 , 0 , 7657 , 146, 93 ), // #477
- INST(Packssdw , ExtRm_P , O(000F00,6B,_,_,_,_,_,_ ), 0 , 4 , 0 , 7664 , 146, 88 ), // #478
- INST(Packsswb , ExtRm_P , O(000F00,63,_,_,_,_,_,_ ), 0 , 4 , 0 , 7674 , 146, 88 ), // #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, 88 ), // #481
- INST(Paddb , ExtRm_P , O(000F00,FC,_,_,_,_,_,_ ), 0 , 4 , 0 , 7704 , 146, 88 ), // #482
- INST(Paddd , ExtRm_P , O(000F00,FE,_,_,_,_,_,_ ), 0 , 4 , 0 , 7711 , 146, 88 ), // #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, 88 ), // #485
- INST(Paddsw , ExtRm_P , O(000F00,ED,_,_,_,_,_,_ ), 0 , 4 , 0 , 7733 , 146, 88 ), // #486
- INST(Paddusb , ExtRm_P , O(000F00,DC,_,_,_,_,_,_ ), 0 , 4 , 0 , 7741 , 146, 88 ), // #487
- INST(Paddusw , ExtRm_P , O(000F00,DD,_,_,_,_,_,_ ), 0 , 4 , 0 , 7750 , 146, 88 ), // #488
- INST(Paddw , ExtRm_P , O(000F00,FD,_,_,_,_,_,_ ), 0 , 4 , 0 , 7759 , 146, 88 ), // #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, 88 ), // #491
- INST(Pandn , ExtRm_P , O(000F00,DF,_,_,_,_,_,_ ), 0 , 4 , 0 , 7788 , 149, 88 ), // #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, 94 ), // #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, 94 ), // #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 , 95 ), // #499
- INST(Pcmpeqb , ExtRm_P , O(000F00,74,_,_,_,_,_,_ ), 0 , 4 , 0 , 8016 , 149, 88 ), // #500
- INST(Pcmpeqd , ExtRm_P , O(000F00,76,_,_,_,_,_,_ ), 0 , 4 , 0 , 8025 , 149, 88 ), // #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, 88 ), // #503
- INST(Pcmpestri , ExtRmi , O(660F3A,61,_,_,_,_,_,_ ), 0 , 8 , 0 , 8052 , 152, 96 ), // #504
- INST(Pcmpestrm , ExtRmi , O(660F3A,60,_,_,_,_,_,_ ), 0 , 8 , 0 , 8063 , 153, 96 ), // #505
- INST(Pcmpgtb , ExtRm_P , O(000F00,64,_,_,_,_,_,_ ), 0 , 4 , 0 , 8074 , 149, 88 ), // #506
- INST(Pcmpgtd , ExtRm_P , O(000F00,66,_,_,_,_,_,_ ), 0 , 4 , 0 , 8083 , 149, 88 ), // #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, 88 ), // #509
- INST(Pcmpistri , ExtRmi , O(660F3A,63,_,_,_,_,_,_ ), 0 , 8 , 0 , 8110 , 154, 96 ), // #510
- INST(Pcmpistrm , ExtRmi , O(660F3A,62,_,_,_,_,_,_ ), 0 , 8 , 0 , 8121 , 155, 96 ), // #511
- INST(Pconfig , X86Op , O(000F01,C5,_,_,_,_,_,_ ), 0 , 21 , 0 , 2084 , 30 , 97 ), // #512
- INST(Pdep , VexRvm_Wx , V(F20F38,F5,_,0,x,_,_,_ ), 0 , 84 , 0 , 2092 , 10 , 92 ), // #513
- INST(Pext , VexRvm_Wx , V(F30F38,F5,_,0,x,_,_,_ ), 0 , 88 , 0 , 2097 , 10 , 92 ), // #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, 98 ), // #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, 99 ), // #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, 99 ), // #529
- INST(Pfpnacc , Ext3dNow , O(000F0F,8E,_,_,_,_,_,_ ), 0 , 87 , 0 , 2175 , 150, 99 ), // #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, 100), // #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, 100), // #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, 93 ), // #540
- INST(Phaddsw , ExtRm_P , O(000F38,03,_,_,_,_,_,_ ), 0 , 83 , 0 , 8728 , 146, 93 ), // #541
- INST(Phaddw , ExtRm_P , O(000F38,01,_,_,_,_,_,_ ), 0 , 83 , 0 , 8797 , 146, 93 ), // #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, 93 ), // #544
- INST(Phsubsw , ExtRm_P , O(000F38,07,_,_,_,_,_,_ ), 0 , 83 , 0 , 8861 , 146, 93 ), // #545
- INST(Phsubw , ExtRm_P , O(000F38,05,_,_,_,_,_,_ ), 0 , 83 , 0 , 8870 , 146, 93 ), // #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, 99 ), // #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, 94 ), // #552
- INST(Pmaddubsw , ExtRm_P , O(000F38,04,_,_,_,_,_,_ ), 0 , 83 , 0 , 9081 , 146, 93 ), // #553
- INST(Pmaddwd , ExtRm_P , O(000F00,F5,_,_,_,_,_,_ ), 0 , 4 , 0 , 9092 , 146, 88 ), // #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, 94 ), // #557
- INST(Pmaxub , ExtRm_P , O(000F00,DE,_,_,_,_,_,_ ), 0 , 4 , 0 , 9155 , 148, 94 ), // #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, 94 ), // #563
- INST(Pminub , ExtRm_P , O(000F00,DA,_,_,_,_,_,_ ), 0 , 4 , 0 , 9219 , 148, 94 ), // #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, 94 ), // #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, 93 ), // #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, 94 ), // #583
- INST(Pmulhw , ExtRm_P , O(000F00,E5,_,_,_,_,_,_ ), 0 , 4 , 0 , 9642 , 146, 88 ), // #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, 88 ), // #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 , 101), // #591
- INST(Popf , X86Op , O(660000,9D,_,_,_,_,_,_ ), 0 , 19 , 0 , 2295 , 30 , 102), // #592
- INST(Popfd , X86Op , O(000000,9D,_,_,_,_,_,_ ), 0 , 0 , 0 , 2300 , 81 , 102), // #593
- INST(Popfq , X86Op , O(000000,9D,_,_,_,_,_,_ ), 0 , 0 , 0 , 2306 , 33 , 102), // #594
- INST(Por , ExtRm_P , O(000F00,EB,_,_,_,_,_,_ ), 0 , 4 , 0 , 9734 , 148, 88 ), // #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 , 80 ), // #597
- INST(Prefetcht0 , X86M_Only , O(000F00,18,1,_,_,_,_,_ ), 0 , 29 , 0 , 2333 , 31 , 80 ), // #598
- INST(Prefetcht1 , X86M_Only , O(000F00,18,2,_,_,_,_,_ ), 0 , 76 , 0 , 2344 , 31 , 80 ), // #599
- INST(Prefetcht2 , X86M_Only , O(000F00,18,3,_,_,_,_,_ ), 0 , 78 , 0 , 2355 , 31 , 80 ), // #600
- INST(Prefetchw , X86M_Only , O(000F00,0D,1,_,_,_,_,_ ), 0 , 29 , 0 , 2366 , 31 , 103), // #601
- INST(Prefetchwt1 , X86M_Only , O(000F00,0D,2,_,_,_,_,_ ), 0 , 76 , 0 , 2376 , 31 , 104), // #602
- INST(Psadbw , ExtRm_P , O(000F00,F6,_,_,_,_,_,_ ), 0 , 4 , 0 , 4644 , 146, 94 ), // #603
- INST(Pshufb , ExtRm_P , O(000F38,00,_,_,_,_,_,_ ), 0 , 83 , 0 , 10060, 146, 93 ), // #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, 80 ), // #608
- INST(Psignb , ExtRm_P , O(000F38,08,_,_,_,_,_,_ ), 0 , 83 , 0 , 10107, 146, 93 ), // #609
- INST(Psignd , ExtRm_P , O(000F38,0A,_,_,_,_,_,_ ), 0 , 83 , 0 , 10115, 146, 93 ), // #610
- INST(Psignw , ExtRm_P , O(000F38,09,_,_,_,_,_,_ ), 0 , 83 , 0 , 10123, 146, 93 ), // #611
- INST(Pslld , ExtRmRi_P , O(000F00,F2,_,_,_,_,_,_ ), O(000F00,72,6,_,_,_,_,_ ), 4 , 68 , 10131, 167, 88 ), // #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, 88 ), // #614
- INST(Psllw , ExtRmRi_P , O(000F00,F1,_,_,_,_,_,_ ), O(000F00,71,6,_,_,_,_,_ ), 4 , 71 , 10177, 167, 88 ), // #615
- INST(Psmash , X86Op , O(F30F01,FF,_,_,_,_,_,_ ), 0 , 25 , 0 , 2395 , 33 , 105), // #616
- INST(Psrad , ExtRmRi_P , O(000F00,E2,_,_,_,_,_,_ ), O(000F00,72,4,_,_,_,_,_ ), 4 , 72 , 10184, 167, 88 ), // #617
- INST(Psraw , ExtRmRi_P , O(000F00,E1,_,_,_,_,_,_ ), O(000F00,71,4,_,_,_,_,_ ), 4 , 73 , 10222, 167, 88 ), // #618
- INST(Psrld , ExtRmRi_P , O(000F00,D2,_,_,_,_,_,_ ), O(000F00,72,2,_,_,_,_,_ ), 4 , 74 , 10229, 167, 88 ), // #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, 88 ), // #621
- INST(Psrlw , ExtRmRi_P , O(000F00,D1,_,_,_,_,_,_ ), O(000F00,71,2,_,_,_,_,_ ), 4 , 77 , 10275, 167, 88 ), // #622
- INST(Psubb , ExtRm_P , O(000F00,F8,_,_,_,_,_,_ ), 0 , 4 , 0 , 10282, 149, 88 ), // #623
- INST(Psubd , ExtRm_P , O(000F00,FA,_,_,_,_,_,_ ), 0 , 4 , 0 , 10289, 149, 88 ), // #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, 88 ), // #626
- INST(Psubsw , ExtRm_P , O(000F00,E9,_,_,_,_,_,_ ), 0 , 4 , 0 , 10311, 149, 88 ), // #627
- INST(Psubusb , ExtRm_P , O(000F00,D8,_,_,_,_,_,_ ), 0 , 4 , 0 , 10319, 149, 88 ), // #628
- INST(Psubusw , ExtRm_P , O(000F00,D9,_,_,_,_,_,_ ), 0 , 4 , 0 , 10328, 149, 88 ), // #629
- INST(Psubw , ExtRm_P , O(000F00,F9,_,_,_,_,_,_ ), 0 , 4 , 0 , 10337, 149, 88 ), // #630
- INST(Pswapd , Ext3dNow , O(000F0F,BB,_,_,_,_,_,_ ), 0 , 87 , 0 , 2402 , 150, 99 ), // #631
- INST(Ptest , ExtRm , O(660F38,17,_,_,_,_,_,_ ), 0 , 2 , 0 , 10366, 5 , 106), // #632
- INST(Ptwrite , X86M , O(F30F00,AE,4,_,_,_,_,_ ), 0 , 91 , 0 , 2409 , 169, 107), // #633
- INST(Punpckhbw , ExtRm_P , O(000F00,68,_,_,_,_,_,_ ), 0 , 4 , 0 , 10449, 146, 88 ), // #634
- INST(Punpckhdq , ExtRm_P , O(000F00,6A,_,_,_,_,_,_ ), 0 , 4 , 0 , 10460, 146, 88 ), // #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, 88 ), // #637
- INST(Punpcklbw , ExtRm_P , O(000F00,60,_,_,_,_,_,_ ), 0 , 4 , 0 , 10494, 170, 88 ), // #638
- INST(Punpckldq , ExtRm_P , O(000F00,62,_,_,_,_,_,_ ), 0 , 4 , 0 , 10505, 170, 88 ), // #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, 88 ), // #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 , 108), // #645
- INST(Pushfd , X86Op , O(000000,9C,_,_,_,_,_,_ ), 0 , 0 , 0 , 2441 , 81 , 108), // #646
- INST(Pushfq , X86Op , O(000000,9C,_,_,_,_,_,_ ), 0 , 0 , 0 , 2448 , 33 , 108), // #647
- INST(Pvalidate , X86Op , O(F20F01,FF,_,_,_,_,_,_ ), 0 , 92 , 0 , 2455 , 30 , 109), // #648
- INST(Pxor , ExtRm_P , O(000F00,EF,_,_,_,_,_,_ ), 0 , 4 , 0 , 10539, 149, 88 ), // #649
- INST(Rcl , X86Rot , O(000000,D0,2,_,x,_,_,_ ), 0 , 1 , 0 , 2465 , 172, 110), // #650
- 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, 110), // #653
- INST(Rdfsbase , X86M , O(F30F00,AE,0,_,x,_,_,_ ), 0 , 6 , 0 , 2473 , 173, 111), // #654
- INST(Rdgsbase , X86M , O(F30F00,AE,1,_,x,_,_,_ ), 0 , 93 , 0 , 2482 , 173, 111), // #655
- INST(Rdmsr , X86Op , O(000F00,32,_,_,_,_,_,_ ), 0 , 4 , 0 , 2491 , 174, 112), // #656
- INST(Rdpid , X86R_Native , O(F30F00,C7,7,_,_,_,_,_ ), 0 , 94 , 0 , 2497 , 175, 113), // #657
- INST(Rdpkru , X86Op , O(000F01,EE,_,_,_,_,_,_ ), 0 , 21 , 0 , 2503 , 174, 114), // #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, 115), // #660
- INST(Rdrand , X86M , O(000F00,C7,6,_,x,_,_,_ ), 0 , 80 , 0 , 2522 , 23 , 116), // #661
- INST(Rdseed , X86M , O(000F00,C7,7,_,x,_,_,_ ), 0 , 22 , 0 , 2529 , 23 , 117), // #662
- 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 , 118), // #665
- INST(Rdtscp , X86Op , O(000F01,F9,_,_,_,_,_,_ ), 0 , 21 , 0 , 2556 , 174, 119), // #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 , 105), // #669
- INST(Rmpupdate , X86Op , O(F20F01,FE,_,_,_,_,_,_ ), 0 , 92 , 0 , 2578 , 33 , 105), // #670
- INST(Rol , X86Rot , O(000000,D0,0,_,x,_,_,_ ), 0 , 0 , 0 , 2588 , 172, 120), // #671
- INST(Ror , X86Rot , O(000000,D0,1,_,x,_,_,_ ), 0 , 31 , 0 , 2592 , 172, 120), // #672
- INST(Rorx , VexRmi_Wx , V(F20F3A,F0,_,0,x,_,_,_ ), 0 , 95 , 0 , 2596 , 178, 92 ), // #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 , 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 , 121), // #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 , 88 , 0 , 2627 , 13 , 92 ), // #685
- INST(Saveprevssp , X86Op , O(F30F01,EA,_,_,_,_,_,_ ), 0 , 25 , 0 , 2632 , 30 , 24 ), // #686
- 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 , 122), // #690
- INST(Seta , X86Set , O(000F00,97,_,_,_,_,_,_ ), 0 , 4 , 0 , 2672 , 181, 59 ), // #691
- INST(Setae , X86Set , O(000F00,93,_,_,_,_,_,_ ), 0 , 4 , 0 , 2677 , 181, 60 ), // #692
- INST(Setb , X86Set , O(000F00,92,_,_,_,_,_,_ ), 0 , 4 , 0 , 2683 , 181, 60 ), // #693
- INST(Setbe , X86Set , O(000F00,96,_,_,_,_,_,_ ), 0 , 4 , 0 , 2688 , 181, 59 ), // #694
- INST(Setc , X86Set , O(000F00,92,_,_,_,_,_,_ ), 0 , 4 , 0 , 2694 , 181, 60 ), // #695
- INST(Sete , X86Set , O(000F00,94,_,_,_,_,_,_ ), 0 , 4 , 0 , 2699 , 181, 61 ), // #696
- INST(Setg , X86Set , O(000F00,9F,_,_,_,_,_,_ ), 0 , 4 , 0 , 2704 , 181, 62 ), // #697
- INST(Setge , X86Set , O(000F00,9D,_,_,_,_,_,_ ), 0 , 4 , 0 , 2709 , 181, 63 ), // #698
- INST(Setl , X86Set , O(000F00,9C,_,_,_,_,_,_ ), 0 , 4 , 0 , 2715 , 181, 63 ), // #699
- INST(Setle , X86Set , O(000F00,9E,_,_,_,_,_,_ ), 0 , 4 , 0 , 2720 , 181, 62 ), // #700
- INST(Setna , X86Set , O(000F00,96,_,_,_,_,_,_ ), 0 , 4 , 0 , 2726 , 181, 59 ), // #701
- INST(Setnae , X86Set , O(000F00,92,_,_,_,_,_,_ ), 0 , 4 , 0 , 2732 , 181, 60 ), // #702
- INST(Setnb , X86Set , O(000F00,93,_,_,_,_,_,_ ), 0 , 4 , 0 , 2739 , 181, 60 ), // #703
- INST(Setnbe , X86Set , O(000F00,97,_,_,_,_,_,_ ), 0 , 4 , 0 , 2745 , 181, 59 ), // #704
- INST(Setnc , X86Set , O(000F00,93,_,_,_,_,_,_ ), 0 , 4 , 0 , 2752 , 181, 60 ), // #705
- INST(Setne , X86Set , O(000F00,95,_,_,_,_,_,_ ), 0 , 4 , 0 , 2758 , 181, 61 ), // #706
- INST(Setng , X86Set , O(000F00,9E,_,_,_,_,_,_ ), 0 , 4 , 0 , 2764 , 181, 62 ), // #707
- INST(Setnge , X86Set , O(000F00,9C,_,_,_,_,_,_ ), 0 , 4 , 0 , 2770 , 181, 63 ), // #708
- INST(Setnl , X86Set , O(000F00,9D,_,_,_,_,_,_ ), 0 , 4 , 0 , 2777 , 181, 63 ), // #709
- INST(Setnle , X86Set , O(000F00,9F,_,_,_,_,_,_ ), 0 , 4 , 0 , 2783 , 181, 62 ), // #710
- INST(Setno , X86Set , O(000F00,91,_,_,_,_,_,_ ), 0 , 4 , 0 , 2790 , 181, 57 ), // #711
- INST(Setnp , X86Set , O(000F00,9B,_,_,_,_,_,_ ), 0 , 4 , 0 , 2796 , 181, 64 ), // #712
- INST(Setns , X86Set , O(000F00,99,_,_,_,_,_,_ ), 0 , 4 , 0 , 2802 , 181, 65 ), // #713
- INST(Setnz , X86Set , O(000F00,95,_,_,_,_,_,_ ), 0 , 4 , 0 , 2808 , 181, 61 ), // #714
- INST(Seto , X86Set , O(000F00,90,_,_,_,_,_,_ ), 0 , 4 , 0 , 2814 , 181, 57 ), // #715
- INST(Setp , X86Set , O(000F00,9A,_,_,_,_,_,_ ), 0 , 4 , 0 , 2819 , 181, 64 ), // #716
- INST(Setpe , X86Set , O(000F00,9A,_,_,_,_,_,_ ), 0 , 4 , 0 , 2824 , 181, 64 ), // #717
- INST(Setpo , X86Set , O(000F00,9B,_,_,_,_,_,_ ), 0 , 4 , 0 , 2830 , 181, 64 ), // #718
- INST(Sets , X86Set , O(000F00,98,_,_,_,_,_,_ ), 0 , 4 , 0 , 2836 , 181, 65 ), // #719
- INST(Setssbsy , X86Op , O(F30F01,E8,_,_,_,_,_,_ ), 0 , 25 , 0 , 2841 , 30 , 56 ), // #720
- 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 , 80 ), // #722
- INST(Sgdt , X86M_Only , O(000F00,01,0,_,_,_,_,_ ), 0 , 4 , 0 , 2862 , 69 , 0 ), // #723
- INST(Sha1msg1 , ExtRm , O(000F38,C9,_,_,_,_,_,_ ), 0 , 83 , 0 , 2867 , 5 , 123), // #724
- INST(Sha1msg2 , ExtRm , O(000F38,CA,_,_,_,_,_,_ ), 0 , 83 , 0 , 2876 , 5 , 123), // #725
- INST(Sha1nexte , ExtRm , O(000F38,C8,_,_,_,_,_,_ ), 0 , 83 , 0 , 2885 , 5 , 123), // #726
- INST(Sha1rnds4 , ExtRmi , O(000F3A,CC,_,_,_,_,_,_ ), 0 , 85 , 0 , 2895 , 8 , 123), // #727
- INST(Sha256msg1 , ExtRm , O(000F38,CC,_,_,_,_,_,_ ), 0 , 83 , 0 , 2905 , 5 , 123), // #728
- INST(Sha256msg2 , ExtRm , O(000F38,CD,_,_,_,_,_,_ ), 0 , 83 , 0 , 2916 , 5 , 123), // #729
- INST(Sha256rnds2 , ExtRm_XMM0 , O(000F38,CB,_,_,_,_,_,_ ), 0 , 83 , 0 , 2927 , 15 , 123), // #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 , 9938 , 182, 1 ), // #732
- INST(Shlx , VexRmv_Wx , V(660F38,F7,_,0,x,_,_,_ ), 0 , 96 , 0 , 2943 , 13 , 92 ), // #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 , 84 , 0 , 2957 , 13 , 92 ), // #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 , 124), // #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, 77 ), // #742
- 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 , 7921 , 30 , 18 ), // #750
- INST(Stgi , X86Op , O(000F01,DC,_,_,_,_,_,_ ), 0 , 21 , 0 , 3000 , 30 , 124), // #751
- INST(Sti , X86Op , O(000000,FB,_,_,_,_,_,_ ), 0 , 0 , 0 , 3005 , 30 , 23 ), // #752
- 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, 78 ), // #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 , 96 , 0 , 3018 , 103, 76 ), // #756
- INST(Stui , X86Op , O(F30F01,EF,_,_,_,_,_,_ ), 0 , 25 , 0 , 3135 , 33 , 25 ), // #757
- 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 , 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 , 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, 125), // #771
- INST(Tdpbssd , AmxRmv , V(F20F38,5E,_,0,0,_,_,_ ), 0 , 84 , 0 , 3101 , 185, 126), // #772
- INST(Tdpbsud , AmxRmv , V(F30F38,5E,_,0,0,_,_,_ ), 0 , 88 , 0 , 3109 , 185, 126), // #773
- INST(Tdpbusd , AmxRmv , V(660F38,5E,_,0,0,_,_,_ ), 0 , 96 , 0 , 3117 , 185, 126), // #774
- INST(Tdpbuud , AmxRmv , V(000F38,5E,_,0,0,_,_,_ ), 0 , 10 , 0 , 3125 , 185, 126), // #775
- 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 , 127), // #777
- INST(Tileloadd , AmxRm , V(F20F38,4B,_,0,0,_,_,_ ), 0 , 84 , 0 , 3140 , 187, 76 ), // #778
- INST(Tileloaddt1 , AmxRm , V(660F38,4B,_,0,0,_,_,_ ), 0 , 96 , 0 , 3150 , 187, 76 ), // #779
- INST(Tilerelease , VexOpMod , V(000F38,49,0,0,0,_,_,_ ), 0 , 10 , 0 , 3162 , 188, 76 ), // #780
- INST(Tilestored , AmxMr , V(F30F38,4B,_,0,0,_,_,_ ), 0 , 88 , 0 , 3174 , 189, 76 ), // #781
- INST(Tilezero , AmxR , V(F20F38,49,_,0,0,_,_,_ ), 0 , 84 , 0 , 3185 , 190, 76 ), // #782
- INST(Tpause , X86R32_EDX_EAX , O(660F00,AE,6,_,_,_,_,_ ), 0 , 26 , 0 , 3194 , 191, 128), // #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 , 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, 129), // #792
- INST(Umwait , X86R32_EDX_EAX , O(F20F00,AE,6,_,_,_,_,_ ), 0 , 100, 0 , 3240 , 191, 128), // #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, 130), // #798
- INST(V4fmaddss , VexRm_T1_4X , E(F20F38,9B,_,0,_,0,4,T4X), 0 , 102, 0 , 3257 , 195, 130), // #799
- INST(V4fnmaddps , VexRm_T1_4X , E(F20F38,AA,_,2,_,0,4,T4X), 0 , 101, 0 , 3267 , 194, 130), // #800
- INST(V4fnmaddss , VexRm_T1_4X , E(F20F38,AB,_,0,_,0,4,T4X), 0 , 102, 0 , 3278 , 195, 130), // #801
- INST(Vaddpd , VexRvm_Lx , V(660F00,58,_,x,I,1,4,FV ), 0 , 103, 0 , 3289 , 196, 131), // #802
- INST(Vaddph , VexRvm_Lx , E(00MAP5,58,_,_,_,0,4,FV ), 0 , 104, 0 , 3296 , 197, 132), // #803
- INST(Vaddps , VexRvm_Lx , V(000F00,58,_,x,I,0,4,FV ), 0 , 105, 0 , 3303 , 198, 131), // #804
- INST(Vaddsd , VexRvm , V(F20F00,58,_,I,I,1,3,T1S), 0 , 106, 0 , 3310 , 199, 133), // #805
- INST(Vaddsh , VexRvm , E(F3MAP5,58,_,_,_,0,1,T1S), 0 , 107, 0 , 3317 , 200, 134), // #806
- INST(Vaddss , VexRvm , V(F30F00,58,_,I,I,0,2,T1S), 0 , 108, 0 , 3324 , 201, 133), // #807
- INST(Vaddsubpd , VexRvm_Lx , V(660F00,D0,_,x,I,_,_,_ ), 0 , 69 , 0 , 3331 , 202, 135), // #808
- INST(Vaddsubps , VexRvm_Lx , V(F20F00,D0,_,x,I,_,_,_ ), 0 , 109, 0 , 3341 , 202, 135), // #809
- INST(Vaesdec , VexRvm_Lx , V(660F38,DE,_,x,I,_,4,FVM), 0 , 110, 0 , 3351 , 203, 136), // #810
- INST(Vaesdeclast , VexRvm_Lx , V(660F38,DF,_,x,I,_,4,FVM), 0 , 110, 0 , 3359 , 203, 136), // #811
- INST(Vaesenc , VexRvm_Lx , V(660F38,DC,_,x,I,_,4,FVM), 0 , 110, 0 , 3371 , 203, 136), // #812
- INST(Vaesenclast , VexRvm_Lx , V(660F38,DD,_,x,I,_,4,FVM), 0 , 110, 0 , 3379 , 203, 136), // #813
- INST(Vaesimc , VexRm , V(660F38,DB,_,0,I,_,_,_ ), 0 , 96 , 0 , 3391 , 204, 137), // #814
- INST(Vaeskeygenassist , VexRmi , V(660F3A,DF,_,0,I,_,_,_ ), 0 , 73 , 0 , 3399 , 205, 137), // #815
- INST(Valignd , VexRvmi_Lx , E(660F3A,03,_,x,_,0,4,FV ), 0 , 111, 0 , 3416 , 206, 138), // #816
- INST(Valignq , VexRvmi_Lx , E(660F3A,03,_,x,_,1,4,FV ), 0 , 112, 0 , 3424 , 207, 138), // #817
- INST(Vandnpd , VexRvm_Lx , V(660F00,55,_,x,I,1,4,FV ), 0 , 103, 0 , 3432 , 208, 139), // #818
- INST(Vandnps , VexRvm_Lx , V(000F00,55,_,x,I,0,4,FV ), 0 , 105, 0 , 3440 , 209, 139), // #819
- INST(Vandpd , VexRvm_Lx , V(660F00,54,_,x,I,1,4,FV ), 0 , 103, 0 , 3448 , 210, 139), // #820
- INST(Vandps , VexRvm_Lx , V(000F00,54,_,x,I,0,4,FV ), 0 , 105, 0 , 3455 , 211, 139), // #821
- INST(Vblendmpd , VexRvm_Lx , E(660F38,65,_,x,_,1,4,FV ), 0 , 113, 0 , 3462 , 212, 138), // #822
- INST(Vblendmps , VexRvm_Lx , E(660F38,65,_,x,_,0,4,FV ), 0 , 114, 0 , 3472 , 213, 138), // #823
- INST(Vblendpd , VexRvmi_Lx , V(660F3A,0D,_,x,I,_,_,_ ), 0 , 73 , 0 , 3482 , 214, 135), // #824
- INST(Vblendps , VexRvmi_Lx , V(660F3A,0C,_,x,I,_,_,_ ), 0 , 73 , 0 , 3491 , 214, 135), // #825
- INST(Vblendvpd , VexRvmr_Lx , V(660F3A,4B,_,x,0,_,_,_ ), 0 , 73 , 0 , 3500 , 215, 135), // #826
- INST(Vblendvps , VexRvmr_Lx , V(660F3A,4A,_,x,0,_,_,_ ), 0 , 73 , 0 , 3510 , 215, 135), // #827
- INST(Vbroadcastf128 , VexRm , V(660F38,1A,_,1,0,_,_,_ ), 0 , 115, 0 , 3520 , 216, 135), // #828
- INST(Vbroadcastf32x2 , VexRm_Lx , E(660F38,19,_,x,_,0,3,T2 ), 0 , 116, 0 , 3535 , 217, 140), // #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, 140), // #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, 141), // #834
- INST(Vbroadcasti32x2 , VexRm_Lx , E(660F38,59,_,x,_,0,3,T2 ), 0 , 116, 0 , 3630 , 220, 140), // #835
- INST(Vbroadcasti32x4 , VexRm_Lx , E(660F38,5A,_,x,_,0,4,T4 ), 0 , 117, 0 , 3646 , 218, 138), // #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, 140), // #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, 142), // #840
- INST(Vbroadcastss , VexRm_Lx , V(660F38,18,_,x,0,0,2,T1S), 0 , 122, 0 , 3723 , 222, 142), // #841
- INST(Vcmppd , VexRvmi_Lx_KEvex , V(660F00,C2,_,x,I,1,4,FV ), 0 , 103, 0 , 3736 , 223, 131), // #842
- INST(Vcmpph , VexRvmi_Lx_KEvex , E(000F3A,C2,_,_,_,0,4,FV ), 0 , 123, 0 , 3743 , 224, 132), // #843
- INST(Vcmpps , VexRvmi_Lx_KEvex , V(000F00,C2,_,x,I,0,4,FV ), 0 , 105, 0 , 3750 , 225, 131), // #844
- INST(Vcmpsd , VexRvmi_KEvex , V(F20F00,C2,_,I,I,1,3,T1S), 0 , 106, 0 , 3757 , 226, 133), // #845
- INST(Vcmpsh , VexRvmi_KEvex , E(F30F3A,C2,_,_,_,0,1,T1S), 0 , 124, 0 , 3764 , 227, 134), // #846
- INST(Vcmpss , VexRvmi_KEvex , V(F30F00,C2,_,I,I,0,2,T1S), 0 , 108, 0 , 3771 , 228, 133), // #847
- INST(Vcomisd , VexRm , V(660F00,2F,_,I,I,1,3,T1S), 0 , 125, 0 , 3778 , 229, 143), // #848
- INST(Vcomish , VexRm , E(00MAP5,2F,_,_,_,0,1,T1S), 0 , 126, 0 , 3786 , 230, 134), // #849
- INST(Vcomiss , VexRm , V(000F00,2F,_,I,I,0,2,T1S), 0 , 127, 0 , 3794 , 231, 143), // #850
- INST(Vcompresspd , VexMr_Lx , E(660F38,8A,_,x,_,1,3,T1S), 0 , 128, 0 , 3802 , 232, 138), // #851
- INST(Vcompressps , VexMr_Lx , E(660F38,8A,_,x,_,0,2,T1S), 0 , 129, 0 , 3814 , 232, 138), // #852
- INST(Vcvtdq2pd , VexRm_Lx , V(F30F00,E6,_,x,I,0,3,HV ), 0 , 130, 0 , 3826 , 233, 131), // #853
- INST(Vcvtdq2ph , VexRm_Lx , E(00MAP5,5B,_,_,_,0,4,FV ), 0 , 104, 0 , 3836 , 234, 132), // #854
- INST(Vcvtdq2ps , VexRm_Lx , V(000F00,5B,_,x,I,0,4,FV ), 0 , 105, 0 , 3846 , 235, 131), // #855
- INST(Vcvtne2ps2bf16 , VexRvm_Lx , E(F20F38,72,_,_,_,0,4,FV ), 0 , 131, 0 , 3856 , 213, 144), // #856
- INST(Vcvtneps2bf16 , VexRm_Lx_Narrow , E(F30F38,72,_,_,_,0,4,FV ), 0 , 132, 0 , 3871 , 236, 144), // #857
- INST(Vcvtpd2dq , VexRm_Lx_Narrow , V(F20F00,E6,_,x,I,1,4,FV ), 0 , 133, 0 , 3885 , 237, 131), // #858
- INST(Vcvtpd2ph , VexRm_Lx , E(66MAP5,5A,_,_,_,1,4,FV ), 0 , 134, 0 , 3895 , 238, 132), // #859
- INST(Vcvtpd2ps , VexRm_Lx_Narrow , V(660F00,5A,_,x,I,1,4,FV ), 0 , 103, 0 , 3905 , 237, 131), // #860
- INST(Vcvtpd2qq , VexRm_Lx , E(660F00,7B,_,x,_,1,4,FV ), 0 , 135, 0 , 3915 , 239, 140), // #861
- INST(Vcvtpd2udq , VexRm_Lx_Narrow , E(000F00,79,_,x,_,1,4,FV ), 0 , 136, 0 , 3925 , 240, 138), // #862
- INST(Vcvtpd2uqq , VexRm_Lx , E(660F00,79,_,x,_,1,4,FV ), 0 , 135, 0 , 3936 , 239, 140), // #863
- INST(Vcvtph2dq , VexRm_Lx , E(66MAP5,5B,_,_,_,0,3,HV ), 0 , 137, 0 , 3947 , 241, 132), // #864
- INST(Vcvtph2pd , VexRm_Lx , E(00MAP5,5A,_,_,_,0,2,QV ), 0 , 138, 0 , 3957 , 242, 132), // #865
- INST(Vcvtph2ps , VexRm_Lx , V(660F38,13,_,x,0,0,3,HVM), 0 , 139, 0 , 3967 , 243, 145), // #866
- INST(Vcvtph2psx , VexRm_Lx , E(66MAP6,13,_,_,_,0,3,HV ), 0 , 140, 0 , 3977 , 244, 132), // #867
- INST(Vcvtph2qq , VexRm_Lx , E(66MAP5,7B,_,_,_,0,2,QV ), 0 , 141, 0 , 3988 , 245, 132), // #868
- INST(Vcvtph2udq , VexRm_Lx , E(00MAP5,79,_,_,_,0,3,HV ), 0 , 142, 0 , 3998 , 241, 132), // #869
- INST(Vcvtph2uqq , VexRm_Lx , E(66MAP5,79,_,_,_,0,2,QV ), 0 , 141, 0 , 4009 , 245, 132), // #870
- INST(Vcvtph2uw , VexRm_Lx , E(00MAP5,7D,_,_,_,0,4,FV ), 0 , 104, 0 , 4020 , 246, 132), // #871
- INST(Vcvtph2w , VexRm_Lx , E(66MAP5,7D,_,_,_,0,4,FV ), 0 , 143, 0 , 4030 , 246, 132), // #872
- INST(Vcvtps2dq , VexRm_Lx , V(660F00,5B,_,x,I,0,4,FV ), 0 , 144, 0 , 4039 , 235, 131), // #873
- INST(Vcvtps2pd , VexRm_Lx , V(000F00,5A,_,x,I,0,3,HV ), 0 , 145, 0 , 4049 , 247, 131), // #874
- INST(Vcvtps2ph , VexMri_Lx , V(660F3A,1D,_,x,0,0,3,HVM), 0 , 146, 0 , 4059 , 248, 145), // #875
- INST(Vcvtps2phx , VexRm_Lx , E(66MAP5,1D,_,_,_,0,4,FV ), 0 , 143, 0 , 4069 , 234, 132), // #876
- INST(Vcvtps2qq , VexRm_Lx , E(660F00,7B,_,x,_,0,3,HV ), 0 , 147, 0 , 4080 , 249, 140), // #877
- INST(Vcvtps2udq , VexRm_Lx , E(000F00,79,_,x,_,0,4,FV ), 0 , 148, 0 , 4090 , 250, 138), // #878
- INST(Vcvtps2uqq , VexRm_Lx , E(660F00,79,_,x,_,0,3,HV ), 0 , 147, 0 , 4101 , 249, 140), // #879
- INST(Vcvtqq2pd , VexRm_Lx , E(F30F00,E6,_,x,_,1,4,FV ), 0 , 149, 0 , 4112 , 239, 140), // #880
- INST(Vcvtqq2ph , VexRm_Lx , E(00MAP5,5B,_,_,_,1,4,FV ), 0 , 150, 0 , 4122 , 238, 132), // #881
- INST(Vcvtqq2ps , VexRm_Lx_Narrow , E(000F00,5B,_,x,_,1,4,FV ), 0 , 136, 0 , 4132 , 240, 140), // #882
- INST(Vcvtsd2sh , VexRvm , E(F2MAP5,5A,_,_,_,1,3,T1S), 0 , 151, 0 , 4142 , 251, 134), // #883
- INST(Vcvtsd2si , VexRm_Wx , V(F20F00,2D,_,I,x,x,3,T1F), 0 , 152, 0 , 4152 , 252, 133), // #884
- INST(Vcvtsd2ss , VexRvm , V(F20F00,5A,_,I,I,1,3,T1S), 0 , 106, 0 , 4162 , 199, 133), // #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, 134), // #887
- INST(Vcvtsh2si , VexRm_Wx , E(F3MAP5,2D,_,_,_,x,1,T1S), 0 , 107, 0 , 4193 , 255, 134), // #888
- INST(Vcvtsh2ss , VexRvm , E(00MAP6,13,_,_,_,0,1,T1S), 0 , 154, 0 , 4203 , 254, 134), // #889
- INST(Vcvtsh2usi , VexRm_Wx , E(F3MAP5,79,_,_,_,x,1,T1S), 0 , 107, 0 , 4213 , 255, 134), // #890
- INST(Vcvtsi2sd , VexRvm_Wx , V(F20F00,2A,_,I,x,x,2,T1W), 0 , 155, 0 , 4224 , 256, 133), // #891
- INST(Vcvtsi2sh , VexRvm_Wx , E(F3MAP5,2A,_,_,_,x,2,T1W), 0 , 156, 0 , 4234 , 257, 134), // #892
- INST(Vcvtsi2ss , VexRvm_Wx , V(F30F00,2A,_,I,x,x,2,T1W), 0 , 157, 0 , 4244 , 256, 133), // #893
- INST(Vcvtss2sd , VexRvm , V(F30F00,5A,_,I,I,0,2,T1S), 0 , 108, 0 , 4254 , 258, 133), // #894
- INST(Vcvtss2sh , VexRvm , E(00MAP5,1D,_,_,_,0,2,T1S), 0 , 158, 0 , 4264 , 259, 134), // #895
- INST(Vcvtss2si , VexRm_Wx , V(F30F00,2D,_,I,x,x,2,T1F), 0 , 108, 0 , 4274 , 260, 133), // #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, 131), // #898
- INST(Vcvttpd2qq , VexRm_Lx , E(660F00,7A,_,x,_,1,4,FV ), 0 , 135, 0 , 4306 , 263, 138), // #899
- INST(Vcvttpd2udq , VexRm_Lx_Narrow , E(000F00,78,_,x,_,1,4,FV ), 0 , 136, 0 , 4317 , 264, 138), // #900
- INST(Vcvttpd2uqq , VexRm_Lx , E(660F00,78,_,x,_,1,4,FV ), 0 , 135, 0 , 4329 , 263, 140), // #901
- INST(Vcvttph2dq , VexRm_Lx , E(F3MAP5,5B,_,_,_,0,3,HV ), 0 , 160, 0 , 4341 , 244, 132), // #902
- INST(Vcvttph2qq , VexRm_Lx , E(66MAP5,7A,_,_,_,0,2,QV ), 0 , 141, 0 , 4352 , 242, 132), // #903
- INST(Vcvttph2udq , VexRm_Lx , E(00MAP5,78,_,_,_,0,3,HV ), 0 , 142, 0 , 4363 , 244, 132), // #904
- INST(Vcvttph2uqq , VexRm_Lx , E(66MAP5,78,_,_,_,0,2,QV ), 0 , 141, 0 , 4375 , 242, 132), // #905
- INST(Vcvttph2uw , VexRm_Lx , E(00MAP5,7C,_,_,_,0,4,FV ), 0 , 104, 0 , 4387 , 265, 132), // #906
- INST(Vcvttph2w , VexRm_Lx , E(66MAP5,7C,_,_,_,0,4,FV ), 0 , 143, 0 , 4398 , 265, 132), // #907
- INST(Vcvttps2dq , VexRm_Lx , V(F30F00,5B,_,x,I,0,4,FV ), 0 , 161, 0 , 4408 , 266, 131), // #908
- INST(Vcvttps2qq , VexRm_Lx , E(660F00,7A,_,x,_,0,3,HV ), 0 , 147, 0 , 4419 , 267, 140), // #909
- INST(Vcvttps2udq , VexRm_Lx , E(000F00,78,_,x,_,0,4,FV ), 0 , 148, 0 , 4430 , 268, 138), // #910
- INST(Vcvttps2uqq , VexRm_Lx , E(660F00,78,_,x,_,0,3,HV ), 0 , 147, 0 , 4442 , 267, 140), // #911
- INST(Vcvttsd2si , VexRm_Wx , V(F20F00,2C,_,I,x,x,3,T1F), 0 , 152, 0 , 4454 , 269, 133), // #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, 134), // #914
- INST(Vcvttsh2usi , VexRm_Wx , E(F3MAP5,78,_,_,_,x,1,T1S), 0 , 107, 0 , 4488 , 271, 134), // #915
- INST(Vcvttss2si , VexRm_Wx , V(F30F00,2C,_,I,x,x,2,T1F), 0 , 108, 0 , 4500 , 272, 133), // #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, 138), // #918
- INST(Vcvtudq2ph , VexRm_Lx , E(F2MAP5,7A,_,_,_,0,4,FV ), 0 , 163, 0 , 4534 , 234, 132), // #919
- INST(Vcvtudq2ps , VexRm_Lx , E(F20F00,7A,_,x,_,0,4,FV ), 0 , 164, 0 , 4545 , 250, 138), // #920
- INST(Vcvtuqq2pd , VexRm_Lx , E(F30F00,7A,_,x,_,1,4,FV ), 0 , 149, 0 , 4556 , 239, 140), // #921
- INST(Vcvtuqq2ph , VexRm_Lx , E(F2MAP5,7A,_,_,_,1,4,FV ), 0 , 165, 0 , 4567 , 238, 132), // #922
- INST(Vcvtuqq2ps , VexRm_Lx_Narrow , E(F20F00,7A,_,x,_,1,4,FV ), 0 , 166, 0 , 4578 , 240, 140), // #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, 134), // #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, 132), // #927
- INST(Vcvtw2ph , VexRm_Lx , E(F3MAP5,7D,_,_,_,0,4,FV ), 0 , 169, 0 , 4632 , 246, 132), // #928
- INST(Vdbpsadbw , VexRvmi_Lx , E(660F3A,42,_,x,_,0,4,FVM), 0 , 111, 0 , 4641 , 275, 146), // #929
- INST(Vdivpd , VexRvm_Lx , V(660F00,5E,_,x,I,1,4,FV ), 0 , 103, 0 , 4651 , 196, 131), // #930
- INST(Vdivph , VexRvm_Lx , E(00MAP5,5E,_,_,_,0,4,FV ), 0 , 104, 0 , 4658 , 197, 132), // #931
- INST(Vdivps , VexRvm_Lx , V(000F00,5E,_,x,I,0,4,FV ), 0 , 105, 0 , 4665 , 198, 131), // #932
- INST(Vdivsd , VexRvm , V(F20F00,5E,_,I,I,1,3,T1S), 0 , 106, 0 , 4672 , 199, 133), // #933
- INST(Vdivsh , VexRvm , E(F3MAP5,5E,_,_,_,0,1,T1S), 0 , 107, 0 , 4679 , 200, 134), // #934
- INST(Vdivss , VexRvm , V(F30F00,5E,_,I,I,0,2,T1S), 0 , 108, 0 , 4686 , 201, 133), // #935
- INST(Vdpbf16ps , VexRvm_Lx , E(F30F38,52,_,_,_,0,4,FV ), 0 , 132, 0 , 4693 , 213, 144), // #936
- INST(Vdppd , VexRvmi_Lx , V(660F3A,41,_,x,I,_,_,_ ), 0 , 73 , 0 , 4703 , 276, 135), // #937
- INST(Vdpps , VexRvmi_Lx , V(660F3A,40,_,x,I,_,_,_ ), 0 , 73 , 0 , 4709 , 214, 135), // #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, 147), // #941
- INST(Vexp2ps , VexRm , E(660F38,C8,_,2,_,0,4,FV ), 0 , 171, 0 , 4733 , 278, 147), // #942
- INST(Vexpandpd , VexRm_Lx , E(660F38,88,_,x,_,1,3,T1S), 0 , 128, 0 , 4741 , 279, 138), // #943
- INST(Vexpandps , VexRm_Lx , E(660F38,88,_,x,_,0,2,T1S), 0 , 129, 0 , 4751 , 279, 138), // #944
- INST(Vextractf128 , VexMri , V(660F3A,19,_,1,0,_,_,_ ), 0 , 172, 0 , 4761 , 280, 135), // #945
- INST(Vextractf32x4 , VexMri_Lx , E(660F3A,19,_,x,_,0,4,T4 ), 0 , 173, 0 , 4774 , 281, 138), // #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, 140), // #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, 141), // #950
- INST(Vextracti32x4 , VexMri_Lx , E(660F3A,39,_,x,_,0,4,T4 ), 0 , 173, 0 , 4843 , 281, 138), // #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, 140), // #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, 133), // #955
- INST(Vfcmaddcph , VexRvm_Lx , E(F2MAP6,56,_,_,_,0,4,FV ), 0 , 178, 0 , 4910 , 284, 132), // #956
- INST(Vfcmaddcsh , VexRvm , E(F2MAP6,57,_,_,_,0,2,T1S), 0 , 179, 0 , 4921 , 259, 132), // #957
- INST(Vfcmulcph , VexRvm_Lx , E(F2MAP6,D6,_,_,_,0,4,FV ), 0 , 178, 0 , 4932 , 284, 132), // #958
- INST(Vfcmulcsh , VexRvm , E(F2MAP6,D7,_,_,_,0,2,T1S), 0 , 179, 0 , 4942 , 259, 132), // #959
- INST(Vfixupimmpd , VexRvmi_Lx , E(660F3A,54,_,x,_,1,4,FV ), 0 , 112, 0 , 4952 , 285, 138), // #960
- INST(Vfixupimmps , VexRvmi_Lx , E(660F3A,54,_,x,_,0,4,FV ), 0 , 111, 0 , 4964 , 286, 138), // #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, 148), // #964
- INST(Vfmadd132ph , VexRvm_Lx , E(66MAP6,98,_,_,_,0,4,FV ), 0 , 183, 0 , 5012 , 197, 132), // #965
- INST(Vfmadd132ps , VexRvm_Lx , V(660F38,98,_,x,0,0,4,FV ), 0 , 110, 0 , 5024 , 198, 148), // #966
- INST(Vfmadd132sd , VexRvm , V(660F38,99,_,I,1,1,3,T1S), 0 , 184, 0 , 5036 , 199, 149), // #967
- INST(Vfmadd132sh , VexRvm , E(66MAP6,99,_,_,_,0,1,T1S), 0 , 185, 0 , 5048 , 200, 134), // #968
- INST(Vfmadd132ss , VexRvm , V(660F38,99,_,I,0,0,2,T1S), 0 , 122, 0 , 5060 , 201, 149), // #969
- INST(Vfmadd213pd , VexRvm_Lx , V(660F38,A8,_,x,1,1,4,FV ), 0 , 182, 0 , 5072 , 196, 148), // #970
- INST(Vfmadd213ph , VexRvm_Lx , E(66MAP6,A8,_,_,_,0,4,FV ), 0 , 183, 0 , 5084 , 197, 132), // #971
- INST(Vfmadd213ps , VexRvm_Lx , V(660F38,A8,_,x,0,0,4,FV ), 0 , 110, 0 , 5096 , 198, 148), // #972
- INST(Vfmadd213sd , VexRvm , V(660F38,A9,_,I,1,1,3,T1S), 0 , 184, 0 , 5108 , 199, 149), // #973
- INST(Vfmadd213sh , VexRvm , E(66MAP6,A9,_,_,_,0,1,T1S), 0 , 185, 0 , 5120 , 200, 134), // #974
- INST(Vfmadd213ss , VexRvm , V(660F38,A9,_,I,0,0,2,T1S), 0 , 122, 0 , 5132 , 201, 149), // #975
- INST(Vfmadd231pd , VexRvm_Lx , V(660F38,B8,_,x,1,1,4,FV ), 0 , 182, 0 , 5144 , 196, 148), // #976
- INST(Vfmadd231ph , VexRvm_Lx , E(66MAP6,B8,_,_,_,0,4,FV ), 0 , 183, 0 , 5156 , 197, 132), // #977
- INST(Vfmadd231ps , VexRvm_Lx , V(660F38,B8,_,x,0,0,4,FV ), 0 , 110, 0 , 5168 , 198, 148), // #978
- INST(Vfmadd231sd , VexRvm , V(660F38,B9,_,I,1,1,3,T1S), 0 , 184, 0 , 5180 , 199, 149), // #979
- INST(Vfmadd231sh , VexRvm , E(66MAP6,B9,_,_,_,0,1,T1S), 0 , 185, 0 , 5192 , 200, 134), // #980
- INST(Vfmadd231ss , VexRvm , V(660F38,B9,_,I,0,0,2,T1S), 0 , 122, 0 , 5204 , 201, 149), // #981
- INST(Vfmaddcph , VexRvm_Lx , E(F3MAP6,56,_,_,_,0,4,FV ), 0 , 186, 0 , 5216 , 284, 132), // #982
- INST(Vfmaddcsh , VexRvm , E(F3MAP6,57,_,_,_,0,2,T1S), 0 , 187, 0 , 5226 , 259, 132), // #983
- INST(Vfmaddpd , Fma4_Lx , V(660F3A,69,_,x,x,_,_,_ ), 0 , 73 , 0 , 5236 , 289, 150), // #984
- INST(Vfmaddps , Fma4_Lx , V(660F3A,68,_,x,x,_,_,_ ), 0 , 73 , 0 , 5245 , 289, 150), // #985
- INST(Vfmaddsd , Fma4 , V(660F3A,6B,_,0,x,_,_,_ ), 0 , 73 , 0 , 5254 , 290, 150), // #986
- INST(Vfmaddss , Fma4 , V(660F3A,6A,_,0,x,_,_,_ ), 0 , 73 , 0 , 5263 , 291, 150), // #987
- INST(Vfmaddsub132pd , VexRvm_Lx , V(660F38,96,_,x,1,1,4,FV ), 0 , 182, 0 , 5272 , 196, 148), // #988
- INST(Vfmaddsub132ph , VexRvm_Lx , E(66MAP6,96,_,_,_,0,4,FV ), 0 , 183, 0 , 5287 , 197, 132), // #989
- INST(Vfmaddsub132ps , VexRvm_Lx , V(660F38,96,_,x,0,0,4,FV ), 0 , 110, 0 , 5302 , 198, 148), // #990
- INST(Vfmaddsub213pd , VexRvm_Lx , V(660F38,A6,_,x,1,1,4,FV ), 0 , 182, 0 , 5317 , 196, 148), // #991
- INST(Vfmaddsub213ph , VexRvm_Lx , E(66MAP6,A6,_,_,_,0,4,FV ), 0 , 183, 0 , 5332 , 197, 132), // #992
- INST(Vfmaddsub213ps , VexRvm_Lx , V(660F38,A6,_,x,0,0,4,FV ), 0 , 110, 0 , 5347 , 198, 148), // #993
- INST(Vfmaddsub231pd , VexRvm_Lx , V(660F38,B6,_,x,1,1,4,FV ), 0 , 182, 0 , 5362 , 196, 148), // #994
- INST(Vfmaddsub231ph , VexRvm_Lx , E(66MAP6,B6,_,_,_,0,4,FV ), 0 , 183, 0 , 5377 , 197, 132), // #995
- INST(Vfmaddsub231ps , VexRvm_Lx , V(660F38,B6,_,x,0,0,4,FV ), 0 , 110, 0 , 5392 , 198, 148), // #996
- INST(Vfmaddsubpd , Fma4_Lx , V(660F3A,5D,_,x,x,_,_,_ ), 0 , 73 , 0 , 5407 , 289, 150), // #997
- INST(Vfmaddsubps , Fma4_Lx , V(660F3A,5C,_,x,x,_,_,_ ), 0 , 73 , 0 , 5419 , 289, 150), // #998
- INST(Vfmsub132pd , VexRvm_Lx , V(660F38,9A,_,x,1,1,4,FV ), 0 , 182, 0 , 5431 , 196, 148), // #999
- INST(Vfmsub132ph , VexRvm_Lx , E(66MAP6,9A,_,_,_,0,4,FV ), 0 , 183, 0 , 5443 , 197, 132), // #1000
- INST(Vfmsub132ps , VexRvm_Lx , V(660F38,9A,_,x,0,0,4,FV ), 0 , 110, 0 , 5455 , 198, 148), // #1001
- INST(Vfmsub132sd , VexRvm , V(660F38,9B,_,I,1,1,3,T1S), 0 , 184, 0 , 5467 , 199, 149), // #1002
- INST(Vfmsub132sh , VexRvm , E(66MAP6,9B,_,_,_,0,1,T1S), 0 , 185, 0 , 5479 , 200, 134), // #1003
- INST(Vfmsub132ss , VexRvm , V(660F38,9B,_,I,0,0,2,T1S), 0 , 122, 0 , 5491 , 201, 149), // #1004
- INST(Vfmsub213pd , VexRvm_Lx , V(660F38,AA,_,x,1,1,4,FV ), 0 , 182, 0 , 5503 , 196, 148), // #1005
- INST(Vfmsub213ph , VexRvm_Lx , E(66MAP6,AA,_,_,_,0,4,FV ), 0 , 183, 0 , 5515 , 197, 132), // #1006
- INST(Vfmsub213ps , VexRvm_Lx , V(660F38,AA,_,x,0,0,4,FV ), 0 , 110, 0 , 5527 , 198, 148), // #1007
- INST(Vfmsub213sd , VexRvm , V(660F38,AB,_,I,1,1,3,T1S), 0 , 184, 0 , 5539 , 199, 149), // #1008
- INST(Vfmsub213sh , VexRvm , E(66MAP6,AB,_,_,_,0,1,T1S), 0 , 185, 0 , 5551 , 200, 134), // #1009
- INST(Vfmsub213ss , VexRvm , V(660F38,AB,_,I,0,0,2,T1S), 0 , 122, 0 , 5563 , 201, 149), // #1010
- INST(Vfmsub231pd , VexRvm_Lx , V(660F38,BA,_,x,1,1,4,FV ), 0 , 182, 0 , 5575 , 196, 148), // #1011
- INST(Vfmsub231ph , VexRvm_Lx , E(66MAP6,BA,_,_,_,0,4,FV ), 0 , 183, 0 , 5587 , 197, 132), // #1012
- INST(Vfmsub231ps , VexRvm_Lx , V(660F38,BA,_,x,0,0,4,FV ), 0 , 110, 0 , 5599 , 198, 148), // #1013
- INST(Vfmsub231sd , VexRvm , V(660F38,BB,_,I,1,1,3,T1S), 0 , 184, 0 , 5611 , 199, 149), // #1014
- INST(Vfmsub231sh , VexRvm , E(66MAP6,BB,_,_,_,0,1,T1S), 0 , 185, 0 , 5623 , 200, 134), // #1015
- INST(Vfmsub231ss , VexRvm , V(660F38,BB,_,I,0,0,2,T1S), 0 , 122, 0 , 5635 , 201, 149), // #1016
- INST(Vfmsubadd132pd , VexRvm_Lx , V(660F38,97,_,x,1,1,4,FV ), 0 , 182, 0 , 5647 , 196, 148), // #1017
- INST(Vfmsubadd132ph , VexRvm_Lx , E(66MAP6,97,_,_,_,0,4,FV ), 0 , 183, 0 , 5662 , 197, 132), // #1018
- INST(Vfmsubadd132ps , VexRvm_Lx , V(660F38,97,_,x,0,0,4,FV ), 0 , 110, 0 , 5677 , 198, 148), // #1019
- INST(Vfmsubadd213pd , VexRvm_Lx , V(660F38,A7,_,x,1,1,4,FV ), 0 , 182, 0 , 5692 , 196, 148), // #1020
- INST(Vfmsubadd213ph , VexRvm_Lx , E(66MAP6,A7,_,_,_,0,4,FV ), 0 , 183, 0 , 5707 , 197, 132), // #1021
- INST(Vfmsubadd213ps , VexRvm_Lx , V(660F38,A7,_,x,0,0,4,FV ), 0 , 110, 0 , 5722 , 198, 148), // #1022
- INST(Vfmsubadd231pd , VexRvm_Lx , V(660F38,B7,_,x,1,1,4,FV ), 0 , 182, 0 , 5737 , 196, 148), // #1023
- INST(Vfmsubadd231ph , VexRvm_Lx , E(66MAP6,B7,_,_,_,0,4,FV ), 0 , 183, 0 , 5752 , 197, 132), // #1024
- INST(Vfmsubadd231ps , VexRvm_Lx , V(660F38,B7,_,x,0,0,4,FV ), 0 , 110, 0 , 5767 , 198, 148), // #1025
- INST(Vfmsubaddpd , Fma4_Lx , V(660F3A,5F,_,x,x,_,_,_ ), 0 , 73 , 0 , 5782 , 289, 150), // #1026
- INST(Vfmsubaddps , Fma4_Lx , V(660F3A,5E,_,x,x,_,_,_ ), 0 , 73 , 0 , 5794 , 289, 150), // #1027
- INST(Vfmsubpd , Fma4_Lx , V(660F3A,6D,_,x,x,_,_,_ ), 0 , 73 , 0 , 5806 , 289, 150), // #1028
- INST(Vfmsubps , Fma4_Lx , V(660F3A,6C,_,x,x,_,_,_ ), 0 , 73 , 0 , 5815 , 289, 150), // #1029
- INST(Vfmsubsd , Fma4 , V(660F3A,6F,_,0,x,_,_,_ ), 0 , 73 , 0 , 5824 , 290, 150), // #1030
- INST(Vfmsubss , Fma4 , V(660F3A,6E,_,0,x,_,_,_ ), 0 , 73 , 0 , 5833 , 291, 150), // #1031
- INST(Vfmulcph , VexRvm_Lx , E(F3MAP6,D6,_,_,_,0,4,FV ), 0 , 186, 0 , 5842 , 284, 132), // #1032
- INST(Vfmulcsh , VexRvm , E(F3MAP6,D7,_,_,_,0,2,T1S), 0 , 187, 0 , 5851 , 259, 132), // #1033
- INST(Vfnmadd132pd , VexRvm_Lx , V(660F38,9C,_,x,1,1,4,FV ), 0 , 182, 0 , 5860 , 196, 148), // #1034
- INST(Vfnmadd132ph , VexRvm_Lx , E(66MAP6,9C,_,_,_,0,4,FV ), 0 , 183, 0 , 5873 , 197, 132), // #1035
- INST(Vfnmadd132ps , VexRvm_Lx , V(660F38,9C,_,x,0,0,4,FV ), 0 , 110, 0 , 5886 , 198, 148), // #1036
- INST(Vfnmadd132sd , VexRvm , V(660F38,9D,_,I,1,1,3,T1S), 0 , 184, 0 , 5899 , 199, 149), // #1037
- INST(Vfnmadd132sh , VexRvm , E(66MAP6,9D,_,_,_,0,1,T1S), 0 , 185, 0 , 5912 , 200, 134), // #1038
- INST(Vfnmadd132ss , VexRvm , V(660F38,9D,_,I,0,0,2,T1S), 0 , 122, 0 , 5925 , 201, 149), // #1039
- INST(Vfnmadd213pd , VexRvm_Lx , V(660F38,AC,_,x,1,1,4,FV ), 0 , 182, 0 , 5938 , 196, 148), // #1040
- INST(Vfnmadd213ph , VexRvm_Lx , E(66MAP6,AC,_,_,_,0,4,FV ), 0 , 183, 0 , 5951 , 197, 132), // #1041
- INST(Vfnmadd213ps , VexRvm_Lx , V(660F38,AC,_,x,0,0,4,FV ), 0 , 110, 0 , 5964 , 198, 148), // #1042
- INST(Vfnmadd213sd , VexRvm , V(660F38,AD,_,I,1,1,3,T1S), 0 , 184, 0 , 5977 , 199, 149), // #1043
- INST(Vfnmadd213sh , VexRvm , E(66MAP6,AD,_,_,_,0,1,T1S), 0 , 185, 0 , 5990 , 200, 134), // #1044
- INST(Vfnmadd213ss , VexRvm , V(660F38,AD,_,I,0,0,2,T1S), 0 , 122, 0 , 6003 , 201, 149), // #1045
- INST(Vfnmadd231pd , VexRvm_Lx , V(660F38,BC,_,x,1,1,4,FV ), 0 , 182, 0 , 6016 , 196, 148), // #1046
- INST(Vfnmadd231ph , VexRvm_Lx , E(66MAP6,BC,_,_,_,0,4,FV ), 0 , 183, 0 , 6029 , 197, 132), // #1047
- INST(Vfnmadd231ps , VexRvm_Lx , V(660F38,BC,_,x,0,0,4,FV ), 0 , 110, 0 , 6042 , 198, 148), // #1048
- INST(Vfnmadd231sd , VexRvm , V(660F38,BD,_,I,1,1,3,T1S), 0 , 184, 0 , 6055 , 199, 149), // #1049
- INST(Vfnmadd231sh , VexRvm , E(66MAP6,BD,_,_,_,0,1,T1S), 0 , 185, 0 , 6068 , 200, 134), // #1050
- INST(Vfnmadd231ss , VexRvm , V(660F38,BD,_,I,0,0,2,T1S), 0 , 122, 0 , 6081 , 201, 149), // #1051
- INST(Vfnmaddpd , Fma4_Lx , V(660F3A,79,_,x,x,_,_,_ ), 0 , 73 , 0 , 6094 , 289, 150), // #1052
- INST(Vfnmaddps , Fma4_Lx , V(660F3A,78,_,x,x,_,_,_ ), 0 , 73 , 0 , 6104 , 289, 150), // #1053
- INST(Vfnmaddsd , Fma4 , V(660F3A,7B,_,0,x,_,_,_ ), 0 , 73 , 0 , 6114 , 290, 150), // #1054
- INST(Vfnmaddss , Fma4 , V(660F3A,7A,_,0,x,_,_,_ ), 0 , 73 , 0 , 6124 , 291, 150), // #1055
- INST(Vfnmsub132pd , VexRvm_Lx , V(660F38,9E,_,x,1,1,4,FV ), 0 , 182, 0 , 6134 , 196, 148), // #1056
- INST(Vfnmsub132ph , VexRvm_Lx , E(66MAP6,9E,_,_,_,0,4,FV ), 0 , 183, 0 , 6147 , 197, 132), // #1057
- INST(Vfnmsub132ps , VexRvm_Lx , V(660F38,9E,_,x,0,0,4,FV ), 0 , 110, 0 , 6160 , 198, 148), // #1058
- INST(Vfnmsub132sd , VexRvm , V(660F38,9F,_,I,1,1,3,T1S), 0 , 184, 0 , 6173 , 199, 149), // #1059
- INST(Vfnmsub132sh , VexRvm , E(66MAP6,9F,_,_,_,0,1,T1S), 0 , 185, 0 , 6186 , 200, 134), // #1060
- INST(Vfnmsub132ss , VexRvm , V(660F38,9F,_,I,0,0,2,T1S), 0 , 122, 0 , 6199 , 201, 149), // #1061
- INST(Vfnmsub213pd , VexRvm_Lx , V(660F38,AE,_,x,1,1,4,FV ), 0 , 182, 0 , 6212 , 196, 148), // #1062
- INST(Vfnmsub213ph , VexRvm_Lx , E(66MAP6,AE,_,_,_,0,4,FV ), 0 , 183, 0 , 6225 , 197, 132), // #1063
- INST(Vfnmsub213ps , VexRvm_Lx , V(660F38,AE,_,x,0,0,4,FV ), 0 , 110, 0 , 6238 , 198, 148), // #1064
- INST(Vfnmsub213sd , VexRvm , V(660F38,AF,_,I,1,1,3,T1S), 0 , 184, 0 , 6251 , 199, 149), // #1065
- INST(Vfnmsub213sh , VexRvm , E(66MAP6,AF,_,_,_,0,1,T1S), 0 , 185, 0 , 6264 , 200, 134), // #1066
- INST(Vfnmsub213ss , VexRvm , V(660F38,AF,_,I,0,0,2,T1S), 0 , 122, 0 , 6277 , 201, 149), // #1067
- INST(Vfnmsub231pd , VexRvm_Lx , V(660F38,BE,_,x,1,1,4,FV ), 0 , 182, 0 , 6290 , 196, 148), // #1068
- INST(Vfnmsub231ph , VexRvm_Lx , E(66MAP6,BE,_,_,_,0,4,FV ), 0 , 183, 0 , 6303 , 197, 132), // #1069
- INST(Vfnmsub231ps , VexRvm_Lx , V(660F38,BE,_,x,0,0,4,FV ), 0 , 110, 0 , 6316 , 198, 148), // #1070
- INST(Vfnmsub231sd , VexRvm , V(660F38,BF,_,I,1,1,3,T1S), 0 , 184, 0 , 6329 , 199, 149), // #1071
- INST(Vfnmsub231sh , VexRvm , E(66MAP6,BF,_,_,_,0,1,T1S), 0 , 185, 0 , 6342 , 200, 134), // #1072
- INST(Vfnmsub231ss , VexRvm , V(660F38,BF,_,I,0,0,2,T1S), 0 , 122, 0 , 6355 , 201, 149), // #1073
- INST(Vfnmsubpd , Fma4_Lx , V(660F3A,7D,_,x,x,_,_,_ ), 0 , 73 , 0 , 6368 , 289, 150), // #1074
- INST(Vfnmsubps , Fma4_Lx , V(660F3A,7C,_,x,x,_,_,_ ), 0 , 73 , 0 , 6378 , 289, 150), // #1075
- INST(Vfnmsubsd , Fma4 , V(660F3A,7F,_,0,x,_,_,_ ), 0 , 73 , 0 , 6388 , 290, 150), // #1076
- INST(Vfnmsubss , Fma4 , V(660F3A,7E,_,0,x,_,_,_ ), 0 , 73 , 0 , 6398 , 291, 150), // #1077
- INST(Vfpclasspd , VexRmi_Lx , E(660F3A,66,_,x,_,1,4,FV ), 0 , 112, 0 , 6408 , 292, 140), // #1078
- INST(Vfpclassph , VexRmi_Lx , E(000F3A,66,_,_,_,0,4,FV ), 0 , 123, 0 , 6419 , 293, 132), // #1079
- INST(Vfpclassps , VexRmi_Lx , E(660F3A,66,_,x,_,0,4,FV ), 0 , 111, 0 , 6430 , 294, 140), // #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, 134), // #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, 151), // #1084
- INST(Vfrczps , VexRm_Lx , V(XOP_M9,80,_,x,0,_,_,_ ), 0 , 79 , 0 , 6482 , 298, 151), // #1085
- INST(Vfrczsd , VexRm , V(XOP_M9,83,_,0,0,_,_,_ ), 0 , 79 , 0 , 6490 , 299, 151), // #1086
- INST(Vfrczss , VexRm , V(XOP_M9,82,_,0,0,_,_,_ ), 0 , 79 , 0 , 6498 , 300, 151), // #1087
- INST(Vgatherdpd , VexRmvRm_VM , V(660F38,92,_,x,1,_,_,_ ), E(660F38,92,_,x,_,1,3,T1S), 189, 80 , 6506 , 301, 152), // #1088
- INST(Vgatherdps , VexRmvRm_VM , V(660F38,92,_,x,0,_,_,_ ), E(660F38,92,_,x,_,0,2,T1S), 96 , 81 , 6517 , 302, 152), // #1089
- INST(Vgatherpf0dpd , VexM_VM , E(660F38,C6,1,2,_,1,3,T1S), 0 , 190, 0 , 6528 , 303, 153), // #1090
- INST(Vgatherpf0dps , VexM_VM , E(660F38,C6,1,2,_,0,2,T1S), 0 , 191, 0 , 6542 , 304, 153), // #1091
- INST(Vgatherpf0qpd , VexM_VM , E(660F38,C7,1,2,_,1,3,T1S), 0 , 190, 0 , 6556 , 305, 153), // #1092
- INST(Vgatherpf0qps , VexM_VM , E(660F38,C7,1,2,_,0,2,T1S), 0 , 191, 0 , 6570 , 305, 153), // #1093
- INST(Vgatherpf1dpd , VexM_VM , E(660F38,C6,2,2,_,1,3,T1S), 0 , 192, 0 , 6584 , 303, 153), // #1094
- INST(Vgatherpf1dps , VexM_VM , E(660F38,C6,2,2,_,0,2,T1S), 0 , 193, 0 , 6598 , 304, 153), // #1095
- INST(Vgatherpf1qpd , VexM_VM , E(660F38,C7,2,2,_,1,3,T1S), 0 , 192, 0 , 6612 , 305, 153), // #1096
- INST(Vgatherpf1qps , VexM_VM , E(660F38,C7,2,2,_,0,2,T1S), 0 , 193, 0 , 6626 , 305, 153), // #1097
- INST(Vgatherqpd , VexRmvRm_VM , V(660F38,93,_,x,1,_,_,_ ), E(660F38,93,_,x,_,1,3,T1S), 189, 82 , 6640 , 306, 152), // #1098
- INST(Vgatherqps , VexRmvRm_VM , V(660F38,93,_,x,0,_,_,_ ), E(660F38,93,_,x,_,0,2,T1S), 96 , 83 , 6651 , 307, 152), // #1099
- INST(Vgetexppd , VexRm_Lx , E(660F38,42,_,x,_,1,4,FV ), 0 , 113, 0 , 6662 , 263, 138), // #1100
- INST(Vgetexpph , VexRm_Lx , E(66MAP6,42,_,_,_,0,4,FV ), 0 , 183, 0 , 6672 , 265, 132), // #1101
- INST(Vgetexpps , VexRm_Lx , E(660F38,42,_,x,_,0,4,FV ), 0 , 114, 0 , 6682 , 268, 138), // #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, 134), // #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, 138), // #1106
- INST(Vgetmantph , VexRmi_Lx , E(000F3A,26,_,_,_,0,4,FV ), 0 , 123, 0 , 6733 , 311, 132), // #1107
- INST(Vgetmantps , VexRmi_Lx , E(660F3A,26,_,x,_,0,4,FV ), 0 , 111, 0 , 6744 , 312, 138), // #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, 134), // #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, 154), // #1112
- INST(Vgf2p8affineqb , VexRvmi_Lx , V(660F3A,CE,_,x,1,1,4,FV ), 0 , 194, 0 , 6806 , 314, 154), // #1113
- INST(Vgf2p8mulb , VexRvm_Lx , V(660F38,CF,_,x,0,0,4,FV ), 0 , 110, 0 , 6821 , 315, 154), // #1114
- INST(Vhaddpd , VexRvm_Lx , V(660F00,7C,_,x,I,_,_,_ ), 0 , 69 , 0 , 6832 , 202, 135), // #1115
- INST(Vhaddps , VexRvm_Lx , V(F20F00,7C,_,x,I,_,_,_ ), 0 , 109, 0 , 6840 , 202, 135), // #1116
- INST(Vhsubpd , VexRvm_Lx , V(660F00,7D,_,x,I,_,_,_ ), 0 , 69 , 0 , 6848 , 202, 135), // #1117
- INST(Vhsubps , VexRvm_Lx , V(F20F00,7D,_,x,I,_,_,_ ), 0 , 109, 0 , 6856 , 202, 135), // #1118
- INST(Vinsertf128 , VexRvmi , V(660F3A,18,_,1,0,_,_,_ ), 0 , 172, 0 , 6864 , 316, 135), // #1119
- INST(Vinsertf32x4 , VexRvmi_Lx , E(660F3A,18,_,x,_,0,4,T4 ), 0 , 173, 0 , 6876 , 317, 138), // #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, 140), // #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, 141), // #1124
- INST(Vinserti32x4 , VexRvmi_Lx , E(660F3A,38,_,x,_,0,4,T4 ), 0 , 173, 0 , 6940 , 317, 138), // #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, 140), // #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, 133), // #1129
- INST(Vlddqu , VexRm_Lx , V(F20F00,F0,_,x,I,_,_,_ ), 0 , 109, 0 , 7002 , 320, 135), // #1130
- INST(Vldmxcsr , VexM , V(000F00,AE,2,0,I,_,_,_ ), 0 , 195, 0 , 7009 , 321, 135), // #1131
- INST(Vmaskmovdqu , VexRm_ZDI , V(660F00,F7,_,0,I,_,_,_ ), 0 , 69 , 0 , 7018 , 322, 135), // #1132
- INST(Vmaskmovpd , VexRvmMvr_Lx , V(660F38,2D,_,x,0,_,_,_ ), V(660F38,2F,_,x,0,_,_,_ ), 96 , 84 , 7030 , 323, 135), // #1133
- INST(Vmaskmovps , VexRvmMvr_Lx , V(660F38,2C,_,x,0,_,_,_ ), V(660F38,2E,_,x,0,_,_,_ ), 96 , 85 , 7041 , 323, 135), // #1134
- INST(Vmaxpd , VexRvm_Lx , V(660F00,5F,_,x,I,1,4,FV ), 0 , 103, 0 , 7052 , 324, 131), // #1135
- INST(Vmaxph , VexRvm_Lx , E(00MAP5,5F,_,_,_,0,4,FV ), 0 , 104, 0 , 7059 , 325, 132), // #1136
- INST(Vmaxps , VexRvm_Lx , V(000F00,5F,_,x,I,0,4,FV ), 0 , 105, 0 , 7066 , 326, 131), // #1137
- INST(Vmaxsd , VexRvm , V(F20F00,5F,_,I,I,1,3,T1S), 0 , 106, 0 , 7073 , 327, 131), // #1138
- INST(Vmaxsh , VexRvm , E(F3MAP5,5F,_,_,_,0,1,T1S), 0 , 107, 0 , 7080 , 254, 134), // #1139
- INST(Vmaxss , VexRvm , V(F30F00,5F,_,I,I,0,2,T1S), 0 , 108, 0 , 7087 , 258, 131), // #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, 131), // #1144
- INST(Vminph , VexRvm_Lx , E(00MAP5,5D,_,_,_,0,4,FV ), 0 , 104, 0 , 7123 , 325, 132), // #1145
- INST(Vminps , VexRvm_Lx , V(000F00,5D,_,x,I,0,4,FV ), 0 , 105, 0 , 7130 , 326, 131), // #1146
- INST(Vminsd , VexRvm , V(F20F00,5D,_,I,I,1,3,T1S), 0 , 106, 0 , 7137 , 327, 131), // #1147
- INST(Vminsh , VexRvm , E(F3MAP5,5D,_,_,_,0,1,T1S), 0 , 107, 0 , 7144 , 254, 134), // #1148
- INST(Vminss , VexRvm , V(F30F00,5D,_,I,I,0,2,T1S), 0 , 108, 0 , 7151 , 258, 131), // #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, 155), // #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, 155), // #1154
- INST(Vmovd , VexMovdMovq , V(660F00,6E,_,0,0,0,2,T1S), V(660F00,7E,_,0,0,0,2,T1S), 196, 88 , 7198 , 330, 133), // #1155
- INST(Vmovddup , VexRm_Lx , V(F20F00,12,_,x,I,1,3,DUP), 0 , 197, 0 , 7204 , 331, 131), // #1156
- INST(Vmovdqa , VexRmMr_Lx , V(660F00,6F,_,x,I,_,_,_ ), V(660F00,7F,_,x,I,_,_,_ ), 69 , 89 , 7213 , 332, 156), // #1157
- INST(Vmovdqa32 , VexRmMr_Lx , E(660F00,6F,_,x,_,0,4,FVM), E(660F00,7F,_,x,_,0,4,FVM), 198, 90 , 7221 , 333, 157), // #1158
- INST(Vmovdqa64 , VexRmMr_Lx , E(660F00,6F,_,x,_,1,4,FVM), E(660F00,7F,_,x,_,1,4,FVM), 135, 91 , 7231 , 333, 157), // #1159
- INST(Vmovdqu , VexRmMr_Lx , V(F30F00,6F,_,x,I,_,_,_ ), V(F30F00,7F,_,x,I,_,_,_ ), 199, 92 , 7241 , 332, 156), // #1160
- INST(Vmovdqu16 , VexRmMr_Lx , E(F20F00,6F,_,x,_,1,4,FVM), E(F20F00,7F,_,x,_,1,4,FVM), 166, 93 , 7249 , 333, 158), // #1161
- INST(Vmovdqu32 , VexRmMr_Lx , E(F30F00,6F,_,x,_,0,4,FVM), E(F30F00,7F,_,x,_,0,4,FVM), 200, 94 , 7259 , 333, 157), // #1162
- INST(Vmovdqu64 , VexRmMr_Lx , E(F30F00,6F,_,x,_,1,4,FVM), E(F30F00,7F,_,x,_,1,4,FVM), 149, 95 , 7269 , 333, 157), // #1163
- INST(Vmovdqu8 , VexRmMr_Lx , E(F20F00,6F,_,x,_,0,4,FVM), E(F20F00,7F,_,x,_,0,4,FVM), 164, 96 , 7279 , 333, 158), // #1164
- INST(Vmovhlps , VexRvm , V(000F00,12,_,0,I,0,_,_ ), 0 , 72 , 0 , 7288 , 334, 133), // #1165
- INST(Vmovhpd , VexRvmMr , V(660F00,16,_,0,I,1,3,T1S), V(660F00,17,_,0,I,1,3,T1S), 125, 97 , 7297 , 335, 133), // #1166
- INST(Vmovhps , VexRvmMr , V(000F00,16,_,0,I,0,3,T2 ), V(000F00,17,_,0,I,0,3,T2 ), 201, 98 , 7305 , 335, 133), // #1167
- INST(Vmovlhps , VexRvm , V(000F00,16,_,0,I,0,_,_ ), 0 , 72 , 0 , 7313 , 334, 133), // #1168
- INST(Vmovlpd , VexRvmMr , V(660F00,12,_,0,I,1,3,T1S), V(660F00,13,_,0,I,1,3,T1S), 125, 99 , 7322 , 335, 133), // #1169
- INST(Vmovlps , VexRvmMr , V(000F00,12,_,0,I,0,3,T2 ), V(000F00,13,_,0,I,0,3,T2 ), 201, 100, 7330 , 335, 133), // #1170
- INST(Vmovmskpd , VexRm_Lx , V(660F00,50,_,x,I,_,_,_ ), 0 , 69 , 0 , 7338 , 336, 135), // #1171
- INST(Vmovmskps , VexRm_Lx , V(000F00,50,_,x,I,_,_,_ ), 0 , 72 , 0 , 7348 , 336, 135), // #1172
- INST(Vmovntdq , VexMr_Lx , V(660F00,E7,_,x,I,0,4,FVM), 0 , 144, 0 , 7358 , 337, 131), // #1173
- INST(Vmovntdqa , VexRm_Lx , V(660F38,2A,_,x,I,0,4,FVM), 0 , 110, 0 , 7367 , 338, 142), // #1174
- INST(Vmovntpd , VexMr_Lx , V(660F00,2B,_,x,I,1,4,FVM), 0 , 103, 0 , 7377 , 337, 131), // #1175
- INST(Vmovntps , VexMr_Lx , V(000F00,2B,_,x,I,0,4,FVM), 0 , 105, 0 , 7386 , 337, 131), // #1176
- INST(Vmovq , VexMovdMovq , V(660F00,6E,_,0,I,1,3,T1S), V(660F00,7E,_,0,I,1,3,T1S), 125, 101, 7395 , 339, 159), // #1177
- INST(Vmovsd , VexMovssMovsd , V(F20F00,10,_,I,I,1,3,T1S), V(F20F00,11,_,I,I,1,3,T1S), 106, 102, 7401 , 340, 159), // #1178
- INST(Vmovsh , VexMovssMovsd , E(F3MAP5,10,_,I,_,0,1,T1S), E(F3MAP5,11,_,I,_,0,1,T1S), 107, 103, 7408 , 341, 134), // #1179
- INST(Vmovshdup , VexRm_Lx , V(F30F00,16,_,x,I,0,4,FVM), 0 , 161, 0 , 7415 , 342, 131), // #1180
- INST(Vmovsldup , VexRm_Lx , V(F30F00,12,_,x,I,0,4,FVM), 0 , 161, 0 , 7425 , 342, 131), // #1181
- INST(Vmovss , VexMovssMovsd , V(F30F00,10,_,I,I,0,2,T1S), V(F30F00,11,_,I,I,0,2,T1S), 108, 104, 7435 , 343, 159), // #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, 155), // #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, 155), // #1184
- INST(Vmovw , VexMovdMovq , E(66MAP5,6E,_,0,_,I,1,T1S), E(66MAP5,7E,_,0,_,I,1,T1S), 202, 107, 7458 , 344, 134), // #1185
- INST(Vmpsadbw , VexRvmi_Lx , V(660F3A,42,_,x,I,_,_,_ ), 0 , 73 , 0 , 7464 , 214, 160), // #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, 131), // #1193
- INST(Vmulph , VexRvm_Lx , E(00MAP5,59,_,_,_,0,4,FV ), 0 , 104, 0 , 7525 , 197, 132), // #1194
- INST(Vmulps , VexRvm_Lx , V(000F00,59,_,x,I,0,4,FV ), 0 , 105, 0 , 7532 , 198, 131), // #1195
- INST(Vmulsd , VexRvm , V(F20F00,59,_,I,I,1,3,T1S), 0 , 106, 0 , 7539 , 199, 133), // #1196
- INST(Vmulsh , VexRvm , E(F3MAP5,59,_,_,_,0,1,T1S), 0 , 107, 0 , 7546 , 200, 134), // #1197
- INST(Vmulss , VexRvm , V(F30F00,59,_,I,I,0,2,T1S), 0 , 108, 0 , 7553 , 201, 133), // #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, 139), // #1201
- INST(Vorps , VexRvm_Lx , V(000F00,56,_,x,I,0,4,FV ), 0 , 105, 0 , 7580 , 211, 139), // #1202
- INST(Vp2intersectd , VexRvm_Lx_2xK , E(F20F38,68,_,_,_,0,4,FV ), 0 , 131, 0 , 7586 , 347, 161), // #1203
- INST(Vp2intersectq , VexRvm_Lx_2xK , E(F20F38,68,_,_,_,1,4,FV ), 0 , 203, 0 , 7600 , 348, 161), // #1204
- INST(Vp4dpwssd , VexRm_T1_4X , E(F20F38,52,_,2,_,0,4,T4X), 0 , 101, 0 , 7614 , 194, 162), // #1205
- INST(Vp4dpwssds , VexRm_T1_4X , E(F20F38,53,_,2,_,0,4,T4X), 0 , 101, 0 , 7624 , 194, 162), // #1206
- INST(Vpabsb , VexRm_Lx , V(660F38,1C,_,x,I,_,4,FVM), 0 , 110, 0 , 7635 , 342, 163), // #1207
- INST(Vpabsd , VexRm_Lx , V(660F38,1E,_,x,I,0,4,FV ), 0 , 110, 0 , 7642 , 349, 142), // #1208
- INST(Vpabsq , VexRm_Lx , E(660F38,1F,_,x,_,1,4,FV ), 0 , 113, 0 , 7649 , 350, 138), // #1209
- INST(Vpabsw , VexRm_Lx , V(660F38,1D,_,x,I,_,4,FVM), 0 , 110, 0 , 7656 , 342, 163), // #1210
- INST(Vpackssdw , VexRvm_Lx , V(660F00,6B,_,x,I,0,4,FV ), 0 , 144, 0 , 7663 , 209, 163), // #1211
- INST(Vpacksswb , VexRvm_Lx , V(660F00,63,_,x,I,I,4,FVM), 0 , 144, 0 , 7673 , 315, 163), // #1212
- INST(Vpackusdw , VexRvm_Lx , V(660F38,2B,_,x,I,0,4,FV ), 0 , 110, 0 , 7683 , 209, 163), // #1213
- INST(Vpackuswb , VexRvm_Lx , V(660F00,67,_,x,I,I,4,FVM), 0 , 144, 0 , 7693 , 315, 163), // #1214
- INST(Vpaddb , VexRvm_Lx , V(660F00,FC,_,x,I,I,4,FVM), 0 , 144, 0 , 7703 , 315, 163), // #1215
- INST(Vpaddd , VexRvm_Lx , V(660F00,FE,_,x,I,0,4,FV ), 0 , 144, 0 , 7710 , 209, 142), // #1216
- INST(Vpaddq , VexRvm_Lx , V(660F00,D4,_,x,I,1,4,FV ), 0 , 103, 0 , 7717 , 208, 142), // #1217
- INST(Vpaddsb , VexRvm_Lx , V(660F00,EC,_,x,I,I,4,FVM), 0 , 144, 0 , 7724 , 315, 163), // #1218
- INST(Vpaddsw , VexRvm_Lx , V(660F00,ED,_,x,I,I,4,FVM), 0 , 144, 0 , 7732 , 315, 163), // #1219
- INST(Vpaddusb , VexRvm_Lx , V(660F00,DC,_,x,I,I,4,FVM), 0 , 144, 0 , 7740 , 315, 163), // #1220
- INST(Vpaddusw , VexRvm_Lx , V(660F00,DD,_,x,I,I,4,FVM), 0 , 144, 0 , 7749 , 315, 163), // #1221
- INST(Vpaddw , VexRvm_Lx , V(660F00,FD,_,x,I,I,4,FVM), 0 , 144, 0 , 7758 , 315, 163), // #1222
- INST(Vpalignr , VexRvmi_Lx , V(660F3A,0F,_,x,I,I,4,FVM), 0 , 204, 0 , 7765 , 314, 163), // #1223
- INST(Vpand , VexRvm_Lx , V(660F00,DB,_,x,I,_,_,_ ), 0 , 69 , 0 , 7774 , 351, 160), // #1224
- INST(Vpandd , VexRvm_Lx , E(660F00,DB,_,x,_,0,4,FV ), 0 , 198, 0 , 7780 , 352, 138), // #1225
- INST(Vpandn , VexRvm_Lx , V(660F00,DF,_,x,I,_,_,_ ), 0 , 69 , 0 , 7787 , 353, 160), // #1226
- INST(Vpandnd , VexRvm_Lx , E(660F00,DF,_,x,_,0,4,FV ), 0 , 198, 0 , 7794 , 354, 138), // #1227
- INST(Vpandnq , VexRvm_Lx , E(660F00,DF,_,x,_,1,4,FV ), 0 , 135, 0 , 7802 , 355, 138), // #1228
- INST(Vpandq , VexRvm_Lx , E(660F00,DB,_,x,_,1,4,FV ), 0 , 135, 0 , 7810 , 356, 138), // #1229
- INST(Vpavgb , VexRvm_Lx , V(660F00,E0,_,x,I,I,4,FVM), 0 , 144, 0 , 7817 , 315, 163), // #1230
- INST(Vpavgw , VexRvm_Lx , V(660F00,E3,_,x,I,I,4,FVM), 0 , 144, 0 , 7824 , 315, 163), // #1231
- INST(Vpblendd , VexRvmi_Lx , V(660F3A,02,_,x,0,_,_,_ ), 0 , 73 , 0 , 7831 , 214, 141), // #1232
- INST(Vpblendmb , VexRvm_Lx , E(660F38,66,_,x,_,0,4,FVM), 0 , 114, 0 , 7840 , 357, 146), // #1233
- INST(Vpblendmd , VexRvm_Lx , E(660F38,64,_,x,_,0,4,FV ), 0 , 114, 0 , 7850 , 213, 138), // #1234
- INST(Vpblendmq , VexRvm_Lx , E(660F38,64,_,x,_,1,4,FV ), 0 , 113, 0 , 7860 , 212, 138), // #1235
- INST(Vpblendmw , VexRvm_Lx , E(660F38,66,_,x,_,1,4,FVM), 0 , 113, 0 , 7870 , 357, 146), // #1236
- INST(Vpblendvb , VexRvmr_Lx , V(660F3A,4C,_,x,0,_,_,_ ), 0 , 73 , 0 , 7880 , 215, 160), // #1237
- INST(Vpblendw , VexRvmi_Lx , V(660F3A,0E,_,x,I,_,_,_ ), 0 , 73 , 0 , 7890 , 214, 160), // #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, 164), // #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, 152), // #1240
- INST(Vpbroadcastmb2q , VexRm_Lx , E(F30F38,2A,_,x,_,1,_,_ ), 0 , 205, 0 , 7925 , 360, 165), // #1241
- INST(Vpbroadcastmw2d , VexRm_Lx , E(F30F38,3A,_,x,_,0,_,_ ), 0 , 206, 0 , 7941 , 360, 165), // #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, 152), // #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, 164), // #1244
- INST(Vpclmulqdq , VexRvmi_Lx , V(660F3A,44,_,x,I,_,4,FVM), 0 , 204, 0 , 7983 , 363, 166), // #1245
- INST(Vpcmov , VexRvrmRvmr_Lx , V(XOP_M8,A2,_,x,x,_,_,_ ), 0 , 208, 0 , 7994 , 289, 151), // #1246
- INST(Vpcmpb , VexRvmi_Lx , E(660F3A,3F,_,x,_,0,4,FVM), 0 , 111, 0 , 8001 , 364, 146), // #1247
- INST(Vpcmpd , VexRvmi_Lx , E(660F3A,1F,_,x,_,0,4,FV ), 0 , 111, 0 , 8008 , 365, 138), // #1248
- INST(Vpcmpeqb , VexRvm_Lx_KEvex , V(660F00,74,_,x,I,I,4,FV ), 0 , 144, 0 , 8015 , 366, 163), // #1249
- INST(Vpcmpeqd , VexRvm_Lx_KEvex , V(660F00,76,_,x,I,0,4,FVM), 0 , 144, 0 , 8024 , 367, 142), // #1250
- INST(Vpcmpeqq , VexRvm_Lx_KEvex , V(660F38,29,_,x,I,1,4,FVM), 0 , 209, 0 , 8033 , 368, 142), // #1251
- INST(Vpcmpeqw , VexRvm_Lx_KEvex , V(660F00,75,_,x,I,I,4,FV ), 0 , 144, 0 , 8042 , 366, 163), // #1252
- INST(Vpcmpestri , VexRmi , V(660F3A,61,_,0,I,_,_,_ ), 0 , 73 , 0 , 8051 , 369, 167), // #1253
- INST(Vpcmpestrm , VexRmi , V(660F3A,60,_,0,I,_,_,_ ), 0 , 73 , 0 , 8062 , 370, 167), // #1254
- INST(Vpcmpgtb , VexRvm_Lx_KEvex , V(660F00,64,_,x,I,I,4,FV ), 0 , 144, 0 , 8073 , 366, 163), // #1255
- INST(Vpcmpgtd , VexRvm_Lx_KEvex , V(660F00,66,_,x,I,0,4,FVM), 0 , 144, 0 , 8082 , 367, 142), // #1256
- INST(Vpcmpgtq , VexRvm_Lx_KEvex , V(660F38,37,_,x,I,1,4,FVM), 0 , 209, 0 , 8091 , 368, 142), // #1257
- INST(Vpcmpgtw , VexRvm_Lx_KEvex , V(660F00,65,_,x,I,I,4,FV ), 0 , 144, 0 , 8100 , 366, 163), // #1258
- INST(Vpcmpistri , VexRmi , V(660F3A,63,_,0,I,_,_,_ ), 0 , 73 , 0 , 8109 , 371, 167), // #1259
- INST(Vpcmpistrm , VexRmi , V(660F3A,62,_,0,I,_,_,_ ), 0 , 73 , 0 , 8120 , 372, 167), // #1260
- INST(Vpcmpq , VexRvmi_Lx , E(660F3A,1F,_,x,_,1,4,FV ), 0 , 112, 0 , 8131 , 373, 138), // #1261
- INST(Vpcmpub , VexRvmi_Lx , E(660F3A,3E,_,x,_,0,4,FVM), 0 , 111, 0 , 8138 , 364, 146), // #1262
- INST(Vpcmpud , VexRvmi_Lx , E(660F3A,1E,_,x,_,0,4,FV ), 0 , 111, 0 , 8146 , 365, 138), // #1263
- INST(Vpcmpuq , VexRvmi_Lx , E(660F3A,1E,_,x,_,1,4,FV ), 0 , 112, 0 , 8154 , 373, 138), // #1264
- INST(Vpcmpuw , VexRvmi_Lx , E(660F3A,3E,_,x,_,1,4,FVM), 0 , 112, 0 , 8162 , 373, 146), // #1265
- INST(Vpcmpw , VexRvmi_Lx , E(660F3A,3F,_,x,_,1,4,FVM), 0 , 112, 0 , 8170 , 373, 146), // #1266
- INST(Vpcomb , VexRvmi , V(XOP_M8,CC,_,0,0,_,_,_ ), 0 , 208, 0 , 8177 , 276, 151), // #1267
- INST(Vpcomd , VexRvmi , V(XOP_M8,CE,_,0,0,_,_,_ ), 0 , 208, 0 , 8184 , 276, 151), // #1268
- INST(Vpcompressb , VexMr_Lx , E(660F38,63,_,x,_,0,0,T1S), 0 , 210, 0 , 8191 , 232, 168), // #1269
- INST(Vpcompressd , VexMr_Lx , E(660F38,8B,_,x,_,0,2,T1S), 0 , 129, 0 , 8203 , 232, 138), // #1270
- INST(Vpcompressq , VexMr_Lx , E(660F38,8B,_,x,_,1,3,T1S), 0 , 128, 0 , 8215 , 232, 138), // #1271
- INST(Vpcompressw , VexMr_Lx , E(660F38,63,_,x,_,1,1,T1S), 0 , 211, 0 , 8227 , 232, 168), // #1272
- INST(Vpcomq , VexRvmi , V(XOP_M8,CF,_,0,0,_,_,_ ), 0 , 208, 0 , 8239 , 276, 151), // #1273
- INST(Vpcomub , VexRvmi , V(XOP_M8,EC,_,0,0,_,_,_ ), 0 , 208, 0 , 8246 , 276, 151), // #1274
- INST(Vpcomud , VexRvmi , V(XOP_M8,EE,_,0,0,_,_,_ ), 0 , 208, 0 , 8254 , 276, 151), // #1275
- INST(Vpcomuq , VexRvmi , V(XOP_M8,EF,_,0,0,_,_,_ ), 0 , 208, 0 , 8262 , 276, 151), // #1276
- INST(Vpcomuw , VexRvmi , V(XOP_M8,ED,_,0,0,_,_,_ ), 0 , 208, 0 , 8270 , 276, 151), // #1277
- INST(Vpcomw , VexRvmi , V(XOP_M8,CD,_,0,0,_,_,_ ), 0 , 208, 0 , 8278 , 276, 151), // #1278
- INST(Vpconflictd , VexRm_Lx , E(660F38,C4,_,x,_,0,4,FV ), 0 , 114, 0 , 8285 , 374, 165), // #1279
- INST(Vpconflictq , VexRm_Lx , E(660F38,C4,_,x,_,1,4,FV ), 0 , 113, 0 , 8297 , 374, 165), // #1280
- INST(Vpdpbusd , VexRvm_Lx , V(660F38,50,_,x,_,0,4,FV ), 0 , 110, 0 , 8309 , 375, 169), // #1281
- INST(Vpdpbusds , VexRvm_Lx , V(660F38,51,_,x,_,0,4,FV ), 0 , 110, 0 , 8318 , 375, 169), // #1282
- INST(Vpdpwssd , VexRvm_Lx , V(660F38,52,_,x,_,0,4,FV ), 0 , 110, 0 , 8328 , 375, 169), // #1283
- INST(Vpdpwssds , VexRvm_Lx , V(660F38,53,_,x,_,0,4,FV ), 0 , 110, 0 , 8337 , 375, 169), // #1284
- INST(Vperm2f128 , VexRvmi , V(660F3A,06,_,1,0,_,_,_ ), 0 , 172, 0 , 8347 , 376, 135), // #1285
- INST(Vperm2i128 , VexRvmi , V(660F3A,46,_,1,0,_,_,_ ), 0 , 172, 0 , 8358 , 376, 141), // #1286
- INST(Vpermb , VexRvm_Lx , E(660F38,8D,_,x,_,0,4,FVM), 0 , 114, 0 , 8369 , 357, 170), // #1287
- INST(Vpermd , VexRvm_Lx , V(660F38,36,_,x,0,0,4,FV ), 0 , 110, 0 , 8376 , 377, 152), // #1288
- INST(Vpermi2b , VexRvm_Lx , E(660F38,75,_,x,_,0,4,FVM), 0 , 114, 0 , 8383 , 357, 170), // #1289
- INST(Vpermi2d , VexRvm_Lx , E(660F38,76,_,x,_,0,4,FV ), 0 , 114, 0 , 8392 , 213, 138), // #1290
- INST(Vpermi2pd , VexRvm_Lx , E(660F38,77,_,x,_,1,4,FV ), 0 , 113, 0 , 8401 , 212, 138), // #1291
- INST(Vpermi2ps , VexRvm_Lx , E(660F38,77,_,x,_,0,4,FV ), 0 , 114, 0 , 8411 , 213, 138), // #1292
- INST(Vpermi2q , VexRvm_Lx , E(660F38,76,_,x,_,1,4,FV ), 0 , 113, 0 , 8421 , 212, 138), // #1293
- INST(Vpermi2w , VexRvm_Lx , E(660F38,75,_,x,_,1,4,FVM), 0 , 113, 0 , 8430 , 357, 146), // #1294
- INST(Vpermil2pd , VexRvrmiRvmri_Lx , V(660F3A,49,_,x,x,_,_,_ ), 0 , 73 , 0 , 8439 , 378, 151), // #1295
- INST(Vpermil2ps , VexRvrmiRvmri_Lx , V(660F3A,48,_,x,x,_,_,_ ), 0 , 73 , 0 , 8450 , 378, 151), // #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, 131), // #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, 131), // #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, 152), // #1299
- INST(Vpermps , VexRvm_Lx , V(660F38,16,_,x,0,0,4,FV ), 0 , 110, 0 , 8489 , 377, 152), // #1300
- INST(Vpermq , VexRvmRmi_Lx , E(660F38,36,_,x,_,1,4,FV ), V(660F3A,00,_,x,1,1,4,FV ), 113, 115, 8497 , 381, 152), // #1301
- INST(Vpermt2b , VexRvm_Lx , E(660F38,7D,_,x,_,0,4,FVM), 0 , 114, 0 , 8504 , 357, 170), // #1302
- INST(Vpermt2d , VexRvm_Lx , E(660F38,7E,_,x,_,0,4,FV ), 0 , 114, 0 , 8513 , 213, 138), // #1303
- INST(Vpermt2pd , VexRvm_Lx , E(660F38,7F,_,x,_,1,4,FV ), 0 , 113, 0 , 8522 , 212, 138), // #1304
- INST(Vpermt2ps , VexRvm_Lx , E(660F38,7F,_,x,_,0,4,FV ), 0 , 114, 0 , 8532 , 213, 138), // #1305
- INST(Vpermt2q , VexRvm_Lx , E(660F38,7E,_,x,_,1,4,FV ), 0 , 113, 0 , 8542 , 212, 138), // #1306
- INST(Vpermt2w , VexRvm_Lx , E(660F38,7D,_,x,_,1,4,FVM), 0 , 113, 0 , 8551 , 357, 146), // #1307
- INST(Vpermw , VexRvm_Lx , E(660F38,8D,_,x,_,1,4,FVM), 0 , 113, 0 , 8560 , 357, 146), // #1308
- INST(Vpexpandb , VexRm_Lx , E(660F38,62,_,x,_,0,0,T1S), 0 , 210, 0 , 8567 , 279, 168), // #1309
- INST(Vpexpandd , VexRm_Lx , E(660F38,89,_,x,_,0,2,T1S), 0 , 129, 0 , 8577 , 279, 138), // #1310
- INST(Vpexpandq , VexRm_Lx , E(660F38,89,_,x,_,1,3,T1S), 0 , 128, 0 , 8587 , 279, 138), // #1311
- INST(Vpexpandw , VexRm_Lx , E(660F38,62,_,x,_,1,1,T1S), 0 , 211, 0 , 8597 , 279, 168), // #1312
- INST(Vpextrb , VexMri , V(660F3A,14,_,0,0,I,0,T1S), 0 , 73 , 0 , 8607 , 382, 171), // #1313
- INST(Vpextrd , VexMri , V(660F3A,16,_,0,0,0,2,T1S), 0 , 177, 0 , 8615 , 283, 172), // #1314
- INST(Vpextrq , VexMri , V(660F3A,16,_,0,1,1,3,T1S), 0 , 213, 0 , 8623 , 383, 172), // #1315
- INST(Vpextrw , VexMri_Vpextrw , V(660F3A,15,_,0,0,I,1,T1S), 0 , 214, 0 , 8631 , 384, 171), // #1316
- INST(Vpgatherdd , VexRmvRm_VM , V(660F38,90,_,x,0,_,_,_ ), E(660F38,90,_,x,_,0,2,T1S), 96 , 116, 8639 , 302, 152), // #1317
- INST(Vpgatherdq , VexRmvRm_VM , V(660F38,90,_,x,1,_,_,_ ), E(660F38,90,_,x,_,1,3,T1S), 189, 117, 8650 , 301, 152), // #1318
- INST(Vpgatherqd , VexRmvRm_VM , V(660F38,91,_,x,0,_,_,_ ), E(660F38,91,_,x,_,0,2,T1S), 96 , 118, 8661 , 307, 152), // #1319
- INST(Vpgatherqq , VexRmvRm_VM , V(660F38,91,_,x,1,_,_,_ ), E(660F38,91,_,x,_,1,3,T1S), 189, 119, 8672 , 306, 152), // #1320
- INST(Vphaddbd , VexRm , V(XOP_M9,C2,_,0,0,_,_,_ ), 0 , 79 , 0 , 8683 , 204, 151), // #1321
- INST(Vphaddbq , VexRm , V(XOP_M9,C3,_,0,0,_,_,_ ), 0 , 79 , 0 , 8692 , 204, 151), // #1322
- INST(Vphaddbw , VexRm , V(XOP_M9,C1,_,0,0,_,_,_ ), 0 , 79 , 0 , 8701 , 204, 151), // #1323
- INST(Vphaddd , VexRvm_Lx , V(660F38,02,_,x,I,_,_,_ ), 0 , 96 , 0 , 8710 , 202, 160), // #1324
- INST(Vphadddq , VexRm , V(XOP_M9,CB,_,0,0,_,_,_ ), 0 , 79 , 0 , 8718 , 204, 151), // #1325
- INST(Vphaddsw , VexRvm_Lx , V(660F38,03,_,x,I,_,_,_ ), 0 , 96 , 0 , 8727 , 202, 160), // #1326
- INST(Vphaddubd , VexRm , V(XOP_M9,D2,_,0,0,_,_,_ ), 0 , 79 , 0 , 8736 , 204, 151), // #1327
- INST(Vphaddubq , VexRm , V(XOP_M9,D3,_,0,0,_,_,_ ), 0 , 79 , 0 , 8746 , 204, 151), // #1328
- INST(Vphaddubw , VexRm , V(XOP_M9,D1,_,0,0,_,_,_ ), 0 , 79 , 0 , 8756 , 204, 151), // #1329
- INST(Vphaddudq , VexRm , V(XOP_M9,DB,_,0,0,_,_,_ ), 0 , 79 , 0 , 8766 , 204, 151), // #1330
- INST(Vphadduwd , VexRm , V(XOP_M9,D6,_,0,0,_,_,_ ), 0 , 79 , 0 , 8776 , 204, 151), // #1331
- INST(Vphadduwq , VexRm , V(XOP_M9,D7,_,0,0,_,_,_ ), 0 , 79 , 0 , 8786 , 204, 151), // #1332
- INST(Vphaddw , VexRvm_Lx , V(660F38,01,_,x,I,_,_,_ ), 0 , 96 , 0 , 8796 , 202, 160), // #1333
- INST(Vphaddwd , VexRm , V(XOP_M9,C6,_,0,0,_,_,_ ), 0 , 79 , 0 , 8804 , 204, 151), // #1334
- INST(Vphaddwq , VexRm , V(XOP_M9,C7,_,0,0,_,_,_ ), 0 , 79 , 0 , 8813 , 204, 151), // #1335
- INST(Vphminposuw , VexRm , V(660F38,41,_,0,I,_,_,_ ), 0 , 96 , 0 , 8822 , 204, 135), // #1336
- INST(Vphsubbw , VexRm , V(XOP_M9,E1,_,0,0,_,_,_ ), 0 , 79 , 0 , 8834 , 204, 151), // #1337
- INST(Vphsubd , VexRvm_Lx , V(660F38,06,_,x,I,_,_,_ ), 0 , 96 , 0 , 8843 , 202, 160), // #1338
- INST(Vphsubdq , VexRm , V(XOP_M9,E3,_,0,0,_,_,_ ), 0 , 79 , 0 , 8851 , 204, 151), // #1339
- INST(Vphsubsw , VexRvm_Lx , V(660F38,07,_,x,I,_,_,_ ), 0 , 96 , 0 , 8860 , 202, 160), // #1340
- INST(Vphsubw , VexRvm_Lx , V(660F38,05,_,x,I,_,_,_ ), 0 , 96 , 0 , 8869 , 202, 160), // #1341
- INST(Vphsubwd , VexRm , V(XOP_M9,E2,_,0,0,_,_,_ ), 0 , 79 , 0 , 8877 , 204, 151), // #1342
- INST(Vpinsrb , VexRvmi , V(660F3A,20,_,0,0,I,0,T1S), 0 , 73 , 0 , 8886 , 385, 171), // #1343
- INST(Vpinsrd , VexRvmi , V(660F3A,22,_,0,0,0,2,T1S), 0 , 177, 0 , 8894 , 386, 172), // #1344
- INST(Vpinsrq , VexRvmi , V(660F3A,22,_,0,1,1,3,T1S), 0 , 213, 0 , 8902 , 387, 172), // #1345
- INST(Vpinsrw , VexRvmi , V(660F00,C4,_,0,0,I,1,T1S), 0 , 215, 0 , 8910 , 388, 171), // #1346
- INST(Vplzcntd , VexRm_Lx , E(660F38,44,_,x,_,0,4,FV ), 0 , 114, 0 , 8918 , 374, 165), // #1347
- INST(Vplzcntq , VexRm_Lx , E(660F38,44,_,x,_,1,4,FV ), 0 , 113, 0 , 8927 , 350, 165), // #1348
- INST(Vpmacsdd , VexRvmr , V(XOP_M8,9E,_,0,0,_,_,_ ), 0 , 208, 0 , 8936 , 389, 151), // #1349
- INST(Vpmacsdqh , VexRvmr , V(XOP_M8,9F,_,0,0,_,_,_ ), 0 , 208, 0 , 8945 , 389, 151), // #1350
- INST(Vpmacsdql , VexRvmr , V(XOP_M8,97,_,0,0,_,_,_ ), 0 , 208, 0 , 8955 , 389, 151), // #1351
- INST(Vpmacssdd , VexRvmr , V(XOP_M8,8E,_,0,0,_,_,_ ), 0 , 208, 0 , 8965 , 389, 151), // #1352
- INST(Vpmacssdqh , VexRvmr , V(XOP_M8,8F,_,0,0,_,_,_ ), 0 , 208, 0 , 8975 , 389, 151), // #1353
- INST(Vpmacssdql , VexRvmr , V(XOP_M8,87,_,0,0,_,_,_ ), 0 , 208, 0 , 8986 , 389, 151), // #1354
- INST(Vpmacsswd , VexRvmr , V(XOP_M8,86,_,0,0,_,_,_ ), 0 , 208, 0 , 8997 , 389, 151), // #1355
- INST(Vpmacssww , VexRvmr , V(XOP_M8,85,_,0,0,_,_,_ ), 0 , 208, 0 , 9007 , 389, 151), // #1356
- INST(Vpmacswd , VexRvmr , V(XOP_M8,96,_,0,0,_,_,_ ), 0 , 208, 0 , 9017 , 389, 151), // #1357
- INST(Vpmacsww , VexRvmr , V(XOP_M8,95,_,0,0,_,_,_ ), 0 , 208, 0 , 9026 , 389, 151), // #1358
- INST(Vpmadcsswd , VexRvmr , V(XOP_M8,A6,_,0,0,_,_,_ ), 0 , 208, 0 , 9035 , 389, 151), // #1359
- INST(Vpmadcswd , VexRvmr , V(XOP_M8,B6,_,0,0,_,_,_ ), 0 , 208, 0 , 9046 , 389, 151), // #1360
- INST(Vpmadd52huq , VexRvm_Lx , E(660F38,B5,_,x,_,1,4,FV ), 0 , 113, 0 , 9056 , 212, 173), // #1361
- INST(Vpmadd52luq , VexRvm_Lx , E(660F38,B4,_,x,_,1,4,FV ), 0 , 113, 0 , 9068 , 212, 173), // #1362
- INST(Vpmaddubsw , VexRvm_Lx , V(660F38,04,_,x,I,I,4,FVM), 0 , 110, 0 , 9080 , 315, 163), // #1363
- INST(Vpmaddwd , VexRvm_Lx , V(660F00,F5,_,x,I,I,4,FVM), 0 , 144, 0 , 9091 , 315, 163), // #1364
- INST(Vpmaskmovd , VexRvmMvr_Lx , V(660F38,8C,_,x,0,_,_,_ ), V(660F38,8E,_,x,0,_,_,_ ), 96 , 120, 9100 , 323, 141), // #1365
- INST(Vpmaskmovq , VexRvmMvr_Lx , V(660F38,8C,_,x,1,_,_,_ ), V(660F38,8E,_,x,1,_,_,_ ), 189, 121, 9111 , 323, 141), // #1366
- INST(Vpmaxsb , VexRvm_Lx , V(660F38,3C,_,x,I,I,4,FVM), 0 , 110, 0 , 9122 , 390, 163), // #1367
- INST(Vpmaxsd , VexRvm_Lx , V(660F38,3D,_,x,I,0,4,FV ), 0 , 110, 0 , 9130 , 211, 142), // #1368
- INST(Vpmaxsq , VexRvm_Lx , E(660F38,3D,_,x,_,1,4,FV ), 0 , 113, 0 , 9138 , 212, 138), // #1369
- INST(Vpmaxsw , VexRvm_Lx , V(660F00,EE,_,x,I,I,4,FVM), 0 , 144, 0 , 9146 , 390, 163), // #1370
- INST(Vpmaxub , VexRvm_Lx , V(660F00,DE,_,x,I,I,4,FVM), 0 , 144, 0 , 9154 , 390, 163), // #1371
- INST(Vpmaxud , VexRvm_Lx , V(660F38,3F,_,x,I,0,4,FV ), 0 , 110, 0 , 9162 , 211, 142), // #1372
- INST(Vpmaxuq , VexRvm_Lx , E(660F38,3F,_,x,_,1,4,FV ), 0 , 113, 0 , 9170 , 212, 138), // #1373
- INST(Vpmaxuw , VexRvm_Lx , V(660F38,3E,_,x,I,I,4,FVM), 0 , 110, 0 , 9178 , 390, 163), // #1374
- INST(Vpminsb , VexRvm_Lx , V(660F38,38,_,x,I,I,4,FVM), 0 , 110, 0 , 9186 , 390, 163), // #1375
- INST(Vpminsd , VexRvm_Lx , V(660F38,39,_,x,I,0,4,FV ), 0 , 110, 0 , 9194 , 211, 142), // #1376
- INST(Vpminsq , VexRvm_Lx , E(660F38,39,_,x,_,1,4,FV ), 0 , 113, 0 , 9202 , 212, 138), // #1377
- INST(Vpminsw , VexRvm_Lx , V(660F00,EA,_,x,I,I,4,FVM), 0 , 144, 0 , 9210 , 390, 163), // #1378
- INST(Vpminub , VexRvm_Lx , V(660F00,DA,_,x,I,_,4,FVM), 0 , 144, 0 , 9218 , 390, 163), // #1379
- INST(Vpminud , VexRvm_Lx , V(660F38,3B,_,x,I,0,4,FV ), 0 , 110, 0 , 9226 , 211, 142), // #1380
- INST(Vpminuq , VexRvm_Lx , E(660F38,3B,_,x,_,1,4,FV ), 0 , 113, 0 , 9234 , 212, 138), // #1381
- INST(Vpminuw , VexRvm_Lx , V(660F38,3A,_,x,I,_,4,FVM), 0 , 110, 0 , 9242 , 390, 163), // #1382
- INST(Vpmovb2m , VexRm_Lx , E(F30F38,29,_,x,_,0,_,_ ), 0 , 206, 0 , 9250 , 391, 146), // #1383
- INST(Vpmovd2m , VexRm_Lx , E(F30F38,39,_,x,_,0,_,_ ), 0 , 206, 0 , 9259 , 391, 140), // #1384
- INST(Vpmovdb , VexMr_Lx , E(F30F38,31,_,x,_,0,2,QVM), 0 , 216, 0 , 9268 , 392, 138), // #1385
- INST(Vpmovdw , VexMr_Lx , E(F30F38,33,_,x,_,0,3,HVM), 0 , 217, 0 , 9276 , 393, 138), // #1386
- INST(Vpmovm2b , VexRm_Lx , E(F30F38,28,_,x,_,0,_,_ ), 0 , 206, 0 , 9284 , 360, 146), // #1387
- INST(Vpmovm2d , VexRm_Lx , E(F30F38,38,_,x,_,0,_,_ ), 0 , 206, 0 , 9293 , 360, 140), // #1388
- INST(Vpmovm2q , VexRm_Lx , E(F30F38,38,_,x,_,1,_,_ ), 0 , 205, 0 , 9302 , 360, 140), // #1389
- INST(Vpmovm2w , VexRm_Lx , E(F30F38,28,_,x,_,1,_,_ ), 0 , 205, 0 , 9311 , 360, 146), // #1390
- INST(Vpmovmskb , VexRm_Lx , V(660F00,D7,_,x,I,_,_,_ ), 0 , 69 , 0 , 9320 , 336, 160), // #1391
- INST(Vpmovq2m , VexRm_Lx , E(F30F38,39,_,x,_,1,_,_ ), 0 , 205, 0 , 9330 , 391, 140), // #1392
- INST(Vpmovqb , VexMr_Lx , E(F30F38,32,_,x,_,0,1,OVM), 0 , 218, 0 , 9339 , 394, 138), // #1393
- INST(Vpmovqd , VexMr_Lx , E(F30F38,35,_,x,_,0,3,HVM), 0 , 217, 0 , 9347 , 393, 138), // #1394
- INST(Vpmovqw , VexMr_Lx , E(F30F38,34,_,x,_,0,2,QVM), 0 , 216, 0 , 9355 , 392, 138), // #1395
- INST(Vpmovsdb , VexMr_Lx , E(F30F38,21,_,x,_,0,2,QVM), 0 , 216, 0 , 9363 , 392, 138), // #1396
- INST(Vpmovsdw , VexMr_Lx , E(F30F38,23,_,x,_,0,3,HVM), 0 , 217, 0 , 9372 , 393, 138), // #1397
- INST(Vpmovsqb , VexMr_Lx , E(F30F38,22,_,x,_,0,1,OVM), 0 , 218, 0 , 9381 , 394, 138), // #1398
- INST(Vpmovsqd , VexMr_Lx , E(F30F38,25,_,x,_,0,3,HVM), 0 , 217, 0 , 9390 , 393, 138), // #1399
- INST(Vpmovsqw , VexMr_Lx , E(F30F38,24,_,x,_,0,2,QVM), 0 , 216, 0 , 9399 , 392, 138), // #1400
- INST(Vpmovswb , VexMr_Lx , E(F30F38,20,_,x,_,0,3,HVM), 0 , 217, 0 , 9408 , 393, 146), // #1401
- INST(Vpmovsxbd , VexRm_Lx , V(660F38,21,_,x,I,I,2,QVM), 0 , 219, 0 , 9417 , 395, 142), // #1402
- INST(Vpmovsxbq , VexRm_Lx , V(660F38,22,_,x,I,I,1,OVM), 0 , 220, 0 , 9427 , 396, 142), // #1403
- INST(Vpmovsxbw , VexRm_Lx , V(660F38,20,_,x,I,I,3,HVM), 0 , 139, 0 , 9437 , 397, 163), // #1404
- INST(Vpmovsxdq , VexRm_Lx , V(660F38,25,_,x,I,0,3,HVM), 0 , 139, 0 , 9447 , 397, 142), // #1405
- INST(Vpmovsxwd , VexRm_Lx , V(660F38,23,_,x,I,I,3,HVM), 0 , 139, 0 , 9457 , 397, 142), // #1406
- INST(Vpmovsxwq , VexRm_Lx , V(660F38,24,_,x,I,I,2,QVM), 0 , 219, 0 , 9467 , 395, 142), // #1407
- INST(Vpmovusdb , VexMr_Lx , E(F30F38,11,_,x,_,0,2,QVM), 0 , 216, 0 , 9477 , 392, 138), // #1408
- INST(Vpmovusdw , VexMr_Lx , E(F30F38,13,_,x,_,0,3,HVM), 0 , 217, 0 , 9487 , 393, 138), // #1409
- INST(Vpmovusqb , VexMr_Lx , E(F30F38,12,_,x,_,0,1,OVM), 0 , 218, 0 , 9497 , 394, 138), // #1410
- INST(Vpmovusqd , VexMr_Lx , E(F30F38,15,_,x,_,0,3,HVM), 0 , 217, 0 , 9507 , 393, 138), // #1411
- INST(Vpmovusqw , VexMr_Lx , E(F30F38,14,_,x,_,0,2,QVM), 0 , 216, 0 , 9517 , 392, 138), // #1412
- INST(Vpmovuswb , VexMr_Lx , E(F30F38,10,_,x,_,0,3,HVM), 0 , 217, 0 , 9527 , 393, 146), // #1413
- INST(Vpmovw2m , VexRm_Lx , E(F30F38,29,_,x,_,1,_,_ ), 0 , 205, 0 , 9537 , 391, 146), // #1414
- INST(Vpmovwb , VexMr_Lx , E(F30F38,30,_,x,_,0,3,HVM), 0 , 217, 0 , 9546 , 393, 146), // #1415
- INST(Vpmovzxbd , VexRm_Lx , V(660F38,31,_,x,I,I,2,QVM), 0 , 219, 0 , 9554 , 395, 142), // #1416
- INST(Vpmovzxbq , VexRm_Lx , V(660F38,32,_,x,I,I,1,OVM), 0 , 220, 0 , 9564 , 396, 142), // #1417
- INST(Vpmovzxbw , VexRm_Lx , V(660F38,30,_,x,I,I,3,HVM), 0 , 139, 0 , 9574 , 397, 163), // #1418
- INST(Vpmovzxdq , VexRm_Lx , V(660F38,35,_,x,I,0,3,HVM), 0 , 139, 0 , 9584 , 397, 142), // #1419
- INST(Vpmovzxwd , VexRm_Lx , V(660F38,33,_,x,I,I,3,HVM), 0 , 139, 0 , 9594 , 397, 142), // #1420
- INST(Vpmovzxwq , VexRm_Lx , V(660F38,34,_,x,I,I,2,QVM), 0 , 219, 0 , 9604 , 395, 142), // #1421
- INST(Vpmuldq , VexRvm_Lx , V(660F38,28,_,x,I,1,4,FV ), 0 , 209, 0 , 9614 , 208, 142), // #1422
- INST(Vpmulhrsw , VexRvm_Lx , V(660F38,0B,_,x,I,I,4,FVM), 0 , 110, 0 , 9622 , 315, 163), // #1423
- INST(Vpmulhuw , VexRvm_Lx , V(660F00,E4,_,x,I,I,4,FVM), 0 , 144, 0 , 9632 , 315, 163), // #1424
- INST(Vpmulhw , VexRvm_Lx , V(660F00,E5,_,x,I,I,4,FVM), 0 , 144, 0 , 9641 , 315, 163), // #1425
- INST(Vpmulld , VexRvm_Lx , V(660F38,40,_,x,I,0,4,FV ), 0 , 110, 0 , 9649 , 209, 142), // #1426
- INST(Vpmullq , VexRvm_Lx , E(660F38,40,_,x,_,1,4,FV ), 0 , 113, 0 , 9657 , 212, 140), // #1427
- INST(Vpmullw , VexRvm_Lx , V(660F00,D5,_,x,I,I,4,FVM), 0 , 144, 0 , 9665 , 315, 163), // #1428
- INST(Vpmultishiftqb , VexRvm_Lx , E(660F38,83,_,x,_,1,4,FV ), 0 , 113, 0 , 9673 , 212, 170), // #1429
- INST(Vpmuludq , VexRvm_Lx , V(660F00,F4,_,x,I,1,4,FV ), 0 , 103, 0 , 9688 , 208, 142), // #1430
- INST(Vpopcntb , VexRm_Lx , E(660F38,54,_,x,_,0,4,FV ), 0 , 114, 0 , 9697 , 279, 174), // #1431
- INST(Vpopcntd , VexRm_Lx , E(660F38,55,_,x,_,0,4,FVM), 0 , 114, 0 , 9706 , 374, 175), // #1432
- INST(Vpopcntq , VexRm_Lx , E(660F38,55,_,x,_,1,4,FVM), 0 , 113, 0 , 9715 , 350, 175), // #1433
- INST(Vpopcntw , VexRm_Lx , E(660F38,54,_,x,_,1,4,FV ), 0 , 113, 0 , 9724 , 279, 174), // #1434
- INST(Vpor , VexRvm_Lx , V(660F00,EB,_,x,I,_,_,_ ), 0 , 69 , 0 , 9733 , 351, 160), // #1435
- INST(Vpord , VexRvm_Lx , E(660F00,EB,_,x,_,0,4,FV ), 0 , 198, 0 , 9738 , 352, 138), // #1436
- INST(Vporq , VexRvm_Lx , E(660F00,EB,_,x,_,1,4,FV ), 0 , 135, 0 , 9744 , 356, 138), // #1437
- INST(Vpperm , VexRvrmRvmr , V(XOP_M8,A3,_,0,x,_,_,_ ), 0 , 208, 0 , 9750 , 398, 151), // #1438
- INST(Vprold , VexVmi_Lx , E(660F00,72,1,x,_,0,4,FV ), 0 , 221, 0 , 9757 , 399, 138), // #1439
- INST(Vprolq , VexVmi_Lx , E(660F00,72,1,x,_,1,4,FV ), 0 , 222, 0 , 9764 , 400, 138), // #1440
- INST(Vprolvd , VexRvm_Lx , E(660F38,15,_,x,_,0,4,FV ), 0 , 114, 0 , 9771 , 213, 138), // #1441
- INST(Vprolvq , VexRvm_Lx , E(660F38,15,_,x,_,1,4,FV ), 0 , 113, 0 , 9779 , 212, 138), // #1442
- INST(Vprord , VexVmi_Lx , E(660F00,72,0,x,_,0,4,FV ), 0 , 198, 0 , 9787 , 399, 138), // #1443
- INST(Vprorq , VexVmi_Lx , E(660F00,72,0,x,_,1,4,FV ), 0 , 135, 0 , 9794 , 400, 138), // #1444
- INST(Vprorvd , VexRvm_Lx , E(660F38,14,_,x,_,0,4,FV ), 0 , 114, 0 , 9801 , 213, 138), // #1445
- INST(Vprorvq , VexRvm_Lx , E(660F38,14,_,x,_,1,4,FV ), 0 , 113, 0 , 9809 , 212, 138), // #1446
- INST(Vprotb , VexRvmRmvRmi , V(XOP_M9,90,_,0,x,_,_,_ ), V(XOP_M8,C0,_,0,x,_,_,_ ), 79 , 122, 9817 , 401, 151), // #1447
- INST(Vprotd , VexRvmRmvRmi , V(XOP_M9,92,_,0,x,_,_,_ ), V(XOP_M8,C2,_,0,x,_,_,_ ), 79 , 123, 9824 , 401, 151), // #1448
- INST(Vprotq , VexRvmRmvRmi , V(XOP_M9,93,_,0,x,_,_,_ ), V(XOP_M8,C3,_,0,x,_,_,_ ), 79 , 124, 9831 , 401, 151), // #1449
- INST(Vprotw , VexRvmRmvRmi , V(XOP_M9,91,_,0,x,_,_,_ ), V(XOP_M8,C1,_,0,x,_,_,_ ), 79 , 125, 9838 , 401, 151), // #1450
- INST(Vpsadbw , VexRvm_Lx , V(660F00,F6,_,x,I,I,4,FVM), 0 , 144, 0 , 9845 , 203, 163), // #1451
- INST(Vpscatterdd , VexMr_VM , E(660F38,A0,_,x,_,0,2,T1S), 0 , 129, 0 , 9853 , 402, 138), // #1452
- INST(Vpscatterdq , VexMr_VM , E(660F38,A0,_,x,_,1,3,T1S), 0 , 128, 0 , 9865 , 403, 138), // #1453
- INST(Vpscatterqd , VexMr_VM , E(660F38,A1,_,x,_,0,2,T1S), 0 , 129, 0 , 9877 , 404, 138), // #1454
- INST(Vpscatterqq , VexMr_VM , E(660F38,A1,_,x,_,1,3,T1S), 0 , 128, 0 , 9889 , 405, 138), // #1455
- INST(Vpshab , VexRvmRmv , V(XOP_M9,98,_,0,x,_,_,_ ), 0 , 79 , 0 , 9901 , 406, 151), // #1456
- INST(Vpshad , VexRvmRmv , V(XOP_M9,9A,_,0,x,_,_,_ ), 0 , 79 , 0 , 9908 , 406, 151), // #1457
- INST(Vpshaq , VexRvmRmv , V(XOP_M9,9B,_,0,x,_,_,_ ), 0 , 79 , 0 , 9915 , 406, 151), // #1458
- INST(Vpshaw , VexRvmRmv , V(XOP_M9,99,_,0,x,_,_,_ ), 0 , 79 , 0 , 9922 , 406, 151), // #1459
- INST(Vpshlb , VexRvmRmv , V(XOP_M9,94,_,0,x,_,_,_ ), 0 , 79 , 0 , 9929 , 406, 151), // #1460
- INST(Vpshld , VexRvmRmv , V(XOP_M9,96,_,0,x,_,_,_ ), 0 , 79 , 0 , 9936 , 406, 151), // #1461
- INST(Vpshldd , VexRvmi_Lx , E(660F3A,71,_,x,_,0,4,FV ), 0 , 111, 0 , 9943 , 206, 168), // #1462
- INST(Vpshldq , VexRvmi_Lx , E(660F3A,71,_,x,_,1,4,FV ), 0 , 112, 0 , 9951 , 207, 168), // #1463
- INST(Vpshldvd , VexRvm_Lx , E(660F38,71,_,x,_,0,4,FV ), 0 , 114, 0 , 9959 , 213, 168), // #1464
- INST(Vpshldvq , VexRvm_Lx , E(660F38,71,_,x,_,1,4,FV ), 0 , 113, 0 , 9968 , 212, 168), // #1465
- INST(Vpshldvw , VexRvm_Lx , E(660F38,70,_,x,_,1,4,FVM), 0 , 113, 0 , 9977 , 357, 168), // #1466
- INST(Vpshldw , VexRvmi_Lx , E(660F3A,70,_,x,_,1,4,FVM), 0 , 112, 0 , 9986 , 275, 168), // #1467
- INST(Vpshlq , VexRvmRmv , V(XOP_M9,97,_,0,x,_,_,_ ), 0 , 79 , 0 , 9994 , 406, 151), // #1468
- INST(Vpshlw , VexRvmRmv , V(XOP_M9,95,_,0,x,_,_,_ ), 0 , 79 , 0 , 10001, 406, 151), // #1469
- INST(Vpshrdd , VexRvmi_Lx , E(660F3A,73,_,x,_,0,4,FV ), 0 , 111, 0 , 10008, 206, 168), // #1470
- INST(Vpshrdq , VexRvmi_Lx , E(660F3A,73,_,x,_,1,4,FV ), 0 , 112, 0 , 10016, 207, 168), // #1471
- INST(Vpshrdvd , VexRvm_Lx , E(660F38,73,_,x,_,0,4,FV ), 0 , 114, 0 , 10024, 213, 168), // #1472
- INST(Vpshrdvq , VexRvm_Lx , E(660F38,73,_,x,_,1,4,FV ), 0 , 113, 0 , 10033, 212, 168), // #1473
- INST(Vpshrdvw , VexRvm_Lx , E(660F38,72,_,x,_,1,4,FVM), 0 , 113, 0 , 10042, 357, 168), // #1474
- INST(Vpshrdw , VexRvmi_Lx , E(660F3A,72,_,x,_,1,4,FVM), 0 , 112, 0 , 10051, 275, 168), // #1475
- INST(Vpshufb , VexRvm_Lx , V(660F38,00,_,x,I,I,4,FVM), 0 , 110, 0 , 10059, 315, 163), // #1476
- INST(Vpshufbitqmb , VexRvm_Lx , E(660F38,8F,_,x,0,0,4,FVM), 0 , 114, 0 , 10067, 407, 174), // #1477
- INST(Vpshufd , VexRmi_Lx , V(660F00,70,_,x,I,0,4,FV ), 0 , 144, 0 , 10080, 408, 142), // #1478
- INST(Vpshufhw , VexRmi_Lx , V(F30F00,70,_,x,I,I,4,FVM), 0 , 161, 0 , 10088, 409, 163), // #1479
- INST(Vpshuflw , VexRmi_Lx , V(F20F00,70,_,x,I,I,4,FVM), 0 , 223, 0 , 10097, 409, 163), // #1480
- INST(Vpsignb , VexRvm_Lx , V(660F38,08,_,x,I,_,_,_ ), 0 , 96 , 0 , 10106, 202, 160), // #1481
- INST(Vpsignd , VexRvm_Lx , V(660F38,0A,_,x,I,_,_,_ ), 0 , 96 , 0 , 10114, 202, 160), // #1482
- INST(Vpsignw , VexRvm_Lx , V(660F38,09,_,x,I,_,_,_ ), 0 , 96 , 0 , 10122, 202, 160), // #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, 142), // #1484
- INST(Vpslldq , VexVmi_Lx_MEvex , V(660F00,73,7,x,I,I,4,FVM), 0 , 225, 0 , 10137, 411, 163), // #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, 142), // #1486
- INST(Vpsllvd , VexRvm_Lx , V(660F38,47,_,x,0,0,4,FV ), 0 , 110, 0 , 10152, 209, 152), // #1487
- INST(Vpsllvq , VexRvm_Lx , V(660F38,47,_,x,1,1,4,FV ), 0 , 182, 0 , 10160, 208, 152), // #1488
- INST(Vpsllvw , VexRvm_Lx , E(660F38,12,_,x,_,1,4,FVM), 0 , 113, 0 , 10168, 357, 146), // #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, 163), // #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, 142), // #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, 138), // #1492
- INST(Vpsravd , VexRvm_Lx , V(660F38,46,_,x,0,0,4,FV ), 0 , 110, 0 , 10197, 209, 152), // #1493
- INST(Vpsravq , VexRvm_Lx , E(660F38,46,_,x,_,1,4,FV ), 0 , 113, 0 , 10205, 212, 138), // #1494
- INST(Vpsravw , VexRvm_Lx , E(660F38,11,_,x,_,1,4,FVM), 0 , 113, 0 , 10213, 357, 146), // #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, 163), // #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, 142), // #1497
- INST(Vpsrldq , VexVmi_Lx_MEvex , V(660F00,73,3,x,I,I,4,FVM), 0 , 228, 0 , 10235, 411, 163), // #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, 142), // #1499
- INST(Vpsrlvd , VexRvm_Lx , V(660F38,45,_,x,0,0,4,FV ), 0 , 110, 0 , 10250, 209, 152), // #1500
- INST(Vpsrlvq , VexRvm_Lx , V(660F38,45,_,x,1,1,4,FV ), 0 , 182, 0 , 10258, 208, 152), // #1501
- INST(Vpsrlvw , VexRvm_Lx , E(660F38,10,_,x,_,1,4,FVM), 0 , 113, 0 , 10266, 357, 146), // #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, 163), // #1503
- INST(Vpsubb , VexRvm_Lx , V(660F00,F8,_,x,I,I,4,FVM), 0 , 144, 0 , 10281, 415, 163), // #1504
- INST(Vpsubd , VexRvm_Lx , V(660F00,FA,_,x,I,0,4,FV ), 0 , 144, 0 , 10288, 416, 142), // #1505
- INST(Vpsubq , VexRvm_Lx , V(660F00,FB,_,x,I,1,4,FV ), 0 , 103, 0 , 10295, 417, 142), // #1506
- INST(Vpsubsb , VexRvm_Lx , V(660F00,E8,_,x,I,I,4,FVM), 0 , 144, 0 , 10302, 415, 163), // #1507
- INST(Vpsubsw , VexRvm_Lx , V(660F00,E9,_,x,I,I,4,FVM), 0 , 144, 0 , 10310, 415, 163), // #1508
- INST(Vpsubusb , VexRvm_Lx , V(660F00,D8,_,x,I,I,4,FVM), 0 , 144, 0 , 10318, 415, 163), // #1509
- INST(Vpsubusw , VexRvm_Lx , V(660F00,D9,_,x,I,I,4,FVM), 0 , 144, 0 , 10327, 415, 163), // #1510
- INST(Vpsubw , VexRvm_Lx , V(660F00,F9,_,x,I,I,4,FVM), 0 , 144, 0 , 10336, 415, 163), // #1511
- INST(Vpternlogd , VexRvmi_Lx , E(660F3A,25,_,x,_,0,4,FV ), 0 , 111, 0 , 10343, 206, 138), // #1512
- INST(Vpternlogq , VexRvmi_Lx , E(660F3A,25,_,x,_,1,4,FV ), 0 , 112, 0 , 10354, 207, 138), // #1513
- INST(Vptest , VexRm_Lx , V(660F38,17,_,x,I,_,_,_ ), 0 , 96 , 0 , 10365, 298, 167), // #1514
- INST(Vptestmb , VexRvm_Lx , E(660F38,26,_,x,_,0,4,FVM), 0 , 114, 0 , 10372, 407, 146), // #1515
- INST(Vptestmd , VexRvm_Lx , E(660F38,27,_,x,_,0,4,FV ), 0 , 114, 0 , 10381, 418, 138), // #1516
- INST(Vptestmq , VexRvm_Lx , E(660F38,27,_,x,_,1,4,FV ), 0 , 113, 0 , 10390, 419, 138), // #1517
- INST(Vptestmw , VexRvm_Lx , E(660F38,26,_,x,_,1,4,FVM), 0 , 113, 0 , 10399, 407, 146), // #1518
- INST(Vptestnmb , VexRvm_Lx , E(F30F38,26,_,x,_,0,4,FVM), 0 , 132, 0 , 10408, 407, 146), // #1519
- INST(Vptestnmd , VexRvm_Lx , E(F30F38,27,_,x,_,0,4,FV ), 0 , 132, 0 , 10418, 418, 138), // #1520
- INST(Vptestnmq , VexRvm_Lx , E(F30F38,27,_,x,_,1,4,FV ), 0 , 229, 0 , 10428, 419, 138), // #1521
- INST(Vptestnmw , VexRvm_Lx , E(F30F38,26,_,x,_,1,4,FVM), 0 , 229, 0 , 10438, 407, 146), // #1522
- INST(Vpunpckhbw , VexRvm_Lx , V(660F00,68,_,x,I,I,4,FVM), 0 , 144, 0 , 10448, 315, 163), // #1523
- INST(Vpunpckhdq , VexRvm_Lx , V(660F00,6A,_,x,I,0,4,FV ), 0 , 144, 0 , 10459, 209, 142), // #1524
- INST(Vpunpckhqdq , VexRvm_Lx , V(660F00,6D,_,x,I,1,4,FV ), 0 , 103, 0 , 10470, 208, 142), // #1525
- INST(Vpunpckhwd , VexRvm_Lx , V(660F00,69,_,x,I,I,4,FVM), 0 , 144, 0 , 10482, 315, 163), // #1526
- INST(Vpunpcklbw , VexRvm_Lx , V(660F00,60,_,x,I,I,4,FVM), 0 , 144, 0 , 10493, 315, 163), // #1527
- INST(Vpunpckldq , VexRvm_Lx , V(660F00,62,_,x,I,0,4,FV ), 0 , 144, 0 , 10504, 209, 142), // #1528
- INST(Vpunpcklqdq , VexRvm_Lx , V(660F00,6C,_,x,I,1,4,FV ), 0 , 103, 0 , 10515, 208, 142), // #1529
- INST(Vpunpcklwd , VexRvm_Lx , V(660F00,61,_,x,I,I,4,FVM), 0 , 144, 0 , 10527, 315, 163), // #1530
- INST(Vpxor , VexRvm_Lx , V(660F00,EF,_,x,I,_,_,_ ), 0 , 69 , 0 , 10538, 353, 160), // #1531
- INST(Vpxord , VexRvm_Lx , E(660F00,EF,_,x,_,0,4,FV ), 0 , 198, 0 , 10544, 354, 138), // #1532
- INST(Vpxorq , VexRvm_Lx , E(660F00,EF,_,x,_,1,4,FV ), 0 , 135, 0 , 10551, 355, 138), // #1533
- INST(Vrangepd , VexRvmi_Lx , E(660F3A,50,_,x,_,1,4,FV ), 0 , 112, 0 , 10558, 285, 140), // #1534
- INST(Vrangeps , VexRvmi_Lx , E(660F3A,50,_,x,_,0,4,FV ), 0 , 111, 0 , 10567, 286, 140), // #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, 138), // #1538
- INST(Vrcp14ps , VexRm_Lx , E(660F38,4C,_,x,_,0,4,FV ), 0 , 114, 0 , 10603, 374, 138), // #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, 147), // #1542
- INST(Vrcp28ps , VexRm , E(660F38,CA,_,2,_,0,4,FV ), 0 , 171, 0 , 10639, 278, 147), // #1543
- INST(Vrcp28sd , VexRvm , E(660F38,CB,_,I,_,1,3,T1S), 0 , 128, 0 , 10648, 308, 147), // #1544
- INST(Vrcp28ss , VexRvm , E(660F38,CB,_,I,_,0,2,T1S), 0 , 129, 0 , 10657, 309, 147), // #1545
- INST(Vrcpph , VexRm_Lx , E(66MAP6,4C,_,_,_,0,4,FV ), 0 , 183, 0 , 10666, 422, 134), // #1546
- INST(Vrcpps , VexRm_Lx , V(000F00,53,_,x,I,_,_,_ ), 0 , 72 , 0 , 10673, 298, 135), // #1547
- INST(Vrcpsh , VexRvm , E(66MAP6,4D,_,_,_,0,1,T1S), 0 , 185, 0 , 10680, 423, 134), // #1548
- INST(Vrcpss , VexRvm , V(F30F00,53,_,I,I,_,_,_ ), 0 , 199, 0 , 10687, 424, 135), // #1549
- INST(Vreducepd , VexRmi_Lx , E(660F3A,56,_,x,_,1,4,FV ), 0 , 112, 0 , 10694, 400, 140), // #1550
- INST(Vreduceph , VexRmi_Lx , E(000F3A,56,_,_,_,0,4,FV ), 0 , 123, 0 , 10704, 311, 132), // #1551
- INST(Vreduceps , VexRmi_Lx , E(660F3A,56,_,x,_,0,4,FV ), 0 , 111, 0 , 10714, 399, 140), // #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, 134), // #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, 138), // #1556
- INST(Vrndscaleph , VexRmi_Lx , E(000F3A,08,_,_,_,0,4,FV ), 0 , 123, 0 , 10766, 311, 132), // #1557
- INST(Vrndscaleps , VexRmi_Lx , E(660F3A,08,_,x,_,0,4,FV ), 0 , 111, 0 , 10778, 312, 138), // #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, 134), // #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, 135), // #1562
- INST(Vroundps , VexRmi_Lx , V(660F3A,08,_,x,I,_,_,_ ), 0 , 73 , 0 , 10835, 427, 135), // #1563
- INST(Vroundsd , VexRvmi , V(660F3A,0B,_,I,I,_,_,_ ), 0 , 73 , 0 , 10844, 428, 135), // #1564
- INST(Vroundss , VexRvmi , V(660F3A,0A,_,I,I,_,_,_ ), 0 , 73 , 0 , 10853, 429, 135), // #1565
- INST(Vrsqrt14pd , VexRm_Lx , E(660F38,4E,_,x,_,1,4,FV ), 0 , 113, 0 , 10862, 350, 138), // #1566
- INST(Vrsqrt14ps , VexRm_Lx , E(660F38,4E,_,x,_,0,4,FV ), 0 , 114, 0 , 10873, 374, 138), // #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, 147), // #1570
- INST(Vrsqrt28ps , VexRm , E(660F38,CC,_,2,_,0,4,FV ), 0 , 171, 0 , 10917, 278, 147), // #1571
- INST(Vrsqrt28sd , VexRvm , E(660F38,CD,_,I,_,1,3,T1S), 0 , 128, 0 , 10928, 308, 147), // #1572
- INST(Vrsqrt28ss , VexRvm , E(660F38,CD,_,I,_,0,2,T1S), 0 , 129, 0 , 10939, 309, 147), // #1573
- INST(Vrsqrtph , VexRm_Lx , E(66MAP6,4E,_,_,_,0,4,FV ), 0 , 183, 0 , 10950, 422, 132), // #1574
- INST(Vrsqrtps , VexRm_Lx , V(000F00,52,_,x,I,_,_,_ ), 0 , 72 , 0 , 10959, 298, 135), // #1575
- INST(Vrsqrtsh , VexRvm , E(66MAP6,4F,_,_,_,0,1,T1S), 0 , 185, 0 , 10968, 423, 134), // #1576
- INST(Vrsqrtss , VexRvm , V(F30F00,52,_,I,I,_,_,_ ), 0 , 199, 0 , 10977, 424, 135), // #1577
- INST(Vscalefpd , VexRvm_Lx , E(660F38,2C,_,x,_,1,4,FV ), 0 , 113, 0 , 10986, 430, 138), // #1578
- INST(Vscalefph , VexRvm_Lx , E(66MAP6,2C,_,_,_,0,4,FV ), 0 , 183, 0 , 10996, 197, 132), // #1579
- INST(Vscalefps , VexRvm_Lx , E(660F38,2C,_,x,_,0,4,FV ), 0 , 114, 0 , 11006, 284, 138), // #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, 134), // #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, 138), // #1584
- INST(Vscatterdps , VexMr_VM , E(660F38,A2,_,x,_,0,2,T1S), 0 , 129, 0 , 11058, 402, 138), // #1585
- INST(Vscatterpf0dpd , VexM_VM , E(660F38,C6,5,2,_,1,3,T1S), 0 , 230, 0 , 11070, 303, 153), // #1586
- INST(Vscatterpf0dps , VexM_VM , E(660F38,C6,5,2,_,0,2,T1S), 0 , 231, 0 , 11085, 304, 153), // #1587
- INST(Vscatterpf0qpd , VexM_VM , E(660F38,C7,5,2,_,1,3,T1S), 0 , 230, 0 , 11100, 305, 153), // #1588
- INST(Vscatterpf0qps , VexM_VM , E(660F38,C7,5,2,_,0,2,T1S), 0 , 231, 0 , 11115, 305, 153), // #1589
- INST(Vscatterpf1dpd , VexM_VM , E(660F38,C6,6,2,_,1,3,T1S), 0 , 232, 0 , 11130, 303, 153), // #1590
- INST(Vscatterpf1dps , VexM_VM , E(660F38,C6,6,2,_,0,2,T1S), 0 , 233, 0 , 11145, 304, 153), // #1591
- INST(Vscatterpf1qpd , VexM_VM , E(660F38,C7,6,2,_,1,3,T1S), 0 , 232, 0 , 11160, 305, 153), // #1592
- INST(Vscatterpf1qps , VexM_VM , E(660F38,C7,6,2,_,0,2,T1S), 0 , 233, 0 , 11175, 305, 153), // #1593
- INST(Vscatterqpd , VexMr_VM , E(660F38,A3,_,x,_,1,3,T1S), 0 , 128, 0 , 11190, 405, 138), // #1594
- INST(Vscatterqps , VexMr_VM , E(660F38,A3,_,x,_,0,2,T1S), 0 , 129, 0 , 11202, 404, 138), // #1595
- INST(Vshuff32x4 , VexRvmi_Lx , E(660F3A,23,_,x,_,0,4,FV ), 0 , 111, 0 , 11214, 431, 138), // #1596
- INST(Vshuff64x2 , VexRvmi_Lx , E(660F3A,23,_,x,_,1,4,FV ), 0 , 112, 0 , 11225, 432, 138), // #1597
- INST(Vshufi32x4 , VexRvmi_Lx , E(660F3A,43,_,x,_,0,4,FV ), 0 , 111, 0 , 11236, 431, 138), // #1598
- INST(Vshufi64x2 , VexRvmi_Lx , E(660F3A,43,_,x,_,1,4,FV ), 0 , 112, 0 , 11247, 432, 138), // #1599
- INST(Vshufpd , VexRvmi_Lx , V(660F00,C6,_,x,I,1,4,FV ), 0 , 103, 0 , 11258, 433, 131), // #1600
- INST(Vshufps , VexRvmi_Lx , V(000F00,C6,_,x,I,0,4,FV ), 0 , 105, 0 , 11266, 434, 131), // #1601
- INST(Vsqrtpd , VexRm_Lx , V(660F00,51,_,x,I,1,4,FV ), 0 , 103, 0 , 11274, 435, 131), // #1602
- INST(Vsqrtph , VexRm_Lx , E(00MAP5,51,_,_,_,0,4,FV ), 0 , 104, 0 , 11282, 246, 132), // #1603
- INST(Vsqrtps , VexRm_Lx , V(000F00,51,_,x,I,0,4,FV ), 0 , 105, 0 , 11290, 235, 131), // #1604
- INST(Vsqrtsd , VexRvm , V(F20F00,51,_,I,I,1,3,T1S), 0 , 106, 0 , 11298, 199, 133), // #1605
- INST(Vsqrtsh , VexRvm , E(F3MAP5,51,_,_,_,0,1,T1S), 0 , 107, 0 , 11306, 200, 134), // #1606
- INST(Vsqrtss , VexRvm , V(F30F00,51,_,I,I,0,2,T1S), 0 , 108, 0 , 11314, 201, 133), // #1607
- INST(Vstmxcsr , VexM , V(000F00,AE,3,0,I,_,_,_ ), 0 , 234, 0 , 11322, 321, 135), // #1608
- INST(Vsubpd , VexRvm_Lx , V(660F00,5C,_,x,I,1,4,FV ), 0 , 103, 0 , 11331, 196, 131), // #1609
- INST(Vsubph , VexRvm_Lx , E(00MAP5,5C,_,_,_,0,4,FV ), 0 , 104, 0 , 11338, 197, 132), // #1610
- INST(Vsubps , VexRvm_Lx , V(000F00,5C,_,x,I,0,4,FV ), 0 , 105, 0 , 11345, 198, 131), // #1611
- INST(Vsubsd , VexRvm , V(F20F00,5C,_,I,I,1,3,T1S), 0 , 106, 0 , 11352, 199, 133), // #1612
- INST(Vsubsh , VexRvm , E(F3MAP5,5C,_,_,_,0,1,T1S), 0 , 107, 0 , 11359, 200, 134), // #1613
- INST(Vsubss , VexRvm , V(F30F00,5C,_,I,I,0,2,T1S), 0 , 108, 0 , 11366, 201, 133), // #1614
- INST(Vtestpd , VexRm_Lx , V(660F38,0F,_,x,0,_,_,_ ), 0 , 96 , 0 , 11373, 298, 167), // #1615
- INST(Vtestps , VexRm_Lx , V(660F38,0E,_,x,0,_,_,_ ), 0 , 96 , 0 , 11381, 298, 167), // #1616
- INST(Vucomisd , VexRm , V(660F00,2E,_,I,I,1,3,T1S), 0 , 125, 0 , 11389, 229, 143), // #1617
- INST(Vucomish , VexRm , E(00MAP5,2E,_,_,_,0,1,T1S), 0 , 126, 0 , 11398, 230, 134), // #1618
- INST(Vucomiss , VexRm , V(000F00,2E,_,I,I,0,2,T1S), 0 , 127, 0 , 11407, 231, 143), // #1619
- INST(Vunpckhpd , VexRvm_Lx , V(660F00,15,_,x,I,1,4,FV ), 0 , 103, 0 , 11416, 208, 131), // #1620
- INST(Vunpckhps , VexRvm_Lx , V(000F00,15,_,x,I,0,4,FV ), 0 , 105, 0 , 11426, 209, 131), // #1621
- INST(Vunpcklpd , VexRvm_Lx , V(660F00,14,_,x,I,1,4,FV ), 0 , 103, 0 , 11436, 208, 131), // #1622
- INST(Vunpcklps , VexRvm_Lx , V(000F00,14,_,x,I,0,4,FV ), 0 , 105, 0 , 11446, 209, 131), // #1623
- INST(Vxorpd , VexRvm_Lx , V(660F00,57,_,x,I,1,4,FV ), 0 , 103, 0 , 11456, 417, 139), // #1624
- INST(Vxorps , VexRvm_Lx , V(000F00,57,_,x,I,0,4,FV ), 0 , 105, 0 , 11463, 416, 139), // #1625
- INST(Vzeroall , VexOp , V(000F00,77,_,1,I,_,_,_ ), 0 , 68 , 0 , 11470, 436, 135), // #1626
- INST(Vzeroupper , VexOp , V(000F00,77,_,0,I,_,_,_ ), 0 , 72 , 0 , 11479, 436, 135), // #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 , 176), // #1629
- INST(Wrfsbase , X86M , O(F30F00,AE,2,_,x,_,_,_ ), 0 , 235, 0 , 11506, 173, 111), // #1630
- INST(Wrgsbase , X86M , O(F30F00,AE,3,_,x,_,_,_ ), 0 , 236, 0 , 11515, 173, 111), // #1631
- INST(Wrmsr , X86Op , O(000F00,30,_,_,_,_,_,_ ), 0 , 4 , 0 , 11524, 174, 112), // #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 , 177), // #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, 177), // #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 , 177), // #1641
- INST(Xgetbv , X86Op , O(000F01,D0,_,_,_,_,_,_ ), 0 , 21 , 0 , 11580, 174, 178), // #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 , 179), // #1647
- INST(Xrstor , X86M_Only_EDX_EAX , O(000F00,AE,5,_,_,_,_,_ ), 0 , 77 , 0 , 1164 , 442, 178), // #1648
- INST(Xrstor64 , X86M_Only_EDX_EAX , O(000F00,AE,5,_,1,_,_,_ ), 0 , 239, 0 , 1172 , 443, 178), // #1649
- INST(Xrstors , X86M_Only_EDX_EAX , O(000F00,C7,3,_,_,_,_,_ ), 0 , 78 , 0 , 11603, 442, 180), // #1650
- INST(Xrstors64 , X86M_Only_EDX_EAX , O(000F00,C7,3,_,1,_,_,_ ), 0 , 240, 0 , 11611, 443, 180), // #1651
- INST(Xsave , X86M_Only_EDX_EAX , O(000F00,AE,4,_,_,_,_,_ ), 0 , 97 , 0 , 1182 , 442, 178), // #1652
- INST(Xsave64 , X86M_Only_EDX_EAX , O(000F00,AE,4,_,1,_,_,_ ), 0 , 241, 0 , 1189 , 443, 178), // #1653
- INST(Xsavec , X86M_Only_EDX_EAX , O(000F00,C7,4,_,_,_,_,_ ), 0 , 97 , 0 , 11621, 442, 181), // #1654
- INST(Xsavec64 , X86M_Only_EDX_EAX , O(000F00,C7,4,_,1,_,_,_ ), 0 , 241, 0 , 11628, 443, 181), // #1655
- INST(Xsaveopt , X86M_Only_EDX_EAX , O(000F00,AE,6,_,_,_,_,_ ), 0 , 80 , 0 , 11637, 442, 182), // #1656
- INST(Xsaveopt64 , X86M_Only_EDX_EAX , O(000F00,AE,6,_,1,_,_,_ ), 0 , 242, 0 , 11646, 443, 182), // #1657
- INST(Xsaves , X86M_Only_EDX_EAX , O(000F00,C7,5,_,_,_,_,_ ), 0 , 77 , 0 , 11657, 442, 180), // #1658
- INST(Xsaves64 , X86M_Only_EDX_EAX , O(000F00,C7,5,_,1,_,_,_ ), 0 , 239, 0 , 11664, 443, 180), // #1659
- INST(Xsetbv , X86Op , O(000F01,D1,_,_,_,_,_,_ ), 0 , 21 , 0 , 11673, 174, 178), // #1660
- INST(Xsusldtrk , X86Op , O(F20F01,E8,_,_,_,_,_,_ ), 0 , 92 , 0 , 11680, 30 , 179), // #1661
- INST(Xtest , X86Op , O(000F01,D6,_,_,_,_,_,_ ), 0 , 21 , 0 , 11690, 30 , 183) // #1662
+ INST(None , None , 0 , 0 , 0 , 0 , 0 , 0 ), // #0
+ INST(Aaa , X86Op_xAX , O(000000,37,_,_,_,_,_,_ ), 0 , 0 , 0 , 1 , 1 ), // #1
+ INST(Aad , X86I_xAX , O(000000,D5,_,_,_,_,_,_ ), 0 , 0 , 0 , 2 , 1 ), // #2
+ INST(Aadd , X86Mr , O(000F38,FC,_,_,_,_,_,_ ), 0 , 1 , 0 , 3 , 2 ), // #3
+ INST(Aam , X86I_xAX , O(000000,D4,_,_,_,_,_,_ ), 0 , 0 , 0 , 2 , 1 ), // #4
+ INST(Aand , X86Mr , O(660F38,FC,_,_,_,_,_,_ ), 0 , 2 , 0 , 3 , 2 ), // #5
+ INST(Aas , X86Op_xAX , O(000000,3F,_,_,_,_,_,_ ), 0 , 0 , 0 , 1 , 1 ), // #6
+ INST(Adc , X86Arith , O(000000,10,2,_,x,_,_,_ ), 0 , 3 , 0 , 4 , 3 ), // #7
+ INST(Adcx , X86Rm , O(660F38,F6,_,_,x,_,_,_ ), 0 , 2 , 0 , 5 , 4 ), // #8
+ INST(Add , X86Arith , O(000000,00,0,_,x,_,_,_ ), 0 , 0 , 0 , 4 , 1 ), // #9
+ INST(Addpd , ExtRm , O(660F00,58,_,_,_,_,_,_ ), 0 , 4 , 0 , 6 , 5 ), // #10
+ INST(Addps , ExtRm , O(000F00,58,_,_,_,_,_,_ ), 0 , 5 , 0 , 6 , 6 ), // #11
+ INST(Addsd , ExtRm , O(F20F00,58,_,_,_,_,_,_ ), 0 , 6 , 0 , 7 , 5 ), // #12
+ INST(Addss , ExtRm , O(F30F00,58,_,_,_,_,_,_ ), 0 , 7 , 0 , 8 , 6 ), // #13
+ INST(Addsubpd , ExtRm , O(660F00,D0,_,_,_,_,_,_ ), 0 , 4 , 0 , 6 , 7 ), // #14
+ INST(Addsubps , ExtRm , O(F20F00,D0,_,_,_,_,_,_ ), 0 , 6 , 0 , 6 , 7 ), // #15
+ INST(Adox , X86Rm , O(F30F38,F6,_,_,x,_,_,_ ), 0 , 8 , 0 , 5 , 8 ), // #16
+ INST(Aesdec , ExtRm , O(660F38,DE,_,_,_,_,_,_ ), 0 , 2 , 0 , 6 , 9 ), // #17
+ INST(Aesdeclast , ExtRm , O(660F38,DF,_,_,_,_,_,_ ), 0 , 2 , 0 , 6 , 9 ), // #18
+ INST(Aesenc , ExtRm , O(660F38,DC,_,_,_,_,_,_ ), 0 , 2 , 0 , 6 , 9 ), // #19
+ INST(Aesenclast , ExtRm , O(660F38,DD,_,_,_,_,_,_ ), 0 , 2 , 0 , 6 , 9 ), // #20
+ INST(Aesimc , ExtRm , O(660F38,DB,_,_,_,_,_,_ ), 0 , 2 , 0 , 6 , 9 ), // #21
+ INST(Aeskeygenassist , ExtRmi , O(660F3A,DF,_,_,_,_,_,_ ), 0 , 9 , 0 , 9 , 9 ), // #22
+ INST(And , X86Arith , O(000000,20,4,_,x,_,_,_ ), 0 , 10 , 0 , 10 , 1 ), // #23
+ INST(Andn , VexRvm_Wx , V(000F38,F2,_,0,x,_,_,_ ), 0 , 11 , 0 , 11 , 10 ), // #24
+ INST(Andnpd , ExtRm , O(660F00,55,_,_,_,_,_,_ ), 0 , 4 , 0 , 6 , 5 ), // #25
+ INST(Andnps , ExtRm , O(000F00,55,_,_,_,_,_,_ ), 0 , 5 , 0 , 6 , 6 ), // #26
+ INST(Andpd , ExtRm , O(660F00,54,_,_,_,_,_,_ ), 0 , 4 , 0 , 12 , 5 ), // #27
+ INST(Andps , ExtRm , O(000F00,54,_,_,_,_,_,_ ), 0 , 5 , 0 , 12 , 6 ), // #28
+ INST(Aor , X86Mr , O(F20F38,FC,_,_,_,_,_,_ ), 0 , 12 , 0 , 3 , 2 ), // #29
+ INST(Arpl , X86Mr_NoSize , O(000000,63,_,_,_,_,_,_ ), 0 , 0 , 0 , 13 , 11 ), // #30
+ INST(Axor , X86Mr , O(F30F38,FC,_,_,_,_,_,_ ), 0 , 8 , 0 , 3 , 2 ), // #31
+ INST(Bextr , VexRmv_Wx , V(000F38,F7,_,0,x,_,_,_ ), 0 , 11 , 0 , 14 , 10 ), // #32
+ INST(Blcfill , VexVm_Wx , V(XOP_M9,01,1,0,x,_,_,_ ), 0 , 13 , 0 , 15 , 12 ), // #33
+ INST(Blci , VexVm_Wx , V(XOP_M9,02,6,0,x,_,_,_ ), 0 , 14 , 0 , 15 , 12 ), // #34
+ INST(Blcic , VexVm_Wx , V(XOP_M9,01,5,0,x,_,_,_ ), 0 , 15 , 0 , 15 , 12 ), // #35
+ INST(Blcmsk , VexVm_Wx , V(XOP_M9,02,1,0,x,_,_,_ ), 0 , 13 , 0 , 15 , 12 ), // #36
+ INST(Blcs , VexVm_Wx , V(XOP_M9,01,3,0,x,_,_,_ ), 0 , 16 , 0 , 15 , 12 ), // #37
+ INST(Blendpd , ExtRmi , O(660F3A,0D,_,_,_,_,_,_ ), 0 , 9 , 0 , 9 , 13 ), // #38
+ INST(Blendps , ExtRmi , O(660F3A,0C,_,_,_,_,_,_ ), 0 , 9 , 0 , 9 , 13 ), // #39
+ INST(Blendvpd , ExtRm_XMM0 , O(660F38,15,_,_,_,_,_,_ ), 0 , 2 , 0 , 16 , 13 ), // #40
+ INST(Blendvps , ExtRm_XMM0 , O(660F38,14,_,_,_,_,_,_ ), 0 , 2 , 0 , 16 , 13 ), // #41
+ INST(Blsfill , VexVm_Wx , V(XOP_M9,01,2,0,x,_,_,_ ), 0 , 17 , 0 , 15 , 12 ), // #42
+ INST(Blsi , VexVm_Wx , V(000F38,F3,3,0,x,_,_,_ ), 0 , 18 , 0 , 15 , 10 ), // #43
+ INST(Blsic , VexVm_Wx , V(XOP_M9,01,6,0,x,_,_,_ ), 0 , 14 , 0 , 15 , 12 ), // #44
+ INST(Blsmsk , VexVm_Wx , V(000F38,F3,2,0,x,_,_,_ ), 0 , 19 , 0 , 15 , 10 ), // #45
+ INST(Blsr , VexVm_Wx , V(000F38,F3,1,0,x,_,_,_ ), 0 , 20 , 0 , 15 , 10 ), // #46
+ INST(Bndcl , X86Rm , O(F30F00,1A,_,_,_,_,_,_ ), 0 , 7 , 0 , 17 , 14 ), // #47
+ INST(Bndcn , X86Rm , O(F20F00,1B,_,_,_,_,_,_ ), 0 , 6 , 0 , 17 , 14 ), // #48
+ INST(Bndcu , X86Rm , O(F20F00,1A,_,_,_,_,_,_ ), 0 , 6 , 0 , 17 , 14 ), // #49
+ INST(Bndldx , X86Rm , O(000F00,1A,_,_,_,_,_,_ ), 0 , 5 , 0 , 18 , 14 ), // #50
+ INST(Bndmk , X86Rm , O(F30F00,1B,_,_,_,_,_,_ ), 0 , 7 , 0 , 19 , 14 ), // #51
+ INST(Bndmov , X86Bndmov , O(660F00,1A,_,_,_,_,_,_ ), O(660F00,1B,_,_,_,_,_,_ ), 4 , 1 , 20 , 14 ), // #52
+ INST(Bndstx , X86Mr , O(000F00,1B,_,_,_,_,_,_ ), 0 , 5 , 0 , 21 , 14 ), // #53
+ INST(Bound , X86Rm , O(000000,62,_,_,_,_,_,_ ), 0 , 0 , 0 , 22 , 0 ), // #54
+ INST(Bsf , X86Rm , O(000F00,BC,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 1 ), // #55
+ INST(Bsr , X86Rm , O(000F00,BD,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 1 ), // #56
+ INST(Bswap , X86Bswap , O(000F00,C8,_,_,x,_,_,_ ), 0 , 5 , 0 , 24 , 0 ), // #57
+ INST(Bt , X86Bt , O(000F00,A3,_,_,x,_,_,_ ), O(000F00,BA,4,_,x,_,_,_ ), 5 , 2 , 25 , 15 ), // #58
+ INST(Btc , X86Bt , O(000F00,BB,_,_,x,_,_,_ ), O(000F00,BA,7,_,x,_,_,_ ), 5 , 3 , 26 , 15 ), // #59
+ INST(Btr , X86Bt , O(000F00,B3,_,_,x,_,_,_ ), O(000F00,BA,6,_,x,_,_,_ ), 5 , 4 , 26 , 15 ), // #60
+ INST(Bts , X86Bt , O(000F00,AB,_,_,x,_,_,_ ), O(000F00,BA,5,_,x,_,_,_ ), 5 , 5 , 26 , 15 ), // #61
+ INST(Bzhi , VexRmv_Wx , V(000F38,F5,_,0,x,_,_,_ ), 0 , 11 , 0 , 14 , 16 ), // #62
+ INST(Call , X86Call , O(000000,FF,2,_,_,_,_,_ ), 0 , 3 , 0 , 27 , 1 ), // #63
+ INST(Cbw , X86Op_xAX , O(660000,98,_,_,_,_,_,_ ), 0 , 21 , 0 , 28 , 0 ), // #64
+ INST(Cdq , X86Op_xDX_xAX , O(000000,99,_,_,_,_,_,_ ), 0 , 0 , 0 , 29 , 0 ), // #65
+ INST(Cdqe , X86Op_xAX , O(000000,98,_,_,1,_,_,_ ), 0 , 22 , 0 , 30 , 0 ), // #66
+ INST(Clac , X86Op , O(000F01,CA,_,_,_,_,_,_ ), 0 , 23 , 0 , 31 , 17 ), // #67
+ INST(Clc , X86Op , O(000000,F8,_,_,_,_,_,_ ), 0 , 0 , 0 , 31 , 18 ), // #68
+ INST(Cld , X86Op , O(000000,FC,_,_,_,_,_,_ ), 0 , 0 , 0 , 31 , 19 ), // #69
+ INST(Cldemote , X86M_Only , O(000F00,1C,0,_,_,_,_,_ ), 0 , 5 , 0 , 32 , 20 ), // #70
+ INST(Clflush , X86M_Only , O(000F00,AE,7,_,_,_,_,_ ), 0 , 24 , 0 , 32 , 21 ), // #71
+ INST(Clflushopt , X86M_Only , O(660F00,AE,7,_,_,_,_,_ ), 0 , 25 , 0 , 32 , 22 ), // #72
+ INST(Clgi , X86Op , O(000F01,DD,_,_,_,_,_,_ ), 0 , 23 , 0 , 31 , 23 ), // #73
+ INST(Cli , X86Op , O(000000,FA,_,_,_,_,_,_ ), 0 , 0 , 0 , 31 , 24 ), // #74
+ INST(Clrssbsy , X86M_Only , O(F30F00,AE,6,_,_,_,_,_ ), 0 , 26 , 0 , 33 , 25 ), // #75
+ INST(Clts , X86Op , O(000F00,06,_,_,_,_,_,_ ), 0 , 5 , 0 , 31 , 0 ), // #76
+ INST(Clui , X86Op , O(F30F01,EE,_,_,_,_,_,_ ), 0 , 27 , 0 , 34 , 26 ), // #77
+ INST(Clwb , X86M_Only , O(660F00,AE,6,_,_,_,_,_ ), 0 , 28 , 0 , 32 , 27 ), // #78
+ INST(Clzero , X86Op_MemZAX , O(000F01,FC,_,_,_,_,_,_ ), 0 , 23 , 0 , 35 , 28 ), // #79
+ INST(Cmc , X86Op , O(000000,F5,_,_,_,_,_,_ ), 0 , 0 , 0 , 31 , 29 ), // #80
+ INST(Cmova , X86Rm , O(000F00,47,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 30 ), // #81
+ INST(Cmovae , X86Rm , O(000F00,43,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 31 ), // #82
+ INST(Cmovb , X86Rm , O(000F00,42,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 31 ), // #83
+ INST(Cmovbe , X86Rm , O(000F00,46,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 30 ), // #84
+ INST(Cmovc , X86Rm , O(000F00,42,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 31 ), // #85
+ INST(Cmove , X86Rm , O(000F00,44,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 32 ), // #86
+ INST(Cmovg , X86Rm , O(000F00,4F,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 33 ), // #87
+ INST(Cmovge , X86Rm , O(000F00,4D,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 34 ), // #88
+ INST(Cmovl , X86Rm , O(000F00,4C,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 34 ), // #89
+ INST(Cmovle , X86Rm , O(000F00,4E,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 33 ), // #90
+ INST(Cmovna , X86Rm , O(000F00,46,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 30 ), // #91
+ INST(Cmovnae , X86Rm , O(000F00,42,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 31 ), // #92
+ INST(Cmovnb , X86Rm , O(000F00,43,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 31 ), // #93
+ INST(Cmovnbe , X86Rm , O(000F00,47,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 30 ), // #94
+ INST(Cmovnc , X86Rm , O(000F00,43,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 31 ), // #95
+ INST(Cmovne , X86Rm , O(000F00,45,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 32 ), // #96
+ INST(Cmovng , X86Rm , O(000F00,4E,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 33 ), // #97
+ INST(Cmovnge , X86Rm , O(000F00,4C,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 34 ), // #98
+ INST(Cmovnl , X86Rm , O(000F00,4D,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 34 ), // #99
+ INST(Cmovnle , X86Rm , O(000F00,4F,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 33 ), // #100
+ INST(Cmovno , X86Rm , O(000F00,41,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 35 ), // #101
+ INST(Cmovnp , X86Rm , O(000F00,4B,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 36 ), // #102
+ INST(Cmovns , X86Rm , O(000F00,49,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 37 ), // #103
+ INST(Cmovnz , X86Rm , O(000F00,45,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 32 ), // #104
+ INST(Cmovo , X86Rm , O(000F00,40,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 35 ), // #105
+ INST(Cmovp , X86Rm , O(000F00,4A,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 36 ), // #106
+ INST(Cmovpe , X86Rm , O(000F00,4A,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 36 ), // #107
+ INST(Cmovpo , X86Rm , O(000F00,4B,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 36 ), // #108
+ INST(Cmovs , X86Rm , O(000F00,48,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 37 ), // #109
+ INST(Cmovz , X86Rm , O(000F00,44,_,_,x,_,_,_ ), 0 , 5 , 0 , 23 , 32 ), // #110
+ INST(Cmp , X86Arith , O(000000,38,7,_,x,_,_,_ ), 0 , 29 , 0 , 36 , 1 ), // #111
+ INST(Cmpbexadd , VexMvr_Wx , V(660F38,E6,_,0,x,_,_,_ ), 0 , 30 , 0 , 37 , 38 ), // #112
+ INST(Cmpbxadd , VexMvr_Wx , V(660F38,E2,_,0,x,_,_,_ ), 0 , 30 , 0 , 37 , 38 ), // #113
+ INST(Cmplexadd , VexMvr_Wx , V(660F38,EE,_,0,x,_,_,_ ), 0 , 30 , 0 , 37 , 38 ), // #114
+ INST(Cmplxadd , VexMvr_Wx , V(660F38,EC,_,0,x,_,_,_ ), 0 , 30 , 0 , 37 , 38 ), // #115
+ INST(Cmpnbexadd , VexMvr_Wx , V(660F38,E7,_,0,x,_,_,_ ), 0 , 30 , 0 , 37 , 38 ), // #116
+ INST(Cmpnbxadd , VexMvr_Wx , V(660F38,E3,_,0,x,_,_,_ ), 0 , 30 , 0 , 37 , 38 ), // #117
+ INST(Cmpnlexadd , VexMvr_Wx , V(660F38,EF,_,0,x,_,_,_ ), 0 , 30 , 0 , 37 , 38 ), // #118
+ INST(Cmpnlxadd , VexMvr_Wx , V(660F38,ED,_,0,x,_,_,_ ), 0 , 30 , 0 , 37 , 38 ), // #119
+ INST(Cmpnoxadd , VexMvr_Wx , V(660F38,E1,_,0,x,_,_,_ ), 0 , 30 , 0 , 37 , 38 ), // #120
+ INST(Cmpnpxadd , VexMvr_Wx , V(660F38,EB,_,0,x,_,_,_ ), 0 , 30 , 0 , 37 , 38 ), // #121
+ INST(Cmpnsxadd , VexMvr_Wx , V(660F38,E9,_,0,x,_,_,_ ), 0 , 30 , 0 , 37 , 38 ), // #122
+ INST(Cmpnzxadd , VexMvr_Wx , V(660F38,E5,_,0,x,_,_,_ ), 0 , 30 , 0 , 37 , 38 ), // #123
+ INST(Cmpoxadd , VexMvr_Wx , V(660F38,E0,_,0,x,_,_,_ ), 0 , 30 , 0 , 37 , 38 ), // #124
+ INST(Cmppd , ExtRmi , O(660F00,C2,_,_,_,_,_,_ ), 0 , 4 , 0 , 9 , 5 ), // #125
+ INST(Cmpps , ExtRmi , O(000F00,C2,_,_,_,_,_,_ ), 0 , 5 , 0 , 9 , 6 ), // #126
+ INST(Cmppxadd , VexMvr_Wx , V(660F38,EA,_,0,x,_,_,_ ), 0 , 30 , 0 , 37 , 38 ), // #127
+ INST(Cmps , X86StrMm , O(000000,A6,_,_,_,_,_,_ ), 0 , 0 , 0 , 38 , 39 ), // #128
+ INST(Cmpsd , ExtRmi , O(F20F00,C2,_,_,_,_,_,_ ), 0 , 6 , 0 , 39 , 5 ), // #129
+ INST(Cmpss , ExtRmi , O(F30F00,C2,_,_,_,_,_,_ ), 0 , 7 , 0 , 40 , 6 ), // #130
+ INST(Cmpsxadd , VexMvr_Wx , V(660F38,E8,_,0,x,_,_,_ ), 0 , 30 , 0 , 37 , 38 ), // #131
+ INST(Cmpxchg , X86Cmpxchg , O(000F00,B0,_,_,x,_,_,_ ), 0 , 5 , 0 , 41 , 40 ), // #132
+ INST(Cmpxchg16b , X86Cmpxchg8b_16b , O(000F00,C7,1,_,1,_,_,_ ), 0 , 31 , 0 , 42 , 41 ), // #133
+ INST(Cmpxchg8b , X86Cmpxchg8b_16b , O(000F00,C7,1,_,_,_,_,_ ), 0 , 32 , 0 , 43 , 42 ), // #134
+ INST(Cmpzxadd , VexMvr_Wx , V(660F38,E4,_,0,x,_,_,_ ), 0 , 30 , 0 , 37 , 38 ), // #135
+ INST(Comisd , ExtRm , O(660F00,2F,_,_,_,_,_,_ ), 0 , 4 , 0 , 7 , 43 ), // #136
+ INST(Comiss , ExtRm , O(000F00,2F,_,_,_,_,_,_ ), 0 , 5 , 0 , 8 , 44 ), // #137
+ INST(Cpuid , X86Op , O(000F00,A2,_,_,_,_,_,_ ), 0 , 5 , 0 , 44 , 45 ), // #138
+ INST(Cqo , X86Op_xDX_xAX , O(000000,99,_,_,1,_,_,_ ), 0 , 22 , 0 , 45 , 0 ), // #139
+ INST(Crc32 , X86Crc , O(F20F38,F0,_,_,x,_,_,_ ), 0 , 12 , 0 , 46 , 46 ), // #140
+ INST(Cvtdq2pd , ExtRm , O(F30F00,E6,_,_,_,_,_,_ ), 0 , 7 , 0 , 7 , 5 ), // #141
+ INST(Cvtdq2ps , ExtRm , O(000F00,5B,_,_,_,_,_,_ ), 0 , 5 , 0 , 6 , 5 ), // #142
+ INST(Cvtpd2dq , ExtRm , O(F20F00,E6,_,_,_,_,_,_ ), 0 , 6 , 0 , 6 , 5 ), // #143
+ INST(Cvtpd2pi , ExtRm , O(660F00,2D,_,_,_,_,_,_ ), 0 , 4 , 0 , 47 , 5 ), // #144
+ INST(Cvtpd2ps , ExtRm , O(660F00,5A,_,_,_,_,_,_ ), 0 , 4 , 0 , 6 , 5 ), // #145
+ INST(Cvtpi2pd , ExtRm , O(660F00,2A,_,_,_,_,_,_ ), 0 , 4 , 0 , 48 , 5 ), // #146
+ INST(Cvtpi2ps , ExtRm , O(000F00,2A,_,_,_,_,_,_ ), 0 , 5 , 0 , 48 , 6 ), // #147
+ INST(Cvtps2dq , ExtRm , O(660F00,5B,_,_,_,_,_,_ ), 0 , 4 , 0 , 6 , 5 ), // #148
+ INST(Cvtps2pd , ExtRm , O(000F00,5A,_,_,_,_,_,_ ), 0 , 5 , 0 , 7 , 5 ), // #149
+ INST(Cvtps2pi , ExtRm , O(000F00,2D,_,_,_,_,_,_ ), 0 , 5 , 0 , 49 , 6 ), // #150
+ INST(Cvtsd2si , ExtRm_Wx_GpqOnly , O(F20F00,2D,_,_,x,_,_,_ ), 0 , 6 , 0 , 50 , 5 ), // #151
+ INST(Cvtsd2ss , ExtRm , O(F20F00,5A,_,_,_,_,_,_ ), 0 , 6 , 0 , 7 , 5 ), // #152
+ INST(Cvtsi2sd , ExtRm_Wx , O(F20F00,2A,_,_,x,_,_,_ ), 0 , 6 , 0 , 51 , 5 ), // #153
+ INST(Cvtsi2ss , ExtRm_Wx , O(F30F00,2A,_,_,x,_,_,_ ), 0 , 7 , 0 , 52 , 6 ), // #154
+ INST(Cvtss2sd , ExtRm , O(F30F00,5A,_,_,_,_,_,_ ), 0 , 7 , 0 , 8 , 5 ), // #155
+ INST(Cvtss2si , ExtRm_Wx_GpqOnly , O(F30F00,2D,_,_,x,_,_,_ ), 0 , 7 , 0 , 53 , 6 ), // #156
+ INST(Cvttpd2dq , ExtRm , O(660F00,E6,_,_,_,_,_,_ ), 0 , 4 , 0 , 6 , 5 ), // #157
+ INST(Cvttpd2pi , ExtRm , O(660F00,2C,_,_,_,_,_,_ ), 0 , 4 , 0 , 47 , 5 ), // #158
+ INST(Cvttps2dq , ExtRm , O(F30F00,5B,_,_,_,_,_,_ ), 0 , 7 , 0 , 6 , 5 ), // #159
+ INST(Cvttps2pi , ExtRm , O(000F00,2C,_,_,_,_,_,_ ), 0 , 5 , 0 , 49 , 6 ), // #160
+ INST(Cvttsd2si , ExtRm_Wx_GpqOnly , O(F20F00,2C,_,_,x,_,_,_ ), 0 , 6 , 0 , 50 , 5 ), // #161
+ INST(Cvttss2si , ExtRm_Wx_GpqOnly , O(F30F00,2C,_,_,x,_,_,_ ), 0 , 7 , 0 , 54 , 6 ), // #162
+ INST(Cwd , X86Op_xDX_xAX , O(660000,99,_,_,_,_,_,_ ), 0 , 21 , 0 , 55 , 0 ), // #163
+ INST(Cwde , X86Op_xAX , O(000000,98,_,_,_,_,_,_ ), 0 , 0 , 0 , 56 , 0 ), // #164
+ INST(Daa , X86Op , O(000000,27,_,_,_,_,_,_ ), 0 , 0 , 0 , 1 , 1 ), // #165
+ INST(Das , X86Op , O(000000,2F,_,_,_,_,_,_ ), 0 , 0 , 0 , 1 , 1 ), // #166
+ INST(Dec , X86IncDec , O(000000,FE,1,_,x,_,_,_ ), O(000000,48,_,_,x,_,_,_ ), 33 , 6 , 57 , 47 ), // #167
+ INST(Div , X86M_GPB_MulDiv , O(000000,F6,6,_,x,_,_,_ ), 0 , 34 , 0 , 58 , 1 ), // #168
+ INST(Divpd , ExtRm , O(660F00,5E,_,_,_,_,_,_ ), 0 , 4 , 0 , 6 , 5 ), // #169
+ INST(Divps , ExtRm , O(000F00,5E,_,_,_,_,_,_ ), 0 , 5 , 0 , 6 , 6 ), // #170
+ INST(Divsd , ExtRm , O(F20F00,5E,_,_,_,_,_,_ ), 0 , 6 , 0 , 7 , 5 ), // #171
+ INST(Divss , ExtRm , O(F30F00,5E,_,_,_,_,_,_ ), 0 , 7 , 0 , 8 , 6 ), // #172
+ INST(Dppd , ExtRmi , O(660F3A,41,_,_,_,_,_,_ ), 0 , 9 , 0 , 9 , 13 ), // #173
+ INST(Dpps , ExtRmi , O(660F3A,40,_,_,_,_,_,_ ), 0 , 9 , 0 , 9 , 13 ), // #174
+ INST(Emms , X86Op , O(000F00,77,_,_,_,_,_,_ ), 0 , 5 , 0 , 59 , 48 ), // #175
+ INST(Endbr32 , X86Op_Mod11RM , O(F30F00,1E,7,_,_,_,_,3 ), 0 , 35 , 0 , 31 , 49 ), // #176
+ INST(Endbr64 , X86Op_Mod11RM , O(F30F00,1E,7,_,_,_,_,2 ), 0 , 36 , 0 , 31 , 49 ), // #177
+ INST(Enqcmd , X86EnqcmdMovdir64b , O(F20F38,F8,_,_,_,_,_,_ ), 0 , 12 , 0 , 60 , 50 ), // #178
+ INST(Enqcmds , X86EnqcmdMovdir64b , O(F30F38,F8,_,_,_,_,_,_ ), 0 , 8 , 0 , 60 , 50 ), // #179
+ INST(Enter , X86Enter , O(000000,C8,_,_,_,_,_,_ ), 0 , 0 , 0 , 61 , 0 ), // #180
+ INST(Extractps , ExtExtract , O(660F3A,17,_,_,_,_,_,_ ), 0 , 9 , 0 , 62 , 13 ), // #181
+ INST(Extrq , ExtExtrq , O(660F00,79,_,_,_,_,_,_ ), O(660F00,78,0,_,_,_,_,_ ), 4 , 7 , 63 , 51 ), // #182
+ INST(F2xm1 , FpuOp , O_FPU(00,D9F0,_) , 0 , 37 , 0 , 31 , 52 ), // #183
+ INST(Fabs , FpuOp , O_FPU(00,D9E1,_) , 0 , 37 , 0 , 31 , 52 ), // #184
+ INST(Fadd , FpuArith , O_FPU(00,C0C0,0) , 0 , 38 , 0 , 64 , 52 ), // #185
+ INST(Faddp , FpuRDef , O_FPU(00,DEC0,_) , 0 , 39 , 0 , 65 , 52 ), // #186
+ INST(Fbld , X86M_Only , O_FPU(00,00DF,4) , 0 , 40 , 0 , 66 , 52 ), // #187
+ INST(Fbstp , X86M_Only , O_FPU(00,00DF,6) , 0 , 41 , 0 , 66 , 52 ), // #188
+ INST(Fchs , FpuOp , O_FPU(00,D9E0,_) , 0 , 37 , 0 , 31 , 52 ), // #189
+ INST(Fclex , FpuOp , O_FPU(9B,DBE2,_) , 0 , 42 , 0 , 31 , 52 ), // #190
+ INST(Fcmovb , FpuR , O_FPU(00,DAC0,_) , 0 , 43 , 0 , 67 , 53 ), // #191
+ INST(Fcmovbe , FpuR , O_FPU(00,DAD0,_) , 0 , 43 , 0 , 67 , 54 ), // #192
+ INST(Fcmove , FpuR , O_FPU(00,DAC8,_) , 0 , 43 , 0 , 67 , 55 ), // #193
+ INST(Fcmovnb , FpuR , O_FPU(00,DBC0,_) , 0 , 44 , 0 , 67 , 53 ), // #194
+ INST(Fcmovnbe , FpuR , O_FPU(00,DBD0,_) , 0 , 44 , 0 , 67 , 54 ), // #195
+ INST(Fcmovne , FpuR , O_FPU(00,DBC8,_) , 0 , 44 , 0 , 67 , 55 ), // #196
+ INST(Fcmovnu , FpuR , O_FPU(00,DBD8,_) , 0 , 44 , 0 , 67 , 56 ), // #197
+ INST(Fcmovu , FpuR , O_FPU(00,DAD8,_) , 0 , 43 , 0 , 67 , 56 ), // #198
+ INST(Fcom , FpuCom , O_FPU(00,D0D0,2) , 0 , 45 , 0 , 68 , 52 ), // #199
+ INST(Fcomi , FpuR , O_FPU(00,DBF0,_) , 0 , 44 , 0 , 67 , 57 ), // #200
+ INST(Fcomip , FpuR , O_FPU(00,DFF0,_) , 0 , 46 , 0 , 67 , 57 ), // #201
+ INST(Fcomp , FpuCom , O_FPU(00,D8D8,3) , 0 , 47 , 0 , 68 , 52 ), // #202
+ INST(Fcompp , FpuOp , O_FPU(00,DED9,_) , 0 , 39 , 0 , 31 , 52 ), // #203
+ INST(Fcos , FpuOp , O_FPU(00,D9FF,_) , 0 , 37 , 0 , 31 , 52 ), // #204
+ INST(Fdecstp , FpuOp , O_FPU(00,D9F6,_) , 0 , 37 , 0 , 31 , 52 ), // #205
+ INST(Fdiv , FpuArith , O_FPU(00,F0F8,6) , 0 , 48 , 0 , 64 , 52 ), // #206
+ INST(Fdivp , FpuRDef , O_FPU(00,DEF8,_) , 0 , 39 , 0 , 65 , 52 ), // #207
+ INST(Fdivr , FpuArith , O_FPU(00,F8F0,7) , 0 , 49 , 0 , 64 , 52 ), // #208
+ INST(Fdivrp , FpuRDef , O_FPU(00,DEF0,_) , 0 , 39 , 0 , 65 , 52 ), // #209
+ INST(Femms , X86Op , O(000F00,0E,_,_,_,_,_,_ ), 0 , 5 , 0 , 31 , 58 ), // #210
+ INST(Ffree , FpuR , O_FPU(00,DDC0,_) , 0 , 50 , 0 , 67 , 52 ), // #211
+ INST(Fiadd , FpuM , O_FPU(00,00DA,0) , 0 , 51 , 0 , 69 , 52 ), // #212
+ INST(Ficom , FpuM , O_FPU(00,00DA,2) , 0 , 52 , 0 , 69 , 52 ), // #213
+ INST(Ficomp , FpuM , O_FPU(00,00DA,3) , 0 , 53 , 0 , 69 , 52 ), // #214
+ INST(Fidiv , FpuM , O_FPU(00,00DA,6) , 0 , 41 , 0 , 69 , 52 ), // #215
+ INST(Fidivr , FpuM , O_FPU(00,00DA,7) , 0 , 54 , 0 , 69 , 52 ), // #216
+ INST(Fild , FpuM , O_FPU(00,00DB,0) , O_FPU(00,00DF,5) , 51 , 8 , 70 , 52 ), // #217
+ INST(Fimul , FpuM , O_FPU(00,00DA,1) , 0 , 55 , 0 , 69 , 52 ), // #218
+ INST(Fincstp , FpuOp , O_FPU(00,D9F7,_) , 0 , 37 , 0 , 31 , 52 ), // #219
+ INST(Finit , FpuOp , O_FPU(9B,DBE3,_) , 0 , 42 , 0 , 31 , 52 ), // #220
+ INST(Fist , FpuM , O_FPU(00,00DB,2) , 0 , 52 , 0 , 69 , 52 ), // #221
+ INST(Fistp , FpuM , O_FPU(00,00DB,3) , O_FPU(00,00DF,7) , 53 , 9 , 70 , 52 ), // #222
+ INST(Fisttp , FpuM , O_FPU(00,00DB,1) , O_FPU(00,00DD,1) , 55 , 10 , 70 , 59 ), // #223
+ INST(Fisub , FpuM , O_FPU(00,00DA,4) , 0 , 40 , 0 , 69 , 52 ), // #224
+ INST(Fisubr , FpuM , O_FPU(00,00DA,5) , 0 , 56 , 0 , 69 , 52 ), // #225
+ INST(Fld , FpuFldFst , O_FPU(00,00D9,0) , O_FPU(00,00DB,5) , 51 , 11 , 71 , 52 ), // #226
+ INST(Fld1 , FpuOp , O_FPU(00,D9E8,_) , 0 , 37 , 0 , 31 , 52 ), // #227
+ INST(Fldcw , X86M_Only , O_FPU(00,00D9,5) , 0 , 56 , 0 , 72 , 52 ), // #228
+ INST(Fldenv , X86M_Only , O_FPU(00,00D9,4) , 0 , 40 , 0 , 32 , 52 ), // #229
+ INST(Fldl2e , FpuOp , O_FPU(00,D9EA,_) , 0 , 37 , 0 , 31 , 52 ), // #230
+ INST(Fldl2t , FpuOp , O_FPU(00,D9E9,_) , 0 , 37 , 0 , 31 , 52 ), // #231
+ INST(Fldlg2 , FpuOp , O_FPU(00,D9EC,_) , 0 , 37 , 0 , 31 , 52 ), // #232
+ INST(Fldln2 , FpuOp , O_FPU(00,D9ED,_) , 0 , 37 , 0 , 31 , 52 ), // #233
+ INST(Fldpi , FpuOp , O_FPU(00,D9EB,_) , 0 , 37 , 0 , 31 , 52 ), // #234
+ INST(Fldz , FpuOp , O_FPU(00,D9EE,_) , 0 , 37 , 0 , 31 , 52 ), // #235
+ INST(Fmul , FpuArith , O_FPU(00,C8C8,1) , 0 , 57 , 0 , 64 , 52 ), // #236
+ INST(Fmulp , FpuRDef , O_FPU(00,DEC8,_) , 0 , 39 , 0 , 65 , 52 ), // #237
+ INST(Fnclex , FpuOp , O_FPU(00,DBE2,_) , 0 , 44 , 0 , 31 , 52 ), // #238
+ INST(Fninit , FpuOp , O_FPU(00,DBE3,_) , 0 , 44 , 0 , 31 , 52 ), // #239
+ INST(Fnop , FpuOp , O_FPU(00,D9D0,_) , 0 , 37 , 0 , 31 , 52 ), // #240
+ INST(Fnsave , X86M_Only , O_FPU(00,00DD,6) , 0 , 41 , 0 , 32 , 52 ), // #241
+ INST(Fnstcw , X86M_Only , O_FPU(00,00D9,7) , 0 , 54 , 0 , 72 , 52 ), // #242
+ INST(Fnstenv , X86M_Only , O_FPU(00,00D9,6) , 0 , 41 , 0 , 32 , 52 ), // #243
+ INST(Fnstsw , FpuStsw , O_FPU(00,00DD,7) , O_FPU(00,DFE0,_) , 54 , 12 , 73 , 52 ), // #244
+ INST(Fpatan , FpuOp , O_FPU(00,D9F3,_) , 0 , 37 , 0 , 31 , 52 ), // #245
+ INST(Fprem , FpuOp , O_FPU(00,D9F8,_) , 0 , 37 , 0 , 31 , 52 ), // #246
+ INST(Fprem1 , FpuOp , O_FPU(00,D9F5,_) , 0 , 37 , 0 , 31 , 52 ), // #247
+ INST(Fptan , FpuOp , O_FPU(00,D9F2,_) , 0 , 37 , 0 , 31 , 52 ), // #248
+ INST(Frndint , FpuOp , O_FPU(00,D9FC,_) , 0 , 37 , 0 , 31 , 52 ), // #249
+ INST(Frstor , X86M_Only , O_FPU(00,00DD,4) , 0 , 40 , 0 , 32 , 52 ), // #250
+ INST(Fsave , X86M_Only , O_FPU(9B,00DD,6) , 0 , 58 , 0 , 32 , 52 ), // #251
+ INST(Fscale , FpuOp , O_FPU(00,D9FD,_) , 0 , 37 , 0 , 31 , 52 ), // #252
+ INST(Fsin , FpuOp , O_FPU(00,D9FE,_) , 0 , 37 , 0 , 31 , 52 ), // #253
+ INST(Fsincos , FpuOp , O_FPU(00,D9FB,_) , 0 , 37 , 0 , 31 , 52 ), // #254
+ INST(Fsqrt , FpuOp , O_FPU(00,D9FA,_) , 0 , 37 , 0 , 31 , 52 ), // #255
+ INST(Fst , FpuFldFst , O_FPU(00,00D9,2) , 0 , 52 , 0 , 74 , 52 ), // #256
+ INST(Fstcw , X86M_Only , O_FPU(9B,00D9,7) , 0 , 59 , 0 , 72 , 52 ), // #257
+ INST(Fstenv , X86M_Only , O_FPU(9B,00D9,6) , 0 , 58 , 0 , 32 , 52 ), // #258
+ INST(Fstp , FpuFldFst , O_FPU(00,00D9,3) , O(000000,DB,7,_,_,_,_,_ ), 53 , 13 , 71 , 52 ), // #259
+ INST(Fstsw , FpuStsw , O_FPU(9B,00DD,7) , O_FPU(9B,DFE0,_) , 59 , 14 , 73 , 52 ), // #260
+ INST(Fsub , FpuArith , O_FPU(00,E0E8,4) , 0 , 60 , 0 , 64 , 52 ), // #261
+ INST(Fsubp , FpuRDef , O_FPU(00,DEE8,_) , 0 , 39 , 0 , 65 , 52 ), // #262
+ INST(Fsubr , FpuArith , O_FPU(00,E8E0,5) , 0 , 61 , 0 , 64 , 52 ), // #263
+ INST(Fsubrp , FpuRDef , O_FPU(00,DEE0,_) , 0 , 39 , 0 , 65 , 52 ), // #264
+ INST(Ftst , FpuOp , O_FPU(00,D9E4,_) , 0 , 37 , 0 , 31 , 52 ), // #265
+ INST(Fucom , FpuRDef , O_FPU(00,DDE0,_) , 0 , 50 , 0 , 65 , 52 ), // #266
+ INST(Fucomi , FpuR , O_FPU(00,DBE8,_) , 0 , 44 , 0 , 67 , 57 ), // #267
+ INST(Fucomip , FpuR , O_FPU(00,DFE8,_) , 0 , 46 , 0 , 67 , 57 ), // #268
+ INST(Fucomp , FpuRDef , O_FPU(00,DDE8,_) , 0 , 50 , 0 , 65 , 52 ), // #269
+ INST(Fucompp , FpuOp , O_FPU(00,DAE9,_) , 0 , 43 , 0 , 31 , 52 ), // #270
+ INST(Fwait , X86Op , O_FPU(00,009B,_) , 0 , 51 , 0 , 31 , 52 ), // #271
+ INST(Fxam , FpuOp , O_FPU(00,D9E5,_) , 0 , 37 , 0 , 31 , 52 ), // #272
+ INST(Fxch , FpuR , O_FPU(00,D9C8,_) , 0 , 37 , 0 , 65 , 52 ), // #273
+ INST(Fxrstor , X86M_Only , O(000F00,AE,1,_,_,_,_,_ ), 0 , 32 , 0 , 32 , 60 ), // #274
+ INST(Fxrstor64 , X86M_Only , O(000F00,AE,1,_,1,_,_,_ ), 0 , 31 , 0 , 75 , 60 ), // #275
+ INST(Fxsave , X86M_Only , O(000F00,AE,0,_,_,_,_,_ ), 0 , 5 , 0 , 32 , 61 ), // #276
+ INST(Fxsave64 , X86M_Only , O(000F00,AE,0,_,1,_,_,_ ), 0 , 62 , 0 , 75 , 61 ), // #277
+ INST(Fxtract , FpuOp , O_FPU(00,D9F4,_) , 0 , 37 , 0 , 31 , 52 ), // #278
+ INST(Fyl2x , FpuOp , O_FPU(00,D9F1,_) , 0 , 37 , 0 , 31 , 52 ), // #279
+ INST(Fyl2xp1 , FpuOp , O_FPU(00,D9F9,_) , 0 , 37 , 0 , 31 , 52 ), // #280
+ INST(Getsec , X86Op , O(000F00,37,_,_,_,_,_,_ ), 0 , 5 , 0 , 56 , 62 ), // #281
+ INST(Gf2p8affineinvqb , ExtRmi , O(660F3A,CF,_,_,_,_,_,_ ), 0 , 9 , 0 , 9 , 63 ), // #282
+ INST(Gf2p8affineqb , ExtRmi , O(660F3A,CE,_,_,_,_,_,_ ), 0 , 9 , 0 , 9 , 63 ), // #283
+ INST(Gf2p8mulb , ExtRm , O(660F38,CF,_,_,_,_,_,_ ), 0 , 2 , 0 , 6 , 63 ), // #284
+ INST(Haddpd , ExtRm , O(660F00,7C,_,_,_,_,_,_ ), 0 , 4 , 0 , 6 , 7 ), // #285
+ INST(Haddps , ExtRm , O(F20F00,7C,_,_,_,_,_,_ ), 0 , 6 , 0 , 6 , 7 ), // #286
+ INST(Hlt , X86Op , O(000000,F4,_,_,_,_,_,_ ), 0 , 0 , 0 , 31 , 0 ), // #287
+ INST(Hreset , X86Op_Mod11RM_I8 , O(F30F3A,F0,0,_,_,_,_,_ ), 0 , 63 , 0 , 76 , 64 ), // #288
+ INST(Hsubpd , ExtRm , O(660F00,7D,_,_,_,_,_,_ ), 0 , 4 , 0 , 6 , 7 ), // #289
+ INST(Hsubps , ExtRm , O(F20F00,7D,_,_,_,_,_,_ ), 0 , 6 , 0 , 6 , 7 ), // #290
+ INST(Idiv , X86M_GPB_MulDiv , O(000000,F6,7,_,x,_,_,_ ), 0 , 29 , 0 , 58 , 1 ), // #291
+ INST(Imul , X86Imul , O(000000,F6,5,_,x,_,_,_ ), 0 , 64 , 0 , 77 , 1 ), // #292
+ INST(In , X86In , O(000000,EC,_,_,_,_,_,_ ), O(000000,E4,_,_,_,_,_,_ ), 0 , 15 , 78 , 0 ), // #293
+ INST(Inc , X86IncDec , O(000000,FE,0,_,x,_,_,_ ), O(000000,40,_,_,x,_,_,_ ), 0 , 16 , 79 , 47 ), // #294
+ INST(Incsspd , X86M , O(F30F00,AE,5,_,0,_,_,_ ), 0 , 65 , 0 , 80 , 65 ), // #295
+ INST(Incsspq , X86M , O(F30F00,AE,5,_,1,_,_,_ ), 0 , 66 , 0 , 81 , 65 ), // #296
+ INST(Ins , X86Ins , O(000000,6C,_,_,_,_,_,_ ), 0 , 0 , 0 , 82 , 0 ), // #297
+ INST(Insertps , ExtRmi , O(660F3A,21,_,_,_,_,_,_ ), 0 , 9 , 0 , 40 , 13 ), // #298
+ INST(Insertq , ExtInsertq , O(F20F00,79,_,_,_,_,_,_ ), O(F20F00,78,_,_,_,_,_,_ ), 6 , 17 , 83 , 51 ), // #299
+ INST(Int , X86Int , O(000000,CD,_,_,_,_,_,_ ), 0 , 0 , 0 , 84 , 0 ), // #300
+ INST(Int3 , X86Op , O(000000,CC,_,_,_,_,_,_ ), 0 , 0 , 0 , 31 , 0 ), // #301
+ INST(Into , X86Op , O(000000,CE,_,_,_,_,_,_ ), 0 , 0 , 0 , 85 , 66 ), // #302
+ INST(Invd , X86Op , O(000F00,08,_,_,_,_,_,_ ), 0 , 5 , 0 , 31 , 45 ), // #303
+ INST(Invept , X86Rm_NoSize , O(660F38,80,_,_,_,_,_,_ ), 0 , 2 , 0 , 86 , 67 ), // #304
+ INST(Invlpg , X86M_Only , O(000F00,01,7,_,_,_,_,_ ), 0 , 24 , 0 , 32 , 45 ), // #305
+ INST(Invlpga , X86Op_xAddr , O(000F01,DF,_,_,_,_,_,_ ), 0 , 23 , 0 , 87 , 23 ), // #306
+ INST(Invlpgb , X86Op , O(000F01,FE,_,_,_,_,_,_ ), 0 , 23 , 0 , 88 , 68 ), // #307
+ INST(Invpcid , X86Rm_NoSize , O(660F38,82,_,_,_,_,_,_ ), 0 , 2 , 0 , 86 , 45 ), // #308
+ INST(Invvpid , X86Rm_NoSize , O(660F38,81,_,_,_,_,_,_ ), 0 , 2 , 0 , 86 , 67 ), // #309
+ INST(Iret , X86Op , O(660000,CF,_,_,_,_,_,_ ), 0 , 21 , 0 , 89 , 1 ), // #310
+ INST(Iretd , X86Op , O(000000,CF,_,_,_,_,_,_ ), 0 , 0 , 0 , 89 , 1 ), // #311
+ INST(Iretq , X86Op , O(000000,CF,_,_,1,_,_,_ ), 0 , 22 , 0 , 90 , 1 ), // #312
+ INST(Ja , X86Jcc , O(000F00,87,_,_,_,_,_,_ ), O(000000,77,_,_,_,_,_,_ ), 5 , 18 , 91 , 69 ), // #313
+ INST(Jae , X86Jcc , O(000F00,83,_,_,_,_,_,_ ), O(000000,73,_,_,_,_,_,_ ), 5 , 19 , 91 , 70 ), // #314
+ INST(Jb , X86Jcc , O(000F00,82,_,_,_,_,_,_ ), O(000000,72,_,_,_,_,_,_ ), 5 , 20 , 91 , 70 ), // #315
+ INST(Jbe , X86Jcc , O(000F00,86,_,_,_,_,_,_ ), O(000000,76,_,_,_,_,_,_ ), 5 , 21 , 91 , 69 ), // #316
+ INST(Jc , X86Jcc , O(000F00,82,_,_,_,_,_,_ ), O(000000,72,_,_,_,_,_,_ ), 5 , 20 , 91 , 70 ), // #317
+ INST(Je , X86Jcc , O(000F00,84,_,_,_,_,_,_ ), O(000000,74,_,_,_,_,_,_ ), 5 , 22 , 91 , 71 ), // #318
+ INST(Jecxz , X86JecxzLoop , 0 , O(000000,E3,_,_,_,_,_,_ ), 0 , 23 , 92 , 0 ), // #319
+ INST(Jg , X86Jcc , O(000F00,8F,_,_,_,_,_,_ ), O(000000,7F,_,_,_,_,_,_ ), 5 , 24 , 91 , 72 ), // #320
+ INST(Jge , X86Jcc , O(000F00,8D,_,_,_,_,_,_ ), O(000000,7D,_,_,_,_,_,_ ), 5 , 25 , 91 , 73 ), // #321
+ INST(Jl , X86Jcc , O(000F00,8C,_,_,_,_,_,_ ), O(000000,7C,_,_,_,_,_,_ ), 5 , 26 , 91 , 73 ), // #322
+ INST(Jle , X86Jcc , O(000F00,8E,_,_,_,_,_,_ ), O(000000,7E,_,_,_,_,_,_ ), 5 , 27 , 91 , 72 ), // #323
+ INST(Jmp , X86Jmp , O(000000,FF,4,_,_,_,_,_ ), O(000000,EB,_,_,_,_,_,_ ), 10 , 28 , 93 , 0 ), // #324
+ INST(Jna , X86Jcc , O(000F00,86,_,_,_,_,_,_ ), O(000000,76,_,_,_,_,_,_ ), 5 , 21 , 91 , 69 ), // #325
+ INST(Jnae , X86Jcc , O(000F00,82,_,_,_,_,_,_ ), O(000000,72,_,_,_,_,_,_ ), 5 , 20 , 91 , 70 ), // #326
+ INST(Jnb , X86Jcc , O(000F00,83,_,_,_,_,_,_ ), O(000000,73,_,_,_,_,_,_ ), 5 , 19 , 91 , 70 ), // #327
+ INST(Jnbe , X86Jcc , O(000F00,87,_,_,_,_,_,_ ), O(000000,77,_,_,_,_,_,_ ), 5 , 18 , 91 , 69 ), // #328
+ INST(Jnc , X86Jcc , O(000F00,83,_,_,_,_,_,_ ), O(000000,73,_,_,_,_,_,_ ), 5 , 19 , 91 , 70 ), // #329
+ INST(Jne , X86Jcc , O(000F00,85,_,_,_,_,_,_ ), O(000000,75,_,_,_,_,_,_ ), 5 , 29 , 91 , 71 ), // #330
+ INST(Jng , X86Jcc , O(000F00,8E,_,_,_,_,_,_ ), O(000000,7E,_,_,_,_,_,_ ), 5 , 27 , 91 , 72 ), // #331
+ INST(Jnge , X86Jcc , O(000F00,8C,_,_,_,_,_,_ ), O(000000,7C,_,_,_,_,_,_ ), 5 , 26 , 91 , 73 ), // #332
+ INST(Jnl , X86Jcc , O(000F00,8D,_,_,_,_,_,_ ), O(000000,7D,_,_,_,_,_,_ ), 5 , 25 , 91 , 73 ), // #333
+ INST(Jnle , X86Jcc , O(000F00,8F,_,_,_,_,_,_ ), O(000000,7F,_,_,_,_,_,_ ), 5 , 24 , 91 , 72 ), // #334
+ INST(Jno , X86Jcc , O(000F00,81,_,_,_,_,_,_ ), O(000000,71,_,_,_,_,_,_ ), 5 , 30 , 91 , 66 ), // #335
+ INST(Jnp , X86Jcc , O(000F00,8B,_,_,_,_,_,_ ), O(000000,7B,_,_,_,_,_,_ ), 5 , 31 , 91 , 74 ), // #336
+ INST(Jns , X86Jcc , O(000F00,89,_,_,_,_,_,_ ), O(000000,79,_,_,_,_,_,_ ), 5 , 32 , 91 , 75 ), // #337
+ INST(Jnz , X86Jcc , O(000F00,85,_,_,_,_,_,_ ), O(000000,75,_,_,_,_,_,_ ), 5 , 29 , 91 , 71 ), // #338
+ INST(Jo , X86Jcc , O(000F00,80,_,_,_,_,_,_ ), O(000000,70,_,_,_,_,_,_ ), 5 , 33 , 91 , 66 ), // #339
+ INST(Jp , X86Jcc , O(000F00,8A,_,_,_,_,_,_ ), O(000000,7A,_,_,_,_,_,_ ), 5 , 34 , 91 , 74 ), // #340
+ INST(Jpe , X86Jcc , O(000F00,8A,_,_,_,_,_,_ ), O(000000,7A,_,_,_,_,_,_ ), 5 , 34 , 91 , 74 ), // #341
+ INST(Jpo , X86Jcc , O(000F00,8B,_,_,_,_,_,_ ), O(000000,7B,_,_,_,_,_,_ ), 5 , 31 , 91 , 74 ), // #342
+ INST(Js , X86Jcc , O(000F00,88,_,_,_,_,_,_ ), O(000000,78,_,_,_,_,_,_ ), 5 , 35 , 91 , 75 ), // #343
+ INST(Jz , X86Jcc , O(000F00,84,_,_,_,_,_,_ ), O(000000,74,_,_,_,_,_,_ ), 5 , 22 , 91 , 71 ), // #344
+ INST(Kaddb , VexRvm , V(660F00,4A,_,1,0,_,_,_ ), 0 , 67 , 0 , 94 , 76 ), // #345
+ INST(Kaddd , VexRvm , V(660F00,4A,_,1,1,_,_,_ ), 0 , 68 , 0 , 94 , 77 ), // #346
+ INST(Kaddq , VexRvm , V(000F00,4A,_,1,1,_,_,_ ), 0 , 69 , 0 , 94 , 77 ), // #347
+ INST(Kaddw , VexRvm , V(000F00,4A,_,1,0,_,_,_ ), 0 , 70 , 0 , 94 , 76 ), // #348
+ INST(Kandb , VexRvm , V(660F00,41,_,1,0,_,_,_ ), 0 , 67 , 0 , 94 , 76 ), // #349
+ INST(Kandd , VexRvm , V(660F00,41,_,1,1,_,_,_ ), 0 , 68 , 0 , 94 , 77 ), // #350
+ INST(Kandnb , VexRvm , V(660F00,42,_,1,0,_,_,_ ), 0 , 67 , 0 , 94 , 76 ), // #351
+ INST(Kandnd , VexRvm , V(660F00,42,_,1,1,_,_,_ ), 0 , 68 , 0 , 94 , 77 ), // #352
+ INST(Kandnq , VexRvm , V(000F00,42,_,1,1,_,_,_ ), 0 , 69 , 0 , 94 , 77 ), // #353
+ INST(Kandnw , VexRvm , V(000F00,42,_,1,0,_,_,_ ), 0 , 70 , 0 , 94 , 78 ), // #354
+ INST(Kandq , VexRvm , V(000F00,41,_,1,1,_,_,_ ), 0 , 69 , 0 , 94 , 77 ), // #355
+ INST(Kandw , VexRvm , V(000F00,41,_,1,0,_,_,_ ), 0 , 70 , 0 , 94 , 78 ), // #356
+ INST(Kmovb , VexKmov , V(660F00,90,_,0,0,_,_,_ ), V(660F00,92,_,0,0,_,_,_ ), 71 , 36 , 95 , 79 ), // #357
+ INST(Kmovd , VexKmov , V(660F00,90,_,0,1,_,_,_ ), V(F20F00,92,_,0,0,_,_,_ ), 72 , 37 , 96 , 80 ), // #358
+ INST(Kmovq , VexKmov , V(000F00,90,_,0,1,_,_,_ ), V(F20F00,92,_,0,1,_,_,_ ), 73 , 38 , 97 , 80 ), // #359
+ INST(Kmovw , VexKmov , V(000F00,90,_,0,0,_,_,_ ), V(000F00,92,_,0,0,_,_,_ ), 74 , 39 , 98 , 81 ), // #360
+ INST(Knotb , VexRm , V(660F00,44,_,0,0,_,_,_ ), 0 , 71 , 0 , 99 , 76 ), // #361
+ INST(Knotd , VexRm , V(660F00,44,_,0,1,_,_,_ ), 0 , 72 , 0 , 99 , 77 ), // #362
+ INST(Knotq , VexRm , V(000F00,44,_,0,1,_,_,_ ), 0 , 73 , 0 , 99 , 77 ), // #363
+ INST(Knotw , VexRm , V(000F00,44,_,0,0,_,_,_ ), 0 , 74 , 0 , 99 , 78 ), // #364
+ INST(Korb , VexRvm , V(660F00,45,_,1,0,_,_,_ ), 0 , 67 , 0 , 94 , 76 ), // #365
+ INST(Kord , VexRvm , V(660F00,45,_,1,1,_,_,_ ), 0 , 68 , 0 , 94 , 77 ), // #366
+ INST(Korq , VexRvm , V(000F00,45,_,1,1,_,_,_ ), 0 , 69 , 0 , 94 , 77 ), // #367
+ INST(Kortestb , VexRm , V(660F00,98,_,0,0,_,_,_ ), 0 , 71 , 0 , 99 , 82 ), // #368
+ INST(Kortestd , VexRm , V(660F00,98,_,0,1,_,_,_ ), 0 , 72 , 0 , 99 , 83 ), // #369
+ INST(Kortestq , VexRm , V(000F00,98,_,0,1,_,_,_ ), 0 , 73 , 0 , 99 , 83 ), // #370
+ INST(Kortestw , VexRm , V(000F00,98,_,0,0,_,_,_ ), 0 , 74 , 0 , 99 , 84 ), // #371
+ INST(Korw , VexRvm , V(000F00,45,_,1,0,_,_,_ ), 0 , 70 , 0 , 94 , 78 ), // #372
+ INST(Kshiftlb , VexRmi , V(660F3A,32,_,0,0,_,_,_ ), 0 , 75 , 0 , 100, 76 ), // #373
+ INST(Kshiftld , VexRmi , V(660F3A,33,_,0,0,_,_,_ ), 0 , 75 , 0 , 100, 77 ), // #374
+ INST(Kshiftlq , VexRmi , V(660F3A,33,_,0,1,_,_,_ ), 0 , 76 , 0 , 100, 77 ), // #375
+ INST(Kshiftlw , VexRmi , V(660F3A,32,_,0,1,_,_,_ ), 0 , 76 , 0 , 100, 78 ), // #376
+ INST(Kshiftrb , VexRmi , V(660F3A,30,_,0,0,_,_,_ ), 0 , 75 , 0 , 100, 76 ), // #377
+ INST(Kshiftrd , VexRmi , V(660F3A,31,_,0,0,_,_,_ ), 0 , 75 , 0 , 100, 77 ), // #378
+ INST(Kshiftrq , VexRmi , V(660F3A,31,_,0,1,_,_,_ ), 0 , 76 , 0 , 100, 77 ), // #379
+ INST(Kshiftrw , VexRmi , V(660F3A,30,_,0,1,_,_,_ ), 0 , 76 , 0 , 100, 78 ), // #380
+ INST(Ktestb , VexRm , V(660F00,99,_,0,0,_,_,_ ), 0 , 71 , 0 , 99 , 82 ), // #381
+ INST(Ktestd , VexRm , V(660F00,99,_,0,1,_,_,_ ), 0 , 72 , 0 , 99 , 83 ), // #382
+ INST(Ktestq , VexRm , V(000F00,99,_,0,1,_,_,_ ), 0 , 73 , 0 , 99 , 83 ), // #383
+ INST(Ktestw , VexRm , V(000F00,99,_,0,0,_,_,_ ), 0 , 74 , 0 , 99 , 82 ), // #384
+ INST(Kunpckbw , VexRvm , V(660F00,4B,_,1,0,_,_,_ ), 0 , 67 , 0 , 94 , 78 ), // #385
+ INST(Kunpckdq , VexRvm , V(000F00,4B,_,1,1,_,_,_ ), 0 , 69 , 0 , 94 , 77 ), // #386
+ INST(Kunpckwd , VexRvm , V(000F00,4B,_,1,0,_,_,_ ), 0 , 70 , 0 , 94 , 77 ), // #387
+ INST(Kxnorb , VexRvm , V(660F00,46,_,1,0,_,_,_ ), 0 , 67 , 0 , 101, 76 ), // #388
+ INST(Kxnord , VexRvm , V(660F00,46,_,1,1,_,_,_ ), 0 , 68 , 0 , 101, 77 ), // #389
+ INST(Kxnorq , VexRvm , V(000F00,46,_,1,1,_,_,_ ), 0 , 69 , 0 , 101, 77 ), // #390
+ INST(Kxnorw , VexRvm , V(000F00,46,_,1,0,_,_,_ ), 0 , 70 , 0 , 101, 78 ), // #391
+ INST(Kxorb , VexRvm , V(660F00,47,_,1,0,_,_,_ ), 0 , 67 , 0 , 101, 76 ), // #392
+ INST(Kxord , VexRvm , V(660F00,47,_,1,1,_,_,_ ), 0 , 68 , 0 , 101, 77 ), // #393
+ INST(Kxorq , VexRvm , V(000F00,47,_,1,1,_,_,_ ), 0 , 69 , 0 , 101, 77 ), // #394
+ INST(Kxorw , VexRvm , V(000F00,47,_,1,0,_,_,_ ), 0 , 70 , 0 , 101, 78 ), // #395
+ INST(Lahf , X86Op , O(000000,9F,_,_,_,_,_,_ ), 0 , 0 , 0 , 102, 85 ), // #396
+ INST(Lar , X86Rm , O(000F00,02,_,_,_,_,_,_ ), 0 , 5 , 0 , 103, 11 ), // #397
+ INST(Lcall , X86LcallLjmp , O(000000,FF,3,_,_,_,_,_ ), O(000000,9A,_,_,_,_,_,_ ), 77 , 40 , 104, 1 ), // #398
+ INST(Lddqu , ExtRm , O(F20F00,F0,_,_,_,_,_,_ ), 0 , 6 , 0 , 105, 7 ), // #399
+ INST(Ldmxcsr , X86M_Only , O(000F00,AE,2,_,_,_,_,_ ), 0 , 78 , 0 , 106, 6 ), // #400
+ INST(Lds , X86Rm , O(000000,C5,_,_,_,_,_,_ ), 0 , 0 , 0 , 107, 0 ), // #401
+ INST(Ldtilecfg , AmxCfg , V(000F38,49,_,0,0,_,_,_ ), 0 , 11 , 0 , 108, 86 ), // #402
+ INST(Lea , X86Lea , O(000000,8D,_,_,x,_,_,_ ), 0 , 0 , 0 , 109, 0 ), // #403
+ INST(Leave , X86Op , O(000000,C9,_,_,_,_,_,_ ), 0 , 0 , 0 , 31 , 0 ), // #404
+ INST(Les , X86Rm , O(000000,C4,_,_,_,_,_,_ ), 0 , 0 , 0 , 107, 0 ), // #405
+ INST(Lfence , X86Fence , O(000F00,AE,5,_,_,_,_,_ ), 0 , 79 , 0 , 31 , 5 ), // #406
+ INST(Lfs , X86Rm , O(000F00,B4,_,_,_,_,_,_ ), 0 , 5 , 0 , 110, 0 ), // #407
+ INST(Lgdt , X86M_Only , O(000F00,01,2,_,_,_,_,_ ), 0 , 78 , 0 , 32 , 0 ), // #408
+ INST(Lgs , X86Rm , O(000F00,B5,_,_,_,_,_,_ ), 0 , 5 , 0 , 110, 0 ), // #409
+ INST(Lidt , X86M_Only , O(000F00,01,3,_,_,_,_,_ ), 0 , 80 , 0 , 32 , 0 ), // #410
+ INST(Ljmp , X86LcallLjmp , O(000000,FF,5,_,_,_,_,_ ), O(000000,EA,_,_,_,_,_,_ ), 64 , 41 , 111, 0 ), // #411
+ INST(Lldt , X86M_NoSize , O(000F00,00,2,_,_,_,_,_ ), 0 , 78 , 0 , 112, 0 ), // #412
+ INST(Llwpcb , VexR_Wx , V(XOP_M9,12,0,0,x,_,_,_ ), 0 , 81 , 0 , 113, 87 ), // #413
+ INST(Lmsw , X86M_NoSize , O(000F00,01,6,_,_,_,_,_ ), 0 , 82 , 0 , 112, 0 ), // #414
+ INST(Lods , X86StrRm , O(000000,AC,_,_,_,_,_,_ ), 0 , 0 , 0 , 114, 88 ), // #415
+ INST(Loop , X86JecxzLoop , 0 , O(000000,E2,_,_,_,_,_,_ ), 0 , 42 , 115, 0 ), // #416
+ INST(Loope , X86JecxzLoop , 0 , O(000000,E1,_,_,_,_,_,_ ), 0 , 43 , 115, 71 ), // #417
+ INST(Loopne , X86JecxzLoop , 0 , O(000000,E0,_,_,_,_,_,_ ), 0 , 44 , 115, 71 ), // #418
+ INST(Lsl , X86Rm , O(000F00,03,_,_,_,_,_,_ ), 0 , 5 , 0 , 116, 11 ), // #419
+ INST(Lss , X86Rm , O(000F00,B2,_,_,_,_,_,_ ), 0 , 5 , 0 , 110, 0 ), // #420
+ INST(Ltr , X86M_NoSize , O(000F00,00,3,_,_,_,_,_ ), 0 , 80 , 0 , 112, 0 ), // #421
+ INST(Lwpins , VexVmi4_Wx , V(XOP_MA,12,0,0,x,_,_,_ ), 0 , 83 , 0 , 117, 87 ), // #422
+ INST(Lwpval , VexVmi4_Wx , V(XOP_MA,12,1,0,x,_,_,_ ), 0 , 84 , 0 , 117, 87 ), // #423
+ INST(Lzcnt , X86Rm_Raw66H , O(F30F00,BD,_,_,x,_,_,_ ), 0 , 7 , 0 , 23 , 89 ), // #424
+ INST(Maskmovdqu , ExtRm_ZDI , O(660F00,F7,_,_,_,_,_,_ ), 0 , 4 , 0 , 118, 5 ), // #425
+ INST(Maskmovq , ExtRm_ZDI , O(000F00,F7,_,_,_,_,_,_ ), 0 , 5 , 0 , 119, 90 ), // #426
+ INST(Maxpd , ExtRm , O(660F00,5F,_,_,_,_,_,_ ), 0 , 4 , 0 , 6 , 5 ), // #427
+ INST(Maxps , ExtRm , O(000F00,5F,_,_,_,_,_,_ ), 0 , 5 , 0 , 6 , 6 ), // #428
+ INST(Maxsd , ExtRm , O(F20F00,5F,_,_,_,_,_,_ ), 0 , 6 , 0 , 7 , 5 ), // #429
+ INST(Maxss , ExtRm , O(F30F00,5F,_,_,_,_,_,_ ), 0 , 7 , 0 , 8 , 6 ), // #430
+ INST(Mcommit , X86Op , O(F30F01,FA,_,_,_,_,_,_ ), 0 , 27 , 0 , 31 , 91 ), // #431
+ INST(Mfence , X86Fence , O(000F00,AE,6,_,_,_,_,_ ), 0 , 82 , 0 , 31 , 5 ), // #432
+ INST(Minpd , ExtRm , O(660F00,5D,_,_,_,_,_,_ ), 0 , 4 , 0 , 6 , 5 ), // #433
+ INST(Minps , ExtRm , O(000F00,5D,_,_,_,_,_,_ ), 0 , 5 , 0 , 6 , 6 ), // #434
+ INST(Minsd , ExtRm , O(F20F00,5D,_,_,_,_,_,_ ), 0 , 6 , 0 , 7 , 5 ), // #435
+ INST(Minss , ExtRm , O(F30F00,5D,_,_,_,_,_,_ ), 0 , 7 , 0 , 8 , 6 ), // #436
+ INST(Monitor , X86Op , O(000F01,C8,_,_,_,_,_,_ ), 0 , 23 , 0 , 120, 92 ), // #437
+ INST(Monitorx , X86Op , O(000F01,FA,_,_,_,_,_,_ ), 0 , 23 , 0 , 120, 93 ), // #438
+ INST(Mov , X86Mov , 0 , 0 , 0 , 0 , 121, 94 ), // #439
+ INST(Movabs , X86Movabs , 0 , 0 , 0 , 0 , 122, 0 ), // #440
+ INST(Movapd , ExtMov , O(660F00,28,_,_,_,_,_,_ ), O(660F00,29,_,_,_,_,_,_ ), 4 , 45 , 123, 95 ), // #441
+ INST(Movaps , ExtMov , O(000F00,28,_,_,_,_,_,_ ), O(000F00,29,_,_,_,_,_,_ ), 5 , 46 , 123, 96 ), // #442
+ INST(Movbe , ExtMovbe , O(000F38,F0,_,_,x,_,_,_ ), O(000F38,F1,_,_,x,_,_,_ ), 1 , 47 , 124, 97 ), // #443
+ INST(Movd , ExtMovd , O(000F00,6E,_,_,_,_,_,_ ), O(000F00,7E,_,_,_,_,_,_ ), 5 , 48 , 125, 98 ), // #444
+ INST(Movddup , ExtMov , O(F20F00,12,_,_,_,_,_,_ ), 0 , 6 , 0 , 7 , 7 ), // #445
+ INST(Movdir64b , X86EnqcmdMovdir64b , O(660F38,F8,_,_,_,_,_,_ ), 0 , 2 , 0 , 126, 99 ), // #446
+ INST(Movdiri , X86MovntiMovdiri , O(000F38,F9,_,_,_,_,_,_ ), 0 , 1 , 0 , 3 , 100), // #447
+ INST(Movdq2q , ExtMov , O(F20F00,D6,_,_,_,_,_,_ ), 0 , 6 , 0 , 127, 5 ), // #448
+ INST(Movdqa , ExtMov , O(660F00,6F,_,_,_,_,_,_ ), O(660F00,7F,_,_,_,_,_,_ ), 4 , 49 , 123, 95 ), // #449
+ INST(Movdqu , ExtMov , O(F30F00,6F,_,_,_,_,_,_ ), O(F30F00,7F,_,_,_,_,_,_ ), 7 , 50 , 123, 95 ), // #450
+ INST(Movhlps , ExtMov , O(000F00,12,_,_,_,_,_,_ ), 0 , 5 , 0 , 128, 6 ), // #451
+ INST(Movhpd , ExtMov , O(660F00,16,_,_,_,_,_,_ ), O(660F00,17,_,_,_,_,_,_ ), 4 , 51 , 129, 5 ), // #452
+ INST(Movhps , ExtMov , O(000F00,16,_,_,_,_,_,_ ), O(000F00,17,_,_,_,_,_,_ ), 5 , 52 , 129, 6 ), // #453
+ INST(Movlhps , ExtMov , O(000F00,16,_,_,_,_,_,_ ), 0 , 5 , 0 , 128, 6 ), // #454
+ INST(Movlpd , ExtMov , O(660F00,12,_,_,_,_,_,_ ), O(660F00,13,_,_,_,_,_,_ ), 4 , 53 , 129, 5 ), // #455
+ INST(Movlps , ExtMov , O(000F00,12,_,_,_,_,_,_ ), O(000F00,13,_,_,_,_,_,_ ), 5 , 54 , 129, 6 ), // #456
+ INST(Movmskpd , ExtMov , O(660F00,50,_,_,_,_,_,_ ), 0 , 4 , 0 , 130, 5 ), // #457
+ INST(Movmskps , ExtMov , O(000F00,50,_,_,_,_,_,_ ), 0 , 5 , 0 , 130, 6 ), // #458
+ INST(Movntdq , ExtMov , 0 , O(660F00,E7,_,_,_,_,_,_ ), 0 , 55 , 131, 5 ), // #459
+ INST(Movntdqa , ExtMov , O(660F38,2A,_,_,_,_,_,_ ), 0 , 2 , 0 , 105, 13 ), // #460
+ INST(Movnti , X86MovntiMovdiri , O(000F00,C3,_,_,x,_,_,_ ), 0 , 5 , 0 , 3 , 5 ), // #461
+ INST(Movntpd , ExtMov , 0 , O(660F00,2B,_,_,_,_,_,_ ), 0 , 56 , 131, 5 ), // #462
+ INST(Movntps , ExtMov , 0 , O(000F00,2B,_,_,_,_,_,_ ), 0 , 57 , 131, 6 ), // #463
+ INST(Movntq , ExtMov , 0 , O(000F00,E7,_,_,_,_,_,_ ), 0 , 58 , 132, 90 ), // #464
+ INST(Movntsd , ExtMov , 0 , O(F20F00,2B,_,_,_,_,_,_ ), 0 , 59 , 133, 51 ), // #465
+ INST(Movntss , ExtMov , 0 , O(F30F00,2B,_,_,_,_,_,_ ), 0 , 60 , 134, 51 ), // #466
+ INST(Movq , ExtMovq , O(000F00,6E,_,_,x,_,_,_ ), O(000F00,7E,_,_,x,_,_,_ ), 5 , 48 , 135, 101), // #467
+ INST(Movq2dq , ExtRm , O(F30F00,D6,_,_,_,_,_,_ ), 0 , 7 , 0 , 136, 5 ), // #468
+ INST(Movs , X86StrMm , O(000000,A4,_,_,_,_,_,_ ), 0 , 0 , 0 , 137, 88 ), // #469
+ INST(Movsd , ExtMov , O(F20F00,10,_,_,_,_,_,_ ), O(F20F00,11,_,_,_,_,_,_ ), 6 , 61 , 138, 95 ), // #470
+ INST(Movshdup , ExtRm , O(F30F00,16,_,_,_,_,_,_ ), 0 , 7 , 0 , 6 , 7 ), // #471
+ INST(Movsldup , ExtRm , O(F30F00,12,_,_,_,_,_,_ ), 0 , 7 , 0 , 6 , 7 ), // #472
+ INST(Movss , ExtMov , O(F30F00,10,_,_,_,_,_,_ ), O(F30F00,11,_,_,_,_,_,_ ), 7 , 62 , 139, 96 ), // #473
+ INST(Movsx , X86MovsxMovzx , O(000F00,BE,_,_,x,_,_,_ ), 0 , 5 , 0 , 140, 0 ), // #474
+ INST(Movsxd , X86Rm , O(000000,63,_,_,x,_,_,_ ), 0 , 0 , 0 , 141, 0 ), // #475
+ INST(Movupd , ExtMov , O(660F00,10,_,_,_,_,_,_ ), O(660F00,11,_,_,_,_,_,_ ), 4 , 63 , 123, 95 ), // #476
+ INST(Movups , ExtMov , O(000F00,10,_,_,_,_,_,_ ), O(000F00,11,_,_,_,_,_,_ ), 5 , 64 , 123, 96 ), // #477
+ INST(Movzx , X86MovsxMovzx , O(000F00,B6,_,_,x,_,_,_ ), 0 , 5 , 0 , 140, 0 ), // #478
+ INST(Mpsadbw , ExtRmi , O(660F3A,42,_,_,_,_,_,_ ), 0 , 9 , 0 , 9 , 13 ), // #479
+ INST(Mul , X86M_GPB_MulDiv , O(000000,F6,4,_,x,_,_,_ ), 0 , 10 , 0 , 58 , 1 ), // #480
+ INST(Mulpd , ExtRm , O(660F00,59,_,_,_,_,_,_ ), 0 , 4 , 0 , 6 , 5 ), // #481
+ INST(Mulps , ExtRm , O(000F00,59,_,_,_,_,_,_ ), 0 , 5 , 0 , 6 , 6 ), // #482
+ INST(Mulsd , ExtRm , O(F20F00,59,_,_,_,_,_,_ ), 0 , 6 , 0 , 7 , 5 ), // #483
+ INST(Mulss , ExtRm , O(F30F00,59,_,_,_,_,_,_ ), 0 , 7 , 0 , 8 , 6 ), // #484
+ INST(Mulx , VexRvm_ZDX_Wx , V(F20F38,F6,_,0,x,_,_,_ ), 0 , 85 , 0 , 142, 102), // #485
+ INST(Mwait , X86Op , O(000F01,C9,_,_,_,_,_,_ ), 0 , 23 , 0 , 143, 92 ), // #486
+ INST(Mwaitx , X86Op , O(000F01,FB,_,_,_,_,_,_ ), 0 , 23 , 0 , 144, 93 ), // #487
+ INST(Neg , X86M_GPB , O(000000,F6,3,_,x,_,_,_ ), 0 , 77 , 0 , 145, 1 ), // #488
+ INST(Nop , X86M_Nop , O(000000,90,_,_,_,_,_,_ ), 0 , 0 , 0 , 146, 0 ), // #489
+ INST(Not , X86M_GPB , O(000000,F6,2,_,x,_,_,_ ), 0 , 3 , 0 , 145, 0 ), // #490
+ INST(Or , X86Arith , O(000000,08,1,_,x,_,_,_ ), 0 , 33 , 0 , 147, 1 ), // #491
+ INST(Orpd , ExtRm , O(660F00,56,_,_,_,_,_,_ ), 0 , 4 , 0 , 12 , 5 ), // #492
+ INST(Orps , ExtRm , O(000F00,56,_,_,_,_,_,_ ), 0 , 5 , 0 , 12 , 6 ), // #493
+ INST(Out , X86Out , O(000000,EE,_,_,_,_,_,_ ), O(000000,E6,_,_,_,_,_,_ ), 0 , 65 , 148, 0 ), // #494
+ INST(Outs , X86Outs , O(000000,6E,_,_,_,_,_,_ ), 0 , 0 , 0 , 149, 0 ), // #495
+ INST(Pabsb , ExtRm_P , O(000F38,1C,_,_,_,_,_,_ ), 0 , 1 , 0 , 150, 103), // #496
+ INST(Pabsd , ExtRm_P , O(000F38,1E,_,_,_,_,_,_ ), 0 , 1 , 0 , 150, 103), // #497
+ INST(Pabsw , ExtRm_P , O(000F38,1D,_,_,_,_,_,_ ), 0 , 1 , 0 , 150, 103), // #498
+ INST(Packssdw , ExtRm_P , O(000F00,6B,_,_,_,_,_,_ ), 0 , 5 , 0 , 150, 98 ), // #499
+ INST(Packsswb , ExtRm_P , O(000F00,63,_,_,_,_,_,_ ), 0 , 5 , 0 , 150, 98 ), // #500
+ INST(Packusdw , ExtRm , O(660F38,2B,_,_,_,_,_,_ ), 0 , 2 , 0 , 6 , 13 ), // #501
+ INST(Packuswb , ExtRm_P , O(000F00,67,_,_,_,_,_,_ ), 0 , 5 , 0 , 150, 98 ), // #502
+ INST(Paddb , ExtRm_P , O(000F00,FC,_,_,_,_,_,_ ), 0 , 5 , 0 , 150, 98 ), // #503
+ INST(Paddd , ExtRm_P , O(000F00,FE,_,_,_,_,_,_ ), 0 , 5 , 0 , 150, 98 ), // #504
+ INST(Paddq , ExtRm_P , O(000F00,D4,_,_,_,_,_,_ ), 0 , 5 , 0 , 150, 5 ), // #505
+ INST(Paddsb , ExtRm_P , O(000F00,EC,_,_,_,_,_,_ ), 0 , 5 , 0 , 150, 98 ), // #506
+ INST(Paddsw , ExtRm_P , O(000F00,ED,_,_,_,_,_,_ ), 0 , 5 , 0 , 150, 98 ), // #507
+ INST(Paddusb , ExtRm_P , O(000F00,DC,_,_,_,_,_,_ ), 0 , 5 , 0 , 150, 98 ), // #508
+ INST(Paddusw , ExtRm_P , O(000F00,DD,_,_,_,_,_,_ ), 0 , 5 , 0 , 150, 98 ), // #509
+ INST(Paddw , ExtRm_P , O(000F00,FD,_,_,_,_,_,_ ), 0 , 5 , 0 , 150, 98 ), // #510
+ INST(Palignr , ExtRmi_P , O(000F3A,0F,_,_,_,_,_,_ ), 0 , 86 , 0 , 151, 103), // #511
+ INST(Pand , ExtRm_P , O(000F00,DB,_,_,_,_,_,_ ), 0 , 5 , 0 , 152, 98 ), // #512
+ INST(Pandn , ExtRm_P , O(000F00,DF,_,_,_,_,_,_ ), 0 , 5 , 0 , 153, 98 ), // #513
+ INST(Pause , X86Op , O(F30000,90,_,_,_,_,_,_ ), 0 , 87 , 0 , 31 , 0 ), // #514
+ INST(Pavgb , ExtRm_P , O(000F00,E0,_,_,_,_,_,_ ), 0 , 5 , 0 , 150, 104), // #515
+ INST(Pavgusb , Ext3dNow , O(000F0F,BF,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 58 ), // #516
+ INST(Pavgw , ExtRm_P , O(000F00,E3,_,_,_,_,_,_ ), 0 , 5 , 0 , 150, 104), // #517
+ INST(Pblendvb , ExtRm_XMM0 , O(660F38,10,_,_,_,_,_,_ ), 0 , 2 , 0 , 16 , 13 ), // #518
+ INST(Pblendw , ExtRmi , O(660F3A,0E,_,_,_,_,_,_ ), 0 , 9 , 0 , 9 , 13 ), // #519
+ INST(Pclmulqdq , ExtRmi , O(660F3A,44,_,_,_,_,_,_ ), 0 , 9 , 0 , 9 , 105), // #520
+ INST(Pcmpeqb , ExtRm_P , O(000F00,74,_,_,_,_,_,_ ), 0 , 5 , 0 , 153, 98 ), // #521
+ INST(Pcmpeqd , ExtRm_P , O(000F00,76,_,_,_,_,_,_ ), 0 , 5 , 0 , 153, 98 ), // #522
+ INST(Pcmpeqq , ExtRm , O(660F38,29,_,_,_,_,_,_ ), 0 , 2 , 0 , 155, 13 ), // #523
+ INST(Pcmpeqw , ExtRm_P , O(000F00,75,_,_,_,_,_,_ ), 0 , 5 , 0 , 153, 98 ), // #524
+ INST(Pcmpestri , ExtRmi , O(660F3A,61,_,_,_,_,_,_ ), 0 , 9 , 0 , 156, 106), // #525
+ INST(Pcmpestrm , ExtRmi , O(660F3A,60,_,_,_,_,_,_ ), 0 , 9 , 0 , 157, 106), // #526
+ INST(Pcmpgtb , ExtRm_P , O(000F00,64,_,_,_,_,_,_ ), 0 , 5 , 0 , 153, 98 ), // #527
+ INST(Pcmpgtd , ExtRm_P , O(000F00,66,_,_,_,_,_,_ ), 0 , 5 , 0 , 153, 98 ), // #528
+ INST(Pcmpgtq , ExtRm , O(660F38,37,_,_,_,_,_,_ ), 0 , 2 , 0 , 155, 46 ), // #529
+ INST(Pcmpgtw , ExtRm_P , O(000F00,65,_,_,_,_,_,_ ), 0 , 5 , 0 , 153, 98 ), // #530
+ INST(Pcmpistri , ExtRmi , O(660F3A,63,_,_,_,_,_,_ ), 0 , 9 , 0 , 158, 106), // #531
+ INST(Pcmpistrm , ExtRmi , O(660F3A,62,_,_,_,_,_,_ ), 0 , 9 , 0 , 159, 106), // #532
+ INST(Pconfig , X86Op , O(000F01,C5,_,_,_,_,_,_ ), 0 , 23 , 0 , 31 , 107), // #533
+ INST(Pdep , VexRvm_Wx , V(F20F38,F5,_,0,x,_,_,_ ), 0 , 85 , 0 , 11 , 102), // #534
+ INST(Pext , VexRvm_Wx , V(F30F38,F5,_,0,x,_,_,_ ), 0 , 89 , 0 , 11 , 102), // #535
+ INST(Pextrb , ExtExtract , O(000F3A,14,_,_,_,_,_,_ ), 0 , 86 , 0 , 160, 13 ), // #536
+ INST(Pextrd , ExtExtract , O(000F3A,16,_,_,_,_,_,_ ), 0 , 86 , 0 , 62 , 13 ), // #537
+ INST(Pextrq , ExtExtract , O(000F3A,16,_,_,1,_,_,_ ), 0 , 90 , 0 , 161, 13 ), // #538
+ INST(Pextrw , ExtPextrw , O(000F00,C5,_,_,_,_,_,_ ), O(000F3A,15,_,_,_,_,_,_ ), 5 , 66 , 162, 108), // #539
+ INST(Pf2id , Ext3dNow , O(000F0F,1D,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 58 ), // #540
+ INST(Pf2iw , Ext3dNow , O(000F0F,1C,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 109), // #541
+ INST(Pfacc , Ext3dNow , O(000F0F,AE,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 58 ), // #542
+ INST(Pfadd , Ext3dNow , O(000F0F,9E,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 58 ), // #543
+ INST(Pfcmpeq , Ext3dNow , O(000F0F,B0,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 58 ), // #544
+ INST(Pfcmpge , Ext3dNow , O(000F0F,90,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 58 ), // #545
+ INST(Pfcmpgt , Ext3dNow , O(000F0F,A0,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 58 ), // #546
+ INST(Pfmax , Ext3dNow , O(000F0F,A4,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 58 ), // #547
+ INST(Pfmin , Ext3dNow , O(000F0F,94,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 58 ), // #548
+ INST(Pfmul , Ext3dNow , O(000F0F,B4,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 58 ), // #549
+ INST(Pfnacc , Ext3dNow , O(000F0F,8A,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 109), // #550
+ INST(Pfpnacc , Ext3dNow , O(000F0F,8E,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 109), // #551
+ INST(Pfrcp , Ext3dNow , O(000F0F,96,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 58 ), // #552
+ INST(Pfrcpit1 , Ext3dNow , O(000F0F,A6,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 58 ), // #553
+ INST(Pfrcpit2 , Ext3dNow , O(000F0F,B6,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 58 ), // #554
+ INST(Pfrcpv , Ext3dNow , O(000F0F,86,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 110), // #555
+ INST(Pfrsqit1 , Ext3dNow , O(000F0F,A7,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 58 ), // #556
+ INST(Pfrsqrt , Ext3dNow , O(000F0F,97,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 58 ), // #557
+ INST(Pfrsqrtv , Ext3dNow , O(000F0F,87,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 110), // #558
+ INST(Pfsub , Ext3dNow , O(000F0F,9A,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 58 ), // #559
+ INST(Pfsubr , Ext3dNow , O(000F0F,AA,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 58 ), // #560
+ INST(Phaddd , ExtRm_P , O(000F38,02,_,_,_,_,_,_ ), 0 , 1 , 0 , 150, 103), // #561
+ INST(Phaddsw , ExtRm_P , O(000F38,03,_,_,_,_,_,_ ), 0 , 1 , 0 , 150, 103), // #562
+ INST(Phaddw , ExtRm_P , O(000F38,01,_,_,_,_,_,_ ), 0 , 1 , 0 , 150, 103), // #563
+ INST(Phminposuw , ExtRm , O(660F38,41,_,_,_,_,_,_ ), 0 , 2 , 0 , 6 , 13 ), // #564
+ INST(Phsubd , ExtRm_P , O(000F38,06,_,_,_,_,_,_ ), 0 , 1 , 0 , 150, 103), // #565
+ INST(Phsubsw , ExtRm_P , O(000F38,07,_,_,_,_,_,_ ), 0 , 1 , 0 , 150, 103), // #566
+ INST(Phsubw , ExtRm_P , O(000F38,05,_,_,_,_,_,_ ), 0 , 1 , 0 , 150, 103), // #567
+ INST(Pi2fd , Ext3dNow , O(000F0F,0D,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 58 ), // #568
+ INST(Pi2fw , Ext3dNow , O(000F0F,0C,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 109), // #569
+ INST(Pinsrb , ExtRmi , O(660F3A,20,_,_,_,_,_,_ ), 0 , 9 , 0 , 163, 13 ), // #570
+ INST(Pinsrd , ExtRmi , O(660F3A,22,_,_,_,_,_,_ ), 0 , 9 , 0 , 164, 13 ), // #571
+ INST(Pinsrq , ExtRmi , O(660F3A,22,_,_,1,_,_,_ ), 0 , 91 , 0 , 165, 13 ), // #572
+ INST(Pinsrw , ExtRmi_P , O(000F00,C4,_,_,_,_,_,_ ), 0 , 5 , 0 , 166, 104), // #573
+ INST(Pmaddubsw , ExtRm_P , O(000F38,04,_,_,_,_,_,_ ), 0 , 1 , 0 , 150, 103), // #574
+ INST(Pmaddwd , ExtRm_P , O(000F00,F5,_,_,_,_,_,_ ), 0 , 5 , 0 , 150, 98 ), // #575
+ INST(Pmaxsb , ExtRm , O(660F38,3C,_,_,_,_,_,_ ), 0 , 2 , 0 , 12 , 13 ), // #576
+ INST(Pmaxsd , ExtRm , O(660F38,3D,_,_,_,_,_,_ ), 0 , 2 , 0 , 12 , 13 ), // #577
+ INST(Pmaxsw , ExtRm_P , O(000F00,EE,_,_,_,_,_,_ ), 0 , 5 , 0 , 152, 104), // #578
+ INST(Pmaxub , ExtRm_P , O(000F00,DE,_,_,_,_,_,_ ), 0 , 5 , 0 , 152, 104), // #579
+ INST(Pmaxud , ExtRm , O(660F38,3F,_,_,_,_,_,_ ), 0 , 2 , 0 , 12 , 13 ), // #580
+ INST(Pmaxuw , ExtRm , O(660F38,3E,_,_,_,_,_,_ ), 0 , 2 , 0 , 12 , 13 ), // #581
+ INST(Pminsb , ExtRm , O(660F38,38,_,_,_,_,_,_ ), 0 , 2 , 0 , 12 , 13 ), // #582
+ INST(Pminsd , ExtRm , O(660F38,39,_,_,_,_,_,_ ), 0 , 2 , 0 , 12 , 13 ), // #583
+ INST(Pminsw , ExtRm_P , O(000F00,EA,_,_,_,_,_,_ ), 0 , 5 , 0 , 152, 104), // #584
+ INST(Pminub , ExtRm_P , O(000F00,DA,_,_,_,_,_,_ ), 0 , 5 , 0 , 152, 104), // #585
+ INST(Pminud , ExtRm , O(660F38,3B,_,_,_,_,_,_ ), 0 , 2 , 0 , 12 , 13 ), // #586
+ INST(Pminuw , ExtRm , O(660F38,3A,_,_,_,_,_,_ ), 0 , 2 , 0 , 12 , 13 ), // #587
+ INST(Pmovmskb , ExtRm_P , O(000F00,D7,_,_,_,_,_,_ ), 0 , 5 , 0 , 167, 104), // #588
+ INST(Pmovsxbd , ExtRm , O(660F38,21,_,_,_,_,_,_ ), 0 , 2 , 0 , 8 , 13 ), // #589
+ INST(Pmovsxbq , ExtRm , O(660F38,22,_,_,_,_,_,_ ), 0 , 2 , 0 , 168, 13 ), // #590
+ INST(Pmovsxbw , ExtRm , O(660F38,20,_,_,_,_,_,_ ), 0 , 2 , 0 , 7 , 13 ), // #591
+ INST(Pmovsxdq , ExtRm , O(660F38,25,_,_,_,_,_,_ ), 0 , 2 , 0 , 7 , 13 ), // #592
+ INST(Pmovsxwd , ExtRm , O(660F38,23,_,_,_,_,_,_ ), 0 , 2 , 0 , 7 , 13 ), // #593
+ INST(Pmovsxwq , ExtRm , O(660F38,24,_,_,_,_,_,_ ), 0 , 2 , 0 , 8 , 13 ), // #594
+ INST(Pmovzxbd , ExtRm , O(660F38,31,_,_,_,_,_,_ ), 0 , 2 , 0 , 8 , 13 ), // #595
+ INST(Pmovzxbq , ExtRm , O(660F38,32,_,_,_,_,_,_ ), 0 , 2 , 0 , 168, 13 ), // #596
+ INST(Pmovzxbw , ExtRm , O(660F38,30,_,_,_,_,_,_ ), 0 , 2 , 0 , 7 , 13 ), // #597
+ INST(Pmovzxdq , ExtRm , O(660F38,35,_,_,_,_,_,_ ), 0 , 2 , 0 , 7 , 13 ), // #598
+ INST(Pmovzxwd , ExtRm , O(660F38,33,_,_,_,_,_,_ ), 0 , 2 , 0 , 7 , 13 ), // #599
+ INST(Pmovzxwq , ExtRm , O(660F38,34,_,_,_,_,_,_ ), 0 , 2 , 0 , 8 , 13 ), // #600
+ INST(Pmuldq , ExtRm , O(660F38,28,_,_,_,_,_,_ ), 0 , 2 , 0 , 6 , 13 ), // #601
+ INST(Pmulhrsw , ExtRm_P , O(000F38,0B,_,_,_,_,_,_ ), 0 , 1 , 0 , 150, 103), // #602
+ INST(Pmulhrw , Ext3dNow , O(000F0F,B7,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 58 ), // #603
+ INST(Pmulhuw , ExtRm_P , O(000F00,E4,_,_,_,_,_,_ ), 0 , 5 , 0 , 150, 104), // #604
+ INST(Pmulhw , ExtRm_P , O(000F00,E5,_,_,_,_,_,_ ), 0 , 5 , 0 , 150, 98 ), // #605
+ INST(Pmulld , ExtRm , O(660F38,40,_,_,_,_,_,_ ), 0 , 2 , 0 , 6 , 13 ), // #606
+ INST(Pmullw , ExtRm_P , O(000F00,D5,_,_,_,_,_,_ ), 0 , 5 , 0 , 150, 98 ), // #607
+ INST(Pmuludq , ExtRm_P , O(000F00,F4,_,_,_,_,_,_ ), 0 , 5 , 0 , 150, 5 ), // #608
+ INST(Pop , X86Pop , O(000000,8F,0,_,_,_,_,_ ), O(000000,58,_,_,_,_,_,_ ), 0 , 67 , 169, 0 ), // #609
+ INST(Popa , X86Op , O(660000,61,_,_,_,_,_,_ ), 0 , 21 , 0 , 85 , 0 ), // #610
+ INST(Popad , X86Op , O(000000,61,_,_,_,_,_,_ ), 0 , 0 , 0 , 85 , 0 ), // #611
+ INST(Popcnt , X86Rm_Raw66H , O(F30F00,B8,_,_,x,_,_,_ ), 0 , 7 , 0 , 23 , 111), // #612
+ INST(Popf , X86Op , O(660000,9D,_,_,_,_,_,_ ), 0 , 21 , 0 , 31 , 112), // #613
+ INST(Popfd , X86Op , O(000000,9D,_,_,_,_,_,_ ), 0 , 0 , 0 , 85 , 112), // #614
+ INST(Popfq , X86Op , O(000000,9D,_,_,_,_,_,_ ), 0 , 0 , 0 , 34 , 112), // #615
+ INST(Por , ExtRm_P , O(000F00,EB,_,_,_,_,_,_ ), 0 , 5 , 0 , 152, 98 ), // #616
+ INST(Prefetch , X86M_Only , O(000F00,0D,0,_,_,_,_,_ ), 0 , 5 , 0 , 32 , 58 ), // #617
+ INST(Prefetchit0 , X86M_Only , O(000F00,18,7,_,_,_,_,_ ), 0 , 24 , 0 , 75 , 113), // #618
+ INST(Prefetchit1 , X86M_Only , O(000F00,18,6,_,_,_,_,_ ), 0 , 82 , 0 , 75 , 113), // #619
+ INST(Prefetchnta , X86M_Only , O(000F00,18,0,_,_,_,_,_ ), 0 , 5 , 0 , 32 , 6 ), // #620
+ INST(Prefetcht0 , X86M_Only , O(000F00,18,1,_,_,_,_,_ ), 0 , 32 , 0 , 32 , 6 ), // #621
+ INST(Prefetcht1 , X86M_Only , O(000F00,18,2,_,_,_,_,_ ), 0 , 78 , 0 , 32 , 6 ), // #622
+ INST(Prefetcht2 , X86M_Only , O(000F00,18,3,_,_,_,_,_ ), 0 , 80 , 0 , 32 , 6 ), // #623
+ INST(Prefetchw , X86M_Only , O(000F00,0D,1,_,_,_,_,_ ), 0 , 32 , 0 , 32 , 114), // #624
+ INST(Prefetchwt1 , X86M_Only , O(000F00,0D,2,_,_,_,_,_ ), 0 , 78 , 0 , 32 , 115), // #625
+ INST(Psadbw , ExtRm_P , O(000F00,F6,_,_,_,_,_,_ ), 0 , 5 , 0 , 150, 104), // #626
+ INST(Pshufb , ExtRm_P , O(000F38,00,_,_,_,_,_,_ ), 0 , 1 , 0 , 150, 103), // #627
+ INST(Pshufd , ExtRmi , O(660F00,70,_,_,_,_,_,_ ), 0 , 4 , 0 , 9 , 5 ), // #628
+ INST(Pshufhw , ExtRmi , O(F30F00,70,_,_,_,_,_,_ ), 0 , 7 , 0 , 9 , 5 ), // #629
+ INST(Pshuflw , ExtRmi , O(F20F00,70,_,_,_,_,_,_ ), 0 , 6 , 0 , 9 , 5 ), // #630
+ INST(Pshufw , ExtRmi_P , O(000F00,70,_,_,_,_,_,_ ), 0 , 5 , 0 , 170, 90 ), // #631
+ INST(Psignb , ExtRm_P , O(000F38,08,_,_,_,_,_,_ ), 0 , 1 , 0 , 150, 103), // #632
+ INST(Psignd , ExtRm_P , O(000F38,0A,_,_,_,_,_,_ ), 0 , 1 , 0 , 150, 103), // #633
+ INST(Psignw , ExtRm_P , O(000F38,09,_,_,_,_,_,_ ), 0 , 1 , 0 , 150, 103), // #634
+ INST(Pslld , ExtRmRi_P , O(000F00,F2,_,_,_,_,_,_ ), O(000F00,72,6,_,_,_,_,_ ), 5 , 68 , 171, 98 ), // #635
+ INST(Pslldq , ExtRmRi , 0 , O(660F00,73,7,_,_,_,_,_ ), 0 , 69 , 172, 5 ), // #636
+ INST(Psllq , ExtRmRi_P , O(000F00,F3,_,_,_,_,_,_ ), O(000F00,73,6,_,_,_,_,_ ), 5 , 70 , 171, 98 ), // #637
+ INST(Psllw , ExtRmRi_P , O(000F00,F1,_,_,_,_,_,_ ), O(000F00,71,6,_,_,_,_,_ ), 5 , 71 , 171, 98 ), // #638
+ INST(Psmash , X86Op , O(F30F01,FF,_,_,_,_,_,_ ), 0 , 27 , 0 , 34 , 116), // #639
+ INST(Psrad , ExtRmRi_P , O(000F00,E2,_,_,_,_,_,_ ), O(000F00,72,4,_,_,_,_,_ ), 5 , 72 , 171, 98 ), // #640
+ INST(Psraw , ExtRmRi_P , O(000F00,E1,_,_,_,_,_,_ ), O(000F00,71,4,_,_,_,_,_ ), 5 , 73 , 171, 98 ), // #641
+ INST(Psrld , ExtRmRi_P , O(000F00,D2,_,_,_,_,_,_ ), O(000F00,72,2,_,_,_,_,_ ), 5 , 74 , 171, 98 ), // #642
+ INST(Psrldq , ExtRmRi , 0 , O(660F00,73,3,_,_,_,_,_ ), 0 , 75 , 172, 5 ), // #643
+ INST(Psrlq , ExtRmRi_P , O(000F00,D3,_,_,_,_,_,_ ), O(000F00,73,2,_,_,_,_,_ ), 5 , 76 , 171, 98 ), // #644
+ INST(Psrlw , ExtRmRi_P , O(000F00,D1,_,_,_,_,_,_ ), O(000F00,71,2,_,_,_,_,_ ), 5 , 77 , 171, 98 ), // #645
+ INST(Psubb , ExtRm_P , O(000F00,F8,_,_,_,_,_,_ ), 0 , 5 , 0 , 153, 98 ), // #646
+ INST(Psubd , ExtRm_P , O(000F00,FA,_,_,_,_,_,_ ), 0 , 5 , 0 , 153, 98 ), // #647
+ INST(Psubq , ExtRm_P , O(000F00,FB,_,_,_,_,_,_ ), 0 , 5 , 0 , 153, 5 ), // #648
+ INST(Psubsb , ExtRm_P , O(000F00,E8,_,_,_,_,_,_ ), 0 , 5 , 0 , 153, 98 ), // #649
+ INST(Psubsw , ExtRm_P , O(000F00,E9,_,_,_,_,_,_ ), 0 , 5 , 0 , 153, 98 ), // #650
+ INST(Psubusb , ExtRm_P , O(000F00,D8,_,_,_,_,_,_ ), 0 , 5 , 0 , 153, 98 ), // #651
+ INST(Psubusw , ExtRm_P , O(000F00,D9,_,_,_,_,_,_ ), 0 , 5 , 0 , 153, 98 ), // #652
+ INST(Psubw , ExtRm_P , O(000F00,F9,_,_,_,_,_,_ ), 0 , 5 , 0 , 153, 98 ), // #653
+ INST(Pswapd , Ext3dNow , O(000F0F,BB,_,_,_,_,_,_ ), 0 , 88 , 0 , 154, 109), // #654
+ INST(Ptest , ExtRm , O(660F38,17,_,_,_,_,_,_ ), 0 , 2 , 0 , 6 , 117), // #655
+ INST(Ptwrite , X86M , O(F30F00,AE,4,_,_,_,_,_ ), 0 , 92 , 0 , 173, 118), // #656
+ INST(Punpckhbw , ExtRm_P , O(000F00,68,_,_,_,_,_,_ ), 0 , 5 , 0 , 150, 98 ), // #657
+ INST(Punpckhdq , ExtRm_P , O(000F00,6A,_,_,_,_,_,_ ), 0 , 5 , 0 , 150, 98 ), // #658
+ INST(Punpckhqdq , ExtRm , O(660F00,6D,_,_,_,_,_,_ ), 0 , 4 , 0 , 6 , 5 ), // #659
+ INST(Punpckhwd , ExtRm_P , O(000F00,69,_,_,_,_,_,_ ), 0 , 5 , 0 , 150, 98 ), // #660
+ INST(Punpcklbw , ExtRm_P , O(000F00,60,_,_,_,_,_,_ ), 0 , 5 , 0 , 174, 98 ), // #661
+ INST(Punpckldq , ExtRm_P , O(000F00,62,_,_,_,_,_,_ ), 0 , 5 , 0 , 174, 98 ), // #662
+ INST(Punpcklqdq , ExtRm , O(660F00,6C,_,_,_,_,_,_ ), 0 , 4 , 0 , 6 , 5 ), // #663
+ INST(Punpcklwd , ExtRm_P , O(000F00,61,_,_,_,_,_,_ ), 0 , 5 , 0 , 174, 98 ), // #664
+ INST(Push , X86Push , O(000000,FF,6,_,_,_,_,_ ), O(000000,50,_,_,_,_,_,_ ), 34 , 78 , 175, 0 ), // #665
+ INST(Pusha , X86Op , O(660000,60,_,_,_,_,_,_ ), 0 , 21 , 0 , 85 , 0 ), // #666
+ INST(Pushad , X86Op , O(000000,60,_,_,_,_,_,_ ), 0 , 0 , 0 , 85 , 0 ), // #667
+ INST(Pushf , X86Op , O(660000,9C,_,_,_,_,_,_ ), 0 , 21 , 0 , 31 , 119), // #668
+ INST(Pushfd , X86Op , O(000000,9C,_,_,_,_,_,_ ), 0 , 0 , 0 , 85 , 119), // #669
+ INST(Pushfq , X86Op , O(000000,9C,_,_,_,_,_,_ ), 0 , 0 , 0 , 34 , 119), // #670
+ INST(Pvalidate , X86Op , O(F20F01,FF,_,_,_,_,_,_ ), 0 , 93 , 0 , 31 , 120), // #671
+ INST(Pxor , ExtRm_P , O(000F00,EF,_,_,_,_,_,_ ), 0 , 5 , 0 , 153, 98 ), // #672
+ INST(Rcl , X86Rot , O(000000,D0,2,_,x,_,_,_ ), 0 , 3 , 0 , 176, 121), // #673
+ INST(Rcpps , ExtRm , O(000F00,53,_,_,_,_,_,_ ), 0 , 5 , 0 , 6 , 6 ), // #674
+ INST(Rcpss , ExtRm , O(F30F00,53,_,_,_,_,_,_ ), 0 , 7 , 0 , 8 , 6 ), // #675
+ INST(Rcr , X86Rot , O(000000,D0,3,_,x,_,_,_ ), 0 , 77 , 0 , 176, 121), // #676
+ INST(Rdfsbase , X86M , O(F30F00,AE,0,_,x,_,_,_ ), 0 , 7 , 0 , 177, 122), // #677
+ INST(Rdgsbase , X86M , O(F30F00,AE,1,_,x,_,_,_ ), 0 , 94 , 0 , 177, 122), // #678
+ INST(Rdmsr , X86Op , O(000F00,32,_,_,_,_,_,_ ), 0 , 5 , 0 , 178, 123), // #679
+ INST(Rdpid , X86R_Native , O(F30F00,C7,7,_,_,_,_,_ ), 0 , 95 , 0 , 179, 124), // #680
+ INST(Rdpkru , X86Op , O(000F01,EE,_,_,_,_,_,_ ), 0 , 23 , 0 , 178, 125), // #681
+ INST(Rdpmc , X86Op , O(000F00,33,_,_,_,_,_,_ ), 0 , 5 , 0 , 178, 0 ), // #682
+ INST(Rdpru , X86Op , O(000F01,FD,_,_,_,_,_,_ ), 0 , 23 , 0 , 178, 126), // #683
+ INST(Rdrand , X86M , O(000F00,C7,6,_,x,_,_,_ ), 0 , 82 , 0 , 24 , 127), // #684
+ INST(Rdseed , X86M , O(000F00,C7,7,_,x,_,_,_ ), 0 , 24 , 0 , 24 , 128), // #685
+ INST(Rdsspd , X86M , O(F30F00,1E,1,_,_,_,_,_ ), 0 , 94 , 0 , 80 , 65 ), // #686
+ INST(Rdsspq , X86M , O(F30F00,1E,1,_,_,_,_,_ ), 0 , 94 , 0 , 81 , 65 ), // #687
+ INST(Rdtsc , X86Op , O(000F00,31,_,_,_,_,_,_ ), 0 , 5 , 0 , 29 , 129), // #688
+ INST(Rdtscp , X86Op , O(000F01,F9,_,_,_,_,_,_ ), 0 , 23 , 0 , 178, 130), // #689
+ INST(Ret , X86Ret , O(000000,C2,_,_,_,_,_,_ ), 0 , 0 , 0 , 180, 0 ), // #690
+ INST(Retf , X86Ret , O(000000,CA,_,_,x,_,_,_ ), 0 , 0 , 0 , 181, 0 ), // #691
+ INST(Rmpadjust , X86Op , O(F30F01,FE,_,_,_,_,_,_ ), 0 , 27 , 0 , 34 , 116), // #692
+ INST(Rmpupdate , X86Op , O(F20F01,FE,_,_,_,_,_,_ ), 0 , 93 , 0 , 34 , 116), // #693
+ INST(Rol , X86Rot , O(000000,D0,0,_,x,_,_,_ ), 0 , 0 , 0 , 176, 131), // #694
+ INST(Ror , X86Rot , O(000000,D0,1,_,x,_,_,_ ), 0 , 33 , 0 , 176, 131), // #695
+ INST(Rorx , VexRmi_Wx , V(F20F3A,F0,_,0,x,_,_,_ ), 0 , 96 , 0 , 182, 102), // #696
+ INST(Roundpd , ExtRmi , O(660F3A,09,_,_,_,_,_,_ ), 0 , 9 , 0 , 9 , 13 ), // #697
+ INST(Roundps , ExtRmi , O(660F3A,08,_,_,_,_,_,_ ), 0 , 9 , 0 , 9 , 13 ), // #698
+ INST(Roundsd , ExtRmi , O(660F3A,0B,_,_,_,_,_,_ ), 0 , 9 , 0 , 39 , 13 ), // #699
+ INST(Roundss , ExtRmi , O(660F3A,0A,_,_,_,_,_,_ ), 0 , 9 , 0 , 40 , 13 ), // #700
+ INST(Rsm , X86Op , O(000F00,AA,_,_,_,_,_,_ ), 0 , 5 , 0 , 85 , 1 ), // #701
+ INST(Rsqrtps , ExtRm , O(000F00,52,_,_,_,_,_,_ ), 0 , 5 , 0 , 6 , 6 ), // #702
+ INST(Rsqrtss , ExtRm , O(F30F00,52,_,_,_,_,_,_ ), 0 , 7 , 0 , 8 , 6 ), // #703
+ INST(Rstorssp , X86M_Only , O(F30F00,01,5,_,_,_,_,_ ), 0 , 65 , 0 , 33 , 25 ), // #704
+ INST(Sahf , X86Op , O(000000,9E,_,_,_,_,_,_ ), 0 , 0 , 0 , 102, 132), // #705
+ INST(Sal , X86Rot , O(000000,D0,4,_,x,_,_,_ ), 0 , 10 , 0 , 176, 1 ), // #706
+ INST(Sar , X86Rot , O(000000,D0,7,_,x,_,_,_ ), 0 , 29 , 0 , 176, 1 ), // #707
+ INST(Sarx , VexRmv_Wx , V(F30F38,F7,_,0,x,_,_,_ ), 0 , 89 , 0 , 14 , 102), // #708
+ INST(Saveprevssp , X86Op , O(F30F01,EA,_,_,_,_,_,_ ), 0 , 27 , 0 , 31 , 25 ), // #709
+ INST(Sbb , X86Arith , O(000000,18,3,_,x,_,_,_ ), 0 , 77 , 0 , 183, 3 ), // #710
+ INST(Scas , X86StrRm , O(000000,AE,_,_,_,_,_,_ ), 0 , 0 , 0 , 184, 39 ), // #711
+ INST(Seamcall , X86Op , O(660F01,CF,_,_,_,_,_,_ ), 0 , 97 , 0 , 31 , 133), // #712
+ INST(Seamops , X86Op , O(660F01,CE,_,_,_,_,_,_ ), 0 , 97 , 0 , 31 , 133), // #713
+ INST(Seamret , X86Op , O(660F01,CD,_,_,_,_,_,_ ), 0 , 97 , 0 , 31 , 133), // #714
+ INST(Senduipi , X86M_NoSize , O(F30F00,C7,6,_,_,_,_,_ ), 0 , 26 , 0 , 81 , 26 ), // #715
+ INST(Serialize , X86Op , O(000F01,E8,_,_,_,_,_,_ ), 0 , 23 , 0 , 31 , 134), // #716
+ INST(Seta , X86Set , O(000F00,97,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 69 ), // #717
+ INST(Setae , X86Set , O(000F00,93,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 70 ), // #718
+ INST(Setb , X86Set , O(000F00,92,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 70 ), // #719
+ INST(Setbe , X86Set , O(000F00,96,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 69 ), // #720
+ INST(Setc , X86Set , O(000F00,92,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 70 ), // #721
+ INST(Sete , X86Set , O(000F00,94,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 71 ), // #722
+ INST(Setg , X86Set , O(000F00,9F,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 72 ), // #723
+ INST(Setge , X86Set , O(000F00,9D,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 73 ), // #724
+ INST(Setl , X86Set , O(000F00,9C,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 73 ), // #725
+ INST(Setle , X86Set , O(000F00,9E,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 72 ), // #726
+ INST(Setna , X86Set , O(000F00,96,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 69 ), // #727
+ INST(Setnae , X86Set , O(000F00,92,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 70 ), // #728
+ INST(Setnb , X86Set , O(000F00,93,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 70 ), // #729
+ INST(Setnbe , X86Set , O(000F00,97,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 69 ), // #730
+ INST(Setnc , X86Set , O(000F00,93,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 70 ), // #731
+ INST(Setne , X86Set , O(000F00,95,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 71 ), // #732
+ INST(Setng , X86Set , O(000F00,9E,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 72 ), // #733
+ INST(Setnge , X86Set , O(000F00,9C,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 73 ), // #734
+ INST(Setnl , X86Set , O(000F00,9D,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 73 ), // #735
+ INST(Setnle , X86Set , O(000F00,9F,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 72 ), // #736
+ INST(Setno , X86Set , O(000F00,91,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 66 ), // #737
+ INST(Setnp , X86Set , O(000F00,9B,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 74 ), // #738
+ INST(Setns , X86Set , O(000F00,99,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 75 ), // #739
+ INST(Setnz , X86Set , O(000F00,95,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 71 ), // #740
+ INST(Seto , X86Set , O(000F00,90,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 66 ), // #741
+ INST(Setp , X86Set , O(000F00,9A,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 74 ), // #742
+ INST(Setpe , X86Set , O(000F00,9A,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 74 ), // #743
+ INST(Setpo , X86Set , O(000F00,9B,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 74 ), // #744
+ INST(Sets , X86Set , O(000F00,98,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 75 ), // #745
+ INST(Setssbsy , X86Op , O(F30F01,E8,_,_,_,_,_,_ ), 0 , 27 , 0 , 31 , 65 ), // #746
+ INST(Setz , X86Set , O(000F00,94,_,_,_,_,_,_ ), 0 , 5 , 0 , 185, 71 ), // #747
+ INST(Sfence , X86Fence , O(000F00,AE,7,_,_,_,_,_ ), 0 , 24 , 0 , 31 , 6 ), // #748
+ INST(Sgdt , X86M_Only , O(000F00,01,0,_,_,_,_,_ ), 0 , 5 , 0 , 32 , 0 ), // #749
+ INST(Sha1msg1 , ExtRm , O(000F38,C9,_,_,_,_,_,_ ), 0 , 1 , 0 , 6 , 135), // #750
+ INST(Sha1msg2 , ExtRm , O(000F38,CA,_,_,_,_,_,_ ), 0 , 1 , 0 , 6 , 135), // #751
+ INST(Sha1nexte , ExtRm , O(000F38,C8,_,_,_,_,_,_ ), 0 , 1 , 0 , 6 , 135), // #752
+ INST(Sha1rnds4 , ExtRmi , O(000F3A,CC,_,_,_,_,_,_ ), 0 , 86 , 0 , 9 , 135), // #753
+ INST(Sha256msg1 , ExtRm , O(000F38,CC,_,_,_,_,_,_ ), 0 , 1 , 0 , 6 , 135), // #754
+ INST(Sha256msg2 , ExtRm , O(000F38,CD,_,_,_,_,_,_ ), 0 , 1 , 0 , 6 , 135), // #755
+ INST(Sha256rnds2 , ExtRm_XMM0 , O(000F38,CB,_,_,_,_,_,_ ), 0 , 1 , 0 , 16 , 135), // #756
+ INST(Shl , X86Rot , O(000000,D0,4,_,x,_,_,_ ), 0 , 10 , 0 , 176, 1 ), // #757
+ INST(Shld , X86ShldShrd , O(000F00,A4,_,_,x,_,_,_ ), 0 , 5 , 0 , 186, 1 ), // #758
+ INST(Shlx , VexRmv_Wx , V(660F38,F7,_,0,x,_,_,_ ), 0 , 30 , 0 , 14 , 102), // #759
+ INST(Shr , X86Rot , O(000000,D0,5,_,x,_,_,_ ), 0 , 64 , 0 , 176, 1 ), // #760
+ INST(Shrd , X86ShldShrd , O(000F00,AC,_,_,x,_,_,_ ), 0 , 5 , 0 , 186, 1 ), // #761
+ INST(Shrx , VexRmv_Wx , V(F20F38,F7,_,0,x,_,_,_ ), 0 , 85 , 0 , 14 , 102), // #762
+ INST(Shufpd , ExtRmi , O(660F00,C6,_,_,_,_,_,_ ), 0 , 4 , 0 , 9 , 5 ), // #763
+ INST(Shufps , ExtRmi , O(000F00,C6,_,_,_,_,_,_ ), 0 , 5 , 0 , 9 , 6 ), // #764
+ INST(Sidt , X86M_Only , O(000F00,01,1,_,_,_,_,_ ), 0 , 32 , 0 , 32 , 0 ), // #765
+ INST(Skinit , X86Op_xAX , O(000F01,DE,_,_,_,_,_,_ ), 0 , 23 , 0 , 56 , 136), // #766
+ INST(Sldt , X86M_NoMemSize , O(000F00,00,0,_,_,_,_,_ ), 0 , 5 , 0 , 187, 0 ), // #767
+ INST(Slwpcb , VexR_Wx , V(XOP_M9,12,1,0,x,_,_,_ ), 0 , 13 , 0 , 113, 87 ), // #768
+ INST(Smsw , X86M_NoMemSize , O(000F00,01,4,_,_,_,_,_ ), 0 , 98 , 0 , 187, 0 ), // #769
+ INST(Sqrtpd , ExtRm , O(660F00,51,_,_,_,_,_,_ ), 0 , 4 , 0 , 6 , 5 ), // #770
+ INST(Sqrtps , ExtRm , O(000F00,51,_,_,_,_,_,_ ), 0 , 5 , 0 , 6 , 6 ), // #771
+ INST(Sqrtsd , ExtRm , O(F20F00,51,_,_,_,_,_,_ ), 0 , 6 , 0 , 7 , 5 ), // #772
+ INST(Sqrtss , ExtRm , O(F30F00,51,_,_,_,_,_,_ ), 0 , 7 , 0 , 8 , 6 ), // #773
+ INST(Stac , X86Op , O(000F01,CB,_,_,_,_,_,_ ), 0 , 23 , 0 , 31 , 17 ), // #774
+ INST(Stc , X86Op , O(000000,F9,_,_,_,_,_,_ ), 0 , 0 , 0 , 31 , 18 ), // #775
+ INST(Std , X86Op , O(000000,FD,_,_,_,_,_,_ ), 0 , 0 , 0 , 31 , 19 ), // #776
+ INST(Stgi , X86Op , O(000F01,DC,_,_,_,_,_,_ ), 0 , 23 , 0 , 31 , 136), // #777
+ INST(Sti , X86Op , O(000000,FB,_,_,_,_,_,_ ), 0 , 0 , 0 , 31 , 24 ), // #778
+ INST(Stmxcsr , X86M_Only , O(000F00,AE,3,_,_,_,_,_ ), 0 , 80 , 0 , 106, 6 ), // #779
+ INST(Stos , X86StrMr , O(000000,AA,_,_,_,_,_,_ ), 0 , 0 , 0 , 188, 88 ), // #780
+ INST(Str , X86M_NoMemSize , O(000F00,00,1,_,_,_,_,_ ), 0 , 32 , 0 , 187, 0 ), // #781
+ INST(Sttilecfg , AmxCfg , V(660F38,49,_,0,0,_,_,_ ), 0 , 30 , 0 , 108, 86 ), // #782
+ INST(Stui , X86Op , O(F30F01,EF,_,_,_,_,_,_ ), 0 , 27 , 0 , 34 , 26 ), // #783
+ INST(Sub , X86Arith , O(000000,28,5,_,x,_,_,_ ), 0 , 64 , 0 , 183, 1 ), // #784
+ INST(Subpd , ExtRm , O(660F00,5C,_,_,_,_,_,_ ), 0 , 4 , 0 , 6 , 5 ), // #785
+ INST(Subps , ExtRm , O(000F00,5C,_,_,_,_,_,_ ), 0 , 5 , 0 , 6 , 6 ), // #786
+ INST(Subsd , ExtRm , O(F20F00,5C,_,_,_,_,_,_ ), 0 , 6 , 0 , 7 , 5 ), // #787
+ INST(Subss , ExtRm , O(F30F00,5C,_,_,_,_,_,_ ), 0 , 7 , 0 , 8 , 6 ), // #788
+ INST(Swapgs , X86Op , O(000F01,F8,_,_,_,_,_,_ ), 0 , 23 , 0 , 34 , 0 ), // #789
+ INST(Syscall , X86Op , O(000F00,05,_,_,_,_,_,_ ), 0 , 5 , 0 , 34 , 0 ), // #790
+ INST(Sysenter , X86Op , O(000F00,34,_,_,_,_,_,_ ), 0 , 5 , 0 , 31 , 0 ), // #791
+ INST(Sysexit , X86Op , O(000F00,35,_,_,_,_,_,_ ), 0 , 5 , 0 , 31 , 0 ), // #792
+ INST(Sysexitq , X86Op , O(000F00,35,_,_,1,_,_,_ ), 0 , 62 , 0 , 34 , 0 ), // #793
+ INST(Sysret , X86Op , O(000F00,07,_,_,_,_,_,_ ), 0 , 5 , 0 , 34 , 0 ), // #794
+ INST(Sysretq , X86Op , O(000F00,07,_,_,1,_,_,_ ), 0 , 62 , 0 , 34 , 0 ), // #795
+ INST(T1mskc , VexVm_Wx , V(XOP_M9,01,7,0,x,_,_,_ ), 0 , 99 , 0 , 15 , 12 ), // #796
+ INST(Tcmmimfp16ps , AmxRmv , V(660F38,6C,_,0,0,_,_,_ ), 0 , 30 , 0 , 189, 137), // #797
+ INST(Tcmmrlfp16ps , AmxRmv , V(000F38,6C,_,0,0,_,_,_ ), 0 , 11 , 0 , 189, 137), // #798
+ INST(Tdcall , X86Op , O(660F01,CC,_,_,_,_,_,_ ), 0 , 97 , 0 , 31 , 133), // #799
+ INST(Tdpbf16ps , AmxRmv , V(F30F38,5C,_,0,0,_,_,_ ), 0 , 89 , 0 , 189, 138), // #800
+ INST(Tdpbssd , AmxRmv , V(F20F38,5E,_,0,0,_,_,_ ), 0 , 85 , 0 , 189, 139), // #801
+ INST(Tdpbsud , AmxRmv , V(F30F38,5E,_,0,0,_,_,_ ), 0 , 89 , 0 , 189, 139), // #802
+ INST(Tdpbusd , AmxRmv , V(660F38,5E,_,0,0,_,_,_ ), 0 , 30 , 0 , 189, 139), // #803
+ INST(Tdpbuud , AmxRmv , V(000F38,5E,_,0,0,_,_,_ ), 0 , 11 , 0 , 189, 139), // #804
+ INST(Tdpfp16ps , AmxRmv , V(F20F38,5C,_,0,0,_,_,_ ), 0 , 85 , 0 , 189, 140), // #805
+ INST(Test , X86Test , O(000000,84,_,_,x,_,_,_ ), O(000000,F6,_,_,x,_,_,_ ), 0 , 79 , 190, 1 ), // #806
+ INST(Testui , X86Op , O(F30F01,ED,_,_,_,_,_,_ ), 0 , 27 , 0 , 34 , 141), // #807
+ INST(Tileloadd , AmxRm , V(F20F38,4B,_,0,0,_,_,_ ), 0 , 85 , 0 , 191, 86 ), // #808
+ INST(Tileloaddt1 , AmxRm , V(660F38,4B,_,0,0,_,_,_ ), 0 , 30 , 0 , 191, 86 ), // #809
+ INST(Tilerelease , VexOpMod , V(000F38,49,0,0,0,_,_,_ ), 0 , 11 , 0 , 192, 86 ), // #810
+ INST(Tilestored , AmxMr , V(F30F38,4B,_,0,0,_,_,_ ), 0 , 89 , 0 , 193, 86 ), // #811
+ INST(Tilezero , AmxR , V(F20F38,49,_,0,0,_,_,_ ), 0 , 85 , 0 , 194, 86 ), // #812
+ INST(Tlbsync , X86Op , O(000F01,FF,_,_,_,_,_,_ ), 0 , 23 , 0 , 31 , 68 ), // #813
+ INST(Tpause , X86R32_EDX_EAX , O(660F00,AE,6,_,_,_,_,_ ), 0 , 28 , 0 , 195, 142), // #814
+ INST(Tzcnt , X86Rm_Raw66H , O(F30F00,BC,_,_,x,_,_,_ ), 0 , 7 , 0 , 23 , 10 ), // #815
+ INST(Tzmsk , VexVm_Wx , V(XOP_M9,01,4,0,x,_,_,_ ), 0 , 100, 0 , 15 , 12 ), // #816
+ INST(Ucomisd , ExtRm , O(660F00,2E,_,_,_,_,_,_ ), 0 , 4 , 0 , 7 , 43 ), // #817
+ INST(Ucomiss , ExtRm , O(000F00,2E,_,_,_,_,_,_ ), 0 , 5 , 0 , 8 , 44 ), // #818
+ INST(Ud0 , X86Rm , O(000F00,FF,_,_,_,_,_,_ ), 0 , 5 , 0 , 196, 0 ), // #819
+ INST(Ud1 , X86Rm , O(000F00,B9,_,_,_,_,_,_ ), 0 , 5 , 0 , 196, 0 ), // #820
+ INST(Ud2 , X86Op , O(000F00,0B,_,_,_,_,_,_ ), 0 , 5 , 0 , 31 , 0 ), // #821
+ INST(Uiret , X86Op , O(F30F01,EC,_,_,_,_,_,_ ), 0 , 27 , 0 , 34 , 26 ), // #822
+ INST(Umonitor , X86R_FromM , O(F30F00,AE,6,_,_,_,_,_ ), 0 , 26 , 0 , 197, 143), // #823
+ INST(Umwait , X86R32_EDX_EAX , O(F20F00,AE,6,_,_,_,_,_ ), 0 , 101, 0 , 195, 142), // #824
+ INST(Unpckhpd , ExtRm , O(660F00,15,_,_,_,_,_,_ ), 0 , 4 , 0 , 6 , 5 ), // #825
+ INST(Unpckhps , ExtRm , O(000F00,15,_,_,_,_,_,_ ), 0 , 5 , 0 , 6 , 6 ), // #826
+ INST(Unpcklpd , ExtRm , O(660F00,14,_,_,_,_,_,_ ), 0 , 4 , 0 , 6 , 5 ), // #827
+ INST(Unpcklps , ExtRm , O(000F00,14,_,_,_,_,_,_ ), 0 , 5 , 0 , 6 , 6 ), // #828
+ INST(V4fmaddps , VexRm_T1_4X , E(F20F38,9A,_,2,_,0,4,T4X), 0 , 102, 0 , 198, 144), // #829
+ INST(V4fmaddss , VexRm_T1_4X , E(F20F38,9B,_,0,_,0,4,T4X), 0 , 103, 0 , 199, 144), // #830
+ INST(V4fnmaddps , VexRm_T1_4X , E(F20F38,AA,_,2,_,0,4,T4X), 0 , 102, 0 , 198, 144), // #831
+ INST(V4fnmaddss , VexRm_T1_4X , E(F20F38,AB,_,0,_,0,4,T4X), 0 , 103, 0 , 199, 144), // #832
+ INST(Vaddpd , VexRvm_Lx , V(660F00,58,_,x,I,1,4,FV ), 0 , 104, 0 , 200, 145), // #833
+ INST(Vaddph , VexRvm_Lx , E(00MAP5,58,_,_,_,0,4,FV ), 0 , 105, 0 , 201, 146), // #834
+ INST(Vaddps , VexRvm_Lx , V(000F00,58,_,x,I,0,4,FV ), 0 , 106, 0 , 202, 145), // #835
+ INST(Vaddsd , VexRvm , V(F20F00,58,_,I,I,1,3,T1S), 0 , 107, 0 , 203, 147), // #836
+ INST(Vaddsh , VexRvm , E(F3MAP5,58,_,_,_,0,1,T1S), 0 , 108, 0 , 204, 148), // #837
+ INST(Vaddss , VexRvm , V(F30F00,58,_,I,I,0,2,T1S), 0 , 109, 0 , 205, 147), // #838
+ INST(Vaddsubpd , VexRvm_Lx , V(660F00,D0,_,x,I,_,_,_ ), 0 , 71 , 0 , 206, 149), // #839
+ INST(Vaddsubps , VexRvm_Lx , V(F20F00,D0,_,x,I,_,_,_ ), 0 , 110, 0 , 206, 149), // #840
+ INST(Vaesdec , VexRvm_Lx , V(660F38,DE,_,x,I,_,4,FVM), 0 , 111, 0 , 207, 150), // #841
+ INST(Vaesdeclast , VexRvm_Lx , V(660F38,DF,_,x,I,_,4,FVM), 0 , 111, 0 , 207, 150), // #842
+ INST(Vaesenc , VexRvm_Lx , V(660F38,DC,_,x,I,_,4,FVM), 0 , 111, 0 , 207, 150), // #843
+ INST(Vaesenclast , VexRvm_Lx , V(660F38,DD,_,x,I,_,4,FVM), 0 , 111, 0 , 207, 150), // #844
+ INST(Vaesimc , VexRm , V(660F38,DB,_,0,I,_,_,_ ), 0 , 30 , 0 , 208, 151), // #845
+ INST(Vaeskeygenassist , VexRmi , V(660F3A,DF,_,0,I,_,_,_ ), 0 , 75 , 0 , 209, 151), // #846
+ INST(Valignd , VexRvmi_Lx , E(660F3A,03,_,x,_,0,4,FV ), 0 , 112, 0 , 210, 152), // #847
+ INST(Valignq , VexRvmi_Lx , E(660F3A,03,_,x,_,1,4,FV ), 0 , 113, 0 , 211, 152), // #848
+ INST(Vandnpd , VexRvm_Lx , V(660F00,55,_,x,I,1,4,FV ), 0 , 104, 0 , 212, 153), // #849
+ INST(Vandnps , VexRvm_Lx , V(000F00,55,_,x,I,0,4,FV ), 0 , 106, 0 , 213, 153), // #850
+ INST(Vandpd , VexRvm_Lx , V(660F00,54,_,x,I,1,4,FV ), 0 , 104, 0 , 214, 153), // #851
+ INST(Vandps , VexRvm_Lx , V(000F00,54,_,x,I,0,4,FV ), 0 , 106, 0 , 215, 153), // #852
+ INST(Vbcstnebf162ps , VexRm_Lx , V(F30F38,B1,_,x,0,_,_,_ ), 0 , 89 , 0 , 216, 154), // #853
+ INST(Vbcstnesh2ps , VexRm_Lx , V(660F38,B1,_,x,0,_,_,_ ), 0 , 30 , 0 , 216, 154), // #854
+ INST(Vblendmpd , VexRvm_Lx , E(660F38,65,_,x,_,1,4,FV ), 0 , 114, 0 , 217, 152), // #855
+ INST(Vblendmps , VexRvm_Lx , E(660F38,65,_,x,_,0,4,FV ), 0 , 115, 0 , 218, 152), // #856
+ INST(Vblendpd , VexRvmi_Lx , V(660F3A,0D,_,x,I,_,_,_ ), 0 , 75 , 0 , 219, 149), // #857
+ INST(Vblendps , VexRvmi_Lx , V(660F3A,0C,_,x,I,_,_,_ ), 0 , 75 , 0 , 219, 149), // #858
+ INST(Vblendvpd , VexRvmr_Lx , V(660F3A,4B,_,x,0,_,_,_ ), 0 , 75 , 0 , 220, 149), // #859
+ INST(Vblendvps , VexRvmr_Lx , V(660F3A,4A,_,x,0,_,_,_ ), 0 , 75 , 0 , 220, 149), // #860
+ INST(Vbroadcastf128 , VexRm , V(660F38,1A,_,1,0,_,_,_ ), 0 , 116, 0 , 221, 149), // #861
+ INST(Vbroadcastf32x2 , VexRm_Lx , E(660F38,19,_,x,_,0,3,T2 ), 0 , 117, 0 , 222, 155), // #862
+ INST(Vbroadcastf32x4 , VexRm_Lx , E(660F38,1A,_,x,_,0,4,T4 ), 0 , 118, 0 , 223, 78 ), // #863
+ INST(Vbroadcastf32x8 , VexRm , E(660F38,1B,_,2,_,0,5,T8 ), 0 , 119, 0 , 224, 76 ), // #864
+ INST(Vbroadcastf64x2 , VexRm_Lx , E(660F38,1A,_,x,_,1,4,T2 ), 0 , 120, 0 , 223, 155), // #865
+ INST(Vbroadcastf64x4 , VexRm , E(660F38,1B,_,2,_,1,5,T4 ), 0 , 121, 0 , 224, 78 ), // #866
+ INST(Vbroadcasti128 , VexRm , V(660F38,5A,_,1,0,_,_,_ ), 0 , 116, 0 , 221, 156), // #867
+ INST(Vbroadcasti32x2 , VexRm_Lx , E(660F38,59,_,x,_,0,3,T2 ), 0 , 117, 0 , 225, 155), // #868
+ INST(Vbroadcasti32x4 , VexRm_Lx , E(660F38,5A,_,x,_,0,4,T4 ), 0 , 118, 0 , 223, 152), // #869
+ INST(Vbroadcasti32x8 , VexRm , E(660F38,5B,_,2,_,0,5,T8 ), 0 , 119, 0 , 224, 76 ), // #870
+ INST(Vbroadcasti64x2 , VexRm_Lx , E(660F38,5A,_,x,_,1,4,T2 ), 0 , 120, 0 , 223, 155), // #871
+ INST(Vbroadcasti64x4 , VexRm , E(660F38,5B,_,2,_,1,5,T4 ), 0 , 121, 0 , 224, 78 ), // #872
+ INST(Vbroadcastsd , VexRm_Lx , V(660F38,19,_,x,0,1,3,T1S), 0 , 122, 0 , 226, 157), // #873
+ INST(Vbroadcastss , VexRm_Lx , V(660F38,18,_,x,0,0,2,T1S), 0 , 123, 0 , 227, 157), // #874
+ INST(Vcmppd , VexRvmi_Lx_KEvex , V(660F00,C2,_,x,I,1,4,FV ), 0 , 104, 0 , 228, 145), // #875
+ INST(Vcmpph , VexRvmi_Lx_KEvex , E(000F3A,C2,_,_,_,0,4,FV ), 0 , 124, 0 , 229, 146), // #876
+ INST(Vcmpps , VexRvmi_Lx_KEvex , V(000F00,C2,_,x,I,0,4,FV ), 0 , 106, 0 , 230, 145), // #877
+ INST(Vcmpsd , VexRvmi_KEvex , V(F20F00,C2,_,I,I,1,3,T1S), 0 , 107, 0 , 231, 147), // #878
+ INST(Vcmpsh , VexRvmi_KEvex , E(F30F3A,C2,_,_,_,0,1,T1S), 0 , 125, 0 , 232, 148), // #879
+ INST(Vcmpss , VexRvmi_KEvex , V(F30F00,C2,_,I,I,0,2,T1S), 0 , 109, 0 , 233, 147), // #880
+ INST(Vcomisd , VexRm , V(660F00,2F,_,I,I,1,3,T1S), 0 , 126, 0 , 234, 158), // #881
+ INST(Vcomish , VexRm , E(00MAP5,2F,_,_,_,0,1,T1S), 0 , 127, 0 , 235, 159), // #882
+ INST(Vcomiss , VexRm , V(000F00,2F,_,I,I,0,2,T1S), 0 , 128, 0 , 236, 158), // #883
+ INST(Vcompresspd , VexMr_Lx , E(660F38,8A,_,x,_,1,3,T1S), 0 , 129, 0 , 237, 152), // #884
+ INST(Vcompressps , VexMr_Lx , E(660F38,8A,_,x,_,0,2,T1S), 0 , 130, 0 , 237, 152), // #885
+ INST(Vcvtdq2pd , VexRm_Lx , V(F30F00,E6,_,x,I,0,3,HV ), 0 , 131, 0 , 238, 145), // #886
+ INST(Vcvtdq2ph , VexRm_Lx_Narrow , E(00MAP5,5B,_,x,0,0,4,FV ), 0 , 105, 0 , 239, 146), // #887
+ INST(Vcvtdq2ps , VexRm_Lx , V(000F00,5B,_,x,I,0,4,FV ), 0 , 106, 0 , 240, 145), // #888
+ INST(Vcvtne2ps2bf16 , VexRvm_Lx , E(F20F38,72,_,_,_,0,4,FV ), 0 , 132, 0 , 218, 160), // #889
+ INST(Vcvtneebf162ps , VexRm_Lx , V(F30F38,B0,_,x,0,_,_,_ ), 0 , 89 , 0 , 241, 154), // #890
+ INST(Vcvtneeph2ps , VexRm_Lx , V(660F38,B0,_,x,0,_,_,_ ), 0 , 30 , 0 , 241, 154), // #891
+ INST(Vcvtneobf162ps , VexRm_Lx , V(F20F38,B0,_,x,0,_,_,_ ), 0 , 85 , 0 , 241, 154), // #892
+ INST(Vcvtneoph2ps , VexRm_Lx , V(000F38,B0,_,x,0,_,_,_ ), 0 , 11 , 0 , 241, 154), // #893
+ INST(Vcvtneps2bf16 , VexRm_Lx_Narrow , V(F30F38,72,_,_,_,0,4,FV ), 0 , 133, 0 , 242, 161), // #894
+ INST(Vcvtpd2dq , VexRm_Lx_Narrow , V(F20F00,E6,_,x,I,1,4,FV ), 0 , 134, 0 , 243, 145), // #895
+ INST(Vcvtpd2ph , VexRm_Lx , E(66MAP5,5A,_,_,_,1,4,FV ), 0 , 135, 0 , 244, 146), // #896
+ INST(Vcvtpd2ps , VexRm_Lx_Narrow , V(660F00,5A,_,x,I,1,4,FV ), 0 , 104, 0 , 243, 145), // #897
+ INST(Vcvtpd2qq , VexRm_Lx , E(660F00,7B,_,x,_,1,4,FV ), 0 , 136, 0 , 245, 155), // #898
+ INST(Vcvtpd2udq , VexRm_Lx_Narrow , E(000F00,79,_,x,_,1,4,FV ), 0 , 137, 0 , 246, 152), // #899
+ INST(Vcvtpd2uqq , VexRm_Lx , E(660F00,79,_,x,_,1,4,FV ), 0 , 136, 0 , 245, 155), // #900
+ INST(Vcvtph2dq , VexRm_Lx , E(66MAP5,5B,_,_,_,0,3,HV ), 0 , 138, 0 , 247, 146), // #901
+ INST(Vcvtph2pd , VexRm_Lx , E(00MAP5,5A,_,_,_,0,2,QV ), 0 , 139, 0 , 248, 146), // #902
+ INST(Vcvtph2ps , VexRm_Lx , V(660F38,13,_,x,0,0,3,HVM), 0 , 140, 0 , 249, 162), // #903
+ INST(Vcvtph2psx , VexRm_Lx , E(66MAP6,13,_,_,_,0,3,HV ), 0 , 141, 0 , 250, 146), // #904
+ INST(Vcvtph2qq , VexRm_Lx , E(66MAP5,7B,_,_,_,0,2,QV ), 0 , 142, 0 , 251, 146), // #905
+ INST(Vcvtph2udq , VexRm_Lx , E(00MAP5,79,_,_,_,0,3,HV ), 0 , 143, 0 , 247, 146), // #906
+ INST(Vcvtph2uqq , VexRm_Lx , E(66MAP5,79,_,_,_,0,2,QV ), 0 , 142, 0 , 251, 146), // #907
+ INST(Vcvtph2uw , VexRm_Lx , E(00MAP5,7D,_,_,_,0,4,FV ), 0 , 105, 0 , 252, 146), // #908
+ INST(Vcvtph2w , VexRm_Lx , E(66MAP5,7D,_,_,_,0,4,FV ), 0 , 144, 0 , 252, 146), // #909
+ INST(Vcvtps2dq , VexRm_Lx , V(660F00,5B,_,x,I,0,4,FV ), 0 , 145, 0 , 240, 145), // #910
+ INST(Vcvtps2pd , VexRm_Lx , V(000F00,5A,_,x,I,0,3,HV ), 0 , 146, 0 , 253, 145), // #911
+ INST(Vcvtps2ph , VexMri_Lx , V(660F3A,1D,_,x,0,0,3,HVM), 0 , 147, 0 , 254, 162), // #912
+ INST(Vcvtps2phx , VexRm_Lx_Narrow , E(66MAP5,1D,_,_,_,0,4,FV ), 0 , 144, 0 , 239, 146), // #913
+ INST(Vcvtps2qq , VexRm_Lx , E(660F00,7B,_,x,_,0,3,HV ), 0 , 148, 0 , 255, 155), // #914
+ INST(Vcvtps2udq , VexRm_Lx , E(000F00,79,_,x,_,0,4,FV ), 0 , 149, 0 , 256, 152), // #915
+ INST(Vcvtps2uqq , VexRm_Lx , E(660F00,79,_,x,_,0,3,HV ), 0 , 148, 0 , 255, 155), // #916
+ INST(Vcvtqq2pd , VexRm_Lx , E(F30F00,E6,_,x,_,1,4,FV ), 0 , 150, 0 , 245, 155), // #917
+ INST(Vcvtqq2ph , VexRm_Lx , E(00MAP5,5B,_,_,_,1,4,FV ), 0 , 151, 0 , 244, 146), // #918
+ INST(Vcvtqq2ps , VexRm_Lx_Narrow , E(000F00,5B,_,x,_,1,4,FV ), 0 , 137, 0 , 246, 155), // #919
+ INST(Vcvtsd2sh , VexRvm , E(F2MAP5,5A,_,_,_,1,3,T1S), 0 , 152, 0 , 257, 148), // #920
+ INST(Vcvtsd2si , VexRm_Wx , V(F20F00,2D,_,I,x,x,3,T1F), 0 , 153, 0 , 258, 147), // #921
+ INST(Vcvtsd2ss , VexRvm , V(F20F00,5A,_,I,I,1,3,T1S), 0 , 107, 0 , 203, 147), // #922
+ INST(Vcvtsd2usi , VexRm_Wx , E(F20F00,79,_,I,_,x,3,T1F), 0 , 154, 0 , 259, 78 ), // #923
+ INST(Vcvtsh2sd , VexRvm , E(F3MAP5,5A,_,_,_,0,1,T1S), 0 , 108, 0 , 260, 148), // #924
+ INST(Vcvtsh2si , VexRm_Wx , E(F3MAP5,2D,_,_,_,x,1,T1S), 0 , 108, 0 , 261, 148), // #925
+ INST(Vcvtsh2ss , VexRvm , E(00MAP6,13,_,_,_,0,1,T1S), 0 , 155, 0 , 260, 148), // #926
+ INST(Vcvtsh2usi , VexRm_Wx , E(F3MAP5,79,_,_,_,x,1,T1S), 0 , 108, 0 , 261, 148), // #927
+ INST(Vcvtsi2sd , VexRvm_Wx , V(F20F00,2A,_,I,x,x,2,T1W), 0 , 156, 0 , 262, 147), // #928
+ INST(Vcvtsi2sh , VexRvm_Wx , E(F3MAP5,2A,_,_,_,x,2,T1W), 0 , 157, 0 , 263, 148), // #929
+ INST(Vcvtsi2ss , VexRvm_Wx , V(F30F00,2A,_,I,x,x,2,T1W), 0 , 158, 0 , 262, 147), // #930
+ INST(Vcvtss2sd , VexRvm , V(F30F00,5A,_,I,I,0,2,T1S), 0 , 109, 0 , 264, 147), // #931
+ INST(Vcvtss2sh , VexRvm , E(00MAP5,1D,_,_,_,0,2,T1S), 0 , 159, 0 , 265, 148), // #932
+ INST(Vcvtss2si , VexRm_Wx , V(F30F00,2D,_,I,x,x,2,T1F), 0 , 109, 0 , 266, 147), // #933
+ INST(Vcvtss2usi , VexRm_Wx , E(F30F00,79,_,I,_,x,2,T1F), 0 , 160, 0 , 267, 78 ), // #934
+ INST(Vcvttpd2dq , VexRm_Lx_Narrow , V(660F00,E6,_,x,I,1,4,FV ), 0 , 104, 0 , 268, 145), // #935
+ INST(Vcvttpd2qq , VexRm_Lx , E(660F00,7A,_,x,_,1,4,FV ), 0 , 136, 0 , 269, 152), // #936
+ INST(Vcvttpd2udq , VexRm_Lx_Narrow , E(000F00,78,_,x,_,1,4,FV ), 0 , 137, 0 , 270, 152), // #937
+ INST(Vcvttpd2uqq , VexRm_Lx , E(660F00,78,_,x,_,1,4,FV ), 0 , 136, 0 , 269, 155), // #938
+ INST(Vcvttph2dq , VexRm_Lx , E(F3MAP5,5B,_,_,_,0,3,HV ), 0 , 161, 0 , 250, 146), // #939
+ INST(Vcvttph2qq , VexRm_Lx , E(66MAP5,7A,_,_,_,0,2,QV ), 0 , 142, 0 , 248, 146), // #940
+ INST(Vcvttph2udq , VexRm_Lx , E(00MAP5,78,_,_,_,0,3,HV ), 0 , 143, 0 , 250, 146), // #941
+ INST(Vcvttph2uqq , VexRm_Lx , E(66MAP5,78,_,_,_,0,2,QV ), 0 , 142, 0 , 248, 146), // #942
+ INST(Vcvttph2uw , VexRm_Lx , E(00MAP5,7C,_,_,_,0,4,FV ), 0 , 105, 0 , 271, 146), // #943
+ INST(Vcvttph2w , VexRm_Lx , E(66MAP5,7C,_,_,_,0,4,FV ), 0 , 144, 0 , 271, 146), // #944
+ INST(Vcvttps2dq , VexRm_Lx , V(F30F00,5B,_,x,I,0,4,FV ), 0 , 162, 0 , 272, 145), // #945
+ INST(Vcvttps2qq , VexRm_Lx , E(660F00,7A,_,x,_,0,3,HV ), 0 , 148, 0 , 273, 155), // #946
+ INST(Vcvttps2udq , VexRm_Lx , E(000F00,78,_,x,_,0,4,FV ), 0 , 149, 0 , 274, 152), // #947
+ INST(Vcvttps2uqq , VexRm_Lx , E(660F00,78,_,x,_,0,3,HV ), 0 , 148, 0 , 273, 155), // #948
+ INST(Vcvttsd2si , VexRm_Wx , V(F20F00,2C,_,I,x,x,3,T1F), 0 , 153, 0 , 275, 147), // #949
+ INST(Vcvttsd2usi , VexRm_Wx , E(F20F00,78,_,I,_,x,3,T1F), 0 , 154, 0 , 276, 78 ), // #950
+ INST(Vcvttsh2si , VexRm_Wx , E(F3MAP5,2C,_,_,_,x,1,T1S), 0 , 108, 0 , 277, 148), // #951
+ INST(Vcvttsh2usi , VexRm_Wx , E(F3MAP5,78,_,_,_,x,1,T1S), 0 , 108, 0 , 277, 148), // #952
+ INST(Vcvttss2si , VexRm_Wx , V(F30F00,2C,_,I,x,x,2,T1F), 0 , 109, 0 , 278, 147), // #953
+ INST(Vcvttss2usi , VexRm_Wx , E(F30F00,78,_,I,_,x,2,T1F), 0 , 160, 0 , 279, 78 ), // #954
+ INST(Vcvtudq2pd , VexRm_Lx , E(F30F00,7A,_,x,_,0,3,HV ), 0 , 163, 0 , 280, 152), // #955
+ INST(Vcvtudq2ph , VexRm_Lx_Narrow , E(F2MAP5,7A,_,_,_,0,4,FV ), 0 , 164, 0 , 239, 146), // #956
+ INST(Vcvtudq2ps , VexRm_Lx , E(F20F00,7A,_,x,_,0,4,FV ), 0 , 165, 0 , 256, 152), // #957
+ INST(Vcvtuqq2pd , VexRm_Lx , E(F30F00,7A,_,x,_,1,4,FV ), 0 , 150, 0 , 245, 155), // #958
+ INST(Vcvtuqq2ph , VexRm_Lx , E(F2MAP5,7A,_,_,_,1,4,FV ), 0 , 166, 0 , 244, 146), // #959
+ INST(Vcvtuqq2ps , VexRm_Lx_Narrow , E(F20F00,7A,_,x,_,1,4,FV ), 0 , 167, 0 , 246, 155), // #960
+ INST(Vcvtusi2sd , VexRvm_Wx , E(F20F00,7B,_,I,_,x,2,T1W), 0 , 168, 0 , 281, 78 ), // #961
+ INST(Vcvtusi2sh , VexRvm_Wx , E(F3MAP5,7B,_,_,_,x,2,T1W), 0 , 157, 0 , 263, 148), // #962
+ INST(Vcvtusi2ss , VexRvm_Wx , E(F30F00,7B,_,I,_,x,2,T1W), 0 , 169, 0 , 281, 78 ), // #963
+ INST(Vcvtuw2ph , VexRm_Lx , E(F2MAP5,7D,_,_,_,0,4,FV ), 0 , 164, 0 , 252, 146), // #964
+ INST(Vcvtw2ph , VexRm_Lx , E(F3MAP5,7D,_,_,_,0,4,FV ), 0 , 170, 0 , 252, 146), // #965
+ INST(Vdbpsadbw , VexRvmi_Lx , E(660F3A,42,_,x,_,0,4,FVM), 0 , 112, 0 , 282, 163), // #966
+ INST(Vdivpd , VexRvm_Lx , V(660F00,5E,_,x,I,1,4,FV ), 0 , 104, 0 , 200, 145), // #967
+ INST(Vdivph , VexRvm_Lx , E(00MAP5,5E,_,_,_,0,4,FV ), 0 , 105, 0 , 201, 146), // #968
+ INST(Vdivps , VexRvm_Lx , V(000F00,5E,_,x,I,0,4,FV ), 0 , 106, 0 , 202, 145), // #969
+ INST(Vdivsd , VexRvm , V(F20F00,5E,_,I,I,1,3,T1S), 0 , 107, 0 , 203, 147), // #970
+ INST(Vdivsh , VexRvm , E(F3MAP5,5E,_,_,_,0,1,T1S), 0 , 108, 0 , 204, 148), // #971
+ INST(Vdivss , VexRvm , V(F30F00,5E,_,I,I,0,2,T1S), 0 , 109, 0 , 205, 147), // #972
+ INST(Vdpbf16ps , VexRvm_Lx , E(F30F38,52,_,_,_,0,4,FV ), 0 , 171, 0 , 218, 160), // #973
+ INST(Vdppd , VexRvmi_Lx , V(660F3A,41,_,x,I,_,_,_ ), 0 , 75 , 0 , 283, 149), // #974
+ INST(Vdpps , VexRvmi_Lx , V(660F3A,40,_,x,I,_,_,_ ), 0 , 75 , 0 , 219, 149), // #975
+ INST(Verr , X86M_NoSize , O(000F00,00,4,_,_,_,_,_ ), 0 , 98 , 0 , 112, 11 ), // #976
+ INST(Verw , X86M_NoSize , O(000F00,00,5,_,_,_,_,_ ), 0 , 79 , 0 , 112, 11 ), // #977
+ INST(Vexp2pd , VexRm , E(660F38,C8,_,2,_,1,4,FV ), 0 , 172, 0 , 284, 164), // #978
+ INST(Vexp2ps , VexRm , E(660F38,C8,_,2,_,0,4,FV ), 0 , 173, 0 , 285, 164), // #979
+ INST(Vexpandpd , VexRm_Lx , E(660F38,88,_,x,_,1,3,T1S), 0 , 129, 0 , 286, 152), // #980
+ INST(Vexpandps , VexRm_Lx , E(660F38,88,_,x,_,0,2,T1S), 0 , 130, 0 , 286, 152), // #981
+ INST(Vextractf128 , VexMri , V(660F3A,19,_,1,0,_,_,_ ), 0 , 174, 0 , 287, 149), // #982
+ INST(Vextractf32x4 , VexMri_Lx , E(660F3A,19,_,x,_,0,4,T4 ), 0 , 175, 0 , 288, 152), // #983
+ INST(Vextractf32x8 , VexMri , E(660F3A,1B,_,2,_,0,5,T8 ), 0 , 176, 0 , 289, 76 ), // #984
+ INST(Vextractf64x2 , VexMri_Lx , E(660F3A,19,_,x,_,1,4,T2 ), 0 , 177, 0 , 288, 155), // #985
+ INST(Vextractf64x4 , VexMri , E(660F3A,1B,_,2,_,1,5,T4 ), 0 , 178, 0 , 289, 78 ), // #986
+ INST(Vextracti128 , VexMri , V(660F3A,39,_,1,0,_,_,_ ), 0 , 174, 0 , 287, 156), // #987
+ INST(Vextracti32x4 , VexMri_Lx , E(660F3A,39,_,x,_,0,4,T4 ), 0 , 175, 0 , 288, 152), // #988
+ INST(Vextracti32x8 , VexMri , E(660F3A,3B,_,2,_,0,5,T8 ), 0 , 176, 0 , 289, 76 ), // #989
+ INST(Vextracti64x2 , VexMri_Lx , E(660F3A,39,_,x,_,1,4,T2 ), 0 , 177, 0 , 288, 155), // #990
+ INST(Vextracti64x4 , VexMri , E(660F3A,3B,_,2,_,1,5,T4 ), 0 , 178, 0 , 289, 78 ), // #991
+ INST(Vextractps , VexMri , V(660F3A,17,_,0,I,I,2,T1S), 0 , 179, 0 , 290, 147), // #992
+ INST(Vfcmaddcph , VexRvm_Lx , E(F2MAP6,56,_,_,_,0,4,FV ), 0 , 180, 0 , 291, 146), // #993
+ INST(Vfcmaddcsh , VexRvm , E(F2MAP6,57,_,_,_,0,2,T1S), 0 , 181, 0 , 265, 148), // #994
+ INST(Vfcmulcph , VexRvm_Lx , E(F2MAP6,D6,_,_,_,0,4,FV ), 0 , 180, 0 , 291, 146), // #995
+ INST(Vfcmulcsh , VexRvm , E(F2MAP6,D7,_,_,_,0,2,T1S), 0 , 181, 0 , 265, 148), // #996
+ INST(Vfixupimmpd , VexRvmi_Lx , E(660F3A,54,_,x,_,1,4,FV ), 0 , 113, 0 , 292, 152), // #997
+ INST(Vfixupimmps , VexRvmi_Lx , E(660F3A,54,_,x,_,0,4,FV ), 0 , 112, 0 , 293, 152), // #998
+ INST(Vfixupimmsd , VexRvmi , E(660F3A,55,_,I,_,1,3,T1S), 0 , 182, 0 , 294, 78 ), // #999
+ INST(Vfixupimmss , VexRvmi , E(660F3A,55,_,I,_,0,2,T1S), 0 , 183, 0 , 295, 78 ), // #1000
+ INST(Vfmadd132pd , VexRvm_Lx , V(660F38,98,_,x,1,1,4,FV ), 0 , 184, 0 , 200, 165), // #1001
+ INST(Vfmadd132ph , VexRvm_Lx , E(66MAP6,98,_,_,_,0,4,FV ), 0 , 185, 0 , 201, 146), // #1002
+ INST(Vfmadd132ps , VexRvm_Lx , V(660F38,98,_,x,0,0,4,FV ), 0 , 111, 0 , 202, 165), // #1003
+ INST(Vfmadd132sd , VexRvm , V(660F38,99,_,I,1,1,3,T1S), 0 , 186, 0 , 203, 166), // #1004
+ INST(Vfmadd132sh , VexRvm , E(66MAP6,99,_,_,_,0,1,T1S), 0 , 187, 0 , 204, 148), // #1005
+ INST(Vfmadd132ss , VexRvm , V(660F38,99,_,I,0,0,2,T1S), 0 , 123, 0 , 205, 166), // #1006
+ INST(Vfmadd213pd , VexRvm_Lx , V(660F38,A8,_,x,1,1,4,FV ), 0 , 184, 0 , 200, 165), // #1007
+ INST(Vfmadd213ph , VexRvm_Lx , E(66MAP6,A8,_,_,_,0,4,FV ), 0 , 185, 0 , 201, 146), // #1008
+ INST(Vfmadd213ps , VexRvm_Lx , V(660F38,A8,_,x,0,0,4,FV ), 0 , 111, 0 , 202, 165), // #1009
+ INST(Vfmadd213sd , VexRvm , V(660F38,A9,_,I,1,1,3,T1S), 0 , 186, 0 , 203, 166), // #1010
+ INST(Vfmadd213sh , VexRvm , E(66MAP6,A9,_,_,_,0,1,T1S), 0 , 187, 0 , 204, 148), // #1011
+ INST(Vfmadd213ss , VexRvm , V(660F38,A9,_,I,0,0,2,T1S), 0 , 123, 0 , 205, 166), // #1012
+ INST(Vfmadd231pd , VexRvm_Lx , V(660F38,B8,_,x,1,1,4,FV ), 0 , 184, 0 , 200, 165), // #1013
+ INST(Vfmadd231ph , VexRvm_Lx , E(66MAP6,B8,_,_,_,0,4,FV ), 0 , 185, 0 , 201, 146), // #1014
+ INST(Vfmadd231ps , VexRvm_Lx , V(660F38,B8,_,x,0,0,4,FV ), 0 , 111, 0 , 202, 165), // #1015
+ INST(Vfmadd231sd , VexRvm , V(660F38,B9,_,I,1,1,3,T1S), 0 , 186, 0 , 203, 166), // #1016
+ INST(Vfmadd231sh , VexRvm , E(66MAP6,B9,_,_,_,0,1,T1S), 0 , 187, 0 , 204, 148), // #1017
+ INST(Vfmadd231ss , VexRvm , V(660F38,B9,_,I,0,0,2,T1S), 0 , 123, 0 , 205, 166), // #1018
+ INST(Vfmaddcph , VexRvm_Lx , E(F3MAP6,56,_,_,_,0,4,FV ), 0 , 188, 0 , 291, 146), // #1019
+ INST(Vfmaddcsh , VexRvm , E(F3MAP6,57,_,_,_,0,2,T1S), 0 , 189, 0 , 265, 148), // #1020
+ INST(Vfmaddpd , Fma4_Lx , V(660F3A,69,_,x,x,_,_,_ ), 0 , 75 , 0 , 296, 167), // #1021
+ INST(Vfmaddps , Fma4_Lx , V(660F3A,68,_,x,x,_,_,_ ), 0 , 75 , 0 , 296, 167), // #1022
+ INST(Vfmaddsd , Fma4 , V(660F3A,6B,_,0,x,_,_,_ ), 0 , 75 , 0 , 297, 167), // #1023
+ INST(Vfmaddss , Fma4 , V(660F3A,6A,_,0,x,_,_,_ ), 0 , 75 , 0 , 298, 167), // #1024
+ INST(Vfmaddsub132pd , VexRvm_Lx , V(660F38,96,_,x,1,1,4,FV ), 0 , 184, 0 , 200, 165), // #1025
+ INST(Vfmaddsub132ph , VexRvm_Lx , E(66MAP6,96,_,_,_,0,4,FV ), 0 , 185, 0 , 201, 146), // #1026
+ INST(Vfmaddsub132ps , VexRvm_Lx , V(660F38,96,_,x,0,0,4,FV ), 0 , 111, 0 , 202, 165), // #1027
+ INST(Vfmaddsub213pd , VexRvm_Lx , V(660F38,A6,_,x,1,1,4,FV ), 0 , 184, 0 , 200, 165), // #1028
+ INST(Vfmaddsub213ph , VexRvm_Lx , E(66MAP6,A6,_,_,_,0,4,FV ), 0 , 185, 0 , 201, 146), // #1029
+ INST(Vfmaddsub213ps , VexRvm_Lx , V(660F38,A6,_,x,0,0,4,FV ), 0 , 111, 0 , 202, 165), // #1030
+ INST(Vfmaddsub231pd , VexRvm_Lx , V(660F38,B6,_,x,1,1,4,FV ), 0 , 184, 0 , 200, 165), // #1031
+ INST(Vfmaddsub231ph , VexRvm_Lx , E(66MAP6,B6,_,_,_,0,4,FV ), 0 , 185, 0 , 201, 146), // #1032
+ INST(Vfmaddsub231ps , VexRvm_Lx , V(660F38,B6,_,x,0,0,4,FV ), 0 , 111, 0 , 202, 165), // #1033
+ INST(Vfmaddsubpd , Fma4_Lx , V(660F3A,5D,_,x,x,_,_,_ ), 0 , 75 , 0 , 296, 167), // #1034
+ INST(Vfmaddsubps , Fma4_Lx , V(660F3A,5C,_,x,x,_,_,_ ), 0 , 75 , 0 , 296, 167), // #1035
+ INST(Vfmsub132pd , VexRvm_Lx , V(660F38,9A,_,x,1,1,4,FV ), 0 , 184, 0 , 200, 165), // #1036
+ INST(Vfmsub132ph , VexRvm_Lx , E(66MAP6,9A,_,_,_,0,4,FV ), 0 , 185, 0 , 201, 146), // #1037
+ INST(Vfmsub132ps , VexRvm_Lx , V(660F38,9A,_,x,0,0,4,FV ), 0 , 111, 0 , 202, 165), // #1038
+ INST(Vfmsub132sd , VexRvm , V(660F38,9B,_,I,1,1,3,T1S), 0 , 186, 0 , 203, 166), // #1039
+ INST(Vfmsub132sh , VexRvm , E(66MAP6,9B,_,_,_,0,1,T1S), 0 , 187, 0 , 204, 148), // #1040
+ INST(Vfmsub132ss , VexRvm , V(660F38,9B,_,I,0,0,2,T1S), 0 , 123, 0 , 205, 166), // #1041
+ INST(Vfmsub213pd , VexRvm_Lx , V(660F38,AA,_,x,1,1,4,FV ), 0 , 184, 0 , 200, 165), // #1042
+ INST(Vfmsub213ph , VexRvm_Lx , E(66MAP6,AA,_,_,_,0,4,FV ), 0 , 185, 0 , 201, 146), // #1043
+ INST(Vfmsub213ps , VexRvm_Lx , V(660F38,AA,_,x,0,0,4,FV ), 0 , 111, 0 , 202, 165), // #1044
+ INST(Vfmsub213sd , VexRvm , V(660F38,AB,_,I,1,1,3,T1S), 0 , 186, 0 , 203, 166), // #1045
+ INST(Vfmsub213sh , VexRvm , E(66MAP6,AB,_,_,_,0,1,T1S), 0 , 187, 0 , 204, 148), // #1046
+ INST(Vfmsub213ss , VexRvm , V(660F38,AB,_,I,0,0,2,T1S), 0 , 123, 0 , 205, 166), // #1047
+ INST(Vfmsub231pd , VexRvm_Lx , V(660F38,BA,_,x,1,1,4,FV ), 0 , 184, 0 , 200, 165), // #1048
+ INST(Vfmsub231ph , VexRvm_Lx , E(66MAP6,BA,_,_,_,0,4,FV ), 0 , 185, 0 , 201, 146), // #1049
+ INST(Vfmsub231ps , VexRvm_Lx , V(660F38,BA,_,x,0,0,4,FV ), 0 , 111, 0 , 202, 165), // #1050
+ INST(Vfmsub231sd , VexRvm , V(660F38,BB,_,I,1,1,3,T1S), 0 , 186, 0 , 203, 166), // #1051
+ INST(Vfmsub231sh , VexRvm , E(66MAP6,BB,_,_,_,0,1,T1S), 0 , 187, 0 , 204, 148), // #1052
+ INST(Vfmsub231ss , VexRvm , V(660F38,BB,_,I,0,0,2,T1S), 0 , 123, 0 , 205, 166), // #1053
+ INST(Vfmsubadd132pd , VexRvm_Lx , V(660F38,97,_,x,1,1,4,FV ), 0 , 184, 0 , 200, 165), // #1054
+ INST(Vfmsubadd132ph , VexRvm_Lx , E(66MAP6,97,_,_,_,0,4,FV ), 0 , 185, 0 , 201, 146), // #1055
+ INST(Vfmsubadd132ps , VexRvm_Lx , V(660F38,97,_,x,0,0,4,FV ), 0 , 111, 0 , 202, 165), // #1056
+ INST(Vfmsubadd213pd , VexRvm_Lx , V(660F38,A7,_,x,1,1,4,FV ), 0 , 184, 0 , 200, 165), // #1057
+ INST(Vfmsubadd213ph , VexRvm_Lx , E(66MAP6,A7,_,_,_,0,4,FV ), 0 , 185, 0 , 201, 146), // #1058
+ INST(Vfmsubadd213ps , VexRvm_Lx , V(660F38,A7,_,x,0,0,4,FV ), 0 , 111, 0 , 202, 165), // #1059
+ INST(Vfmsubadd231pd , VexRvm_Lx , V(660F38,B7,_,x,1,1,4,FV ), 0 , 184, 0 , 200, 165), // #1060
+ INST(Vfmsubadd231ph , VexRvm_Lx , E(66MAP6,B7,_,_,_,0,4,FV ), 0 , 185, 0 , 201, 146), // #1061
+ INST(Vfmsubadd231ps , VexRvm_Lx , V(660F38,B7,_,x,0,0,4,FV ), 0 , 111, 0 , 202, 165), // #1062
+ INST(Vfmsubaddpd , Fma4_Lx , V(660F3A,5F,_,x,x,_,_,_ ), 0 , 75 , 0 , 296, 167), // #1063
+ INST(Vfmsubaddps , Fma4_Lx , V(660F3A,5E,_,x,x,_,_,_ ), 0 , 75 , 0 , 296, 167), // #1064
+ INST(Vfmsubpd , Fma4_Lx , V(660F3A,6D,_,x,x,_,_,_ ), 0 , 75 , 0 , 296, 167), // #1065
+ INST(Vfmsubps , Fma4_Lx , V(660F3A,6C,_,x,x,_,_,_ ), 0 , 75 , 0 , 296, 167), // #1066
+ INST(Vfmsubsd , Fma4 , V(660F3A,6F,_,0,x,_,_,_ ), 0 , 75 , 0 , 297, 167), // #1067
+ INST(Vfmsubss , Fma4 , V(660F3A,6E,_,0,x,_,_,_ ), 0 , 75 , 0 , 298, 167), // #1068
+ INST(Vfmulcph , VexRvm_Lx , E(F3MAP6,D6,_,_,_,0,4,FV ), 0 , 188, 0 , 291, 146), // #1069
+ INST(Vfmulcsh , VexRvm , E(F3MAP6,D7,_,_,_,0,2,T1S), 0 , 189, 0 , 265, 146), // #1070
+ INST(Vfnmadd132pd , VexRvm_Lx , V(660F38,9C,_,x,1,1,4,FV ), 0 , 184, 0 , 200, 165), // #1071
+ INST(Vfnmadd132ph , VexRvm_Lx , E(66MAP6,9C,_,_,_,0,4,FV ), 0 , 185, 0 , 201, 146), // #1072
+ INST(Vfnmadd132ps , VexRvm_Lx , V(660F38,9C,_,x,0,0,4,FV ), 0 , 111, 0 , 202, 165), // #1073
+ INST(Vfnmadd132sd , VexRvm , V(660F38,9D,_,I,1,1,3,T1S), 0 , 186, 0 , 203, 166), // #1074
+ INST(Vfnmadd132sh , VexRvm , E(66MAP6,9D,_,_,_,0,1,T1S), 0 , 187, 0 , 204, 148), // #1075
+ INST(Vfnmadd132ss , VexRvm , V(660F38,9D,_,I,0,0,2,T1S), 0 , 123, 0 , 205, 166), // #1076
+ INST(Vfnmadd213pd , VexRvm_Lx , V(660F38,AC,_,x,1,1,4,FV ), 0 , 184, 0 , 200, 165), // #1077
+ INST(Vfnmadd213ph , VexRvm_Lx , E(66MAP6,AC,_,_,_,0,4,FV ), 0 , 185, 0 , 201, 146), // #1078
+ INST(Vfnmadd213ps , VexRvm_Lx , V(660F38,AC,_,x,0,0,4,FV ), 0 , 111, 0 , 202, 165), // #1079
+ INST(Vfnmadd213sd , VexRvm , V(660F38,AD,_,I,1,1,3,T1S), 0 , 186, 0 , 203, 166), // #1080
+ INST(Vfnmadd213sh , VexRvm , E(66MAP6,AD,_,_,_,0,1,T1S), 0 , 187, 0 , 204, 148), // #1081
+ INST(Vfnmadd213ss , VexRvm , V(660F38,AD,_,I,0,0,2,T1S), 0 , 123, 0 , 205, 166), // #1082
+ INST(Vfnmadd231pd , VexRvm_Lx , V(660F38,BC,_,x,1,1,4,FV ), 0 , 184, 0 , 200, 165), // #1083
+ INST(Vfnmadd231ph , VexRvm_Lx , E(66MAP6,BC,_,_,_,0,4,FV ), 0 , 185, 0 , 201, 146), // #1084
+ INST(Vfnmadd231ps , VexRvm_Lx , V(660F38,BC,_,x,0,0,4,FV ), 0 , 111, 0 , 202, 165), // #1085
+ INST(Vfnmadd231sd , VexRvm , V(660F38,BD,_,I,1,1,3,T1S), 0 , 186, 0 , 203, 166), // #1086
+ INST(Vfnmadd231sh , VexRvm , E(66MAP6,BD,_,_,_,0,1,T1S), 0 , 187, 0 , 204, 148), // #1087
+ INST(Vfnmadd231ss , VexRvm , V(660F38,BD,_,I,0,0,2,T1S), 0 , 123, 0 , 205, 166), // #1088
+ INST(Vfnmaddpd , Fma4_Lx , V(660F3A,79,_,x,x,_,_,_ ), 0 , 75 , 0 , 296, 167), // #1089
+ INST(Vfnmaddps , Fma4_Lx , V(660F3A,78,_,x,x,_,_,_ ), 0 , 75 , 0 , 296, 167), // #1090
+ INST(Vfnmaddsd , Fma4 , V(660F3A,7B,_,0,x,_,_,_ ), 0 , 75 , 0 , 297, 167), // #1091
+ INST(Vfnmaddss , Fma4 , V(660F3A,7A,_,0,x,_,_,_ ), 0 , 75 , 0 , 298, 167), // #1092
+ INST(Vfnmsub132pd , VexRvm_Lx , V(660F38,9E,_,x,1,1,4,FV ), 0 , 184, 0 , 200, 165), // #1093
+ INST(Vfnmsub132ph , VexRvm_Lx , E(66MAP6,9E,_,_,_,0,4,FV ), 0 , 185, 0 , 201, 146), // #1094
+ INST(Vfnmsub132ps , VexRvm_Lx , V(660F38,9E,_,x,0,0,4,FV ), 0 , 111, 0 , 202, 165), // #1095
+ INST(Vfnmsub132sd , VexRvm , V(660F38,9F,_,I,1,1,3,T1S), 0 , 186, 0 , 203, 166), // #1096
+ INST(Vfnmsub132sh , VexRvm , E(66MAP6,9F,_,_,_,0,1,T1S), 0 , 187, 0 , 204, 148), // #1097
+ INST(Vfnmsub132ss , VexRvm , V(660F38,9F,_,I,0,0,2,T1S), 0 , 123, 0 , 205, 166), // #1098
+ INST(Vfnmsub213pd , VexRvm_Lx , V(660F38,AE,_,x,1,1,4,FV ), 0 , 184, 0 , 200, 165), // #1099
+ INST(Vfnmsub213ph , VexRvm_Lx , E(66MAP6,AE,_,_,_,0,4,FV ), 0 , 185, 0 , 201, 146), // #1100
+ INST(Vfnmsub213ps , VexRvm_Lx , V(660F38,AE,_,x,0,0,4,FV ), 0 , 111, 0 , 202, 165), // #1101
+ INST(Vfnmsub213sd , VexRvm , V(660F38,AF,_,I,1,1,3,T1S), 0 , 186, 0 , 203, 166), // #1102
+ INST(Vfnmsub213sh , VexRvm , E(66MAP6,AF,_,_,_,0,1,T1S), 0 , 187, 0 , 204, 148), // #1103
+ INST(Vfnmsub213ss , VexRvm , V(660F38,AF,_,I,0,0,2,T1S), 0 , 123, 0 , 205, 166), // #1104
+ INST(Vfnmsub231pd , VexRvm_Lx , V(660F38,BE,_,x,1,1,4,FV ), 0 , 184, 0 , 200, 165), // #1105
+ INST(Vfnmsub231ph , VexRvm_Lx , E(66MAP6,BE,_,_,_,0,4,FV ), 0 , 185, 0 , 201, 146), // #1106
+ INST(Vfnmsub231ps , VexRvm_Lx , V(660F38,BE,_,x,0,0,4,FV ), 0 , 111, 0 , 202, 165), // #1107
+ INST(Vfnmsub231sd , VexRvm , V(660F38,BF,_,I,1,1,3,T1S), 0 , 186, 0 , 203, 166), // #1108
+ INST(Vfnmsub231sh , VexRvm , E(66MAP6,BF,_,_,_,0,1,T1S), 0 , 187, 0 , 204, 148), // #1109
+ INST(Vfnmsub231ss , VexRvm , V(660F38,BF,_,I,0,0,2,T1S), 0 , 123, 0 , 205, 166), // #1110
+ INST(Vfnmsubpd , Fma4_Lx , V(660F3A,7D,_,x,x,_,_,_ ), 0 , 75 , 0 , 296, 167), // #1111
+ INST(Vfnmsubps , Fma4_Lx , V(660F3A,7C,_,x,x,_,_,_ ), 0 , 75 , 0 , 296, 167), // #1112
+ INST(Vfnmsubsd , Fma4 , V(660F3A,7F,_,0,x,_,_,_ ), 0 , 75 , 0 , 297, 167), // #1113
+ INST(Vfnmsubss , Fma4 , V(660F3A,7E,_,0,x,_,_,_ ), 0 , 75 , 0 , 298, 167), // #1114
+ INST(Vfpclasspd , VexRmi_Lx , E(660F3A,66,_,x,_,1,4,FV ), 0 , 113, 0 , 299, 155), // #1115
+ INST(Vfpclassph , VexRmi_Lx , E(000F3A,66,_,_,_,0,4,FV ), 0 , 124, 0 , 300, 146), // #1116
+ INST(Vfpclassps , VexRmi_Lx , E(660F3A,66,_,x,_,0,4,FV ), 0 , 112, 0 , 301, 155), // #1117
+ INST(Vfpclasssd , VexRmi , E(660F3A,67,_,I,_,1,3,T1S), 0 , 182, 0 , 302, 76 ), // #1118
+ INST(Vfpclasssh , VexRmi , E(000F3A,67,_,_,_,0,1,T1S), 0 , 190, 0 , 303, 148), // #1119
+ INST(Vfpclassss , VexRmi , E(660F3A,67,_,I,_,0,2,T1S), 0 , 183, 0 , 304, 76 ), // #1120
+ INST(Vfrczpd , VexRm_Lx , V(XOP_M9,81,_,x,0,_,_,_ ), 0 , 81 , 0 , 305, 168), // #1121
+ INST(Vfrczps , VexRm_Lx , V(XOP_M9,80,_,x,0,_,_,_ ), 0 , 81 , 0 , 305, 168), // #1122
+ INST(Vfrczsd , VexRm , V(XOP_M9,83,_,0,0,_,_,_ ), 0 , 81 , 0 , 306, 168), // #1123
+ INST(Vfrczss , VexRm , V(XOP_M9,82,_,0,0,_,_,_ ), 0 , 81 , 0 , 307, 168), // #1124
+ INST(Vgatherdpd , VexRmvRm_VM , V(660F38,92,_,x,1,_,_,_ ), E(660F38,92,_,x,_,1,3,T1S), 191, 80 , 308, 169), // #1125
+ INST(Vgatherdps , VexRmvRm_VM , V(660F38,92,_,x,0,_,_,_ ), E(660F38,92,_,x,_,0,2,T1S), 30 , 81 , 309, 169), // #1126
+ INST(Vgatherpf0dpd , VexM_VM , E(660F38,C6,1,2,_,1,3,T1S), 0 , 192, 0 , 310, 170), // #1127
+ INST(Vgatherpf0dps , VexM_VM , E(660F38,C6,1,2,_,0,2,T1S), 0 , 193, 0 , 311, 170), // #1128
+ INST(Vgatherpf0qpd , VexM_VM , E(660F38,C7,1,2,_,1,3,T1S), 0 , 192, 0 , 312, 170), // #1129
+ INST(Vgatherpf0qps , VexM_VM , E(660F38,C7,1,2,_,0,2,T1S), 0 , 193, 0 , 312, 170), // #1130
+ INST(Vgatherpf1dpd , VexM_VM , E(660F38,C6,2,2,_,1,3,T1S), 0 , 194, 0 , 310, 170), // #1131
+ INST(Vgatherpf1dps , VexM_VM , E(660F38,C6,2,2,_,0,2,T1S), 0 , 195, 0 , 311, 170), // #1132
+ INST(Vgatherpf1qpd , VexM_VM , E(660F38,C7,2,2,_,1,3,T1S), 0 , 194, 0 , 312, 170), // #1133
+ INST(Vgatherpf1qps , VexM_VM , E(660F38,C7,2,2,_,0,2,T1S), 0 , 195, 0 , 312, 170), // #1134
+ INST(Vgatherqpd , VexRmvRm_VM , V(660F38,93,_,x,1,_,_,_ ), E(660F38,93,_,x,_,1,3,T1S), 191, 82 , 313, 169), // #1135
+ INST(Vgatherqps , VexRmvRm_VM , V(660F38,93,_,x,0,_,_,_ ), E(660F38,93,_,x,_,0,2,T1S), 30 , 83 , 314, 169), // #1136
+ INST(Vgetexppd , VexRm_Lx , E(660F38,42,_,x,_,1,4,FV ), 0 , 114, 0 , 269, 152), // #1137
+ INST(Vgetexpph , VexRm_Lx , E(66MAP6,42,_,_,_,0,4,FV ), 0 , 185, 0 , 271, 146), // #1138
+ INST(Vgetexpps , VexRm_Lx , E(660F38,42,_,x,_,0,4,FV ), 0 , 115, 0 , 274, 152), // #1139
+ INST(Vgetexpsd , VexRvm , E(660F38,43,_,I,_,1,3,T1S), 0 , 129, 0 , 315, 78 ), // #1140
+ INST(Vgetexpsh , VexRvm , E(66MAP6,43,_,_,_,0,1,T1S), 0 , 187, 0 , 260, 148), // #1141
+ INST(Vgetexpss , VexRvm , E(660F38,43,_,I,_,0,2,T1S), 0 , 130, 0 , 316, 78 ), // #1142
+ INST(Vgetmantpd , VexRmi_Lx , E(660F3A,26,_,x,_,1,4,FV ), 0 , 113, 0 , 317, 152), // #1143
+ INST(Vgetmantph , VexRmi_Lx , E(000F3A,26,_,_,_,0,4,FV ), 0 , 124, 0 , 318, 146), // #1144
+ INST(Vgetmantps , VexRmi_Lx , E(660F3A,26,_,x,_,0,4,FV ), 0 , 112, 0 , 319, 152), // #1145
+ INST(Vgetmantsd , VexRvmi , E(660F3A,27,_,I,_,1,3,T1S), 0 , 182, 0 , 294, 78 ), // #1146
+ INST(Vgetmantsh , VexRvmi , E(000F3A,27,_,_,_,0,1,T1S), 0 , 190, 0 , 320, 148), // #1147
+ INST(Vgetmantss , VexRvmi , E(660F3A,27,_,I,_,0,2,T1S), 0 , 183, 0 , 295, 78 ), // #1148
+ INST(Vgf2p8affineinvqb, VexRvmi_Lx , V(660F3A,CF,_,x,1,1,4,FV ), 0 , 196, 0 , 321, 171), // #1149
+ INST(Vgf2p8affineqb , VexRvmi_Lx , V(660F3A,CE,_,x,1,1,4,FV ), 0 , 196, 0 , 321, 171), // #1150
+ INST(Vgf2p8mulb , VexRvm_Lx , V(660F38,CF,_,x,0,0,4,FV ), 0 , 111, 0 , 322, 171), // #1151
+ INST(Vhaddpd , VexRvm_Lx , V(660F00,7C,_,x,I,_,_,_ ), 0 , 71 , 0 , 206, 149), // #1152
+ INST(Vhaddps , VexRvm_Lx , V(F20F00,7C,_,x,I,_,_,_ ), 0 , 110, 0 , 206, 149), // #1153
+ INST(Vhsubpd , VexRvm_Lx , V(660F00,7D,_,x,I,_,_,_ ), 0 , 71 , 0 , 206, 149), // #1154
+ INST(Vhsubps , VexRvm_Lx , V(F20F00,7D,_,x,I,_,_,_ ), 0 , 110, 0 , 206, 149), // #1155
+ INST(Vinsertf128 , VexRvmi , V(660F3A,18,_,1,0,_,_,_ ), 0 , 174, 0 , 323, 149), // #1156
+ INST(Vinsertf32x4 , VexRvmi_Lx , E(660F3A,18,_,x,_,0,4,T4 ), 0 , 175, 0 , 324, 152), // #1157
+ INST(Vinsertf32x8 , VexRvmi , E(660F3A,1A,_,2,_,0,5,T8 ), 0 , 176, 0 , 325, 76 ), // #1158
+ INST(Vinsertf64x2 , VexRvmi_Lx , E(660F3A,18,_,x,_,1,4,T2 ), 0 , 177, 0 , 324, 155), // #1159
+ INST(Vinsertf64x4 , VexRvmi , E(660F3A,1A,_,2,_,1,5,T4 ), 0 , 178, 0 , 325, 78 ), // #1160
+ INST(Vinserti128 , VexRvmi , V(660F3A,38,_,1,0,_,_,_ ), 0 , 174, 0 , 323, 156), // #1161
+ INST(Vinserti32x4 , VexRvmi_Lx , E(660F3A,38,_,x,_,0,4,T4 ), 0 , 175, 0 , 324, 152), // #1162
+ INST(Vinserti32x8 , VexRvmi , E(660F3A,3A,_,2,_,0,5,T8 ), 0 , 176, 0 , 325, 76 ), // #1163
+ INST(Vinserti64x2 , VexRvmi_Lx , E(660F3A,38,_,x,_,1,4,T2 ), 0 , 177, 0 , 324, 155), // #1164
+ INST(Vinserti64x4 , VexRvmi , E(660F3A,3A,_,2,_,1,5,T4 ), 0 , 178, 0 , 325, 78 ), // #1165
+ INST(Vinsertps , VexRvmi , V(660F3A,21,_,0,I,0,2,T1S), 0 , 179, 0 , 326, 147), // #1166
+ INST(Vlddqu , VexRm_Lx , V(F20F00,F0,_,x,I,_,_,_ ), 0 , 110, 0 , 241, 149), // #1167
+ INST(Vldmxcsr , VexM , V(000F00,AE,2,0,I,_,_,_ ), 0 , 197, 0 , 327, 149), // #1168
+ INST(Vmaskmovdqu , VexRm_ZDI , V(660F00,F7,_,0,I,_,_,_ ), 0 , 71 , 0 , 328, 149), // #1169
+ INST(Vmaskmovpd , VexRvmMvr_Lx , V(660F38,2D,_,x,0,_,_,_ ), V(660F38,2F,_,x,0,_,_,_ ), 30 , 84 , 329, 149), // #1170
+ INST(Vmaskmovps , VexRvmMvr_Lx , V(660F38,2C,_,x,0,_,_,_ ), V(660F38,2E,_,x,0,_,_,_ ), 30 , 85 , 329, 149), // #1171
+ INST(Vmaxpd , VexRvm_Lx , V(660F00,5F,_,x,I,1,4,FV ), 0 , 104, 0 , 330, 145), // #1172
+ INST(Vmaxph , VexRvm_Lx , E(00MAP5,5F,_,_,_,0,4,FV ), 0 , 105, 0 , 331, 146), // #1173
+ INST(Vmaxps , VexRvm_Lx , V(000F00,5F,_,x,I,0,4,FV ), 0 , 106, 0 , 332, 145), // #1174
+ INST(Vmaxsd , VexRvm , V(F20F00,5F,_,I,I,1,3,T1S), 0 , 107, 0 , 333, 147), // #1175
+ INST(Vmaxsh , VexRvm , E(F3MAP5,5F,_,_,_,0,1,T1S), 0 , 108, 0 , 260, 148), // #1176
+ INST(Vmaxss , VexRvm , V(F30F00,5F,_,I,I,0,2,T1S), 0 , 109, 0 , 264, 147), // #1177
+ INST(Vmcall , X86Op , O(000F01,C1,_,_,_,_,_,_ ), 0 , 23 , 0 , 31 , 67 ), // #1178
+ INST(Vmclear , X86M_Only , O(660F00,C7,6,_,_,_,_,_ ), 0 , 28 , 0 , 33 , 67 ), // #1179
+ INST(Vmfunc , X86Op , O(000F01,D4,_,_,_,_,_,_ ), 0 , 23 , 0 , 31 , 67 ), // #1180
+ INST(Vmgexit , X86Op , O(F20F01,D9,_,_,_,_,_,_ ), 0 , 93 , 0 , 31 , 172), // #1181
+ INST(Vminpd , VexRvm_Lx , V(660F00,5D,_,x,I,1,4,FV ), 0 , 104, 0 , 330, 145), // #1182
+ INST(Vminph , VexRvm_Lx , E(00MAP5,5D,_,_,_,0,4,FV ), 0 , 105, 0 , 331, 146), // #1183
+ INST(Vminps , VexRvm_Lx , V(000F00,5D,_,x,I,0,4,FV ), 0 , 106, 0 , 332, 145), // #1184
+ INST(Vminsd , VexRvm , V(F20F00,5D,_,I,I,1,3,T1S), 0 , 107, 0 , 333, 147), // #1185
+ INST(Vminsh , VexRvm , E(F3MAP5,5D,_,_,_,0,1,T1S), 0 , 108, 0 , 260, 148), // #1186
+ INST(Vminss , VexRvm , V(F30F00,5D,_,I,I,0,2,T1S), 0 , 109, 0 , 264, 147), // #1187
+ INST(Vmlaunch , X86Op , O(000F01,C2,_,_,_,_,_,_ ), 0 , 23 , 0 , 31 , 67 ), // #1188
+ INST(Vmload , X86Op_xAX , O(000F01,DA,_,_,_,_,_,_ ), 0 , 23 , 0 , 334, 23 ), // #1189
+ INST(Vmmcall , X86Op , O(000F01,D9,_,_,_,_,_,_ ), 0 , 23 , 0 , 31 , 23 ), // #1190
+ INST(Vmovapd , VexRmMr_Lx , V(660F00,28,_,x,I,1,4,FVM), V(660F00,29,_,x,I,1,4,FVM), 104, 86 , 335, 173), // #1191
+ INST(Vmovaps , VexRmMr_Lx , V(000F00,28,_,x,I,0,4,FVM), V(000F00,29,_,x,I,0,4,FVM), 106, 87 , 335, 173), // #1192
+ INST(Vmovd , VexMovdMovq , V(660F00,6E,_,0,0,0,2,T1S), V(660F00,7E,_,0,0,0,2,T1S), 198, 88 , 336, 147), // #1193
+ INST(Vmovddup , VexRm_Lx , V(F20F00,12,_,x,I,1,3,DUP), 0 , 199, 0 , 337, 145), // #1194
+ INST(Vmovdqa , VexRmMr_Lx , V(660F00,6F,_,x,I,_,_,_ ), V(660F00,7F,_,x,I,_,_,_ ), 71 , 89 , 338, 174), // #1195
+ INST(Vmovdqa32 , VexRmMr_Lx , E(660F00,6F,_,x,_,0,4,FVM), E(660F00,7F,_,x,_,0,4,FVM), 200, 90 , 339, 175), // #1196
+ INST(Vmovdqa64 , VexRmMr_Lx , E(660F00,6F,_,x,_,1,4,FVM), E(660F00,7F,_,x,_,1,4,FVM), 136, 91 , 339, 175), // #1197
+ INST(Vmovdqu , VexRmMr_Lx , V(F30F00,6F,_,x,I,_,_,_ ), V(F30F00,7F,_,x,I,_,_,_ ), 201, 92 , 338, 174), // #1198
+ INST(Vmovdqu16 , VexRmMr_Lx , E(F20F00,6F,_,x,_,1,4,FVM), E(F20F00,7F,_,x,_,1,4,FVM), 167, 93 , 339, 176), // #1199
+ INST(Vmovdqu32 , VexRmMr_Lx , E(F30F00,6F,_,x,_,0,4,FVM), E(F30F00,7F,_,x,_,0,4,FVM), 202, 94 , 339, 175), // #1200
+ INST(Vmovdqu64 , VexRmMr_Lx , E(F30F00,6F,_,x,_,1,4,FVM), E(F30F00,7F,_,x,_,1,4,FVM), 150, 95 , 339, 175), // #1201
+ INST(Vmovdqu8 , VexRmMr_Lx , E(F20F00,6F,_,x,_,0,4,FVM), E(F20F00,7F,_,x,_,0,4,FVM), 165, 96 , 339, 176), // #1202
+ INST(Vmovhlps , VexRvm , V(000F00,12,_,0,I,0,_,_ ), 0 , 74 , 0 , 340, 147), // #1203
+ INST(Vmovhpd , VexRvmMr , V(660F00,16,_,0,I,1,3,T1S), V(660F00,17,_,0,I,1,3,T1S), 126, 97 , 341, 147), // #1204
+ INST(Vmovhps , VexRvmMr , V(000F00,16,_,0,I,0,3,T2 ), V(000F00,17,_,0,I,0,3,T2 ), 203, 98 , 341, 147), // #1205
+ INST(Vmovlhps , VexRvm , V(000F00,16,_,0,I,0,_,_ ), 0 , 74 , 0 , 340, 147), // #1206
+ INST(Vmovlpd , VexRvmMr , V(660F00,12,_,0,I,1,3,T1S), V(660F00,13,_,0,I,1,3,T1S), 126, 99 , 341, 147), // #1207
+ INST(Vmovlps , VexRvmMr , V(000F00,12,_,0,I,0,3,T2 ), V(000F00,13,_,0,I,0,3,T2 ), 203, 100, 341, 147), // #1208
+ INST(Vmovmskpd , VexRm_Lx , V(660F00,50,_,x,I,_,_,_ ), 0 , 71 , 0 , 342, 149), // #1209
+ INST(Vmovmskps , VexRm_Lx , V(000F00,50,_,x,I,_,_,_ ), 0 , 74 , 0 , 342, 149), // #1210
+ INST(Vmovntdq , VexMr_Lx , V(660F00,E7,_,x,I,0,4,FVM), 0 , 145, 0 , 343, 145), // #1211
+ INST(Vmovntdqa , VexRm_Lx , V(660F38,2A,_,x,I,0,4,FVM), 0 , 111, 0 , 344, 157), // #1212
+ INST(Vmovntpd , VexMr_Lx , V(660F00,2B,_,x,I,1,4,FVM), 0 , 104, 0 , 343, 145), // #1213
+ INST(Vmovntps , VexMr_Lx , V(000F00,2B,_,x,I,0,4,FVM), 0 , 106, 0 , 343, 145), // #1214
+ INST(Vmovq , VexMovdMovq , V(660F00,6E,_,0,I,1,3,T1S), V(660F00,7E,_,0,I,1,3,T1S), 126, 101, 345, 177), // #1215
+ INST(Vmovsd , VexMovssMovsd , V(F20F00,10,_,I,I,1,3,T1S), V(F20F00,11,_,I,I,1,3,T1S), 107, 102, 346, 177), // #1216
+ INST(Vmovsh , VexMovssMovsd , E(F3MAP5,10,_,I,_,0,1,T1S), E(F3MAP5,11,_,I,_,0,1,T1S), 108, 103, 347, 148), // #1217
+ INST(Vmovshdup , VexRm_Lx , V(F30F00,16,_,x,I,0,4,FVM), 0 , 162, 0 , 348, 145), // #1218
+ INST(Vmovsldup , VexRm_Lx , V(F30F00,12,_,x,I,0,4,FVM), 0 , 162, 0 , 348, 145), // #1219
+ INST(Vmovss , VexMovssMovsd , V(F30F00,10,_,I,I,0,2,T1S), V(F30F00,11,_,I,I,0,2,T1S), 109, 104, 349, 177), // #1220
+ INST(Vmovupd , VexRmMr_Lx , V(660F00,10,_,x,I,1,4,FVM), V(660F00,11,_,x,I,1,4,FVM), 104, 105, 335, 173), // #1221
+ INST(Vmovups , VexRmMr_Lx , V(000F00,10,_,x,I,0,4,FVM), V(000F00,11,_,x,I,0,4,FVM), 106, 106, 335, 173), // #1222
+ INST(Vmovw , VexMovdMovq , E(66MAP5,6E,_,0,_,I,1,T1S), E(66MAP5,7E,_,0,_,I,1,T1S), 204, 107, 350, 148), // #1223
+ INST(Vmpsadbw , VexRvmi_Lx , V(660F3A,42,_,x,I,_,_,_ ), 0 , 75 , 0 , 219, 178), // #1224
+ INST(Vmptrld , X86M_Only , O(000F00,C7,6,_,_,_,_,_ ), 0 , 82 , 0 , 33 , 67 ), // #1225
+ INST(Vmptrst , X86M_Only , O(000F00,C7,7,_,_,_,_,_ ), 0 , 24 , 0 , 33 , 67 ), // #1226
+ INST(Vmread , X86Mr_NoSize , O(000F00,78,_,_,_,_,_,_ ), 0 , 5 , 0 , 351, 67 ), // #1227
+ INST(Vmresume , X86Op , O(000F01,C3,_,_,_,_,_,_ ), 0 , 23 , 0 , 31 , 67 ), // #1228
+ INST(Vmrun , X86Op_xAX , O(000F01,D8,_,_,_,_,_,_ ), 0 , 23 , 0 , 334, 23 ), // #1229
+ INST(Vmsave , X86Op_xAX , O(000F01,DB,_,_,_,_,_,_ ), 0 , 23 , 0 , 334, 23 ), // #1230
+ INST(Vmulpd , VexRvm_Lx , V(660F00,59,_,x,I,1,4,FV ), 0 , 104, 0 , 200, 145), // #1231
+ INST(Vmulph , VexRvm_Lx , E(00MAP5,59,_,_,_,0,4,FV ), 0 , 105, 0 , 201, 146), // #1232
+ INST(Vmulps , VexRvm_Lx , V(000F00,59,_,x,I,0,4,FV ), 0 , 106, 0 , 202, 145), // #1233
+ INST(Vmulsd , VexRvm , V(F20F00,59,_,I,I,1,3,T1S), 0 , 107, 0 , 203, 147), // #1234
+ INST(Vmulsh , VexRvm , E(F3MAP5,59,_,_,_,0,1,T1S), 0 , 108, 0 , 204, 148), // #1235
+ INST(Vmulss , VexRvm , V(F30F00,59,_,I,I,0,2,T1S), 0 , 109, 0 , 205, 147), // #1236
+ INST(Vmwrite , X86Rm_NoSize , O(000F00,79,_,_,_,_,_,_ ), 0 , 5 , 0 , 352, 67 ), // #1237
+ INST(Vmxoff , X86Op , O(000F01,C4,_,_,_,_,_,_ ), 0 , 23 , 0 , 31 , 67 ), // #1238
+ INST(Vmxon , X86M_Only , O(F30F00,C7,6,_,_,_,_,_ ), 0 , 26 , 0 , 33 , 67 ), // #1239
+ INST(Vorpd , VexRvm_Lx , V(660F00,56,_,x,I,1,4,FV ), 0 , 104, 0 , 214, 153), // #1240
+ INST(Vorps , VexRvm_Lx , V(000F00,56,_,x,I,0,4,FV ), 0 , 106, 0 , 215, 153), // #1241
+ INST(Vp2intersectd , VexRvm_Lx_2xK , E(F20F38,68,_,_,_,0,4,FV ), 0 , 132, 0 , 353, 179), // #1242
+ INST(Vp2intersectq , VexRvm_Lx_2xK , E(F20F38,68,_,_,_,1,4,FV ), 0 , 205, 0 , 354, 179), // #1243
+ INST(Vp4dpwssd , VexRm_T1_4X , E(F20F38,52,_,2,_,0,4,T4X), 0 , 102, 0 , 198, 180), // #1244
+ INST(Vp4dpwssds , VexRm_T1_4X , E(F20F38,53,_,2,_,0,4,T4X), 0 , 102, 0 , 198, 180), // #1245
+ INST(Vpabsb , VexRm_Lx , V(660F38,1C,_,x,I,_,4,FVM), 0 , 111, 0 , 348, 181), // #1246
+ INST(Vpabsd , VexRm_Lx , V(660F38,1E,_,x,I,0,4,FV ), 0 , 111, 0 , 355, 157), // #1247
+ INST(Vpabsq , VexRm_Lx , E(660F38,1F,_,x,_,1,4,FV ), 0 , 114, 0 , 356, 152), // #1248
+ INST(Vpabsw , VexRm_Lx , V(660F38,1D,_,x,I,_,4,FVM), 0 , 111, 0 , 348, 181), // #1249
+ INST(Vpackssdw , VexRvm_Lx , V(660F00,6B,_,x,I,0,4,FV ), 0 , 145, 0 , 213, 181), // #1250
+ INST(Vpacksswb , VexRvm_Lx , V(660F00,63,_,x,I,I,4,FVM), 0 , 145, 0 , 322, 181), // #1251
+ INST(Vpackusdw , VexRvm_Lx , V(660F38,2B,_,x,I,0,4,FV ), 0 , 111, 0 , 213, 181), // #1252
+ INST(Vpackuswb , VexRvm_Lx , V(660F00,67,_,x,I,I,4,FVM), 0 , 145, 0 , 322, 181), // #1253
+ INST(Vpaddb , VexRvm_Lx , V(660F00,FC,_,x,I,I,4,FVM), 0 , 145, 0 , 322, 181), // #1254
+ INST(Vpaddd , VexRvm_Lx , V(660F00,FE,_,x,I,0,4,FV ), 0 , 145, 0 , 213, 157), // #1255
+ INST(Vpaddq , VexRvm_Lx , V(660F00,D4,_,x,I,1,4,FV ), 0 , 104, 0 , 212, 157), // #1256
+ INST(Vpaddsb , VexRvm_Lx , V(660F00,EC,_,x,I,I,4,FVM), 0 , 145, 0 , 322, 181), // #1257
+ INST(Vpaddsw , VexRvm_Lx , V(660F00,ED,_,x,I,I,4,FVM), 0 , 145, 0 , 322, 181), // #1258
+ INST(Vpaddusb , VexRvm_Lx , V(660F00,DC,_,x,I,I,4,FVM), 0 , 145, 0 , 322, 181), // #1259
+ INST(Vpaddusw , VexRvm_Lx , V(660F00,DD,_,x,I,I,4,FVM), 0 , 145, 0 , 322, 181), // #1260
+ INST(Vpaddw , VexRvm_Lx , V(660F00,FD,_,x,I,I,4,FVM), 0 , 145, 0 , 322, 181), // #1261
+ INST(Vpalignr , VexRvmi_Lx , V(660F3A,0F,_,x,I,I,4,FVM), 0 , 206, 0 , 321, 181), // #1262
+ INST(Vpand , VexRvm_Lx , V(660F00,DB,_,x,I,_,_,_ ), 0 , 71 , 0 , 357, 178), // #1263
+ INST(Vpandd , VexRvm_Lx , E(660F00,DB,_,x,_,0,4,FV ), 0 , 200, 0 , 358, 152), // #1264
+ INST(Vpandn , VexRvm_Lx , V(660F00,DF,_,x,I,_,_,_ ), 0 , 71 , 0 , 359, 178), // #1265
+ INST(Vpandnd , VexRvm_Lx , E(660F00,DF,_,x,_,0,4,FV ), 0 , 200, 0 , 360, 152), // #1266
+ INST(Vpandnq , VexRvm_Lx , E(660F00,DF,_,x,_,1,4,FV ), 0 , 136, 0 , 361, 152), // #1267
+ INST(Vpandq , VexRvm_Lx , E(660F00,DB,_,x,_,1,4,FV ), 0 , 136, 0 , 362, 152), // #1268
+ INST(Vpavgb , VexRvm_Lx , V(660F00,E0,_,x,I,I,4,FVM), 0 , 145, 0 , 322, 181), // #1269
+ INST(Vpavgw , VexRvm_Lx , V(660F00,E3,_,x,I,I,4,FVM), 0 , 145, 0 , 322, 181), // #1270
+ INST(Vpblendd , VexRvmi_Lx , V(660F3A,02,_,x,0,_,_,_ ), 0 , 75 , 0 , 219, 156), // #1271
+ INST(Vpblendmb , VexRvm_Lx , E(660F38,66,_,x,_,0,4,FVM), 0 , 115, 0 , 363, 163), // #1272
+ INST(Vpblendmd , VexRvm_Lx , E(660F38,64,_,x,_,0,4,FV ), 0 , 115, 0 , 218, 152), // #1273
+ INST(Vpblendmq , VexRvm_Lx , E(660F38,64,_,x,_,1,4,FV ), 0 , 114, 0 , 217, 152), // #1274
+ INST(Vpblendmw , VexRvm_Lx , E(660F38,66,_,x,_,1,4,FVM), 0 , 114, 0 , 363, 163), // #1275
+ INST(Vpblendvb , VexRvmr_Lx , V(660F3A,4C,_,x,0,_,_,_ ), 0 , 75 , 0 , 220, 178), // #1276
+ INST(Vpblendw , VexRvmi_Lx , V(660F3A,0E,_,x,I,_,_,_ ), 0 , 75 , 0 , 219, 178), // #1277
+ INST(Vpbroadcastb , VexRm_Lx_Bcst , V(660F38,78,_,x,0,0,0,T1S), E(660F38,7A,_,x,0,0,0,T1S), 30 , 108, 364, 182), // #1278
+ INST(Vpbroadcastd , VexRm_Lx_Bcst , V(660F38,58,_,x,0,0,2,T1S), E(660F38,7C,_,x,0,0,0,T1S), 123, 109, 365, 169), // #1279
+ INST(Vpbroadcastmb2q , VexRm_Lx , E(F30F38,2A,_,x,_,1,_,_ ), 0 , 207, 0 , 366, 183), // #1280
+ INST(Vpbroadcastmw2d , VexRm_Lx , E(F30F38,3A,_,x,_,0,_,_ ), 0 , 208, 0 , 366, 183), // #1281
+ INST(Vpbroadcastq , VexRm_Lx_Bcst , V(660F38,59,_,x,0,1,3,T1S), E(660F38,7C,_,x,0,1,0,T1S), 122, 110, 367, 169), // #1282
+ INST(Vpbroadcastw , VexRm_Lx_Bcst , V(660F38,79,_,x,0,0,1,T1S), E(660F38,7B,_,x,0,0,0,T1S), 209, 111, 368, 182), // #1283
+ INST(Vpclmulqdq , VexRvmi_Lx , V(660F3A,44,_,x,I,_,4,FVM), 0 , 206, 0 , 369, 184), // #1284
+ INST(Vpcmov , VexRvrmRvmr_Lx , V(XOP_M8,A2,_,x,x,_,_,_ ), 0 , 210, 0 , 296, 168), // #1285
+ INST(Vpcmpb , VexRvmi_Lx , E(660F3A,3F,_,x,_,0,4,FVM), 0 , 112, 0 , 370, 163), // #1286
+ INST(Vpcmpd , VexRvmi_Lx , E(660F3A,1F,_,x,_,0,4,FV ), 0 , 112, 0 , 371, 152), // #1287
+ INST(Vpcmpeqb , VexRvm_Lx_KEvex , V(660F00,74,_,x,I,I,4,FV ), 0 , 145, 0 , 372, 181), // #1288
+ INST(Vpcmpeqd , VexRvm_Lx_KEvex , V(660F00,76,_,x,I,0,4,FVM), 0 , 145, 0 , 373, 157), // #1289
+ INST(Vpcmpeqq , VexRvm_Lx_KEvex , V(660F38,29,_,x,I,1,4,FVM), 0 , 211, 0 , 374, 157), // #1290
+ INST(Vpcmpeqw , VexRvm_Lx_KEvex , V(660F00,75,_,x,I,I,4,FV ), 0 , 145, 0 , 372, 181), // #1291
+ INST(Vpcmpestri , VexRmi , V(660F3A,61,_,0,I,_,_,_ ), 0 , 75 , 0 , 375, 185), // #1292
+ INST(Vpcmpestrm , VexRmi , V(660F3A,60,_,0,I,_,_,_ ), 0 , 75 , 0 , 376, 185), // #1293
+ INST(Vpcmpgtb , VexRvm_Lx_KEvex , V(660F00,64,_,x,I,I,4,FV ), 0 , 145, 0 , 372, 181), // #1294
+ INST(Vpcmpgtd , VexRvm_Lx_KEvex , V(660F00,66,_,x,I,0,4,FVM), 0 , 145, 0 , 373, 157), // #1295
+ INST(Vpcmpgtq , VexRvm_Lx_KEvex , V(660F38,37,_,x,I,1,4,FVM), 0 , 211, 0 , 374, 157), // #1296
+ INST(Vpcmpgtw , VexRvm_Lx_KEvex , V(660F00,65,_,x,I,I,4,FV ), 0 , 145, 0 , 372, 181), // #1297
+ INST(Vpcmpistri , VexRmi , V(660F3A,63,_,0,I,_,_,_ ), 0 , 75 , 0 , 377, 185), // #1298
+ INST(Vpcmpistrm , VexRmi , V(660F3A,62,_,0,I,_,_,_ ), 0 , 75 , 0 , 378, 185), // #1299
+ INST(Vpcmpq , VexRvmi_Lx , E(660F3A,1F,_,x,_,1,4,FV ), 0 , 113, 0 , 379, 152), // #1300
+ INST(Vpcmpub , VexRvmi_Lx , E(660F3A,3E,_,x,_,0,4,FVM), 0 , 112, 0 , 370, 163), // #1301
+ INST(Vpcmpud , VexRvmi_Lx , E(660F3A,1E,_,x,_,0,4,FV ), 0 , 112, 0 , 371, 152), // #1302
+ INST(Vpcmpuq , VexRvmi_Lx , E(660F3A,1E,_,x,_,1,4,FV ), 0 , 113, 0 , 379, 152), // #1303
+ INST(Vpcmpuw , VexRvmi_Lx , E(660F3A,3E,_,x,_,1,4,FVM), 0 , 113, 0 , 379, 163), // #1304
+ INST(Vpcmpw , VexRvmi_Lx , E(660F3A,3F,_,x,_,1,4,FVM), 0 , 113, 0 , 379, 163), // #1305
+ INST(Vpcomb , VexRvmi , V(XOP_M8,CC,_,0,0,_,_,_ ), 0 , 210, 0 , 283, 168), // #1306
+ INST(Vpcomd , VexRvmi , V(XOP_M8,CE,_,0,0,_,_,_ ), 0 , 210, 0 , 283, 168), // #1307
+ INST(Vpcompressb , VexMr_Lx , E(660F38,63,_,x,_,0,0,T1S), 0 , 212, 0 , 237, 186), // #1308
+ INST(Vpcompressd , VexMr_Lx , E(660F38,8B,_,x,_,0,2,T1S), 0 , 130, 0 , 237, 152), // #1309
+ INST(Vpcompressq , VexMr_Lx , E(660F38,8B,_,x,_,1,3,T1S), 0 , 129, 0 , 237, 152), // #1310
+ INST(Vpcompressw , VexMr_Lx , E(660F38,63,_,x,_,1,1,T1S), 0 , 213, 0 , 237, 186), // #1311
+ INST(Vpcomq , VexRvmi , V(XOP_M8,CF,_,0,0,_,_,_ ), 0 , 210, 0 , 283, 168), // #1312
+ INST(Vpcomub , VexRvmi , V(XOP_M8,EC,_,0,0,_,_,_ ), 0 , 210, 0 , 283, 168), // #1313
+ INST(Vpcomud , VexRvmi , V(XOP_M8,EE,_,0,0,_,_,_ ), 0 , 210, 0 , 283, 168), // #1314
+ INST(Vpcomuq , VexRvmi , V(XOP_M8,EF,_,0,0,_,_,_ ), 0 , 210, 0 , 283, 168), // #1315
+ INST(Vpcomuw , VexRvmi , V(XOP_M8,ED,_,0,0,_,_,_ ), 0 , 210, 0 , 283, 168), // #1316
+ INST(Vpcomw , VexRvmi , V(XOP_M8,CD,_,0,0,_,_,_ ), 0 , 210, 0 , 283, 168), // #1317
+ INST(Vpconflictd , VexRm_Lx , E(660F38,C4,_,x,_,0,4,FV ), 0 , 115, 0 , 380, 183), // #1318
+ INST(Vpconflictq , VexRm_Lx , E(660F38,C4,_,x,_,1,4,FV ), 0 , 114, 0 , 380, 183), // #1319
+ INST(Vpdpbssd , VexRvm_Lx , V(F20F38,50,_,x,0,_,_,_ ), 0 , 85 , 0 , 206, 187), // #1320
+ INST(Vpdpbssds , VexRvm_Lx , V(F20F38,51,_,x,0,_,_,_ ), 0 , 85 , 0 , 206, 187), // #1321
+ INST(Vpdpbsud , VexRvm_Lx , V(F30F38,50,_,x,0,_,_,_ ), 0 , 89 , 0 , 206, 187), // #1322
+ INST(Vpdpbsuds , VexRvm_Lx , V(F30F38,51,_,x,0,_,_,_ ), 0 , 89 , 0 , 206, 187), // #1323
+ INST(Vpdpbusd , VexRvm_Lx , V(660F38,50,_,x,_,0,4,FV ), 0 , 111, 0 , 381, 188), // #1324
+ INST(Vpdpbusds , VexRvm_Lx , V(660F38,51,_,x,_,0,4,FV ), 0 , 111, 0 , 381, 188), // #1325
+ INST(Vpdpbuud , VexRvm_Lx , V(000F38,50,_,x,0,_,_,_ ), 0 , 11 , 0 , 206, 187), // #1326
+ INST(Vpdpbuuds , VexRvm_Lx , V(000F38,51,_,x,0,_,_,_ ), 0 , 11 , 0 , 206, 187), // #1327
+ INST(Vpdpwssd , VexRvm_Lx , V(660F38,52,_,x,_,0,4,FV ), 0 , 111, 0 , 381, 188), // #1328
+ INST(Vpdpwssds , VexRvm_Lx , V(660F38,53,_,x,_,0,4,FV ), 0 , 111, 0 , 381, 188), // #1329
+ INST(Vpdpwsud , VexRvm_Lx , V(F30F38,D2,_,x,0,_,_,_ ), 0 , 89 , 0 , 206, 189), // #1330
+ INST(Vpdpwsuds , VexRvm_Lx , V(F30F38,D3,_,x,0,_,_,_ ), 0 , 89 , 0 , 206, 189), // #1331
+ INST(Vpdpwusd , VexRvm_Lx , V(660F38,D2,_,x,0,_,_,_ ), 0 , 30 , 0 , 206, 189), // #1332
+ INST(Vpdpwusds , VexRvm_Lx , V(660F38,D3,_,x,0,_,_,_ ), 0 , 30 , 0 , 206, 189), // #1333
+ INST(Vpdpwuud , VexRvm_Lx , V(000F38,D2,_,x,0,_,_,_ ), 0 , 11 , 0 , 206, 189), // #1334
+ INST(Vpdpwuuds , VexRvm_Lx , V(000F38,D3,_,x,0,_,_,_ ), 0 , 11 , 0 , 206, 189), // #1335
+ INST(Vperm2f128 , VexRvmi , V(660F3A,06,_,1,0,_,_,_ ), 0 , 174, 0 , 382, 149), // #1336
+ INST(Vperm2i128 , VexRvmi , V(660F3A,46,_,1,0,_,_,_ ), 0 , 174, 0 , 382, 156), // #1337
+ INST(Vpermb , VexRvm_Lx , E(660F38,8D,_,x,_,0,4,FVM), 0 , 115, 0 , 363, 190), // #1338
+ INST(Vpermd , VexRvm_Lx , V(660F38,36,_,x,0,0,4,FV ), 0 , 111, 0 , 383, 169), // #1339
+ INST(Vpermi2b , VexRvm_Lx , E(660F38,75,_,x,_,0,4,FVM), 0 , 115, 0 , 363, 190), // #1340
+ INST(Vpermi2d , VexRvm_Lx , E(660F38,76,_,x,_,0,4,FV ), 0 , 115, 0 , 218, 152), // #1341
+ INST(Vpermi2pd , VexRvm_Lx , E(660F38,77,_,x,_,1,4,FV ), 0 , 114, 0 , 217, 152), // #1342
+ INST(Vpermi2ps , VexRvm_Lx , E(660F38,77,_,x,_,0,4,FV ), 0 , 115, 0 , 218, 152), // #1343
+ INST(Vpermi2q , VexRvm_Lx , E(660F38,76,_,x,_,1,4,FV ), 0 , 114, 0 , 217, 152), // #1344
+ INST(Vpermi2w , VexRvm_Lx , E(660F38,75,_,x,_,1,4,FVM), 0 , 114, 0 , 363, 163), // #1345
+ INST(Vpermil2pd , VexRvrmiRvmri_Lx , V(660F3A,49,_,x,x,_,_,_ ), 0 , 75 , 0 , 384, 168), // #1346
+ INST(Vpermil2ps , VexRvrmiRvmri_Lx , V(660F3A,48,_,x,x,_,_,_ ), 0 , 75 , 0 , 384, 168), // #1347
+ INST(Vpermilpd , VexRvmRmi_Lx , V(660F38,0D,_,x,0,1,4,FV ), V(660F3A,05,_,x,0,1,4,FV ), 211, 112, 385, 145), // #1348
+ INST(Vpermilps , VexRvmRmi_Lx , V(660F38,0C,_,x,0,0,4,FV ), V(660F3A,04,_,x,0,0,4,FV ), 111, 113, 386, 145), // #1349
+ INST(Vpermpd , VexRvmRmi_Lx , E(660F38,16,_,x,1,1,4,FV ), V(660F3A,01,_,x,1,1,4,FV ), 214, 114, 387, 169), // #1350
+ INST(Vpermps , VexRvm_Lx , V(660F38,16,_,x,0,0,4,FV ), 0 , 111, 0 , 383, 169), // #1351
+ INST(Vpermq , VexRvmRmi_Lx , E(660F38,36,_,x,_,1,4,FV ), V(660F3A,00,_,x,1,1,4,FV ), 114, 115, 387, 169), // #1352
+ INST(Vpermt2b , VexRvm_Lx , E(660F38,7D,_,x,_,0,4,FVM), 0 , 115, 0 , 363, 190), // #1353
+ INST(Vpermt2d , VexRvm_Lx , E(660F38,7E,_,x,_,0,4,FV ), 0 , 115, 0 , 218, 152), // #1354
+ INST(Vpermt2pd , VexRvm_Lx , E(660F38,7F,_,x,_,1,4,FV ), 0 , 114, 0 , 217, 152), // #1355
+ INST(Vpermt2ps , VexRvm_Lx , E(660F38,7F,_,x,_,0,4,FV ), 0 , 115, 0 , 218, 152), // #1356
+ INST(Vpermt2q , VexRvm_Lx , E(660F38,7E,_,x,_,1,4,FV ), 0 , 114, 0 , 217, 152), // #1357
+ INST(Vpermt2w , VexRvm_Lx , E(660F38,7D,_,x,_,1,4,FVM), 0 , 114, 0 , 363, 163), // #1358
+ INST(Vpermw , VexRvm_Lx , E(660F38,8D,_,x,_,1,4,FVM), 0 , 114, 0 , 363, 163), // #1359
+ INST(Vpexpandb , VexRm_Lx , E(660F38,62,_,x,_,0,0,T1S), 0 , 212, 0 , 286, 186), // #1360
+ INST(Vpexpandd , VexRm_Lx , E(660F38,89,_,x,_,0,2,T1S), 0 , 130, 0 , 286, 152), // #1361
+ INST(Vpexpandq , VexRm_Lx , E(660F38,89,_,x,_,1,3,T1S), 0 , 129, 0 , 286, 152), // #1362
+ INST(Vpexpandw , VexRm_Lx , E(660F38,62,_,x,_,1,1,T1S), 0 , 213, 0 , 286, 186), // #1363
+ INST(Vpextrb , VexMri , V(660F3A,14,_,0,0,I,0,T1S), 0 , 75 , 0 , 388, 191), // #1364
+ INST(Vpextrd , VexMri , V(660F3A,16,_,0,0,0,2,T1S), 0 , 179, 0 , 290, 192), // #1365
+ INST(Vpextrq , VexMri , V(660F3A,16,_,0,1,1,3,T1S), 0 , 215, 0 , 389, 192), // #1366
+ INST(Vpextrw , VexMri_Vpextrw , V(660F3A,15,_,0,0,I,1,T1S), 0 , 216, 0 , 390, 191), // #1367
+ INST(Vpgatherdd , VexRmvRm_VM , V(660F38,90,_,x,0,_,_,_ ), E(660F38,90,_,x,_,0,2,T1S), 30 , 116, 309, 169), // #1368
+ INST(Vpgatherdq , VexRmvRm_VM , V(660F38,90,_,x,1,_,_,_ ), E(660F38,90,_,x,_,1,3,T1S), 191, 117, 308, 169), // #1369
+ INST(Vpgatherqd , VexRmvRm_VM , V(660F38,91,_,x,0,_,_,_ ), E(660F38,91,_,x,_,0,2,T1S), 30 , 118, 314, 169), // #1370
+ INST(Vpgatherqq , VexRmvRm_VM , V(660F38,91,_,x,1,_,_,_ ), E(660F38,91,_,x,_,1,3,T1S), 191, 119, 313, 169), // #1371
+ INST(Vphaddbd , VexRm , V(XOP_M9,C2,_,0,0,_,_,_ ), 0 , 81 , 0 , 208, 168), // #1372
+ INST(Vphaddbq , VexRm , V(XOP_M9,C3,_,0,0,_,_,_ ), 0 , 81 , 0 , 208, 168), // #1373
+ INST(Vphaddbw , VexRm , V(XOP_M9,C1,_,0,0,_,_,_ ), 0 , 81 , 0 , 208, 168), // #1374
+ INST(Vphaddd , VexRvm_Lx , V(660F38,02,_,x,I,_,_,_ ), 0 , 30 , 0 , 206, 178), // #1375
+ INST(Vphadddq , VexRm , V(XOP_M9,CB,_,0,0,_,_,_ ), 0 , 81 , 0 , 208, 168), // #1376
+ INST(Vphaddsw , VexRvm_Lx , V(660F38,03,_,x,I,_,_,_ ), 0 , 30 , 0 , 206, 178), // #1377
+ INST(Vphaddubd , VexRm , V(XOP_M9,D2,_,0,0,_,_,_ ), 0 , 81 , 0 , 208, 168), // #1378
+ INST(Vphaddubq , VexRm , V(XOP_M9,D3,_,0,0,_,_,_ ), 0 , 81 , 0 , 208, 168), // #1379
+ INST(Vphaddubw , VexRm , V(XOP_M9,D1,_,0,0,_,_,_ ), 0 , 81 , 0 , 208, 168), // #1380
+ INST(Vphaddudq , VexRm , V(XOP_M9,DB,_,0,0,_,_,_ ), 0 , 81 , 0 , 208, 168), // #1381
+ INST(Vphadduwd , VexRm , V(XOP_M9,D6,_,0,0,_,_,_ ), 0 , 81 , 0 , 208, 168), // #1382
+ INST(Vphadduwq , VexRm , V(XOP_M9,D7,_,0,0,_,_,_ ), 0 , 81 , 0 , 208, 168), // #1383
+ INST(Vphaddw , VexRvm_Lx , V(660F38,01,_,x,I,_,_,_ ), 0 , 30 , 0 , 206, 178), // #1384
+ INST(Vphaddwd , VexRm , V(XOP_M9,C6,_,0,0,_,_,_ ), 0 , 81 , 0 , 208, 168), // #1385
+ INST(Vphaddwq , VexRm , V(XOP_M9,C7,_,0,0,_,_,_ ), 0 , 81 , 0 , 208, 168), // #1386
+ INST(Vphminposuw , VexRm , V(660F38,41,_,0,I,_,_,_ ), 0 , 30 , 0 , 208, 149), // #1387
+ INST(Vphsubbw , VexRm , V(XOP_M9,E1,_,0,0,_,_,_ ), 0 , 81 , 0 , 208, 168), // #1388
+ INST(Vphsubd , VexRvm_Lx , V(660F38,06,_,x,I,_,_,_ ), 0 , 30 , 0 , 206, 178), // #1389
+ INST(Vphsubdq , VexRm , V(XOP_M9,E3,_,0,0,_,_,_ ), 0 , 81 , 0 , 208, 168), // #1390
+ INST(Vphsubsw , VexRvm_Lx , V(660F38,07,_,x,I,_,_,_ ), 0 , 30 , 0 , 206, 178), // #1391
+ INST(Vphsubw , VexRvm_Lx , V(660F38,05,_,x,I,_,_,_ ), 0 , 30 , 0 , 206, 178), // #1392
+ INST(Vphsubwd , VexRm , V(XOP_M9,E2,_,0,0,_,_,_ ), 0 , 81 , 0 , 208, 168), // #1393
+ INST(Vpinsrb , VexRvmi , V(660F3A,20,_,0,0,I,0,T1S), 0 , 75 , 0 , 391, 191), // #1394
+ INST(Vpinsrd , VexRvmi , V(660F3A,22,_,0,0,0,2,T1S), 0 , 179, 0 , 392, 192), // #1395
+ INST(Vpinsrq , VexRvmi , V(660F3A,22,_,0,1,1,3,T1S), 0 , 215, 0 , 393, 192), // #1396
+ INST(Vpinsrw , VexRvmi , V(660F00,C4,_,0,0,I,1,T1S), 0 , 217, 0 , 394, 191), // #1397
+ INST(Vplzcntd , VexRm_Lx , E(660F38,44,_,x,_,0,4,FV ), 0 , 115, 0 , 380, 183), // #1398
+ INST(Vplzcntq , VexRm_Lx , E(660F38,44,_,x,_,1,4,FV ), 0 , 114, 0 , 356, 183), // #1399
+ INST(Vpmacsdd , VexRvmr , V(XOP_M8,9E,_,0,0,_,_,_ ), 0 , 210, 0 , 395, 168), // #1400
+ INST(Vpmacsdqh , VexRvmr , V(XOP_M8,9F,_,0,0,_,_,_ ), 0 , 210, 0 , 395, 168), // #1401
+ INST(Vpmacsdql , VexRvmr , V(XOP_M8,97,_,0,0,_,_,_ ), 0 , 210, 0 , 395, 168), // #1402
+ INST(Vpmacssdd , VexRvmr , V(XOP_M8,8E,_,0,0,_,_,_ ), 0 , 210, 0 , 395, 168), // #1403
+ INST(Vpmacssdqh , VexRvmr , V(XOP_M8,8F,_,0,0,_,_,_ ), 0 , 210, 0 , 395, 168), // #1404
+ INST(Vpmacssdql , VexRvmr , V(XOP_M8,87,_,0,0,_,_,_ ), 0 , 210, 0 , 395, 168), // #1405
+ INST(Vpmacsswd , VexRvmr , V(XOP_M8,86,_,0,0,_,_,_ ), 0 , 210, 0 , 395, 168), // #1406
+ INST(Vpmacssww , VexRvmr , V(XOP_M8,85,_,0,0,_,_,_ ), 0 , 210, 0 , 395, 168), // #1407
+ INST(Vpmacswd , VexRvmr , V(XOP_M8,96,_,0,0,_,_,_ ), 0 , 210, 0 , 395, 168), // #1408
+ INST(Vpmacsww , VexRvmr , V(XOP_M8,95,_,0,0,_,_,_ ), 0 , 210, 0 , 395, 168), // #1409
+ INST(Vpmadcsswd , VexRvmr , V(XOP_M8,A6,_,0,0,_,_,_ ), 0 , 210, 0 , 395, 168), // #1410
+ INST(Vpmadcswd , VexRvmr , V(XOP_M8,B6,_,0,0,_,_,_ ), 0 , 210, 0 , 395, 168), // #1411
+ INST(Vpmadd52huq , VexRvm_Lx , V(660F38,B5,_,x,1,1,4,FV ), 0 , 184, 0 , 396, 193), // #1412
+ INST(Vpmadd52luq , VexRvm_Lx , V(660F38,B4,_,x,1,1,4,FV ), 0 , 184, 0 , 396, 193), // #1413
+ INST(Vpmaddubsw , VexRvm_Lx , V(660F38,04,_,x,I,I,4,FVM), 0 , 111, 0 , 322, 181), // #1414
+ INST(Vpmaddwd , VexRvm_Lx , V(660F00,F5,_,x,I,I,4,FVM), 0 , 145, 0 , 322, 181), // #1415
+ INST(Vpmaskmovd , VexRvmMvr_Lx , V(660F38,8C,_,x,0,_,_,_ ), V(660F38,8E,_,x,0,_,_,_ ), 30 , 120, 329, 156), // #1416
+ INST(Vpmaskmovq , VexRvmMvr_Lx , V(660F38,8C,_,x,1,_,_,_ ), V(660F38,8E,_,x,1,_,_,_ ), 191, 121, 329, 156), // #1417
+ INST(Vpmaxsb , VexRvm_Lx , V(660F38,3C,_,x,I,I,4,FVM), 0 , 111, 0 , 397, 181), // #1418
+ INST(Vpmaxsd , VexRvm_Lx , V(660F38,3D,_,x,I,0,4,FV ), 0 , 111, 0 , 215, 157), // #1419
+ INST(Vpmaxsq , VexRvm_Lx , E(660F38,3D,_,x,_,1,4,FV ), 0 , 114, 0 , 217, 152), // #1420
+ INST(Vpmaxsw , VexRvm_Lx , V(660F00,EE,_,x,I,I,4,FVM), 0 , 145, 0 , 397, 181), // #1421
+ INST(Vpmaxub , VexRvm_Lx , V(660F00,DE,_,x,I,I,4,FVM), 0 , 145, 0 , 397, 181), // #1422
+ INST(Vpmaxud , VexRvm_Lx , V(660F38,3F,_,x,I,0,4,FV ), 0 , 111, 0 , 215, 157), // #1423
+ INST(Vpmaxuq , VexRvm_Lx , E(660F38,3F,_,x,_,1,4,FV ), 0 , 114, 0 , 217, 152), // #1424
+ INST(Vpmaxuw , VexRvm_Lx , V(660F38,3E,_,x,I,I,4,FVM), 0 , 111, 0 , 397, 181), // #1425
+ INST(Vpminsb , VexRvm_Lx , V(660F38,38,_,x,I,I,4,FVM), 0 , 111, 0 , 397, 181), // #1426
+ INST(Vpminsd , VexRvm_Lx , V(660F38,39,_,x,I,0,4,FV ), 0 , 111, 0 , 215, 157), // #1427
+ INST(Vpminsq , VexRvm_Lx , E(660F38,39,_,x,_,1,4,FV ), 0 , 114, 0 , 217, 152), // #1428
+ INST(Vpminsw , VexRvm_Lx , V(660F00,EA,_,x,I,I,4,FVM), 0 , 145, 0 , 397, 181), // #1429
+ INST(Vpminub , VexRvm_Lx , V(660F00,DA,_,x,I,_,4,FVM), 0 , 145, 0 , 397, 181), // #1430
+ INST(Vpminud , VexRvm_Lx , V(660F38,3B,_,x,I,0,4,FV ), 0 , 111, 0 , 215, 157), // #1431
+ INST(Vpminuq , VexRvm_Lx , E(660F38,3B,_,x,_,1,4,FV ), 0 , 114, 0 , 217, 152), // #1432
+ INST(Vpminuw , VexRvm_Lx , V(660F38,3A,_,x,I,_,4,FVM), 0 , 111, 0 , 397, 181), // #1433
+ INST(Vpmovb2m , VexRm_Lx , E(F30F38,29,_,x,_,0,_,_ ), 0 , 208, 0 , 398, 163), // #1434
+ INST(Vpmovd2m , VexRm_Lx , E(F30F38,39,_,x,_,0,_,_ ), 0 , 208, 0 , 398, 155), // #1435
+ INST(Vpmovdb , VexMr_Lx , E(F30F38,31,_,x,_,0,2,QVM), 0 , 218, 0 , 399, 152), // #1436
+ INST(Vpmovdw , VexMr_Lx , E(F30F38,33,_,x,_,0,3,HVM), 0 , 219, 0 , 400, 152), // #1437
+ INST(Vpmovm2b , VexRm_Lx , E(F30F38,28,_,x,_,0,_,_ ), 0 , 208, 0 , 366, 163), // #1438
+ INST(Vpmovm2d , VexRm_Lx , E(F30F38,38,_,x,_,0,_,_ ), 0 , 208, 0 , 366, 155), // #1439
+ INST(Vpmovm2q , VexRm_Lx , E(F30F38,38,_,x,_,1,_,_ ), 0 , 207, 0 , 366, 155), // #1440
+ INST(Vpmovm2w , VexRm_Lx , E(F30F38,28,_,x,_,1,_,_ ), 0 , 207, 0 , 366, 163), // #1441
+ INST(Vpmovmskb , VexRm_Lx , V(660F00,D7,_,x,I,_,_,_ ), 0 , 71 , 0 , 342, 178), // #1442
+ INST(Vpmovq2m , VexRm_Lx , E(F30F38,39,_,x,_,1,_,_ ), 0 , 207, 0 , 398, 155), // #1443
+ INST(Vpmovqb , VexMr_Lx , E(F30F38,32,_,x,_,0,1,OVM), 0 , 220, 0 , 401, 152), // #1444
+ INST(Vpmovqd , VexMr_Lx , E(F30F38,35,_,x,_,0,3,HVM), 0 , 219, 0 , 400, 152), // #1445
+ INST(Vpmovqw , VexMr_Lx , E(F30F38,34,_,x,_,0,2,QVM), 0 , 218, 0 , 399, 152), // #1446
+ INST(Vpmovsdb , VexMr_Lx , E(F30F38,21,_,x,_,0,2,QVM), 0 , 218, 0 , 399, 152), // #1447
+ INST(Vpmovsdw , VexMr_Lx , E(F30F38,23,_,x,_,0,3,HVM), 0 , 219, 0 , 400, 152), // #1448
+ INST(Vpmovsqb , VexMr_Lx , E(F30F38,22,_,x,_,0,1,OVM), 0 , 220, 0 , 401, 152), // #1449
+ INST(Vpmovsqd , VexMr_Lx , E(F30F38,25,_,x,_,0,3,HVM), 0 , 219, 0 , 400, 152), // #1450
+ INST(Vpmovsqw , VexMr_Lx , E(F30F38,24,_,x,_,0,2,QVM), 0 , 218, 0 , 399, 152), // #1451
+ INST(Vpmovswb , VexMr_Lx , E(F30F38,20,_,x,_,0,3,HVM), 0 , 219, 0 , 400, 163), // #1452
+ INST(Vpmovsxbd , VexRm_Lx , V(660F38,21,_,x,I,I,2,QVM), 0 , 221, 0 , 402, 157), // #1453
+ INST(Vpmovsxbq , VexRm_Lx , V(660F38,22,_,x,I,I,1,OVM), 0 , 222, 0 , 403, 157), // #1454
+ INST(Vpmovsxbw , VexRm_Lx , V(660F38,20,_,x,I,I,3,HVM), 0 , 140, 0 , 404, 181), // #1455
+ INST(Vpmovsxdq , VexRm_Lx , V(660F38,25,_,x,I,0,3,HVM), 0 , 140, 0 , 404, 157), // #1456
+ INST(Vpmovsxwd , VexRm_Lx , V(660F38,23,_,x,I,I,3,HVM), 0 , 140, 0 , 404, 157), // #1457
+ INST(Vpmovsxwq , VexRm_Lx , V(660F38,24,_,x,I,I,2,QVM), 0 , 221, 0 , 402, 157), // #1458
+ INST(Vpmovusdb , VexMr_Lx , E(F30F38,11,_,x,_,0,2,QVM), 0 , 218, 0 , 399, 152), // #1459
+ INST(Vpmovusdw , VexMr_Lx , E(F30F38,13,_,x,_,0,3,HVM), 0 , 219, 0 , 400, 152), // #1460
+ INST(Vpmovusqb , VexMr_Lx , E(F30F38,12,_,x,_,0,1,OVM), 0 , 220, 0 , 401, 152), // #1461
+ INST(Vpmovusqd , VexMr_Lx , E(F30F38,15,_,x,_,0,3,HVM), 0 , 219, 0 , 400, 152), // #1462
+ INST(Vpmovusqw , VexMr_Lx , E(F30F38,14,_,x,_,0,2,QVM), 0 , 218, 0 , 399, 152), // #1463
+ INST(Vpmovuswb , VexMr_Lx , E(F30F38,10,_,x,_,0,3,HVM), 0 , 219, 0 , 400, 163), // #1464
+ INST(Vpmovw2m , VexRm_Lx , E(F30F38,29,_,x,_,1,_,_ ), 0 , 207, 0 , 398, 163), // #1465
+ INST(Vpmovwb , VexMr_Lx , E(F30F38,30,_,x,_,0,3,HVM), 0 , 219, 0 , 400, 163), // #1466
+ INST(Vpmovzxbd , VexRm_Lx , V(660F38,31,_,x,I,I,2,QVM), 0 , 221, 0 , 402, 157), // #1467
+ INST(Vpmovzxbq , VexRm_Lx , V(660F38,32,_,x,I,I,1,OVM), 0 , 222, 0 , 403, 157), // #1468
+ INST(Vpmovzxbw , VexRm_Lx , V(660F38,30,_,x,I,I,3,HVM), 0 , 140, 0 , 404, 181), // #1469
+ INST(Vpmovzxdq , VexRm_Lx , V(660F38,35,_,x,I,0,3,HVM), 0 , 140, 0 , 404, 157), // #1470
+ INST(Vpmovzxwd , VexRm_Lx , V(660F38,33,_,x,I,I,3,HVM), 0 , 140, 0 , 404, 157), // #1471
+ INST(Vpmovzxwq , VexRm_Lx , V(660F38,34,_,x,I,I,2,QVM), 0 , 221, 0 , 402, 157), // #1472
+ INST(Vpmuldq , VexRvm_Lx , V(660F38,28,_,x,I,1,4,FV ), 0 , 211, 0 , 212, 157), // #1473
+ INST(Vpmulhrsw , VexRvm_Lx , V(660F38,0B,_,x,I,I,4,FVM), 0 , 111, 0 , 322, 181), // #1474
+ INST(Vpmulhuw , VexRvm_Lx , V(660F00,E4,_,x,I,I,4,FVM), 0 , 145, 0 , 322, 181), // #1475
+ INST(Vpmulhw , VexRvm_Lx , V(660F00,E5,_,x,I,I,4,FVM), 0 , 145, 0 , 322, 181), // #1476
+ INST(Vpmulld , VexRvm_Lx , V(660F38,40,_,x,I,0,4,FV ), 0 , 111, 0 , 213, 157), // #1477
+ INST(Vpmullq , VexRvm_Lx , E(660F38,40,_,x,_,1,4,FV ), 0 , 114, 0 , 217, 155), // #1478
+ INST(Vpmullw , VexRvm_Lx , V(660F00,D5,_,x,I,I,4,FVM), 0 , 145, 0 , 322, 181), // #1479
+ INST(Vpmultishiftqb , VexRvm_Lx , E(660F38,83,_,x,_,1,4,FV ), 0 , 114, 0 , 217, 190), // #1480
+ INST(Vpmuludq , VexRvm_Lx , V(660F00,F4,_,x,I,1,4,FV ), 0 , 104, 0 , 212, 157), // #1481
+ INST(Vpopcntb , VexRm_Lx , E(660F38,54,_,x,_,0,4,FV ), 0 , 115, 0 , 286, 194), // #1482
+ INST(Vpopcntd , VexRm_Lx , E(660F38,55,_,x,_,0,4,FVM), 0 , 115, 0 , 380, 195), // #1483
+ INST(Vpopcntq , VexRm_Lx , E(660F38,55,_,x,_,1,4,FVM), 0 , 114, 0 , 356, 195), // #1484
+ INST(Vpopcntw , VexRm_Lx , E(660F38,54,_,x,_,1,4,FV ), 0 , 114, 0 , 286, 194), // #1485
+ INST(Vpor , VexRvm_Lx , V(660F00,EB,_,x,I,_,_,_ ), 0 , 71 , 0 , 357, 178), // #1486
+ INST(Vpord , VexRvm_Lx , E(660F00,EB,_,x,_,0,4,FV ), 0 , 200, 0 , 358, 152), // #1487
+ INST(Vporq , VexRvm_Lx , E(660F00,EB,_,x,_,1,4,FV ), 0 , 136, 0 , 362, 152), // #1488
+ INST(Vpperm , VexRvrmRvmr , V(XOP_M8,A3,_,0,x,_,_,_ ), 0 , 210, 0 , 405, 168), // #1489
+ INST(Vprold , VexVmi_Lx , E(660F00,72,1,x,_,0,4,FV ), 0 , 223, 0 , 406, 152), // #1490
+ INST(Vprolq , VexVmi_Lx , E(660F00,72,1,x,_,1,4,FV ), 0 , 224, 0 , 407, 152), // #1491
+ INST(Vprolvd , VexRvm_Lx , E(660F38,15,_,x,_,0,4,FV ), 0 , 115, 0 , 218, 152), // #1492
+ INST(Vprolvq , VexRvm_Lx , E(660F38,15,_,x,_,1,4,FV ), 0 , 114, 0 , 217, 152), // #1493
+ INST(Vprord , VexVmi_Lx , E(660F00,72,0,x,_,0,4,FV ), 0 , 200, 0 , 406, 152), // #1494
+ INST(Vprorq , VexVmi_Lx , E(660F00,72,0,x,_,1,4,FV ), 0 , 136, 0 , 407, 152), // #1495
+ INST(Vprorvd , VexRvm_Lx , E(660F38,14,_,x,_,0,4,FV ), 0 , 115, 0 , 218, 152), // #1496
+ INST(Vprorvq , VexRvm_Lx , E(660F38,14,_,x,_,1,4,FV ), 0 , 114, 0 , 217, 152), // #1497
+ INST(Vprotb , VexRvmRmvRmi , V(XOP_M9,90,_,0,x,_,_,_ ), V(XOP_M8,C0,_,0,x,_,_,_ ), 81 , 122, 408, 168), // #1498
+ INST(Vprotd , VexRvmRmvRmi , V(XOP_M9,92,_,0,x,_,_,_ ), V(XOP_M8,C2,_,0,x,_,_,_ ), 81 , 123, 408, 168), // #1499
+ INST(Vprotq , VexRvmRmvRmi , V(XOP_M9,93,_,0,x,_,_,_ ), V(XOP_M8,C3,_,0,x,_,_,_ ), 81 , 124, 408, 168), // #1500
+ INST(Vprotw , VexRvmRmvRmi , V(XOP_M9,91,_,0,x,_,_,_ ), V(XOP_M8,C1,_,0,x,_,_,_ ), 81 , 125, 408, 168), // #1501
+ INST(Vpsadbw , VexRvm_Lx , V(660F00,F6,_,x,I,I,4,FVM), 0 , 145, 0 , 207, 181), // #1502
+ INST(Vpscatterdd , VexMr_VM , E(660F38,A0,_,x,_,0,2,T1S), 0 , 130, 0 , 409, 152), // #1503
+ INST(Vpscatterdq , VexMr_VM , E(660F38,A0,_,x,_,1,3,T1S), 0 , 129, 0 , 410, 152), // #1504
+ INST(Vpscatterqd , VexMr_VM , E(660F38,A1,_,x,_,0,2,T1S), 0 , 130, 0 , 411, 152), // #1505
+ INST(Vpscatterqq , VexMr_VM , E(660F38,A1,_,x,_,1,3,T1S), 0 , 129, 0 , 412, 152), // #1506
+ INST(Vpshab , VexRvmRmv , V(XOP_M9,98,_,0,x,_,_,_ ), 0 , 81 , 0 , 413, 168), // #1507
+ INST(Vpshad , VexRvmRmv , V(XOP_M9,9A,_,0,x,_,_,_ ), 0 , 81 , 0 , 413, 168), // #1508
+ INST(Vpshaq , VexRvmRmv , V(XOP_M9,9B,_,0,x,_,_,_ ), 0 , 81 , 0 , 413, 168), // #1509
+ INST(Vpshaw , VexRvmRmv , V(XOP_M9,99,_,0,x,_,_,_ ), 0 , 81 , 0 , 413, 168), // #1510
+ INST(Vpshlb , VexRvmRmv , V(XOP_M9,94,_,0,x,_,_,_ ), 0 , 81 , 0 , 413, 168), // #1511
+ INST(Vpshld , VexRvmRmv , V(XOP_M9,96,_,0,x,_,_,_ ), 0 , 81 , 0 , 413, 168), // #1512
+ INST(Vpshldd , VexRvmi_Lx , E(660F3A,71,_,x,_,0,4,FV ), 0 , 112, 0 , 210, 186), // #1513
+ INST(Vpshldq , VexRvmi_Lx , E(660F3A,71,_,x,_,1,4,FV ), 0 , 113, 0 , 211, 186), // #1514
+ INST(Vpshldvd , VexRvm_Lx , E(660F38,71,_,x,_,0,4,FV ), 0 , 115, 0 , 218, 186), // #1515
+ INST(Vpshldvq , VexRvm_Lx , E(660F38,71,_,x,_,1,4,FV ), 0 , 114, 0 , 217, 186), // #1516
+ INST(Vpshldvw , VexRvm_Lx , E(660F38,70,_,x,_,1,4,FVM), 0 , 114, 0 , 363, 186), // #1517
+ INST(Vpshldw , VexRvmi_Lx , E(660F3A,70,_,x,_,1,4,FVM), 0 , 113, 0 , 282, 186), // #1518
+ INST(Vpshlq , VexRvmRmv , V(XOP_M9,97,_,0,x,_,_,_ ), 0 , 81 , 0 , 413, 168), // #1519
+ INST(Vpshlw , VexRvmRmv , V(XOP_M9,95,_,0,x,_,_,_ ), 0 , 81 , 0 , 413, 168), // #1520
+ INST(Vpshrdd , VexRvmi_Lx , E(660F3A,73,_,x,_,0,4,FV ), 0 , 112, 0 , 210, 186), // #1521
+ INST(Vpshrdq , VexRvmi_Lx , E(660F3A,73,_,x,_,1,4,FV ), 0 , 113, 0 , 211, 186), // #1522
+ INST(Vpshrdvd , VexRvm_Lx , E(660F38,73,_,x,_,0,4,FV ), 0 , 115, 0 , 218, 186), // #1523
+ INST(Vpshrdvq , VexRvm_Lx , E(660F38,73,_,x,_,1,4,FV ), 0 , 114, 0 , 217, 186), // #1524
+ INST(Vpshrdvw , VexRvm_Lx , E(660F38,72,_,x,_,1,4,FVM), 0 , 114, 0 , 363, 186), // #1525
+ INST(Vpshrdw , VexRvmi_Lx , E(660F3A,72,_,x,_,1,4,FVM), 0 , 113, 0 , 282, 186), // #1526
+ INST(Vpshufb , VexRvm_Lx , V(660F38,00,_,x,I,I,4,FVM), 0 , 111, 0 , 322, 181), // #1527
+ INST(Vpshufbitqmb , VexRvm_Lx , E(660F38,8F,_,x,0,0,4,FVM), 0 , 115, 0 , 414, 194), // #1528
+ INST(Vpshufd , VexRmi_Lx , V(660F00,70,_,x,I,0,4,FV ), 0 , 145, 0 , 415, 157), // #1529
+ INST(Vpshufhw , VexRmi_Lx , V(F30F00,70,_,x,I,I,4,FVM), 0 , 162, 0 , 416, 181), // #1530
+ INST(Vpshuflw , VexRmi_Lx , V(F20F00,70,_,x,I,I,4,FVM), 0 , 225, 0 , 416, 181), // #1531
+ INST(Vpsignb , VexRvm_Lx , V(660F38,08,_,x,I,_,_,_ ), 0 , 30 , 0 , 206, 178), // #1532
+ INST(Vpsignd , VexRvm_Lx , V(660F38,0A,_,x,I,_,_,_ ), 0 , 30 , 0 , 206, 178), // #1533
+ INST(Vpsignw , VexRvm_Lx , V(660F38,09,_,x,I,_,_,_ ), 0 , 30 , 0 , 206, 178), // #1534
+ INST(Vpslld , VexRvmVmi_Lx_MEvex , V(660F00,F2,_,x,I,0,4,128), V(660F00,72,6,x,I,0,4,FV ), 226, 126, 417, 157), // #1535
+ INST(Vpslldq , VexVmi_Lx_MEvex , V(660F00,73,7,x,I,I,4,FVM), 0 , 227, 0 , 418, 181), // #1536
+ INST(Vpsllq , VexRvmVmi_Lx_MEvex , V(660F00,F3,_,x,I,1,4,128), V(660F00,73,6,x,I,1,4,FV ), 228, 127, 419, 157), // #1537
+ INST(Vpsllvd , VexRvm_Lx , V(660F38,47,_,x,0,0,4,FV ), 0 , 111, 0 , 213, 169), // #1538
+ INST(Vpsllvq , VexRvm_Lx , V(660F38,47,_,x,1,1,4,FV ), 0 , 184, 0 , 212, 169), // #1539
+ INST(Vpsllvw , VexRvm_Lx , E(660F38,12,_,x,_,1,4,FVM), 0 , 114, 0 , 363, 163), // #1540
+ INST(Vpsllw , VexRvmVmi_Lx_MEvex , V(660F00,F1,_,x,I,I,4,128), V(660F00,71,6,x,I,I,4,FVM), 226, 128, 420, 181), // #1541
+ INST(Vpsrad , VexRvmVmi_Lx_MEvex , V(660F00,E2,_,x,I,0,4,128), V(660F00,72,4,x,I,0,4,FV ), 226, 129, 417, 157), // #1542
+ INST(Vpsraq , VexRvmVmi_Lx_MEvex , E(660F00,E2,_,x,_,1,4,128), E(660F00,72,4,x,_,1,4,FV ), 229, 130, 421, 152), // #1543
+ INST(Vpsravd , VexRvm_Lx , V(660F38,46,_,x,0,0,4,FV ), 0 , 111, 0 , 213, 169), // #1544
+ INST(Vpsravq , VexRvm_Lx , E(660F38,46,_,x,_,1,4,FV ), 0 , 114, 0 , 217, 152), // #1545
+ INST(Vpsravw , VexRvm_Lx , E(660F38,11,_,x,_,1,4,FVM), 0 , 114, 0 , 363, 163), // #1546
+ INST(Vpsraw , VexRvmVmi_Lx_MEvex , V(660F00,E1,_,x,I,I,4,128), V(660F00,71,4,x,I,I,4,FVM), 226, 131, 420, 181), // #1547
+ INST(Vpsrld , VexRvmVmi_Lx_MEvex , V(660F00,D2,_,x,I,0,4,128), V(660F00,72,2,x,I,0,4,FV ), 226, 132, 417, 157), // #1548
+ INST(Vpsrldq , VexVmi_Lx_MEvex , V(660F00,73,3,x,I,I,4,FVM), 0 , 230, 0 , 418, 181), // #1549
+ INST(Vpsrlq , VexRvmVmi_Lx_MEvex , V(660F00,D3,_,x,I,1,4,128), V(660F00,73,2,x,I,1,4,FV ), 228, 133, 419, 157), // #1550
+ INST(Vpsrlvd , VexRvm_Lx , V(660F38,45,_,x,0,0,4,FV ), 0 , 111, 0 , 213, 169), // #1551
+ INST(Vpsrlvq , VexRvm_Lx , V(660F38,45,_,x,1,1,4,FV ), 0 , 184, 0 , 212, 169), // #1552
+ INST(Vpsrlvw , VexRvm_Lx , E(660F38,10,_,x,_,1,4,FVM), 0 , 114, 0 , 363, 163), // #1553
+ INST(Vpsrlw , VexRvmVmi_Lx_MEvex , V(660F00,D1,_,x,I,I,4,128), V(660F00,71,2,x,I,I,4,FVM), 226, 134, 420, 181), // #1554
+ INST(Vpsubb , VexRvm_Lx , V(660F00,F8,_,x,I,I,4,FVM), 0 , 145, 0 , 422, 181), // #1555
+ INST(Vpsubd , VexRvm_Lx , V(660F00,FA,_,x,I,0,4,FV ), 0 , 145, 0 , 423, 157), // #1556
+ INST(Vpsubq , VexRvm_Lx , V(660F00,FB,_,x,I,1,4,FV ), 0 , 104, 0 , 424, 157), // #1557
+ INST(Vpsubsb , VexRvm_Lx , V(660F00,E8,_,x,I,I,4,FVM), 0 , 145, 0 , 422, 181), // #1558
+ INST(Vpsubsw , VexRvm_Lx , V(660F00,E9,_,x,I,I,4,FVM), 0 , 145, 0 , 422, 181), // #1559
+ INST(Vpsubusb , VexRvm_Lx , V(660F00,D8,_,x,I,I,4,FVM), 0 , 145, 0 , 422, 181), // #1560
+ INST(Vpsubusw , VexRvm_Lx , V(660F00,D9,_,x,I,I,4,FVM), 0 , 145, 0 , 422, 181), // #1561
+ INST(Vpsubw , VexRvm_Lx , V(660F00,F9,_,x,I,I,4,FVM), 0 , 145, 0 , 422, 181), // #1562
+ INST(Vpternlogd , VexRvmi_Lx , E(660F3A,25,_,x,_,0,4,FV ), 0 , 112, 0 , 210, 152), // #1563
+ INST(Vpternlogq , VexRvmi_Lx , E(660F3A,25,_,x,_,1,4,FV ), 0 , 113, 0 , 211, 152), // #1564
+ INST(Vptest , VexRm_Lx , V(660F38,17,_,x,I,_,_,_ ), 0 , 30 , 0 , 305, 185), // #1565
+ INST(Vptestmb , VexRvm_Lx , E(660F38,26,_,x,_,0,4,FVM), 0 , 115, 0 , 414, 163), // #1566
+ INST(Vptestmd , VexRvm_Lx , E(660F38,27,_,x,_,0,4,FV ), 0 , 115, 0 , 425, 152), // #1567
+ INST(Vptestmq , VexRvm_Lx , E(660F38,27,_,x,_,1,4,FV ), 0 , 114, 0 , 426, 152), // #1568
+ INST(Vptestmw , VexRvm_Lx , E(660F38,26,_,x,_,1,4,FVM), 0 , 114, 0 , 414, 163), // #1569
+ INST(Vptestnmb , VexRvm_Lx , E(F30F38,26,_,x,_,0,4,FVM), 0 , 171, 0 , 414, 163), // #1570
+ INST(Vptestnmd , VexRvm_Lx , E(F30F38,27,_,x,_,0,4,FV ), 0 , 171, 0 , 425, 152), // #1571
+ INST(Vptestnmq , VexRvm_Lx , E(F30F38,27,_,x,_,1,4,FV ), 0 , 231, 0 , 426, 152), // #1572
+ INST(Vptestnmw , VexRvm_Lx , E(F30F38,26,_,x,_,1,4,FVM), 0 , 231, 0 , 414, 163), // #1573
+ INST(Vpunpckhbw , VexRvm_Lx , V(660F00,68,_,x,I,I,4,FVM), 0 , 145, 0 , 322, 181), // #1574
+ INST(Vpunpckhdq , VexRvm_Lx , V(660F00,6A,_,x,I,0,4,FV ), 0 , 145, 0 , 213, 157), // #1575
+ INST(Vpunpckhqdq , VexRvm_Lx , V(660F00,6D,_,x,I,1,4,FV ), 0 , 104, 0 , 212, 157), // #1576
+ INST(Vpunpckhwd , VexRvm_Lx , V(660F00,69,_,x,I,I,4,FVM), 0 , 145, 0 , 322, 181), // #1577
+ INST(Vpunpcklbw , VexRvm_Lx , V(660F00,60,_,x,I,I,4,FVM), 0 , 145, 0 , 322, 181), // #1578
+ INST(Vpunpckldq , VexRvm_Lx , V(660F00,62,_,x,I,0,4,FV ), 0 , 145, 0 , 213, 157), // #1579
+ INST(Vpunpcklqdq , VexRvm_Lx , V(660F00,6C,_,x,I,1,4,FV ), 0 , 104, 0 , 212, 157), // #1580
+ INST(Vpunpcklwd , VexRvm_Lx , V(660F00,61,_,x,I,I,4,FVM), 0 , 145, 0 , 322, 181), // #1581
+ INST(Vpxor , VexRvm_Lx , V(660F00,EF,_,x,I,_,_,_ ), 0 , 71 , 0 , 359, 178), // #1582
+ INST(Vpxord , VexRvm_Lx , E(660F00,EF,_,x,_,0,4,FV ), 0 , 200, 0 , 360, 152), // #1583
+ INST(Vpxorq , VexRvm_Lx , E(660F00,EF,_,x,_,1,4,FV ), 0 , 136, 0 , 361, 152), // #1584
+ INST(Vrangepd , VexRvmi_Lx , E(660F3A,50,_,x,_,1,4,FV ), 0 , 113, 0 , 292, 155), // #1585
+ INST(Vrangeps , VexRvmi_Lx , E(660F3A,50,_,x,_,0,4,FV ), 0 , 112, 0 , 293, 155), // #1586
+ INST(Vrangesd , VexRvmi , E(660F3A,51,_,I,_,1,3,T1S), 0 , 182, 0 , 294, 76 ), // #1587
+ INST(Vrangess , VexRvmi , E(660F3A,51,_,I,_,0,2,T1S), 0 , 183, 0 , 295, 76 ), // #1588
+ INST(Vrcp14pd , VexRm_Lx , E(660F38,4C,_,x,_,1,4,FV ), 0 , 114, 0 , 356, 152), // #1589
+ INST(Vrcp14ps , VexRm_Lx , E(660F38,4C,_,x,_,0,4,FV ), 0 , 115, 0 , 380, 152), // #1590
+ INST(Vrcp14sd , VexRvm , E(660F38,4D,_,I,_,1,3,T1S), 0 , 129, 0 , 427, 78 ), // #1591
+ INST(Vrcp14ss , VexRvm , E(660F38,4D,_,I,_,0,2,T1S), 0 , 130, 0 , 428, 78 ), // #1592
+ INST(Vrcp28pd , VexRm , E(660F38,CA,_,2,_,1,4,FV ), 0 , 172, 0 , 284, 164), // #1593
+ INST(Vrcp28ps , VexRm , E(660F38,CA,_,2,_,0,4,FV ), 0 , 173, 0 , 285, 164), // #1594
+ INST(Vrcp28sd , VexRvm , E(660F38,CB,_,I,_,1,3,T1S), 0 , 129, 0 , 315, 164), // #1595
+ INST(Vrcp28ss , VexRvm , E(660F38,CB,_,I,_,0,2,T1S), 0 , 130, 0 , 316, 164), // #1596
+ INST(Vrcpph , VexRm_Lx , E(66MAP6,4C,_,_,_,0,4,FV ), 0 , 185, 0 , 429, 148), // #1597
+ INST(Vrcpps , VexRm_Lx , V(000F00,53,_,x,I,_,_,_ ), 0 , 74 , 0 , 305, 149), // #1598
+ INST(Vrcpsh , VexRvm , E(66MAP6,4D,_,_,_,0,1,T1S), 0 , 187, 0 , 430, 148), // #1599
+ INST(Vrcpss , VexRvm , V(F30F00,53,_,I,I,_,_,_ ), 0 , 201, 0 , 431, 149), // #1600
+ INST(Vreducepd , VexRmi_Lx , E(660F3A,56,_,x,_,1,4,FV ), 0 , 113, 0 , 407, 155), // #1601
+ INST(Vreduceph , VexRmi_Lx , E(000F3A,56,_,_,_,0,4,FV ), 0 , 124, 0 , 318, 146), // #1602
+ INST(Vreduceps , VexRmi_Lx , E(660F3A,56,_,x,_,0,4,FV ), 0 , 112, 0 , 406, 155), // #1603
+ INST(Vreducesd , VexRvmi , E(660F3A,57,_,I,_,1,3,T1S), 0 , 182, 0 , 432, 76 ), // #1604
+ INST(Vreducesh , VexRvmi , E(000F3A,57,_,_,_,0,1,T1S), 0 , 190, 0 , 320, 148), // #1605
+ INST(Vreducess , VexRvmi , E(660F3A,57,_,I,_,0,2,T1S), 0 , 183, 0 , 433, 76 ), // #1606
+ INST(Vrndscalepd , VexRmi_Lx , E(660F3A,09,_,x,_,1,4,FV ), 0 , 113, 0 , 317, 152), // #1607
+ INST(Vrndscaleph , VexRmi_Lx , E(000F3A,08,_,_,_,0,4,FV ), 0 , 124, 0 , 318, 146), // #1608
+ INST(Vrndscaleps , VexRmi_Lx , E(660F3A,08,_,x,_,0,4,FV ), 0 , 112, 0 , 319, 152), // #1609
+ INST(Vrndscalesd , VexRvmi , E(660F3A,0B,_,I,_,1,3,T1S), 0 , 182, 0 , 294, 78 ), // #1610
+ INST(Vrndscalesh , VexRvmi , E(000F3A,0A,_,_,_,0,1,T1S), 0 , 190, 0 , 320, 148), // #1611
+ INST(Vrndscaless , VexRvmi , E(660F3A,0A,_,I,_,0,2,T1S), 0 , 183, 0 , 295, 78 ), // #1612
+ INST(Vroundpd , VexRmi_Lx , V(660F3A,09,_,x,I,_,_,_ ), 0 , 75 , 0 , 434, 149), // #1613
+ INST(Vroundps , VexRmi_Lx , V(660F3A,08,_,x,I,_,_,_ ), 0 , 75 , 0 , 434, 149), // #1614
+ INST(Vroundsd , VexRvmi , V(660F3A,0B,_,I,I,_,_,_ ), 0 , 75 , 0 , 435, 149), // #1615
+ INST(Vroundss , VexRvmi , V(660F3A,0A,_,I,I,_,_,_ ), 0 , 75 , 0 , 436, 149), // #1616
+ INST(Vrsqrt14pd , VexRm_Lx , E(660F38,4E,_,x,_,1,4,FV ), 0 , 114, 0 , 356, 152), // #1617
+ INST(Vrsqrt14ps , VexRm_Lx , E(660F38,4E,_,x,_,0,4,FV ), 0 , 115, 0 , 380, 152), // #1618
+ INST(Vrsqrt14sd , VexRvm , E(660F38,4F,_,I,_,1,3,T1S), 0 , 129, 0 , 427, 78 ), // #1619
+ INST(Vrsqrt14ss , VexRvm , E(660F38,4F,_,I,_,0,2,T1S), 0 , 130, 0 , 428, 78 ), // #1620
+ INST(Vrsqrt28pd , VexRm , E(660F38,CC,_,2,_,1,4,FV ), 0 , 172, 0 , 284, 164), // #1621
+ INST(Vrsqrt28ps , VexRm , E(660F38,CC,_,2,_,0,4,FV ), 0 , 173, 0 , 285, 164), // #1622
+ INST(Vrsqrt28sd , VexRvm , E(660F38,CD,_,I,_,1,3,T1S), 0 , 129, 0 , 315, 164), // #1623
+ INST(Vrsqrt28ss , VexRvm , E(660F38,CD,_,I,_,0,2,T1S), 0 , 130, 0 , 316, 164), // #1624
+ INST(Vrsqrtph , VexRm_Lx , E(66MAP6,4E,_,_,_,0,4,FV ), 0 , 185, 0 , 429, 146), // #1625
+ INST(Vrsqrtps , VexRm_Lx , V(000F00,52,_,x,I,_,_,_ ), 0 , 74 , 0 , 305, 149), // #1626
+ INST(Vrsqrtsh , VexRvm , E(66MAP6,4F,_,_,_,0,1,T1S), 0 , 187, 0 , 430, 148), // #1627
+ INST(Vrsqrtss , VexRvm , V(F30F00,52,_,I,I,_,_,_ ), 0 , 201, 0 , 431, 149), // #1628
+ INST(Vscalefpd , VexRvm_Lx , E(660F38,2C,_,x,_,1,4,FV ), 0 , 114, 0 , 437, 152), // #1629
+ INST(Vscalefph , VexRvm_Lx , E(66MAP6,2C,_,_,_,0,4,FV ), 0 , 185, 0 , 201, 146), // #1630
+ INST(Vscalefps , VexRvm_Lx , E(660F38,2C,_,x,_,0,4,FV ), 0 , 115, 0 , 291, 152), // #1631
+ INST(Vscalefsd , VexRvm , E(660F38,2D,_,I,_,1,3,T1S), 0 , 129, 0 , 257, 78 ), // #1632
+ INST(Vscalefsh , VexRvm , E(66MAP6,2D,_,_,_,0,1,T1S), 0 , 187, 0 , 204, 148), // #1633
+ INST(Vscalefss , VexRvm , E(660F38,2D,_,I,_,0,2,T1S), 0 , 130, 0 , 265, 78 ), // #1634
+ INST(Vscatterdpd , VexMr_VM , E(660F38,A2,_,x,_,1,3,T1S), 0 , 129, 0 , 410, 152), // #1635
+ INST(Vscatterdps , VexMr_VM , E(660F38,A2,_,x,_,0,2,T1S), 0 , 130, 0 , 409, 152), // #1636
+ INST(Vscatterpf0dpd , VexM_VM , E(660F38,C6,5,2,_,1,3,T1S), 0 , 232, 0 , 310, 170), // #1637
+ INST(Vscatterpf0dps , VexM_VM , E(660F38,C6,5,2,_,0,2,T1S), 0 , 233, 0 , 311, 170), // #1638
+ INST(Vscatterpf0qpd , VexM_VM , E(660F38,C7,5,2,_,1,3,T1S), 0 , 232, 0 , 312, 170), // #1639
+ INST(Vscatterpf0qps , VexM_VM , E(660F38,C7,5,2,_,0,2,T1S), 0 , 233, 0 , 312, 170), // #1640
+ INST(Vscatterpf1dpd , VexM_VM , E(660F38,C6,6,2,_,1,3,T1S), 0 , 234, 0 , 310, 170), // #1641
+ INST(Vscatterpf1dps , VexM_VM , E(660F38,C6,6,2,_,0,2,T1S), 0 , 235, 0 , 311, 170), // #1642
+ INST(Vscatterpf1qpd , VexM_VM , E(660F38,C7,6,2,_,1,3,T1S), 0 , 234, 0 , 312, 170), // #1643
+ INST(Vscatterpf1qps , VexM_VM , E(660F38,C7,6,2,_,0,2,T1S), 0 , 235, 0 , 312, 170), // #1644
+ INST(Vscatterqpd , VexMr_VM , E(660F38,A3,_,x,_,1,3,T1S), 0 , 129, 0 , 412, 152), // #1645
+ INST(Vscatterqps , VexMr_VM , E(660F38,A3,_,x,_,0,2,T1S), 0 , 130, 0 , 411, 152), // #1646
+ INST(Vsha512msg1 , VexRm , V(F20F38,CC,_,1,0,_,_,_ ), 0 , 236, 0 , 438, 196), // #1647
+ INST(Vsha512msg2 , VexRm , V(F20F38,CD,_,1,0,_,_,_ ), 0 , 236, 0 , 439, 196), // #1648
+ INST(Vsha512rnds2 , VexRvm , V(F20F38,CB,_,1,0,_,_,_ ), 0 , 236, 0 , 440, 196), // #1649
+ INST(Vshuff32x4 , VexRvmi_Lx , E(660F3A,23,_,x,_,0,4,FV ), 0 , 112, 0 , 441, 152), // #1650
+ INST(Vshuff64x2 , VexRvmi_Lx , E(660F3A,23,_,x,_,1,4,FV ), 0 , 113, 0 , 442, 152), // #1651
+ INST(Vshufi32x4 , VexRvmi_Lx , E(660F3A,43,_,x,_,0,4,FV ), 0 , 112, 0 , 441, 152), // #1652
+ INST(Vshufi64x2 , VexRvmi_Lx , E(660F3A,43,_,x,_,1,4,FV ), 0 , 113, 0 , 442, 152), // #1653
+ INST(Vshufpd , VexRvmi_Lx , V(660F00,C6,_,x,I,1,4,FV ), 0 , 104, 0 , 443, 145), // #1654
+ INST(Vshufps , VexRvmi_Lx , V(000F00,C6,_,x,I,0,4,FV ), 0 , 106, 0 , 444, 145), // #1655
+ INST(Vsm3msg1 , VexRvm , V(000F38,DA,_,0,0,_,_,_ ), 0 , 11 , 0 , 445, 197), // #1656
+ INST(Vsm3msg2 , VexRvm , V(660F38,DA,_,0,0,_,_,_ ), 0 , 30 , 0 , 445, 197), // #1657
+ INST(Vsm3rnds2 , VexRvmi , V(660F3A,DE,_,0,0,_,_,_ ), 0 , 75 , 0 , 283, 197), // #1658
+ INST(Vsm4key4 , VexRvm_Lx , V(F30F38,DA,_,x,0,_,_,_ ), 0 , 89 , 0 , 206, 198), // #1659
+ INST(Vsm4rnds4 , VexRvm_Lx , V(F20F38,DA,_,x,0,_,_,_ ), 0 , 85 , 0 , 206, 198), // #1660
+ INST(Vsqrtpd , VexRm_Lx , V(660F00,51,_,x,I,1,4,FV ), 0 , 104, 0 , 446, 145), // #1661
+ INST(Vsqrtph , VexRm_Lx , E(00MAP5,51,_,_,_,0,4,FV ), 0 , 105, 0 , 252, 146), // #1662
+ INST(Vsqrtps , VexRm_Lx , V(000F00,51,_,x,I,0,4,FV ), 0 , 106, 0 , 240, 145), // #1663
+ INST(Vsqrtsd , VexRvm , V(F20F00,51,_,I,I,1,3,T1S), 0 , 107, 0 , 203, 147), // #1664
+ INST(Vsqrtsh , VexRvm , E(F3MAP5,51,_,_,_,0,1,T1S), 0 , 108, 0 , 204, 148), // #1665
+ INST(Vsqrtss , VexRvm , V(F30F00,51,_,I,I,0,2,T1S), 0 , 109, 0 , 205, 147), // #1666
+ INST(Vstmxcsr , VexM , V(000F00,AE,3,0,I,_,_,_ ), 0 , 237, 0 , 327, 149), // #1667
+ INST(Vsubpd , VexRvm_Lx , V(660F00,5C,_,x,I,1,4,FV ), 0 , 104, 0 , 200, 145), // #1668
+ INST(Vsubph , VexRvm_Lx , E(00MAP5,5C,_,_,_,0,4,FV ), 0 , 105, 0 , 201, 146), // #1669
+ INST(Vsubps , VexRvm_Lx , V(000F00,5C,_,x,I,0,4,FV ), 0 , 106, 0 , 202, 145), // #1670
+ INST(Vsubsd , VexRvm , V(F20F00,5C,_,I,I,1,3,T1S), 0 , 107, 0 , 203, 147), // #1671
+ INST(Vsubsh , VexRvm , E(F3MAP5,5C,_,_,_,0,1,T1S), 0 , 108, 0 , 204, 148), // #1672
+ INST(Vsubss , VexRvm , V(F30F00,5C,_,I,I,0,2,T1S), 0 , 109, 0 , 205, 147), // #1673
+ INST(Vtestpd , VexRm_Lx , V(660F38,0F,_,x,0,_,_,_ ), 0 , 30 , 0 , 305, 185), // #1674
+ INST(Vtestps , VexRm_Lx , V(660F38,0E,_,x,0,_,_,_ ), 0 , 30 , 0 , 305, 185), // #1675
+ INST(Vucomisd , VexRm , V(660F00,2E,_,I,I,1,3,T1S), 0 , 126, 0 , 234, 158), // #1676
+ INST(Vucomish , VexRm , E(00MAP5,2E,_,_,_,0,1,T1S), 0 , 127, 0 , 235, 159), // #1677
+ INST(Vucomiss , VexRm , V(000F00,2E,_,I,I,0,2,T1S), 0 , 128, 0 , 236, 158), // #1678
+ INST(Vunpckhpd , VexRvm_Lx , V(660F00,15,_,x,I,1,4,FV ), 0 , 104, 0 , 212, 145), // #1679
+ INST(Vunpckhps , VexRvm_Lx , V(000F00,15,_,x,I,0,4,FV ), 0 , 106, 0 , 213, 145), // #1680
+ INST(Vunpcklpd , VexRvm_Lx , V(660F00,14,_,x,I,1,4,FV ), 0 , 104, 0 , 212, 145), // #1681
+ INST(Vunpcklps , VexRvm_Lx , V(000F00,14,_,x,I,0,4,FV ), 0 , 106, 0 , 213, 145), // #1682
+ INST(Vxorpd , VexRvm_Lx , V(660F00,57,_,x,I,1,4,FV ), 0 , 104, 0 , 424, 153), // #1683
+ INST(Vxorps , VexRvm_Lx , V(000F00,57,_,x,I,0,4,FV ), 0 , 106, 0 , 423, 153), // #1684
+ INST(Vzeroall , VexOp , V(000F00,77,_,1,I,_,_,_ ), 0 , 70 , 0 , 447, 149), // #1685
+ INST(Vzeroupper , VexOp , V(000F00,77,_,0,I,_,_,_ ), 0 , 74 , 0 , 447, 149), // #1686
+ INST(Wbinvd , X86Op , O(000F00,09,_,_,_,_,_,_ ), 0 , 5 , 0 , 31 , 45 ), // #1687
+ INST(Wbnoinvd , X86Op , O(F30F00,09,_,_,_,_,_,_ ), 0 , 7 , 0 , 31 , 199), // #1688
+ INST(Wrfsbase , X86M , O(F30F00,AE,2,_,x,_,_,_ ), 0 , 238, 0 , 177, 122), // #1689
+ INST(Wrgsbase , X86M , O(F30F00,AE,3,_,x,_,_,_ ), 0 , 239, 0 , 177, 122), // #1690
+ INST(Wrmsr , X86Op , O(000F00,30,_,_,_,_,_,_ ), 0 , 5 , 0 , 178, 123), // #1691
+ INST(Wrssd , X86Mr , O(000F38,F6,_,_,_,_,_,_ ), 0 , 1 , 0 , 448, 65 ), // #1692
+ INST(Wrssq , X86Mr , O(000F38,F6,_,_,1,_,_,_ ), 0 , 240, 0 , 449, 65 ), // #1693
+ INST(Wrussd , X86Mr , O(660F38,F5,_,_,_,_,_,_ ), 0 , 2 , 0 , 448, 65 ), // #1694
+ INST(Wrussq , X86Mr , O(660F38,F5,_,_,1,_,_,_ ), 0 , 241, 0 , 449, 65 ), // #1695
+ INST(Xabort , X86Op_Mod11RM_I8 , O(000000,C6,7,_,_,_,_,_ ), 0 , 29 , 0 , 84 , 200), // #1696
+ INST(Xadd , X86Xadd , O(000F00,C0,_,_,x,_,_,_ ), 0 , 5 , 0 , 450, 40 ), // #1697
+ INST(Xbegin , X86JmpRel , O(000000,C7,7,_,_,_,_,_ ), 0 , 29 , 0 , 451, 200), // #1698
+ INST(Xchg , X86Xchg , O(000000,86,_,_,x,_,_,_ ), 0 , 0 , 0 , 452, 0 ), // #1699
+ INST(Xend , X86Op , O(000F01,D5,_,_,_,_,_,_ ), 0 , 23 , 0 , 31 , 200), // #1700
+ INST(Xgetbv , X86Op , O(000F01,D0,_,_,_,_,_,_ ), 0 , 23 , 0 , 178, 201), // #1701
+ INST(Xlatb , X86Op , O(000000,D7,_,_,_,_,_,_ ), 0 , 0 , 0 , 31 , 0 ), // #1702
+ INST(Xor , X86Arith , O(000000,30,6,_,x,_,_,_ ), 0 , 34 , 0 , 183, 1 ), // #1703
+ INST(Xorpd , ExtRm , O(660F00,57,_,_,_,_,_,_ ), 0 , 4 , 0 , 155, 5 ), // #1704
+ INST(Xorps , ExtRm , O(000F00,57,_,_,_,_,_,_ ), 0 , 5 , 0 , 155, 6 ), // #1705
+ INST(Xresldtrk , X86Op , O(F20F01,E9,_,_,_,_,_,_ ), 0 , 93 , 0 , 31 , 202), // #1706
+ INST(Xrstor , X86M_Only_EDX_EAX , O(000F00,AE,5,_,_,_,_,_ ), 0 , 79 , 0 , 453, 201), // #1707
+ INST(Xrstor64 , X86M_Only_EDX_EAX , O(000F00,AE,5,_,1,_,_,_ ), 0 , 242, 0 , 454, 201), // #1708
+ INST(Xrstors , X86M_Only_EDX_EAX , O(000F00,C7,3,_,_,_,_,_ ), 0 , 80 , 0 , 453, 203), // #1709
+ INST(Xrstors64 , X86M_Only_EDX_EAX , O(000F00,C7,3,_,1,_,_,_ ), 0 , 243, 0 , 454, 203), // #1710
+ INST(Xsave , X86M_Only_EDX_EAX , O(000F00,AE,4,_,_,_,_,_ ), 0 , 98 , 0 , 453, 201), // #1711
+ INST(Xsave64 , X86M_Only_EDX_EAX , O(000F00,AE,4,_,1,_,_,_ ), 0 , 244, 0 , 454, 201), // #1712
+ INST(Xsavec , X86M_Only_EDX_EAX , O(000F00,C7,4,_,_,_,_,_ ), 0 , 98 , 0 , 453, 204), // #1713
+ INST(Xsavec64 , X86M_Only_EDX_EAX , O(000F00,C7,4,_,1,_,_,_ ), 0 , 244, 0 , 454, 204), // #1714
+ INST(Xsaveopt , X86M_Only_EDX_EAX , O(000F00,AE,6,_,_,_,_,_ ), 0 , 82 , 0 , 453, 205), // #1715
+ INST(Xsaveopt64 , X86M_Only_EDX_EAX , O(000F00,AE,6,_,1,_,_,_ ), 0 , 245, 0 , 454, 205), // #1716
+ INST(Xsaves , X86M_Only_EDX_EAX , O(000F00,C7,5,_,_,_,_,_ ), 0 , 79 , 0 , 453, 203), // #1717
+ INST(Xsaves64 , X86M_Only_EDX_EAX , O(000F00,C7,5,_,1,_,_,_ ), 0 , 242, 0 , 454, 203), // #1718
+ INST(Xsetbv , X86Op , O(000F01,D1,_,_,_,_,_,_ ), 0 , 23 , 0 , 178, 201), // #1719
+ INST(Xsusldtrk , X86Op , O(F20F01,E8,_,_,_,_,_,_ ), 0 , 93 , 0 , 31 , 202), // #1720
+ INST(Xtest , X86Op , O(000F01,D6,_,_,_,_,_,_ ), 0 , 23 , 0 , 31 , 206) // #1721
// ${InstInfo:End}
};
#undef NAME_DATA_INDEX
@@ -1747,248 +1780,251 @@ const InstDB::InstInfo InstDB::_instInfoTable[] = {
// ------------------- Automatically generated, do not edit -------------------
const uint32_t InstDB::_mainOpcodeTable[] = {
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]
+ O(000F38,00,0,0,0,0,0,0 ), // #1 [ref=25x]
+ O(660F38,00,0,0,0,0,0,0 ), // #2 [ref=44x]
+ O(000000,00,2,0,0,0,0,0 ), // #3 [ref=4x]
+ O(660F00,00,0,0,0,0,0,0 ), // #4 [ref=38x]
+ O(000F00,00,0,0,0,0,0,0 ), // #5 [ref=231x]
+ O(F20F00,00,0,0,0,0,0,0 ), // #6 [ref=24x]
+ O(F30F00,00,0,0,0,0,0,0 ), // #7 [ref=29x]
+ O(F30F38,00,0,0,0,0,0,0 ), // #8 [ref=3x]
+ O(660F3A,00,0,0,0,0,0,0 ), // #9 [ref=22x]
+ O(000000,00,4,0,0,0,0,0 ), // #10 [ref=5x]
+ V(000F38,00,0,0,0,0,0,None), // #11 [ref=13x]
+ O(F20F38,00,0,0,0,0,0,0 ), // #12 [ref=3x]
+ V(XOP_M9,00,1,0,0,0,0,None), // #13 [ref=3x]
+ V(XOP_M9,00,6,0,0,0,0,None), // #14 [ref=2x]
+ V(XOP_M9,00,5,0,0,0,0,None), // #15 [ref=1x]
+ V(XOP_M9,00,3,0,0,0,0,None), // #16 [ref=1x]
+ V(XOP_M9,00,2,0,0,0,0,None), // #17 [ref=1x]
+ V(000F38,00,3,0,0,0,0,None), // #18 [ref=1x]
+ V(000F38,00,2,0,0,0,0,None), // #19 [ref=1x]
+ V(000F38,00,1,0,0,0,0,None), // #20 [ref=1x]
+ O(660000,00,0,0,0,0,0,0 ), // #21 [ref=7x]
+ O(000000,00,0,0,1,0,0,0 ), // #22 [ref=3x]
+ O(000F01,00,0,0,0,0,0,0 ), // #23 [ref=32x]
+ O(000F00,00,7,0,0,0,0,0 ), // #24 [ref=6x]
+ O(660F00,00,7,0,0,0,0,0 ), // #25 [ref=1x]
+ O(F30F00,00,6,0,0,0,0,0 ), // #26 [ref=4x]
+ O(F30F01,00,0,0,0,0,0,0 ), // #27 [ref=9x]
+ O(660F00,00,6,0,0,0,0,0 ), // #28 [ref=3x]
+ O(000000,00,7,0,0,0,0,0 ), // #29 [ref=5x]
+ V(660F38,00,0,0,0,0,0,None), // #30 [ref=48x]
+ O(000F00,00,1,0,1,0,0,0 ), // #31 [ref=2x]
+ O(000F00,00,1,0,0,0,0,0 ), // #32 [ref=6x]
+ O(000000,00,1,0,0,0,0,0 ), // #33 [ref=3x]
+ O(000000,00,6,0,0,0,0,0 ), // #34 [ref=3x]
+ O(F30F00,00,7,0,0,0,0,3 ), // #35 [ref=1x]
+ O(F30F00,00,7,0,0,0,0,2 ), // #36 [ref=1x]
+ O_FPU(00,D900,0) , // #37 [ref=29x]
+ O_FPU(00,C000,0) , // #38 [ref=1x]
+ O_FPU(00,DE00,0) , // #39 [ref=7x]
+ O_FPU(00,0000,4) , // #40 [ref=4x]
+ O_FPU(00,0000,6) , // #41 [ref=4x]
+ O_FPU(9B,DB00,0) , // #42 [ref=2x]
+ O_FPU(00,DA00,0) , // #43 [ref=5x]
+ O_FPU(00,DB00,0) , // #44 [ref=8x]
+ O_FPU(00,D000,2) , // #45 [ref=1x]
+ O_FPU(00,DF00,0) , // #46 [ref=2x]
+ O_FPU(00,D800,3) , // #47 [ref=1x]
+ O_FPU(00,F000,6) , // #48 [ref=1x]
+ O_FPU(00,F800,7) , // #49 [ref=1x]
+ O_FPU(00,DD00,0) , // #50 [ref=3x]
+ O_FPU(00,0000,0) , // #51 [ref=4x]
+ O_FPU(00,0000,2) , // #52 [ref=3x]
+ O_FPU(00,0000,3) , // #53 [ref=3x]
+ O_FPU(00,0000,7) , // #54 [ref=3x]
+ O_FPU(00,0000,1) , // #55 [ref=2x]
+ O_FPU(00,0000,5) , // #56 [ref=2x]
+ O_FPU(00,C800,1) , // #57 [ref=1x]
+ O_FPU(9B,0000,6) , // #58 [ref=2x]
+ O_FPU(9B,0000,7) , // #59 [ref=2x]
+ O_FPU(00,E000,4) , // #60 [ref=1x]
+ O_FPU(00,E800,5) , // #61 [ref=1x]
+ O(000F00,00,0,0,1,0,0,0 ), // #62 [ref=3x]
+ O(F30F3A,00,0,0,0,0,0,0 ), // #63 [ref=1x]
+ O(000000,00,5,0,0,0,0,0 ), // #64 [ref=4x]
+ O(F30F00,00,5,0,0,0,0,0 ), // #65 [ref=2x]
+ O(F30F00,00,5,0,1,0,0,0 ), // #66 [ref=1x]
+ V(660F00,00,0,1,0,0,0,None), // #67 [ref=7x]
+ V(660F00,00,0,1,1,0,0,None), // #68 [ref=6x]
+ V(000F00,00,0,1,1,0,0,None), // #69 [ref=7x]
+ V(000F00,00,0,1,0,0,0,None), // #70 [ref=8x]
+ V(660F00,00,0,0,0,0,0,None), // #71 [ref=15x]
+ V(660F00,00,0,0,1,0,0,None), // #72 [ref=4x]
+ V(000F00,00,0,0,1,0,0,None), // #73 [ref=4x]
+ V(000F00,00,0,0,0,0,0,None), // #74 [ref=10x]
+ V(660F3A,00,0,0,0,0,0,None), // #75 [ref=48x]
+ V(660F3A,00,0,0,1,0,0,None), // #76 [ref=4x]
+ O(000000,00,3,0,0,0,0,0 ), // #77 [ref=4x]
+ O(000F00,00,2,0,0,0,0,0 ), // #78 [ref=5x]
+ O(000F00,00,5,0,0,0,0,0 ), // #79 [ref=4x]
+ O(000F00,00,3,0,0,0,0,0 ), // #80 [ref=5x]
+ V(XOP_M9,00,0,0,0,0,0,None), // #81 [ref=32x]
+ O(000F00,00,6,0,0,0,0,0 ), // #82 [ref=6x]
+ V(XOP_MA,00,0,0,0,0,0,None), // #83 [ref=1x]
+ V(XOP_MA,00,1,0,0,0,0,None), // #84 [ref=1x]
+ V(F20F38,00,0,0,0,0,0,None), // #85 [ref=11x]
+ O(000F3A,00,0,0,0,0,0,0 ), // #86 [ref=4x]
+ O(F30000,00,0,0,0,0,0,0 ), // #87 [ref=1x]
+ O(000F0F,00,0,0,0,0,0,0 ), // #88 [ref=26x]
+ V(F30F38,00,0,0,0,0,0,None), // #89 [ref=12x]
+ O(000F3A,00,0,0,1,0,0,0 ), // #90 [ref=1x]
+ O(660F3A,00,0,0,1,0,0,0 ), // #91 [ref=1x]
+ O(F30F00,00,4,0,0,0,0,0 ), // #92 [ref=1x]
+ O(F20F01,00,0,0,0,0,0,0 ), // #93 [ref=5x]
+ O(F30F00,00,1,0,0,0,0,0 ), // #94 [ref=3x]
+ O(F30F00,00,7,0,0,0,0,0 ), // #95 [ref=1x]
+ V(F20F3A,00,0,0,0,0,0,None), // #96 [ref=1x]
+ O(660F01,00,0,0,0,0,0,0 ), // #97 [ref=4x]
+ O(000F00,00,4,0,0,0,0,0 ), // #98 [ref=4x]
+ V(XOP_M9,00,7,0,0,0,0,None), // #99 [ref=1x]
+ V(XOP_M9,00,4,0,0,0,0,None), // #100 [ref=1x]
+ O(F20F00,00,6,0,0,0,0,0 ), // #101 [ref=1x]
+ E(F20F38,00,0,2,0,0,4,None), // #102 [ref=4x]
+ E(F20F38,00,0,0,0,0,4,None), // #103 [ref=2x]
+ V(660F00,00,0,0,0,1,4,ByLL), // #104 [ref=25x]
+ E(00MAP5,00,0,0,0,0,4,ByLL), // #105 [ref=10x]
+ V(000F00,00,0,0,0,0,4,ByLL), // #106 [ref=19x]
+ V(F20F00,00,0,0,0,1,3,None), // #107 [ref=10x]
+ E(F3MAP5,00,0,0,0,0,1,None), // #108 [ref=13x]
+ V(F30F00,00,0,0,0,0,2,None), // #109 [ref=12x]
+ V(F20F00,00,0,0,0,0,0,None), // #110 [ref=4x]
+ V(660F38,00,0,0,0,0,4,ByLL), // #111 [ref=50x]
+ E(660F3A,00,0,0,0,0,4,ByLL), // #112 [ref=17x]
+ E(660F3A,00,0,0,0,1,4,ByLL), // #113 [ref=18x]
+ E(660F38,00,0,0,0,1,4,ByLL), // #114 [ref=38x]
+ E(660F38,00,0,0,0,0,4,ByLL), // #115 [ref=25x]
+ V(660F38,00,0,1,0,0,0,None), // #116 [ref=2x]
+ E(660F38,00,0,0,0,0,3,None), // #117 [ref=2x]
+ E(660F38,00,0,0,0,0,4,None), // #118 [ref=2x]
+ E(660F38,00,0,2,0,0,5,None), // #119 [ref=2x]
+ E(660F38,00,0,0,0,1,4,None), // #120 [ref=2x]
+ E(660F38,00,0,2,0,1,5,None), // #121 [ref=2x]
+ V(660F38,00,0,0,0,1,3,None), // #122 [ref=2x]
+ V(660F38,00,0,0,0,0,2,None), // #123 [ref=14x]
+ E(000F3A,00,0,0,0,0,4,ByLL), // #124 [ref=5x]
+ E(F30F3A,00,0,0,0,0,1,None), // #125 [ref=1x]
+ V(660F00,00,0,0,0,1,3,None), // #126 [ref=5x]
+ E(00MAP5,00,0,0,0,0,1,None), // #127 [ref=2x]
+ V(000F00,00,0,0,0,0,2,None), // #128 [ref=2x]
+ E(660F38,00,0,0,0,1,3,None), // #129 [ref=14x]
+ E(660F38,00,0,0,0,0,2,None), // #130 [ref=14x]
+ V(F30F00,00,0,0,0,0,3,ByLL), // #131 [ref=1x]
+ E(F20F38,00,0,0,0,0,4,ByLL), // #132 [ref=2x]
+ V(F30F38,00,0,0,0,0,4,ByLL), // #133 [ref=1x]
+ V(F20F00,00,0,0,0,1,4,ByLL), // #134 [ref=1x]
+ E(66MAP5,00,0,0,0,1,4,ByLL), // #135 [ref=1x]
+ E(660F00,00,0,0,0,1,4,ByLL), // #136 [ref=10x]
+ E(000F00,00,0,0,0,1,4,ByLL), // #137 [ref=3x]
+ E(66MAP5,00,0,0,0,0,3,ByLL), // #138 [ref=1x]
+ E(00MAP5,00,0,0,0,0,2,ByLL), // #139 [ref=1x]
+ V(660F38,00,0,0,0,0,3,ByLL), // #140 [ref=7x]
+ E(66MAP6,00,0,0,0,0,3,ByLL), // #141 [ref=1x]
+ E(66MAP5,00,0,0,0,0,2,ByLL), // #142 [ref=4x]
+ E(00MAP5,00,0,0,0,0,3,ByLL), // #143 [ref=2x]
+ E(66MAP5,00,0,0,0,0,4,ByLL), // #144 [ref=3x]
+ V(660F00,00,0,0,0,0,4,ByLL), // #145 [ref=43x]
+ V(000F00,00,0,0,0,0,3,ByLL), // #146 [ref=1x]
+ V(660F3A,00,0,0,0,0,3,ByLL), // #147 [ref=1x]
+ E(660F00,00,0,0,0,0,3,ByLL), // #148 [ref=4x]
+ E(000F00,00,0,0,0,0,4,ByLL), // #149 [ref=2x]
+ E(F30F00,00,0,0,0,1,4,ByLL), // #150 [ref=3x]
+ E(00MAP5,00,0,0,0,1,4,ByLL), // #151 [ref=1x]
+ E(F2MAP5,00,0,0,0,1,3,None), // #152 [ref=1x]
+ V(F20F00,00,0,0,0,0,3,None), // #153 [ref=2x]
+ E(F20F00,00,0,0,0,0,3,None), // #154 [ref=2x]
+ E(00MAP6,00,0,0,0,0,1,None), // #155 [ref=1x]
+ V(F20F00,00,0,0,0,0,2,T1W ), // #156 [ref=1x]
+ E(F3MAP5,00,0,0,0,0,2,T1W ), // #157 [ref=2x]
+ V(F30F00,00,0,0,0,0,2,T1W ), // #158 [ref=1x]
+ E(00MAP5,00,0,0,0,0,2,None), // #159 [ref=1x]
+ E(F30F00,00,0,0,0,0,2,None), // #160 [ref=2x]
+ E(F3MAP5,00,0,0,0,0,3,ByLL), // #161 [ref=1x]
+ V(F30F00,00,0,0,0,0,4,ByLL), // #162 [ref=4x]
+ E(F30F00,00,0,0,0,0,3,ByLL), // #163 [ref=1x]
+ E(F2MAP5,00,0,0,0,0,4,ByLL), // #164 [ref=2x]
+ E(F20F00,00,0,0,0,0,4,ByLL), // #165 [ref=2x]
+ E(F2MAP5,00,0,0,0,1,4,ByLL), // #166 [ref=1x]
+ E(F20F00,00,0,0,0,1,4,ByLL), // #167 [ref=2x]
+ E(F20F00,00,0,0,0,0,2,T1W ), // #168 [ref=1x]
+ E(F30F00,00,0,0,0,0,2,T1W ), // #169 [ref=1x]
+ E(F3MAP5,00,0,0,0,0,4,ByLL), // #170 [ref=1x]
+ E(F30F38,00,0,0,0,0,4,ByLL), // #171 [ref=3x]
+ E(660F38,00,0,2,0,1,4,ByLL), // #172 [ref=3x]
+ E(660F38,00,0,2,0,0,4,ByLL), // #173 [ref=3x]
+ V(660F3A,00,0,1,0,0,0,None), // #174 [ref=6x]
+ E(660F3A,00,0,0,0,0,4,None), // #175 [ref=4x]
+ E(660F3A,00,0,2,0,0,5,None), // #176 [ref=4x]
+ E(660F3A,00,0,0,0,1,4,None), // #177 [ref=4x]
+ E(660F3A,00,0,2,0,1,5,None), // #178 [ref=4x]
+ V(660F3A,00,0,0,0,0,2,None), // #179 [ref=4x]
+ E(F2MAP6,00,0,0,0,0,4,ByLL), // #180 [ref=2x]
+ E(F2MAP6,00,0,0,0,0,2,None), // #181 [ref=2x]
+ E(660F3A,00,0,0,0,1,3,None), // #182 [ref=6x]
+ E(660F3A,00,0,0,0,0,2,None), // #183 [ref=6x]
+ V(660F38,00,0,0,1,1,4,ByLL), // #184 [ref=22x]
+ E(66MAP6,00,0,0,0,0,4,ByLL), // #185 [ref=22x]
+ V(660F38,00,0,0,1,1,3,None), // #186 [ref=12x]
+ E(66MAP6,00,0,0,0,0,1,None), // #187 [ref=16x]
+ E(F3MAP6,00,0,0,0,0,4,ByLL), // #188 [ref=2x]
+ E(F3MAP6,00,0,0,0,0,2,None), // #189 [ref=2x]
+ E(000F3A,00,0,0,0,0,1,None), // #190 [ref=4x]
+ V(660F38,00,0,0,1,0,0,None), // #191 [ref=5x]
+ E(660F38,00,1,2,0,1,3,None), // #192 [ref=2x]
+ E(660F38,00,1,2,0,0,2,None), // #193 [ref=2x]
+ E(660F38,00,2,2,0,1,3,None), // #194 [ref=2x]
+ E(660F38,00,2,2,0,0,2,None), // #195 [ref=2x]
+ V(660F3A,00,0,0,1,1,4,ByLL), // #196 [ref=2x]
+ V(000F00,00,2,0,0,0,0,None), // #197 [ref=1x]
+ V(660F00,00,0,0,0,0,2,None), // #198 [ref=1x]
+ V(F20F00,00,0,0,0,1,3,DUP ), // #199 [ref=1x]
+ E(660F00,00,0,0,0,0,4,ByLL), // #200 [ref=6x]
+ V(F30F00,00,0,0,0,0,0,None), // #201 [ref=3x]
+ E(F30F00,00,0,0,0,0,4,ByLL), // #202 [ref=1x]
+ V(000F00,00,0,0,0,0,3,None), // #203 [ref=2x]
+ E(66MAP5,00,0,0,0,0,1,None), // #204 [ref=1x]
+ E(F20F38,00,0,0,0,1,4,ByLL), // #205 [ref=1x]
+ V(660F3A,00,0,0,0,0,4,ByLL), // #206 [ref=2x]
+ E(F30F38,00,0,0,0,1,0,None), // #207 [ref=5x]
+ E(F30F38,00,0,0,0,0,0,None), // #208 [ref=5x]
+ V(660F38,00,0,0,0,0,1,None), // #209 [ref=1x]
+ V(XOP_M8,00,0,0,0,0,0,None), // #210 [ref=22x]
+ V(660F38,00,0,0,0,1,4,ByLL), // #211 [ref=4x]
+ E(660F38,00,0,0,0,0,0,None), // #212 [ref=2x]
+ E(660F38,00,0,0,0,1,1,None), // #213 [ref=2x]
+ E(660F38,00,0,0,1,1,4,ByLL), // #214 [ref=1x]
+ V(660F3A,00,0,0,1,1,3,None), // #215 [ref=2x]
+ V(660F3A,00,0,0,0,0,1,None), // #216 [ref=1x]
+ V(660F00,00,0,0,0,0,1,None), // #217 [ref=1x]
+ E(F30F38,00,0,0,0,0,2,ByLL), // #218 [ref=6x]
+ E(F30F38,00,0,0,0,0,3,ByLL), // #219 [ref=9x]
+ E(F30F38,00,0,0,0,0,1,ByLL), // #220 [ref=3x]
+ V(660F38,00,0,0,0,0,2,ByLL), // #221 [ref=4x]
+ V(660F38,00,0,0,0,0,1,ByLL), // #222 [ref=2x]
+ E(660F00,00,1,0,0,0,4,ByLL), // #223 [ref=1x]
+ E(660F00,00,1,0,0,1,4,ByLL), // #224 [ref=1x]
+ V(F20F00,00,0,0,0,0,4,ByLL), // #225 [ref=1x]
+ V(660F00,00,0,0,0,0,4,None), // #226 [ref=6x]
+ V(660F00,00,7,0,0,0,4,ByLL), // #227 [ref=1x]
+ V(660F00,00,0,0,0,1,4,None), // #228 [ref=2x]
+ E(660F00,00,0,0,0,1,4,None), // #229 [ref=1x]
+ V(660F00,00,3,0,0,0,4,ByLL), // #230 [ref=1x]
+ E(F30F38,00,0,0,0,1,4,ByLL), // #231 [ref=2x]
+ E(660F38,00,5,2,0,1,3,None), // #232 [ref=2x]
+ E(660F38,00,5,2,0,0,2,None), // #233 [ref=2x]
+ E(660F38,00,6,2,0,1,3,None), // #234 [ref=2x]
+ E(660F38,00,6,2,0,0,2,None), // #235 [ref=2x]
+ V(F20F38,00,0,1,0,0,0,None), // #236 [ref=3x]
+ V(000F00,00,3,0,0,0,0,None), // #237 [ref=1x]
+ O(F30F00,00,2,0,0,0,0,0 ), // #238 [ref=1x]
+ O(F30F00,00,3,0,0,0,0,0 ), // #239 [ref=1x]
+ O(000F38,00,0,0,1,0,0,0 ), // #240 [ref=1x]
+ O(660F38,00,0,0,1,0,0,0 ), // #241 [ref=1x]
+ O(000F00,00,5,0,1,0,0,0 ), // #242 [ref=2x]
+ O(000F00,00,3,0,1,0,0,0 ), // #243 [ref=1x]
+ O(000F00,00,4,0,1,0,0,0 ), // #244 [ref=2x]
+ O(000F00,00,6,0,1,0,0,0 ) // #245 [ref=1x]
};
// ----------------------------------------------------------------------------
// ${MainOpcodeTable:End}
@@ -1996,7 +2032,7 @@ const uint32_t InstDB::_mainOpcodeTable[] = {
// ${AltOpcodeTable:Begin}
// ------------------- Automatically generated, do not edit -------------------
const uint32_t InstDB::_altOpcodeTable[] = {
- O(000000,00,0,0,0,0,0,0 ), // #0 [ref=1514x]
+ O(000000,00,0,0,0,0,0,0 ), // #0 [ref=1573x]
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]
@@ -2151,449 +2187,460 @@ const uint32_t InstDB::_altOpcodeTable[] = {
#define SAME_REG_HINT(VAL) uint8_t(InstSameRegHint::k##VAL)
const InstDB::CommonInfo InstDB::_commonInfoTable[] = {
{ 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(K)|X(SAE)|X(Z) , 197, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #223 [ref=1x]
- { F(Evex)|F(Vec) , X(B16)|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(K)|X(SAE)|X(Z) , 197, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #225 [ref=1x]
- { F(Evex)|F(EvexKReg)|F(Vec)|F(Vex) , X(K)|X(SAE)|X(Z) , 484, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #226 [ref=1x]
- { F(Evex)|F(Vec) , 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(K)|X(SAE)|X(Z) , 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(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(K) , 493, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #294 [ref=1x]
- { F(Evex)|F(Vec) , 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(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(K) , 200, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #364 [ref=2x]
- { F(Evex)|F(Vec) , X(B32)|X(K) , 200, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #365 [ref=2x]
- { F(Evex)|F(EvexKReg)|F(Vec)|F(Vex) , 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(K) , 251, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #367 [ref=2x]
- { F(Evex)|F(EvexKReg)|F(Vec)|F(Vex) , X(B64)|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(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(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(K) , 272, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #418 [ref=2x]
- { F(Evex)|F(Vec) , X(B64)|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]
+ { 0 , 0 , 455, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #1 [ref=4x]
+ { 0 , 0 , 456, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #2 [ref=2x]
+ { 0 , 0 , 108, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #3 [ref=6x]
+ { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 20 , 13, CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #4 [ref=2x]
+ { 0 , 0 , 50 , 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #5 [ref=2x]
+ { F(Vec) , 0 , 72 , 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #6 [ref=54x]
+ { F(Vec) , 0 , 143, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #7 [ref=19x]
+ { F(Vec) , 0 , 283, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #8 [ref=16x]
+ { F(Vec) , 0 , 292, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #9 [ref=20x]
+ { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 33 , 12, CONTROL_FLOW(Regular), SAME_REG_HINT(RO)}, // #10 [ref=1x]
+ { F(Vex) , 0 , 325, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #11 [ref=3x]
+ { F(Vec) , 0 , 72 , 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(RO)}, // #12 [ref=12x]
+ { 0 , 0 , 457, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #13 [ref=1x]
+ { F(Vex) , 0 , 327, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #14 [ref=5x]
+ { F(Vex) , 0 , 50 , 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #15 [ref=12x]
+ { F(Vec) , 0 , 458, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #16 [ref=4x]
+ { 0 , 0 , 329, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #17 [ref=3x]
+ { F(Mib) , 0 , 459, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #18 [ref=1x]
+ { 0 , 0 , 460, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #19 [ref=1x]
+ { 0 , 0 , 331, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #20 [ref=1x]
+ { F(Mib) , 0 , 461, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #21 [ref=1x]
+ { 0 , 0 , 333, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #22 [ref=1x]
+ { 0 , 0 , 49 , 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #23 [ref=35x]
+ { 0 , 0 , 335, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #24 [ref=3x]
+ { 0 , 0 , 134, 5 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #25 [ref=1x]
+ { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 134, 5 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #26 [ref=3x]
+ { F(Rep)|F(RepIgnored) , 0 , 235, 3 , CONTROL_FLOW(Call), SAME_REG_HINT(None)}, // #27 [ref=1x]
+ { 0 , 0 , 462, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #28 [ref=1x]
+ { 0 , 0 , 463, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #29 [ref=2x]
+ { 0 , 0 , 436, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #30 [ref=1x]
+ { 0 , 0 , 110, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #31 [ref=88x]
+ { 0 , 0 , 464, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #32 [ref=24x]
+ { 0 , 0 , 465, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #33 [ref=6x]
+ { 0 , 0 , 466, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #34 [ref=14x]
+ { 0 , 0 , 467, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #35 [ref=1x]
+ { 0 , 0 , 20 , 13, CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #36 [ref=1x]
+ { F(Vex) , 0 , 337, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #37 [ref=16x]
+ { F(Rep) , 0 , 179, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #38 [ref=1x]
+ { F(Vec) , 0 , 468, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #39 [ref=2x]
+ { F(Vec) , 0 , 469, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #40 [ref=3x]
+ { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 183, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #41 [ref=1x]
+ { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 470, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #42 [ref=1x]
+ { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 471, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #43 [ref=1x]
+ { 0 , 0 , 472, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #44 [ref=1x]
+ { 0 , 0 , 473, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #45 [ref=1x]
+ { 0 , 0 , 339, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #46 [ref=1x]
+ { F(Mmx)|F(Vec) , 0 , 474, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #47 [ref=2x]
+ { F(Mmx)|F(Vec) , 0 , 475, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #48 [ref=2x]
+ { F(Mmx)|F(Vec) , 0 , 476, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #49 [ref=2x]
+ { F(Vec) , 0 , 341, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #50 [ref=2x]
+ { F(Vec) , 0 , 343, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #51 [ref=1x]
+ { F(Vec) , 0 , 345, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #52 [ref=1x]
+ { F(Vec) , 0 , 347, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #53 [ref=1x]
+ { F(Vec) , 0 , 349, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #54 [ref=1x]
+ { 0 , 0 , 477, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #55 [ref=1x]
+ { 0 , 0 , 478, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #56 [ref=3x]
+ { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 238, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #57 [ref=1x]
+ { 0 , 0 , 45 , 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #58 [ref=3x]
+ { F(Mmx) , 0 , 110, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #59 [ref=1x]
+ { 0 , 0 , 351, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #60 [ref=2x]
+ { 0 , 0 , 479, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #61 [ref=1x]
+ { F(Vec) , 0 , 480, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #62 [ref=2x]
+ { F(Vec) , 0 , 353, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #63 [ref=1x]
+ { F(FpuM32)|F(FpuM64) , 0 , 241, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #64 [ref=6x]
+ { 0 , 0 , 355, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #65 [ref=9x]
+ { F(FpuM80) , 0 , 481, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #66 [ref=2x]
+ { 0 , 0 , 356, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #67 [ref=13x]
+ { F(FpuM32)|F(FpuM64) , 0 , 357, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #68 [ref=2x]
+ { F(FpuM16)|F(FpuM32) , 0 , 482, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #69 [ref=9x]
+ { F(FpuM16)|F(FpuM32)|F(FpuM64) , 0 , 483, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #70 [ref=3x]
+ { F(FpuM32)|F(FpuM64)|F(FpuM80) , 0 , 484, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #71 [ref=2x]
+ { F(FpuM16) , 0 , 485, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #72 [ref=3x]
+ { F(FpuM16) , 0 , 486, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #73 [ref=2x]
+ { F(FpuM32)|F(FpuM64) , 0 , 358, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #74 [ref=1x]
+ { 0 , 0 , 487, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #75 [ref=4x]
+ { 0 , 0 , 488, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #76 [ref=1x]
+ { 0 , 0 , 45 , 10, CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #77 [ref=1x]
+ { 0 , 0 , 489, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #78 [ref=1x]
+ { F(Lock) , 0 , 238, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #79 [ref=1x]
+ { 0 , 0 , 379, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #80 [ref=2x]
+ { 0 , 0 , 336, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #81 [ref=3x]
+ { F(Rep) , 0 , 490, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #82 [ref=1x]
+ { F(Vec) , 0 , 359, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #83 [ref=1x]
+ { 0 , 0 , 491, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #84 [ref=2x]
+ { 0 , 0 , 492, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #85 [ref=8x]
+ { 0 , 0 , 361, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #86 [ref=3x]
+ { 0 , 0 , 363, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #87 [ref=1x]
+ { 0 , 0 , 365, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #88 [ref=1x]
+ { 0 , 0 , 110, 1 , CONTROL_FLOW(Return), SAME_REG_HINT(None)}, // #89 [ref=2x]
+ { 0 , 0 , 466, 1 , CONTROL_FLOW(Return), SAME_REG_HINT(None)}, // #90 [ref=1x]
+ { F(Rep) , 0 , 244, 1 , CONTROL_FLOW(Branch), SAME_REG_HINT(None)}, // #91 [ref=30x]
+ { F(Rep) , 0 , 367, 2 , CONTROL_FLOW(Branch), SAME_REG_HINT(None)}, // #92 [ref=1x]
+ { F(Rep) , 0 , 244, 3 , CONTROL_FLOW(Jump), SAME_REG_HINT(None)}, // #93 [ref=1x]
+ { F(Vex) , 0 , 493, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #94 [ref=19x]
+ { F(Vex) , 0 , 369, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #95 [ref=1x]
+ { F(Vex) , 0 , 371, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #96 [ref=1x]
+ { F(Vex) , 0 , 187, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #97 [ref=1x]
+ { F(Vex) , 0 , 373, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #98 [ref=1x]
+ { F(Vex) , 0 , 494, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #99 [ref=12x]
+ { F(Vex) , 0 , 495, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #100 [ref=8x]
+ { F(Vex) , 0 , 493, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #101 [ref=8x]
+ { 0 , 0 , 496, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #102 [ref=2x]
+ { 0 , 0 , 253, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #103 [ref=1x]
+ { 0 , 0 , 247, 3 , CONTROL_FLOW(Call), SAME_REG_HINT(None)}, // #104 [ref=1x]
+ { F(Vec) , 0 , 169, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #105 [ref=2x]
+ { 0 , 0 , 497, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #106 [ref=2x]
+ { 0 , 0 , 375, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #107 [ref=2x]
+ { F(Vex) , 0 , 498, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #108 [ref=2x]
+ { 0 , 0 , 377, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #109 [ref=1x]
+ { 0 , 0 , 250, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #110 [ref=3x]
+ { 0 , 0 , 247, 3 , CONTROL_FLOW(Jump), SAME_REG_HINT(None)}, // #111 [ref=1x]
+ { 0 , 0 , 499, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #112 [ref=5x]
+ { F(Vex) , 0 , 379, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #113 [ref=2x]
+ { F(Rep) , 0 , 191, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #114 [ref=1x]
+ { 0 , 0 , 367, 2 , CONTROL_FLOW(Branch), SAME_REG_HINT(None)}, // #115 [ref=3x]
+ { 0 , 0 , 253, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #116 [ref=1x]
+ { F(Vex) , 0 , 381, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #117 [ref=2x]
+ { F(Vec) , 0 , 500, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #118 [ref=1x]
+ { F(Mmx) , 0 , 501, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #119 [ref=1x]
+ { 0 , 0 , 502, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #120 [ref=2x]
+ { F(XRelease) , 0 , 0 , 20, CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #121 [ref=1x]
+ { 0 , 0 , 55 , 9 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #122 [ref=1x]
+ { F(Vec) , 0 , 72 , 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #123 [ref=6x]
+ { 0 , 0 , 104, 6 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #124 [ref=1x]
+ { F(Mmx)|F(Vec) , 0 , 383, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #125 [ref=1x]
+ { 0 , 0 , 385, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #126 [ref=1x]
+ { F(Mmx)|F(Vec) , 0 , 503, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #127 [ref=1x]
+ { F(Vec) , 0 , 354, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #128 [ref=2x]
+ { F(Vec) , 0 , 80 , 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #129 [ref=4x]
+ { F(Vec) , 0 , 504, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #130 [ref=2x]
+ { F(Vec) , 0 , 73 , 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #131 [ref=3x]
+ { F(Mmx) , 0 , 505, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #132 [ref=1x]
+ { F(Vec) , 0 , 80 , 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #133 [ref=1x]
+ { F(Vec) , 0 , 88 , 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #134 [ref=1x]
+ { F(Mmx)|F(Vec) , 0 , 139, 5 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #135 [ref=1x]
+ { F(Mmx)|F(Vec) , 0 , 506, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #136 [ref=1x]
+ { F(Rep) , 0 , 195, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #137 [ref=1x]
+ { F(Vec) , 0 , 387, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #138 [ref=1x]
+ { F(Vec) , 0 , 389, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #139 [ref=1x]
+ { 0 , 0 , 256, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #140 [ref=2x]
+ { 0 , 0 , 391, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #141 [ref=1x]
+ { F(Vex) , 0 , 393, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #142 [ref=1x]
+ { 0 , 0 , 507, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #143 [ref=1x]
+ { 0 , 0 , 508, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #144 [ref=1x]
+ { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 239, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #145 [ref=2x]
+ { 0 , 0 , 110, 6 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #146 [ref=1x]
+ { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 20 , 13, CONTROL_FLOW(Regular), SAME_REG_HINT(RO)}, // #147 [ref=1x]
+ { 0 , 0 , 509, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #148 [ref=1x]
+ { F(Rep) , 0 , 510, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #149 [ref=1x]
+ { F(Mmx)|F(Vec) , 0 , 395, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #150 [ref=37x]
+ { F(Mmx)|F(Vec) , 0 , 397, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #151 [ref=1x]
+ { F(Mmx)|F(Vec) , 0 , 395, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(RO)}, // #152 [ref=6x]
+ { F(Mmx)|F(Vec) , 0 , 395, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #153 [ref=16x]
+ { F(Mmx) , 0 , 139, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #154 [ref=26x]
+ { F(Vec) , 0 , 72 , 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #155 [ref=4x]
+ { F(Vec) , 0 , 511, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #156 [ref=1x]
+ { F(Vec) , 0 , 512, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #157 [ref=1x]
+ { F(Vec) , 0 , 513, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #158 [ref=1x]
+ { F(Vec) , 0 , 514, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #159 [ref=1x]
+ { F(Vec) , 0 , 515, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #160 [ref=1x]
+ { F(Vec) , 0 , 516, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #161 [ref=1x]
+ { F(Mmx)|F(Vec) , 0 , 399, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #162 [ref=1x]
+ { F(Vec) , 0 , 517, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #163 [ref=1x]
+ { F(Vec) , 0 , 518, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #164 [ref=1x]
+ { F(Vec) , 0 , 519, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #165 [ref=1x]
+ { F(Mmx)|F(Vec) , 0 , 520, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #166 [ref=1x]
+ { F(Mmx)|F(Vec) , 0 , 521, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #167 [ref=1x]
+ { F(Vec) , 0 , 313, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #168 [ref=2x]
+ { 0 , 0 , 144, 5 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #169 [ref=1x]
+ { F(Mmx) , 0 , 397, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #170 [ref=1x]
+ { F(Mmx)|F(Vec) , 0 , 401, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #171 [ref=8x]
+ { F(Vec) , 0 , 522, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #172 [ref=2x]
+ { 0 , 0 , 403, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #173 [ref=1x]
+ { F(Mmx)|F(Vec) , 0 , 405, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #174 [ref=3x]
+ { 0 , 0 , 149, 5 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #175 [ref=1x]
+ { 0 , 0 , 407, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #176 [ref=8x]
+ { 0 , 0 , 523, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #177 [ref=4x]
+ { 0 , 0 , 524, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #178 [ref=8x]
+ { 0 , 0 , 409, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #179 [ref=1x]
+ { F(Rep)|F(RepIgnored) , 0 , 411, 2 , CONTROL_FLOW(Return), SAME_REG_HINT(None)}, // #180 [ref=1x]
+ { 0 , 0 , 411, 2 , CONTROL_FLOW(Return), SAME_REG_HINT(None)}, // #181 [ref=1x]
+ { F(Vex) , 0 , 413, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #182 [ref=1x]
+ { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 20 , 13, CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #183 [ref=3x]
+ { F(Rep) , 0 , 199, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #184 [ref=1x]
+ { 0 , 0 , 525, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #185 [ref=30x]
+ { 0 , 0 , 259, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #186 [ref=2x]
+ { 0 , 0 , 415, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #187 [ref=3x]
+ { F(Rep) , 0 , 203, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #188 [ref=1x]
+ { F(Vex) , 0 , 526, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #189 [ref=8x]
+ { 0 , 0 , 64 , 8 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #190 [ref=1x]
+ { F(Tsib)|F(Vex) , 0 , 527, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #191 [ref=2x]
+ { F(Vex) , 0 , 466, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #192 [ref=1x]
+ { F(Tsib)|F(Vex) , 0 , 528, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #193 [ref=1x]
+ { F(Vex) , 0 , 529, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #194 [ref=1x]
+ { 0 , 0 , 530, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #195 [ref=2x]
+ { 0 , 0 , 50 , 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #196 [ref=2x]
+ { 0 , 0 , 417, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #197 [ref=1x]
+ { F(Evex)|F(Vec) , X(K)|X(T4X)|X(Z) , 531, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #198 [ref=4x]
+ { F(Evex)|F(Vec) , X(K)|X(T4X)|X(Z) , 532, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #199 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B64)|X(ER)|X(K)|X(SAE)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #200 [ref=22x]
+ { F(Evex)|F(Vec) , X(B16)|X(ER)|X(K)|X(SAE)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #201 [ref=23x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(ER)|X(K)|X(SAE)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #202 [ref=22x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(ER)|X(K)|X(SAE)|X(Z) , 533, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #203 [ref=18x]
+ { F(Evex)|F(Vec) , X(ER)|X(K)|X(SAE)|X(Z) , 534, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #204 [ref=18x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(ER)|X(K)|X(SAE)|X(Z) , 535, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #205 [ref=17x]
+ { F(Vec)|F(Vex) , 0 , 262, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #206 [ref=29x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #207 [ref=5x]
+ { F(Vec)|F(Vex) , 0 , 72 , 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #208 [ref=17x]
+ { F(Vec)|F(Vex) , 0 , 292, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #209 [ref=1x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(Z) , 265, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #210 [ref=4x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(Z) , 265, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #211 [ref=4x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B64)|X(K)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #212 [ref=10x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(K)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #213 [ref=12x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B64)|X(K)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(RO)}, // #214 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(K)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(RO)}, // #215 [ref=6x]
+ { F(Vec)|F(Vex) , 0 , 536, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #216 [ref=2x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #217 [ref=17x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #218 [ref=12x]
+ { F(Vec)|F(Vex) , 0 , 265, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #219 [ref=6x]
+ { F(Vec)|F(Vex) , 0 , 419, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #220 [ref=3x]
+ { F(EvexTransformable)|F(Vec)|F(Vex) , 0 , 537, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #221 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 538, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #222 [ref=1x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 539, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #223 [ref=4x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 540, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #224 [ref=4x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 445, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #225 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 538, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #226 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 541, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #227 [ref=1x]
+ { F(Evex)|F(EvexKReg)|F(Vec)|F(Vex) , X(B64)|X(ImplicitZ)|X(K)|X(SAE), 268, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #228 [ref=1x]
+ { F(Evex)|F(Vec) , X(B16)|X(ImplicitZ)|X(K)|X(SAE), 271, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #229 [ref=1x]
+ { F(Evex)|F(EvexKReg)|F(Vec)|F(Vex) , X(B32)|X(ImplicitZ)|X(K)|X(SAE), 268, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #230 [ref=1x]
+ { F(Evex)|F(EvexKReg)|F(Vec)|F(Vex) , X(ImplicitZ)|X(K)|X(SAE) , 542, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #231 [ref=1x]
+ { F(Evex)|F(Vec) , X(ImplicitZ)|X(K)|X(SAE) , 543, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #232 [ref=1x]
+ { F(Evex)|F(EvexKReg)|F(Vec)|F(Vex) , X(ImplicitZ)|X(K)|X(SAE) , 544, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #233 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(SAE) , 143, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #234 [ref=2x]
+ { F(Evex)|F(Vec) , X(SAE) , 313, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #235 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(SAE) , 283, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #236 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 274, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #237 [ref=6x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(K)|X(Z) , 277, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #238 [ref=1x]
+ { F(Evex)|F(Vec) , X(B32)|X(ER)|X(K)|X(SAE)|X(Z) , 421, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #239 [ref=3x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(ER)|X(K)|X(SAE)|X(Z) , 280, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #240 [ref=3x]
+ { F(Vec)|F(Vex) , 0 , 169, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #241 [ref=5x]
+ { F(Evex)|F(EvexCompat)|F(PreferEvex)|F(Vec)|F(Vex) , X(B32)|X(K)|X(Z) , 421, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #242 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B64)|X(ER)|X(K)|X(SAE)|X(Z) , 421, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #243 [ref=2x]
+ { F(Evex)|F(Vec) , X(B64)|X(ER)|X(K)|X(SAE)|X(Z) , 545, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #244 [ref=3x]
+ { F(Evex)|F(Vec) , X(B64)|X(ER)|X(K)|X(SAE)|X(Z) , 280, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #245 [ref=4x]
+ { F(Evex)|F(Vec) , X(B64)|X(ER)|X(K)|X(SAE)|X(Z) , 421, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #246 [ref=3x]
+ { F(Evex)|F(Vec) , X(B16)|X(ER)|X(K)|X(SAE)|X(Z) , 277, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #247 [ref=2x]
+ { F(Evex)|F(Vec) , X(B16)|X(K)|X(SAE)|X(Z) , 283, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #248 [ref=3x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(SAE)|X(Z) , 277, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #249 [ref=1x]
+ { F(Evex)|F(Vec) , X(B16)|X(K)|X(SAE)|X(Z) , 277, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #250 [ref=3x]
+ { F(Evex)|F(Vec) , X(B16)|X(ER)|X(K)|X(SAE)|X(Z) , 283, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #251 [ref=2x]
+ { F(Evex)|F(Vec) , X(B16)|X(ER)|X(K)|X(SAE)|X(Z) , 280, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #252 [ref=5x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(ER)|X(K)|X(SAE)|X(Z) , 277, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #253 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(SAE)|X(Z) , 286, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #254 [ref=1x]
+ { F(Evex)|F(Vec) , X(B32)|X(ER)|X(K)|X(SAE)|X(Z) , 277, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #255 [ref=2x]
+ { F(Evex)|F(Vec) , X(B32)|X(ER)|X(K)|X(SAE)|X(Z) , 280, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #256 [ref=2x]
+ { F(Evex)|F(Vec) , X(ER)|X(K)|X(SAE)|X(Z) , 533, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #257 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(ER)|X(SAE) , 341, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #258 [ref=1x]
+ { F(Evex)|F(Vec) , X(ER)|X(SAE) , 341, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #259 [ref=1x]
+ { F(Evex)|F(Vec) , X(K)|X(SAE)|X(Z) , 534, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #260 [ref=5x]
+ { F(Evex)|F(Vec) , X(ER)|X(SAE) , 423, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #261 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(ER)|X(SAE) , 425, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #262 [ref=2x]
+ { F(Evex)|F(Vec) , X(ER)|X(SAE) , 427, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #263 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(SAE)|X(Z) , 535, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #264 [ref=3x]
+ { F(Evex)|F(Vec) , X(ER)|X(K)|X(SAE)|X(Z) , 535, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #265 [ref=6x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(ER)|X(SAE) , 347, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #266 [ref=1x]
+ { F(Evex)|F(Vec) , X(ER)|X(SAE) , 347, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #267 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B64)|X(K)|X(SAE)|X(Z) , 421, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #268 [ref=1x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(SAE)|X(Z) , 280, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #269 [ref=3x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(SAE)|X(Z) , 421, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #270 [ref=1x]
+ { F(Evex)|F(Vec) , X(B16)|X(K)|X(SAE)|X(Z) , 280, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #271 [ref=3x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(K)|X(SAE)|X(Z) , 280, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #272 [ref=1x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(SAE)|X(Z) , 277, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #273 [ref=2x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(SAE)|X(Z) , 280, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #274 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(SAE) , 341, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #275 [ref=1x]
+ { F(Evex)|F(Vec) , X(SAE) , 341, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #276 [ref=1x]
+ { F(Evex)|F(Vec) , X(SAE) , 423, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #277 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(SAE) , 347, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #278 [ref=1x]
+ { F(Evex)|F(Vec) , X(SAE) , 347, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #279 [ref=1x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(Z) , 277, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #280 [ref=1x]
+ { F(Evex)|F(Vec) , X(ER)|X(SAE) , 425, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #281 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 265, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #282 [ref=3x]
+ { F(Vec)|F(Vex) , 0 , 265, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #283 [ref=10x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(SAE)|X(Z) , 78 , 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #284 [ref=3x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(SAE)|X(Z) , 78 , 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #285 [ref=3x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 280, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #286 [ref=8x]
+ { F(EvexTransformable)|F(Vec)|F(Vex) , 0 , 287, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #287 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 546, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #288 [ref=4x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 288, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #289 [ref=4x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 480, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #290 [ref=2x]
+ { F(Evex)|F(Vec) , X(B32)|X(ER)|X(K)|X(SAE)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #291 [ref=5x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(SAE)|X(Z) , 265, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #292 [ref=2x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(SAE)|X(Z) , 265, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #293 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(SAE)|X(Z) , 547, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #294 [ref=4x]
+ { F(Evex)|F(Vec) , X(K)|X(SAE)|X(Z) , 548, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #295 [ref=4x]
+ { F(Vec)|F(Vex) , 0 , 207, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #296 [ref=13x]
+ { F(Vec)|F(Vex) , 0 , 429, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #297 [ref=4x]
+ { F(Vec)|F(Vex) , 0 , 431, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #298 [ref=4x]
+ { F(Evex)|F(Vec) , X(B64)|X(ImplicitZ)|X(K) , 549, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #299 [ref=1x]
+ { F(Evex)|F(Vec) , X(B16)|X(K) , 549, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #300 [ref=1x]
+ { F(Evex)|F(Vec) , X(B32)|X(ImplicitZ)|X(K) , 549, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #301 [ref=1x]
+ { F(Evex)|F(Vec) , X(ImplicitZ)|X(K) , 550, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #302 [ref=1x]
+ { F(Evex)|F(Vec) , X(K) , 551, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #303 [ref=1x]
+ { F(Evex)|F(Vec) , X(ImplicitZ)|X(K) , 552, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #304 [ref=1x]
+ { F(Vec)|F(Vex) , 0 , 280, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #305 [ref=7x]
+ { F(Vec)|F(Vex) , 0 , 143, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #306 [ref=1x]
+ { F(Vec)|F(Vex) , 0 , 283, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #307 [ref=1x]
+ { F(Evex)|F(EvexTwoOp)|F(Vec)|F(Vex)|F(Vsib) , X(K) , 211, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #308 [ref=2x]
+ { F(Evex)|F(EvexTwoOp)|F(Vec)|F(Vex)|F(Vsib) , X(K) , 154, 5 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #309 [ref=2x]
+ { F(Evex)|F(Vsib) , X(K) , 553, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #310 [ref=4x]
+ { F(Evex)|F(Vsib) , X(K) , 554, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #311 [ref=4x]
+ { F(Evex)|F(Vsib) , X(K) , 555, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #312 [ref=8x]
+ { F(Evex)|F(EvexTwoOp)|F(Vec)|F(Vex)|F(Vsib) , X(K) , 159, 5 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #313 [ref=2x]
+ { F(Evex)|F(EvexTwoOp)|F(Vec)|F(Vex)|F(Vsib) , X(K) , 289, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #314 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(SAE)|X(Z) , 533, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #315 [ref=3x]
+ { F(Evex)|F(Vec) , X(K)|X(SAE)|X(Z) , 535, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #316 [ref=3x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(SAE)|X(Z) , 292, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #317 [ref=2x]
+ { F(Evex)|F(Vec) , X(B16)|X(K)|X(SAE)|X(Z) , 292, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #318 [ref=3x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(SAE)|X(Z) , 292, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #319 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(SAE)|X(Z) , 556, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #320 [ref=3x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 265, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #321 [ref=3x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #322 [ref=22x]
+ { F(EvexTransformable)|F(Vec)|F(Vex) , 0 , 433, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #323 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 433, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #324 [ref=4x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 557, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #325 [ref=4x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 548, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #326 [ref=1x]
+ { F(Vex) , 0 , 497, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #327 [ref=2x]
+ { F(Vec)|F(Vex) , 0 , 500, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #328 [ref=1x]
+ { F(Vec)|F(Vex) , 0 , 215, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #329 [ref=4x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B64)|X(K)|X(SAE)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #330 [ref=2x]
+ { F(Evex)|F(Vec) , X(B16)|X(K)|X(SAE)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #331 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(K)|X(SAE)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #332 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(SAE)|X(Z) , 533, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #333 [ref=2x]
+ { 0 , 0 , 435, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #334 [ref=3x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 72 , 8 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #335 [ref=4x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 437, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #336 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 295, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #337 [ref=1x]
+ { F(EvexTransformable)|F(Vec)|F(Vex) , 0 , 72 , 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #338 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 116, 6 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #339 [ref=6x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 82 , 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #340 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 219, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #341 [ref=4x]
+ { F(Vec)|F(Vex) , 0 , 558, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #342 [ref=3x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 164, 5 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #343 [ref=3x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 169, 5 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #344 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 174, 5 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #345 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 80 , 8 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #346 [ref=1x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 223, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #347 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 280, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #348 [ref=4x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 88 , 8 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #349 [ref=1x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 439, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #350 [ref=1x]
+ { 0 , 0 , 441, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #351 [ref=1x]
+ { 0 , 0 , 443, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #352 [ref=1x]
+ { F(Evex)|F(Vec) , X(B32) , 298, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #353 [ref=1x]
+ { F(Evex)|F(Vec) , X(B64) , 298, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #354 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(K)|X(Z) , 280, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #355 [ref=1x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(Z) , 280, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #356 [ref=5x]
+ { F(EvexTransformable)|F(Vec)|F(Vex) , 0 , 262, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(RO)}, // #357 [ref=2x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(RO)}, // #358 [ref=2x]
+ { F(EvexTransformable)|F(Vec)|F(Vex) , 0 , 262, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #359 [ref=2x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #360 [ref=2x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #361 [ref=2x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(RO)}, // #362 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #363 [ref=13x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 559, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #364 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 560, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #365 [ref=1x]
+ { F(Evex)|F(Vec) , 0 , 561, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #366 [ref=6x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 445, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #367 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 562, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #368 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 265, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #369 [ref=1x]
+ { F(Evex)|F(Vec) , X(ImplicitZ)|X(K) , 271, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #370 [ref=2x]
+ { F(Evex)|F(Vec) , X(B32)|X(ImplicitZ)|X(K) , 271, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #371 [ref=2x]
+ { F(Evex)|F(EvexKReg)|F(Vec)|F(Vex) , X(ImplicitZ)|X(K) , 301, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #372 [ref=4x]
+ { F(Evex)|F(EvexKReg)|F(Vec)|F(Vex) , X(B32)|X(ImplicitZ)|X(K) , 301, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #373 [ref=2x]
+ { F(Evex)|F(EvexKReg)|F(Vec)|F(Vex) , X(B64)|X(ImplicitZ)|X(K) , 301, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #374 [ref=2x]
+ { F(Vec)|F(Vex) , 0 , 511, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #375 [ref=1x]
+ { F(Vec)|F(Vex) , 0 , 512, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #376 [ref=1x]
+ { F(Vec)|F(Vex) , 0 , 513, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #377 [ref=1x]
+ { F(Vec)|F(Vex) , 0 , 514, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #378 [ref=1x]
+ { F(Evex)|F(Vec) , X(B64)|X(ImplicitZ)|X(K) , 271, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #379 [ref=4x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(Z) , 280, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #380 [ref=6x]
+ { F(Evex)|F(EvexCompat)|F(PreferEvex)|F(Vec)|F(Vex) , X(B32)|X(K)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #381 [ref=4x]
+ { F(Vec)|F(Vex) , 0 , 266, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #382 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(K)|X(Z) , 263, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #383 [ref=2x]
+ { F(Vec)|F(Vex) , 0 , 227, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #384 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B64)|X(K)|X(Z) , 96 , 8 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #385 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(K)|X(Z) , 96 , 8 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #386 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B64)|X(K)|X(Z) , 231, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #387 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 515, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #388 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 516, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #389 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 563, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #390 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 564, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #391 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 565, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #392 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 566, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #393 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 567, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #394 [ref=1x]
+ { F(Vec)|F(Vex) , 0 , 419, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #395 [ref=12x]
+ { F(Evex)|F(EvexCompat)|F(PreferEvex)|F(Vec)|F(Vex) , X(B64)|X(K)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #396 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(RO)}, // #397 [ref=8x]
+ { F(Evex)|F(Vec) , 0 , 568, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #398 [ref=4x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 304, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #399 [ref=6x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 307, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #400 [ref=9x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 310, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #401 [ref=3x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 283, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #402 [ref=4x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 313, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #403 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 277, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #404 [ref=6x]
+ { F(Vec)|F(Vex) , 0 , 207, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #405 [ref=1x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(Z) , 292, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #406 [ref=3x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(Z) , 292, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #407 [ref=3x]
+ { F(Vec)|F(Vex) , 0 , 447, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #408 [ref=4x]
+ { F(Evex)|F(Vec)|F(Vsib) , X(K) , 316, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #409 [ref=2x]
+ { F(Evex)|F(Vec)|F(Vsib) , X(K) , 449, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #410 [ref=2x]
+ { F(Evex)|F(Vec)|F(Vsib) , X(K) , 451, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #411 [ref=2x]
+ { F(Evex)|F(Vec)|F(Vsib) , X(K) , 319, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #412 [ref=2x]
+ { F(Vec)|F(Vex) , 0 , 453, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #413 [ref=8x]
+ { F(Evex)|F(Vec) , X(ImplicitZ)|X(K) , 322, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #414 [ref=5x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(K)|X(Z) , 292, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #415 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 292, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #416 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(K)|X(Z) , 122, 6 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #417 [ref=3x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 292, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #418 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B64)|X(K)|X(Z) , 122, 6 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #419 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 122, 6 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #420 [ref=3x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(Z) , 128, 6 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #421 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #422 [ref=6x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(K)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #423 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B64)|X(K)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #424 [ref=2x]
+ { F(Evex)|F(Vec) , X(B32)|X(ImplicitZ)|X(K) , 322, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #425 [ref=2x]
+ { F(Evex)|F(Vec) , X(B64)|X(ImplicitZ)|X(K) , 322, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #426 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 533, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #427 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 535, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #428 [ref=2x]
+ { F(Evex)|F(Vec) , X(B16)|X(K)|X(Z) , 280, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #429 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 534, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #430 [ref=2x]
+ { F(Vec)|F(Vex) , 0 , 535, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #431 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 547, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #432 [ref=1x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 548, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #433 [ref=1x]
+ { F(EvexTransformable)|F(Vec)|F(Vex) , 0 , 292, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #434 [ref=2x]
+ { F(EvexTransformable)|F(Vec)|F(Vex) , 0 , 547, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #435 [ref=1x]
+ { F(EvexTransformable)|F(Vec)|F(Vex) , 0 , 548, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #436 [ref=1x]
+ { F(Evex)|F(Vec) , X(B64)|X(ER)|X(K)|X(SAE)|X(Z) , 262, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #437 [ref=1x]
+ { F(Vec)|F(Vex) , 0 , 569, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #438 [ref=1x]
+ { F(Vec)|F(Vex) , 0 , 570, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #439 [ref=1x]
+ { F(Vec)|F(Vex) , 0 , 571, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #440 [ref=1x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(Z) , 266, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #441 [ref=2x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(Z) , 266, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #442 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B64)|X(K)|X(Z) , 265, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #443 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(K)|X(Z) , 265, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #444 [ref=1x]
+ { F(Vec)|F(Vex) , 0 , 262, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #445 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B64)|X(ER)|X(K)|X(SAE)|X(Z) , 280, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #446 [ref=1x]
+ { F(Vec)|F(Vex) , 0 , 110, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #447 [ref=2x]
+ { 0 , 0 , 27 , 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #448 [ref=2x]
+ { 0 , 0 , 28 , 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #449 [ref=2x]
+ { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 25 , 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #450 [ref=1x]
+ { 0 , 0 , 236, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #451 [ref=1x]
+ { F(XAcquire) , 0 , 25 , 8 , CONTROL_FLOW(Regular), SAME_REG_HINT(RO)}, // #452 [ref=1x]
+ { 0 , 0 , 572, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #453 [ref=6x]
+ { 0 , 0 , 573, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)} // #454 [ref=6x]
};
#undef SAME_REG_HINT
#undef CONTROL_FLOW
@@ -2609,197 +2656,220 @@ const InstDB::CommonInfo InstDB::_commonInfoTable[] = {
// ------------------- Automatically generated, do not edit -------------------
#define EXT(VAL) uint32_t(CpuFeatures::X86::k##VAL)
const InstDB::AdditionalInfo InstDB::_additionalInfoTable[] = {
- { 0, 0, { 0 } }, // #0 [ref=148x]
+ { 0, 0, { 0 } }, // #0 [ref=67x]
{ 0, 1, { 0 } }, // #1 [ref=32x]
- { 0, 2, { 0 } }, // #2 [ref=2x]
- { 0, 3, { EXT(ADX) } }, // #3 [ref=1x]
- { 0, 0, { EXT(SSE2) } }, // #4 [ref=60x]
- { 0, 0, { EXT(SSE) } }, // #5 [ref=41x]
- { 0, 0, { EXT(SSE3) } }, // #6 [ref=12x]
- { 0, 4, { EXT(ADX) } }, // #7 [ref=1x]
- { 0, 0, { EXT(AESNI) } }, // #8 [ref=6x]
- { 0, 1, { EXT(BMI) } }, // #9 [ref=6x]
- { 0, 5, { 0 } }, // #10 [ref=5x]
- { 0, 0, { EXT(TBM) } }, // #11 [ref=9x]
- { 0, 0, { EXT(SSE4_1) } }, // #12 [ref=47x]
- { 0, 0, { EXT(MPX) } }, // #13 [ref=7x]
- { 0, 6, { 0 } }, // #14 [ref=4x]
- { 0, 1, { EXT(BMI2) } }, // #15 [ref=1x]
- { 0, 7, { EXT(SMAP) } }, // #16 [ref=2x]
- { 0, 8, { 0 } }, // #17 [ref=2x]
- { 0, 9, { 0 } }, // #18 [ref=2x]
- { 0, 0, { EXT(CLDEMOTE) } }, // #19 [ref=1x]
- { 0, 0, { EXT(CLFLUSH) } }, // #20 [ref=1x]
- { 0, 0, { EXT(CLFLUSHOPT) } }, // #21 [ref=1x]
- { 0, 0, { EXT(SVM) } }, // #22 [ref=6x]
- { 0, 10, { 0 } }, // #23 [ref=2x]
- { 0, 1, { EXT(CET_SS) } }, // #24 [ref=3x]
- { 0, 0, { EXT(UINTR) } }, // #25 [ref=4x]
- { 0, 0, { EXT(CLWB) } }, // #26 [ref=1x]
- { 0, 0, { EXT(CLZERO) } }, // #27 [ref=1x]
- { 0, 3, { 0 } }, // #28 [ref=1x]
- { 0, 11, { EXT(CMOV) } }, // #29 [ref=6x]
- { 0, 12, { EXT(CMOV) } }, // #30 [ref=8x]
- { 0, 13, { EXT(CMOV) } }, // #31 [ref=6x]
- { 0, 14, { EXT(CMOV) } }, // #32 [ref=4x]
- { 0, 15, { EXT(CMOV) } }, // #33 [ref=4x]
- { 0, 16, { EXT(CMOV) } }, // #34 [ref=2x]
- { 0, 17, { EXT(CMOV) } }, // #35 [ref=6x]
- { 0, 18, { EXT(CMOV) } }, // #36 [ref=2x]
- { 0, 19, { 0 } }, // #37 [ref=2x]
- { 0, 1, { EXT(I486) } }, // #38 [ref=2x]
- { 0, 5, { EXT(CMPXCHG16B) } }, // #39 [ref=1x]
- { 0, 5, { EXT(CMPXCHG8B) } }, // #40 [ref=1x]
- { 0, 1, { EXT(SSE2) } }, // #41 [ref=2x]
- { 0, 1, { EXT(SSE) } }, // #42 [ref=2x]
- { 0, 0, { EXT(I486) } }, // #43 [ref=4x]
- { 0, 0, { EXT(SSE4_2) } }, // #44 [ref=2x]
- { 0, 20, { 0 } }, // #45 [ref=2x]
- { 0, 0, { EXT(MMX) } }, // #46 [ref=1x]
- { 0, 0, { EXT(CET_IBT) } }, // #47 [ref=2x]
- { 0, 0, { EXT(ENQCMD) } }, // #48 [ref=2x]
- { 0, 0, { EXT(SSE4A) } }, // #49 [ref=4x]
- { 0, 21, { 0 } }, // #50 [ref=4x]
- { 0, 0, { EXT(3DNOW) } }, // #51 [ref=21x]
- { 0, 0, { EXT(FXSR) } }, // #52 [ref=4x]
- { 0, 0, { EXT(SMX) } }, // #53 [ref=1x]
- { 0, 0, { EXT(GFNI) } }, // #54 [ref=3x]
- { 0, 0, { EXT(HRESET) } }, // #55 [ref=1x]
- { 0, 0, { EXT(CET_SS) } }, // #56 [ref=9x]
- { 0, 16, { 0 } }, // #57 [ref=5x]
- { 0, 0, { EXT(VMX) } }, // #58 [ref=12x]
- { 0, 11, { 0 } }, // #59 [ref=8x]
- { 0, 12, { 0 } }, // #60 [ref=12x]
- { 0, 13, { 0 } }, // #61 [ref=10x]
- { 0, 14, { 0 } }, // #62 [ref=8x]
- { 0, 15, { 0 } }, // #63 [ref=8x]
- { 0, 17, { 0 } }, // #64 [ref=8x]
- { 0, 18, { 0 } }, // #65 [ref=4x]
- { 0, 0, { EXT(AVX512_DQ) } }, // #66 [ref=22x]
- { 0, 0, { EXT(AVX512_BW) } }, // #67 [ref=20x]
- { 0, 0, { EXT(AVX512_F) } }, // #68 [ref=36x]
- { 1, 0, { EXT(AVX512_DQ) } }, // #69 [ref=1x]
- { 1, 0, { EXT(AVX512_BW) } }, // #70 [ref=2x]
- { 1, 0, { EXT(AVX512_F) } }, // #71 [ref=1x]
- { 0, 1, { EXT(AVX512_DQ) } }, // #72 [ref=3x]
- { 0, 1, { EXT(AVX512_BW) } }, // #73 [ref=4x]
- { 0, 1, { EXT(AVX512_F) } }, // #74 [ref=1x]
- { 0, 22, { EXT(LAHFSAHF) } }, // #75 [ref=1x]
- { 0, 0, { EXT(AMX_TILE) } }, // #76 [ref=7x]
- { 0, 0, { EXT(LWP) } }, // #77 [ref=4x]
- { 0, 23, { 0 } }, // #78 [ref=3x]
- { 0, 1, { EXT(LZCNT) } }, // #79 [ref=1x]
- { 0, 0, { EXT(MMX2) } }, // #80 [ref=8x]
- { 0, 1, { EXT(MCOMMIT) } }, // #81 [ref=1x]
- { 0, 0, { EXT(MONITOR) } }, // #82 [ref=2x]
- { 0, 0, { EXT(MONITORX) } }, // #83 [ref=2x]
- { 1, 0, { 0 } }, // #84 [ref=1x]
- { 1, 0, { EXT(SSE2) } }, // #85 [ref=5x]
- { 1, 0, { EXT(SSE) } }, // #86 [ref=3x]
- { 0, 0, { EXT(MOVBE) } }, // #87 [ref=1x]
- { 0, 0, { EXT(MMX), EXT(SSE2) } }, // #88 [ref=45x]
- { 0, 0, { EXT(MOVDIR64B) } }, // #89 [ref=1x]
- { 0, 0, { EXT(MOVDIRI) } }, // #90 [ref=1x]
- { 1, 0, { EXT(MMX), EXT(SSE2) } }, // #91 [ref=1x]
- { 0, 0, { EXT(BMI2) } }, // #92 [ref=7x]
- { 0, 0, { EXT(SSSE3) } }, // #93 [ref=15x]
- { 0, 0, { EXT(MMX2), EXT(SSE2) } }, // #94 [ref=10x]
- { 0, 0, { EXT(PCLMULQDQ) } }, // #95 [ref=1x]
- { 0, 1, { EXT(SSE4_2) } }, // #96 [ref=4x]
- { 0, 0, { EXT(PCONFIG) } }, // #97 [ref=1x]
- { 0, 0, { EXT(MMX2), EXT(SSE2), EXT(SSE4_1) } }, // #98 [ref=1x]
- { 0, 0, { EXT(3DNOW2) } }, // #99 [ref=5x]
- { 0, 0, { EXT(GEODE) } }, // #100 [ref=2x]
- { 0, 1, { EXT(POPCNT) } }, // #101 [ref=1x]
- { 0, 24, { 0 } }, // #102 [ref=3x]
- { 0, 1, { EXT(PREFETCHW) } }, // #103 [ref=1x]
- { 0, 1, { EXT(PREFETCHWT1) } }, // #104 [ref=1x]
- { 0, 20, { EXT(SNP) } }, // #105 [ref=3x]
- { 0, 1, { EXT(SSE4_1) } }, // #106 [ref=1x]
- { 0, 0, { EXT(PTWRITE) } }, // #107 [ref=1x]
- { 0, 25, { 0 } }, // #108 [ref=3x]
- { 0, 1, { EXT(SNP) } }, // #109 [ref=1x]
- { 0, 26, { 0 } }, // #110 [ref=2x]
- { 0, 0, { EXT(FSGSBASE) } }, // #111 [ref=4x]
- { 0, 0, { EXT(MSR) } }, // #112 [ref=2x]
- { 0, 0, { EXT(RDPID) } }, // #113 [ref=1x]
- { 0, 0, { EXT(OSPKE) } }, // #114 [ref=1x]
- { 0, 0, { EXT(RDPRU) } }, // #115 [ref=1x]
- { 0, 1, { EXT(RDRAND) } }, // #116 [ref=1x]
- { 0, 1, { EXT(RDSEED) } }, // #117 [ref=1x]
- { 0, 0, { EXT(RDTSC) } }, // #118 [ref=1x]
- { 0, 0, { EXT(RDTSCP) } }, // #119 [ref=1x]
- { 0, 27, { 0 } }, // #120 [ref=2x]
- { 0, 28, { EXT(LAHFSAHF) } }, // #121 [ref=1x]
- { 0, 0, { EXT(SERIALIZE) } }, // #122 [ref=1x]
- { 0, 0, { EXT(SHA) } }, // #123 [ref=7x]
- { 0, 0, { EXT(SKINIT) } }, // #124 [ref=2x]
- { 0, 0, { EXT(AMX_BF16) } }, // #125 [ref=1x]
- { 0, 0, { EXT(AMX_INT8) } }, // #126 [ref=4x]
- { 0, 1, { EXT(UINTR) } }, // #127 [ref=1x]
- { 0, 1, { EXT(WAITPKG) } }, // #128 [ref=2x]
- { 0, 0, { EXT(WAITPKG) } }, // #129 [ref=1x]
- { 0, 0, { EXT(AVX512_4FMAPS) } }, // #130 [ref=4x]
- { 0, 0, { EXT(AVX), EXT(AVX512_F), EXT(AVX512_VL) } }, // #131 [ref=42x]
- { 0, 0, { EXT(AVX512_FP16), EXT(AVX512_VL) } }, // #132 [ref=63x]
- { 0, 0, { EXT(AVX), EXT(AVX512_F) } }, // #133 [ref=29x]
- { 0, 0, { EXT(AVX512_FP16) } }, // #134 [ref=43x]
- { 0, 0, { EXT(AVX) } }, // #135 [ref=35x]
- { 0, 0, { EXT(AESNI), EXT(AVX), EXT(AVX512_F), EXT(AVX512_VL), EXT(VAES) } }, // #136 [ref=4x]
- { 0, 0, { EXT(AESNI), EXT(AVX) } }, // #137 [ref=2x]
- { 0, 0, { EXT(AVX512_F), EXT(AVX512_VL) } }, // #138 [ref=108x]
- { 0, 0, { EXT(AVX), EXT(AVX512_DQ), EXT(AVX512_VL) } }, // #139 [ref=8x]
- { 0, 0, { EXT(AVX512_DQ), EXT(AVX512_VL) } }, // #140 [ref=30x]
- { 0, 0, { EXT(AVX2) } }, // #141 [ref=7x]
- { 0, 0, { EXT(AVX), EXT(AVX2), EXT(AVX512_F), EXT(AVX512_VL) } }, // #142 [ref=39x]
- { 0, 1, { EXT(AVX), EXT(AVX512_F) } }, // #143 [ref=4x]
- { 0, 0, { EXT(AVX512_BF16), EXT(AVX512_VL) } }, // #144 [ref=3x]
- { 0, 0, { EXT(AVX512_F), EXT(AVX512_VL), EXT(F16C) } }, // #145 [ref=2x]
- { 0, 0, { EXT(AVX512_BW), EXT(AVX512_VL) } }, // #146 [ref=24x]
- { 0, 0, { EXT(AVX512_ERI) } }, // #147 [ref=10x]
- { 0, 0, { EXT(AVX512_F), EXT(AVX512_VL), EXT(FMA) } }, // #148 [ref=36x]
- { 0, 0, { EXT(AVX512_F), EXT(FMA) } }, // #149 [ref=24x]
- { 0, 0, { EXT(FMA4) } }, // #150 [ref=20x]
- { 0, 0, { EXT(XOP) } }, // #151 [ref=55x]
- { 0, 0, { EXT(AVX2), EXT(AVX512_F), EXT(AVX512_VL) } }, // #152 [ref=19x]
- { 0, 0, { EXT(AVX512_PFI) } }, // #153 [ref=16x]
- { 0, 0, { EXT(AVX), EXT(AVX512_F), EXT(AVX512_VL), EXT(GFNI) } }, // #154 [ref=3x]
- { 1, 0, { EXT(AVX), EXT(AVX512_F), EXT(AVX512_VL) } }, // #155 [ref=4x]
- { 1, 0, { EXT(AVX) } }, // #156 [ref=2x]
- { 1, 0, { EXT(AVX512_F), EXT(AVX512_VL) } }, // #157 [ref=4x]
- { 1, 0, { EXT(AVX512_BW), EXT(AVX512_VL) } }, // #158 [ref=2x]
- { 1, 0, { EXT(AVX), EXT(AVX512_F) } }, // #159 [ref=3x]
- { 0, 0, { EXT(AVX), EXT(AVX2) } }, // #160 [ref=17x]
- { 0, 0, { EXT(AVX512_VP2INTERSECT) } }, // #161 [ref=2x]
- { 0, 0, { EXT(AVX512_4VNNIW) } }, // #162 [ref=2x]
- { 0, 0, { EXT(AVX), EXT(AVX2), EXT(AVX512_BW), EXT(AVX512_VL) } }, // #163 [ref=54x]
- { 0, 0, { EXT(AVX2), EXT(AVX512_BW), EXT(AVX512_VL) } }, // #164 [ref=2x]
- { 0, 0, { EXT(AVX512_CDI), EXT(AVX512_VL) } }, // #165 [ref=6x]
- { 0, 0, { EXT(AVX), EXT(AVX512_F), EXT(AVX512_VL), EXT(PCLMULQDQ), EXT(VPCLMULQDQ) } }, // #166 [ref=1x]
- { 0, 1, { EXT(AVX) } }, // #167 [ref=7x]
- { 0, 0, { EXT(AVX512_VBMI2), EXT(AVX512_VL) } }, // #168 [ref=16x]
- { 0, 0, { EXT(AVX512_VL), EXT(AVX512_VNNI), EXT(AVX_VNNI) } }, // #169 [ref=4x]
- { 0, 0, { EXT(AVX512_VBMI), EXT(AVX512_VL) } }, // #170 [ref=4x]
- { 0, 0, { EXT(AVX), EXT(AVX512_BW) } }, // #171 [ref=4x]
- { 0, 0, { EXT(AVX), EXT(AVX512_DQ) } }, // #172 [ref=4x]
- { 0, 0, { EXT(AVX512_IFMA), EXT(AVX512_VL) } }, // #173 [ref=2x]
- { 0, 0, { EXT(AVX512_BITALG), EXT(AVX512_VL) } }, // #174 [ref=3x]
- { 0, 0, { EXT(AVX512_VL), EXT(AVX512_VPOPCNTDQ) } }, // #175 [ref=2x]
- { 0, 0, { EXT(WBNOINVD) } }, // #176 [ref=1x]
- { 0, 0, { EXT(RTM) } }, // #177 [ref=3x]
- { 0, 0, { EXT(XSAVE) } }, // #178 [ref=6x]
- { 0, 0, { EXT(TSXLDTRK) } }, // #179 [ref=2x]
- { 0, 0, { EXT(XSAVES) } }, // #180 [ref=4x]
- { 0, 0, { EXT(XSAVEC) } }, // #181 [ref=2x]
- { 0, 0, { EXT(XSAVEOPT) } }, // #182 [ref=2x]
- { 0, 1, { EXT(TSX) } } // #183 [ref=1x]
+ { 0, 0, { EXT(RAO_INT) } }, // #2 [ref=4x]
+ { 0, 2, { 0 } }, // #3 [ref=2x]
+ { 0, 3, { EXT(ADX) } }, // #4 [ref=1x]
+ { 0, 0, { EXT(SSE2) } }, // #5 [ref=60x]
+ { 0, 0, { EXT(SSE) } }, // #6 [ref=46x]
+ { 0, 0, { EXT(SSE3) } }, // #7 [ref=10x]
+ { 0, 4, { EXT(ADX) } }, // #8 [ref=1x]
+ { 0, 0, { EXT(AESNI) } }, // #9 [ref=6x]
+ { 0, 1, { EXT(BMI) } }, // #10 [ref=6x]
+ { 0, 5, { 0 } }, // #11 [ref=5x]
+ { 0, 0, { EXT(TBM) } }, // #12 [ref=9x]
+ { 0, 0, { EXT(SSE4_1) } }, // #13 [ref=47x]
+ { 0, 0, { EXT(MPX) } }, // #14 [ref=7x]
+ { 0, 6, { 0 } }, // #15 [ref=4x]
+ { 0, 1, { EXT(BMI2) } }, // #16 [ref=1x]
+ { 0, 7, { EXT(SMAP) } }, // #17 [ref=2x]
+ { 0, 8, { 0 } }, // #18 [ref=2x]
+ { 0, 9, { 0 } }, // #19 [ref=2x]
+ { 0, 0, { EXT(CLDEMOTE) } }, // #20 [ref=1x]
+ { 0, 0, { EXT(CLFLUSH) } }, // #21 [ref=1x]
+ { 0, 0, { EXT(CLFLUSHOPT) } }, // #22 [ref=1x]
+ { 0, 0, { EXT(SVM) } }, // #23 [ref=6x]
+ { 0, 10, { 0 } }, // #24 [ref=2x]
+ { 0, 1, { EXT(CET_SS) } }, // #25 [ref=3x]
+ { 0, 0, { EXT(UINTR) } }, // #26 [ref=4x]
+ { 0, 0, { EXT(CLWB) } }, // #27 [ref=1x]
+ { 0, 0, { EXT(CLZERO) } }, // #28 [ref=1x]
+ { 0, 3, { 0 } }, // #29 [ref=1x]
+ { 0, 11, { EXT(CMOV) } }, // #30 [ref=4x]
+ { 0, 12, { EXT(CMOV) } }, // #31 [ref=6x]
+ { 0, 13, { EXT(CMOV) } }, // #32 [ref=4x]
+ { 0, 14, { EXT(CMOV) } }, // #33 [ref=4x]
+ { 0, 15, { EXT(CMOV) } }, // #34 [ref=4x]
+ { 0, 16, { EXT(CMOV) } }, // #35 [ref=2x]
+ { 0, 17, { EXT(CMOV) } }, // #36 [ref=4x]
+ { 0, 18, { EXT(CMOV) } }, // #37 [ref=2x]
+ { 0, 1, { EXT(CMPCCXADD) } }, // #38 [ref=16x]
+ { 0, 19, { 0 } }, // #39 [ref=2x]
+ { 0, 1, { EXT(I486) } }, // #40 [ref=2x]
+ { 0, 5, { EXT(CMPXCHG16B) } }, // #41 [ref=1x]
+ { 0, 5, { EXT(CMPXCHG8B) } }, // #42 [ref=1x]
+ { 0, 1, { EXT(SSE2) } }, // #43 [ref=2x]
+ { 0, 1, { EXT(SSE) } }, // #44 [ref=2x]
+ { 0, 0, { EXT(I486) } }, // #45 [ref=5x]
+ { 0, 0, { EXT(SSE4_2) } }, // #46 [ref=2x]
+ { 0, 20, { 0 } }, // #47 [ref=2x]
+ { 0, 0, { EXT(MMX) } }, // #48 [ref=1x]
+ { 0, 0, { EXT(CET_IBT) } }, // #49 [ref=2x]
+ { 0, 1, { EXT(ENQCMD) } }, // #50 [ref=2x]
+ { 0, 0, { EXT(SSE4A) } }, // #51 [ref=4x]
+ { 0, 21, { EXT(FPU) } }, // #52 [ref=80x]
+ { 0, 22, { EXT(CMOV), EXT(FPU) } }, // #53 [ref=2x]
+ { 0, 23, { EXT(CMOV), EXT(FPU) } }, // #54 [ref=2x]
+ { 0, 24, { EXT(CMOV), EXT(FPU) } }, // #55 [ref=2x]
+ { 0, 25, { EXT(CMOV), EXT(FPU) } }, // #56 [ref=2x]
+ { 0, 26, { EXT(FPU) } }, // #57 [ref=4x]
+ { 0, 0, { EXT(3DNOW) } }, // #58 [ref=21x]
+ { 0, 21, { EXT(SSE3), EXT(FPU) } }, // #59 [ref=1x]
+ { 0, 21, { EXT(FXSR) } }, // #60 [ref=2x]
+ { 0, 27, { EXT(FXSR) } }, // #61 [ref=2x]
+ { 0, 0, { EXT(SMX) } }, // #62 [ref=1x]
+ { 0, 0, { EXT(GFNI) } }, // #63 [ref=3x]
+ { 0, 0, { EXT(HRESET) } }, // #64 [ref=1x]
+ { 0, 0, { EXT(CET_SS) } }, // #65 [ref=9x]
+ { 0, 16, { 0 } }, // #66 [ref=5x]
+ { 0, 0, { EXT(VMX) } }, // #67 [ref=13x]
+ { 0, 0, { EXT(INVLPGB) } }, // #68 [ref=2x]
+ { 0, 11, { 0 } }, // #69 [ref=8x]
+ { 0, 12, { 0 } }, // #70 [ref=12x]
+ { 0, 13, { 0 } }, // #71 [ref=10x]
+ { 0, 14, { 0 } }, // #72 [ref=8x]
+ { 0, 15, { 0 } }, // #73 [ref=8x]
+ { 0, 17, { 0 } }, // #74 [ref=8x]
+ { 0, 18, { 0 } }, // #75 [ref=4x]
+ { 0, 0, { EXT(AVX512_DQ) } }, // #76 [ref=22x]
+ { 0, 0, { EXT(AVX512_BW) } }, // #77 [ref=20x]
+ { 0, 0, { EXT(AVX512_F) } }, // #78 [ref=36x]
+ { 1, 0, { EXT(AVX512_DQ) } }, // #79 [ref=1x]
+ { 1, 0, { EXT(AVX512_BW) } }, // #80 [ref=2x]
+ { 1, 0, { EXT(AVX512_F) } }, // #81 [ref=1x]
+ { 0, 1, { EXT(AVX512_DQ) } }, // #82 [ref=3x]
+ { 0, 1, { EXT(AVX512_BW) } }, // #83 [ref=4x]
+ { 0, 1, { EXT(AVX512_F) } }, // #84 [ref=1x]
+ { 0, 28, { EXT(LAHFSAHF) } }, // #85 [ref=1x]
+ { 0, 0, { EXT(AMX_TILE) } }, // #86 [ref=7x]
+ { 0, 0, { EXT(LWP) } }, // #87 [ref=4x]
+ { 0, 29, { 0 } }, // #88 [ref=3x]
+ { 0, 1, { EXT(LZCNT) } }, // #89 [ref=1x]
+ { 0, 0, { EXT(MMX2) } }, // #90 [ref=3x]
+ { 0, 1, { EXT(MCOMMIT) } }, // #91 [ref=1x]
+ { 0, 0, { EXT(MONITOR) } }, // #92 [ref=2x]
+ { 0, 0, { EXT(MONITORX) } }, // #93 [ref=2x]
+ { 1, 0, { 0 } }, // #94 [ref=1x]
+ { 1, 0, { EXT(SSE2) } }, // #95 [ref=5x]
+ { 1, 0, { EXT(SSE) } }, // #96 [ref=3x]
+ { 0, 0, { EXT(MOVBE) } }, // #97 [ref=1x]
+ { 0, 0, { EXT(MMX), EXT(SSE2) } }, // #98 [ref=45x]
+ { 0, 0, { EXT(MOVDIR64B) } }, // #99 [ref=1x]
+ { 0, 0, { EXT(MOVDIRI) } }, // #100 [ref=1x]
+ { 1, 0, { EXT(MMX), EXT(SSE2) } }, // #101 [ref=1x]
+ { 0, 0, { EXT(BMI2) } }, // #102 [ref=7x]
+ { 0, 0, { EXT(SSSE3) } }, // #103 [ref=16x]
+ { 0, 0, { EXT(MMX2), EXT(SSE2) } }, // #104 [ref=10x]
+ { 0, 0, { EXT(PCLMULQDQ) } }, // #105 [ref=1x]
+ { 0, 1, { EXT(SSE4_2) } }, // #106 [ref=4x]
+ { 0, 0, { EXT(PCONFIG) } }, // #107 [ref=1x]
+ { 0, 0, { EXT(MMX2), EXT(SSE2), EXT(SSE4_1) } }, // #108 [ref=1x]
+ { 0, 0, { EXT(3DNOW2) } }, // #109 [ref=5x]
+ { 0, 0, { EXT(GEODE) } }, // #110 [ref=2x]
+ { 0, 1, { EXT(POPCNT) } }, // #111 [ref=1x]
+ { 0, 30, { 0 } }, // #112 [ref=3x]
+ { 0, 0, { EXT(PREFETCHI) } }, // #113 [ref=2x]
+ { 0, 1, { EXT(PREFETCHW) } }, // #114 [ref=1x]
+ { 0, 1, { EXT(PREFETCHWT1) } }, // #115 [ref=1x]
+ { 0, 20, { EXT(SEV_SNP) } }, // #116 [ref=3x]
+ { 0, 1, { EXT(SSE4_1) } }, // #117 [ref=1x]
+ { 0, 0, { EXT(PTWRITE) } }, // #118 [ref=1x]
+ { 0, 31, { 0 } }, // #119 [ref=3x]
+ { 0, 1, { EXT(SEV_SNP) } }, // #120 [ref=1x]
+ { 0, 32, { 0 } }, // #121 [ref=2x]
+ { 0, 0, { EXT(FSGSBASE) } }, // #122 [ref=4x]
+ { 0, 0, { EXT(MSR) } }, // #123 [ref=2x]
+ { 0, 0, { EXT(RDPID) } }, // #124 [ref=1x]
+ { 0, 0, { EXT(OSPKE) } }, // #125 [ref=1x]
+ { 0, 0, { EXT(RDPRU) } }, // #126 [ref=1x]
+ { 0, 1, { EXT(RDRAND) } }, // #127 [ref=1x]
+ { 0, 1, { EXT(RDSEED) } }, // #128 [ref=1x]
+ { 0, 0, { EXT(RDTSC) } }, // #129 [ref=1x]
+ { 0, 0, { EXT(RDTSCP) } }, // #130 [ref=1x]
+ { 0, 33, { 0 } }, // #131 [ref=2x]
+ { 0, 34, { EXT(LAHFSAHF) } }, // #132 [ref=1x]
+ { 0, 0, { EXT(SEAM) } }, // #133 [ref=4x]
+ { 0, 0, { EXT(SERIALIZE) } }, // #134 [ref=1x]
+ { 0, 0, { EXT(SHA) } }, // #135 [ref=7x]
+ { 0, 0, { EXT(SKINIT) } }, // #136 [ref=2x]
+ { 0, 0, { EXT(AMX_COMPLEX) } }, // #137 [ref=2x]
+ { 0, 0, { EXT(AMX_BF16) } }, // #138 [ref=1x]
+ { 0, 0, { EXT(AMX_INT8) } }, // #139 [ref=4x]
+ { 0, 0, { EXT(AMX_FP16) } }, // #140 [ref=1x]
+ { 0, 1, { EXT(UINTR) } }, // #141 [ref=1x]
+ { 0, 1, { EXT(WAITPKG) } }, // #142 [ref=2x]
+ { 0, 0, { EXT(WAITPKG) } }, // #143 [ref=1x]
+ { 0, 0, { EXT(AVX512_4FMAPS) } }, // #144 [ref=4x]
+ { 0, 0, { EXT(AVX), EXT(AVX512_F), EXT(AVX512_VL) } }, // #145 [ref=38x]
+ { 0, 0, { EXT(AVX512_FP16), EXT(AVX512_VL) } }, // #146 [ref=60x]
+ { 0, 0, { EXT(AVX), EXT(AVX512_F) } }, // #147 [ref=33x]
+ { 0, 0, { EXT(AVX512_FP16) } }, // #148 [ref=44x]
+ { 0, 0, { EXT(AVX) } }, // #149 [ref=35x]
+ { 0, 0, { EXT(AESNI), EXT(VAES), EXT(AVX), EXT(AVX512_F), EXT(AVX512_VL) } }, // #150 [ref=4x]
+ { 0, 0, { EXT(AESNI), EXT(AVX) } }, // #151 [ref=2x]
+ { 0, 0, { EXT(AVX512_F), EXT(AVX512_VL) } }, // #152 [ref=108x]
+ { 0, 0, { EXT(AVX), EXT(AVX512_DQ), EXT(AVX512_VL) } }, // #153 [ref=8x]
+ { 0, 0, { EXT(AVX_NE_CONVERT) } }, // #154 [ref=6x]
+ { 0, 0, { EXT(AVX512_DQ), EXT(AVX512_VL) } }, // #155 [ref=30x]
+ { 0, 0, { EXT(AVX2) } }, // #156 [ref=7x]
+ { 0, 0, { EXT(AVX), EXT(AVX2), EXT(AVX512_F), EXT(AVX512_VL) } }, // #157 [ref=39x]
+ { 0, 1, { EXT(AVX), EXT(AVX512_F) } }, // #158 [ref=4x]
+ { 0, 1, { EXT(AVX512_FP16) } }, // #159 [ref=2x]
+ { 0, 0, { EXT(AVX512_BF16), EXT(AVX512_VL) } }, // #160 [ref=2x]
+ { 0, 0, { EXT(AVX_NE_CONVERT), EXT(AVX512_BF16), EXT(AVX512_VL) } }, // #161 [ref=1x]
+ { 0, 0, { EXT(F16C), EXT(AVX512_F), EXT(AVX512_VL) } }, // #162 [ref=2x]
+ { 0, 0, { EXT(AVX512_BW), EXT(AVX512_VL) } }, // #163 [ref=24x]
+ { 0, 0, { EXT(AVX512_ER) } }, // #164 [ref=10x]
+ { 0, 0, { EXT(FMA), EXT(AVX512_F), EXT(AVX512_VL) } }, // #165 [ref=36x]
+ { 0, 0, { EXT(FMA), EXT(AVX512_F) } }, // #166 [ref=24x]
+ { 0, 0, { EXT(FMA4) } }, // #167 [ref=20x]
+ { 0, 0, { EXT(XOP) } }, // #168 [ref=55x]
+ { 0, 0, { EXT(AVX2), EXT(AVX512_F), EXT(AVX512_VL) } }, // #169 [ref=19x]
+ { 0, 0, { EXT(AVX512_PF) } }, // #170 [ref=16x]
+ { 0, 0, { EXT(GFNI), EXT(AVX), EXT(AVX512_F), EXT(AVX512_VL) } }, // #171 [ref=3x]
+ { 0, 0, { EXT(SEV_ES) } }, // #172 [ref=1x]
+ { 1, 0, { EXT(AVX), EXT(AVX512_F), EXT(AVX512_VL) } }, // #173 [ref=4x]
+ { 1, 0, { EXT(AVX) } }, // #174 [ref=2x]
+ { 1, 0, { EXT(AVX512_F), EXT(AVX512_VL) } }, // #175 [ref=4x]
+ { 1, 0, { EXT(AVX512_BW), EXT(AVX512_VL) } }, // #176 [ref=2x]
+ { 1, 0, { EXT(AVX), EXT(AVX512_F) } }, // #177 [ref=3x]
+ { 0, 0, { EXT(AVX), EXT(AVX2) } }, // #178 [ref=17x]
+ { 0, 0, { EXT(AVX512_VL), EXT(AVX512_VP2INTERSECT) } }, // #179 [ref=2x]
+ { 0, 0, { EXT(AVX512_4VNNIW) } }, // #180 [ref=2x]
+ { 0, 0, { EXT(AVX), EXT(AVX2), EXT(AVX512_BW), EXT(AVX512_VL) } }, // #181 [ref=54x]
+ { 0, 0, { EXT(AVX2), EXT(AVX512_BW), EXT(AVX512_VL) } }, // #182 [ref=2x]
+ { 0, 0, { EXT(AVX512_CD), EXT(AVX512_VL) } }, // #183 [ref=6x]
+ { 0, 0, { EXT(PCLMULQDQ), EXT(VPCLMULQDQ), EXT(AVX), EXT(AVX512_F), EXT(AVX512_VL) } }, // #184 [ref=1x]
+ { 0, 1, { EXT(AVX) } }, // #185 [ref=7x]
+ { 0, 0, { EXT(AVX512_VBMI2), EXT(AVX512_VL) } }, // #186 [ref=16x]
+ { 0, 0, { EXT(AVX_VNNI_INT8) } }, // #187 [ref=6x]
+ { 0, 0, { EXT(AVX_VNNI), EXT(AVX512_VL), EXT(AVX512_VNNI) } }, // #188 [ref=4x]
+ { 0, 0, { EXT(AVX_VNNI_INT16) } }, // #189 [ref=6x]
+ { 0, 0, { EXT(AVX512_VBMI), EXT(AVX512_VL) } }, // #190 [ref=4x]
+ { 0, 0, { EXT(AVX), EXT(AVX512_BW) } }, // #191 [ref=4x]
+ { 0, 0, { EXT(AVX), EXT(AVX512_DQ) } }, // #192 [ref=4x]
+ { 0, 0, { EXT(AVX_IFMA), EXT(AVX512_IFMA), EXT(AVX512_VL) } }, // #193 [ref=2x]
+ { 0, 0, { EXT(AVX512_BITALG), EXT(AVX512_VL) } }, // #194 [ref=3x]
+ { 0, 0, { EXT(AVX512_VL), EXT(AVX512_VPOPCNTDQ) } }, // #195 [ref=2x]
+ { 0, 0, { EXT(SHA512), EXT(AVX) } }, // #196 [ref=3x]
+ { 0, 0, { EXT(SM3), EXT(AVX) } }, // #197 [ref=3x]
+ { 0, 0, { EXT(SM4), EXT(AVX) } }, // #198 [ref=2x]
+ { 0, 0, { EXT(WBNOINVD) } }, // #199 [ref=1x]
+ { 0, 0, { EXT(RTM) } }, // #200 [ref=3x]
+ { 0, 0, { EXT(XSAVE) } }, // #201 [ref=6x]
+ { 0, 0, { EXT(TSXLDTRK) } }, // #202 [ref=2x]
+ { 0, 0, { EXT(XSAVES) } }, // #203 [ref=4x]
+ { 0, 0, { EXT(XSAVEC) } }, // #204 [ref=2x]
+ { 0, 0, { EXT(XSAVEOPT) } }, // #205 [ref=2x]
+ { 0, 1, { EXT(TSX) } } // #206 [ref=1x]
};
#undef EXT
#define FLAG(VAL) uint32_t(CpuRWFlags::kX86_##VAL)
const InstDB::RWFlagsInfoTable InstDB::_rwFlagsInfoTable[] = {
- { 0, 0 }, // #0 [ref=1429x]
- { 0, FLAG(AF) | FLAG(CF) | FLAG(OF) | FLAG(PF) | FLAG(SF) | FLAG(ZF) }, // #1 [ref=84x]
+ { 0, 0 }, // #0 [ref=1383x]
+ { 0, FLAG(AF) | FLAG(CF) | FLAG(OF) | FLAG(PF) | FLAG(SF) | FLAG(ZF) }, // #1 [ref=104x]
{ FLAG(CF), FLAG(AF) | FLAG(CF) | FLAG(OF) | FLAG(PF) | FLAG(SF) | FLAG(ZF) }, // #2 [ref=2x]
{ FLAG(CF), FLAG(CF) }, // #3 [ref=2x]
{ FLAG(OF), FLAG(OF) }, // #4 [ref=1x]
@@ -2809,30 +2879,36 @@ const InstDB::RWFlagsInfoTable InstDB::_rwFlagsInfoTable[] = {
{ 0, FLAG(CF) }, // #8 [ref=2x]
{ 0, FLAG(DF) }, // #9 [ref=2x]
{ 0, FLAG(IF) }, // #10 [ref=2x]
- { FLAG(CF) | FLAG(ZF), 0 }, // #11 [ref=14x]
- { FLAG(CF), 0 }, // #12 [ref=20x]
- { FLAG(ZF), 0 }, // #13 [ref=16x]
+ { FLAG(CF) | FLAG(ZF), 0 }, // #11 [ref=12x]
+ { FLAG(CF), 0 }, // #12 [ref=18x]
+ { FLAG(ZF), 0 }, // #13 [ref=14x]
{ FLAG(OF) | FLAG(SF) | FLAG(ZF), 0 }, // #14 [ref=12x]
{ FLAG(OF) | FLAG(SF), 0 }, // #15 [ref=12x]
{ FLAG(OF), 0 }, // #16 [ref=7x]
- { FLAG(PF), 0 }, // #17 [ref=14x]
+ { FLAG(PF), 0 }, // #17 [ref=12x]
{ FLAG(SF), 0 }, // #18 [ref=6x]
{ FLAG(DF), FLAG(AF) | FLAG(CF) | FLAG(OF) | FLAG(PF) | FLAG(SF) | FLAG(ZF) }, // #19 [ref=2x]
{ 0, FLAG(AF) | FLAG(OF) | FLAG(PF) | FLAG(SF) | FLAG(ZF) }, // #20 [ref=5x]
- { 0, FLAG(CF) | FLAG(PF) | FLAG(ZF) }, // #21 [ref=4x]
- { FLAG(AF) | FLAG(CF) | FLAG(PF) | FLAG(SF) | FLAG(ZF), 0 }, // #22 [ref=1x]
- { FLAG(DF), 0 }, // #23 [ref=3x]
- { 0, FLAG(AF) | FLAG(CF) | FLAG(DF) | FLAG(IF) | FLAG(OF) | FLAG(PF) | FLAG(SF) | FLAG(ZF) }, // #24 [ref=3x]
- { FLAG(AF) | FLAG(CF) | FLAG(DF) | FLAG(IF) | FLAG(OF) | FLAG(PF) | FLAG(SF) | FLAG(ZF), 0 }, // #25 [ref=3x]
- { FLAG(CF) | FLAG(OF), FLAG(CF) | FLAG(OF) }, // #26 [ref=2x]
- { 0, FLAG(CF) | FLAG(OF) }, // #27 [ref=2x]
- { 0, FLAG(AF) | FLAG(CF) | FLAG(PF) | FLAG(SF) | FLAG(ZF) } // #28 [ref=1x]
+ { 0, FLAG(C0) | FLAG(C1) | FLAG(C2) | FLAG(C3) }, // #21 [ref=83x]
+ { FLAG(CF), FLAG(C0) | FLAG(C1) | FLAG(C2) | FLAG(C3) }, // #22 [ref=2x]
+ { FLAG(CF) | FLAG(ZF), FLAG(C0) | FLAG(C1) | FLAG(C2) | FLAG(C3) }, // #23 [ref=2x]
+ { FLAG(ZF), FLAG(C0) | FLAG(C1) | FLAG(C2) | FLAG(C3) }, // #24 [ref=2x]
+ { FLAG(PF), FLAG(C0) | FLAG(C1) | FLAG(C2) | FLAG(C3) }, // #25 [ref=2x]
+ { 0, FLAG(C1) | FLAG(CF) | FLAG(PF) | FLAG(ZF) }, // #26 [ref=4x]
+ { FLAG(C0) | FLAG(C1) | FLAG(C2) | FLAG(C3), 0 }, // #27 [ref=2x]
+ { FLAG(AF) | FLAG(CF) | FLAG(PF) | FLAG(SF) | FLAG(ZF), 0 }, // #28 [ref=1x]
+ { FLAG(DF), 0 }, // #29 [ref=3x]
+ { 0, FLAG(AF) | FLAG(CF) | FLAG(DF) | FLAG(IF) | FLAG(OF) | FLAG(PF) | FLAG(SF) | FLAG(ZF) }, // #30 [ref=3x]
+ { FLAG(AF) | FLAG(CF) | FLAG(DF) | FLAG(IF) | FLAG(OF) | FLAG(PF) | FLAG(SF) | FLAG(ZF), 0 }, // #31 [ref=3x]
+ { FLAG(CF) | FLAG(OF), FLAG(CF) | FLAG(OF) }, // #32 [ref=2x]
+ { 0, FLAG(CF) | FLAG(OF) }, // #33 [ref=2x]
+ { 0, FLAG(AF) | FLAG(CF) | FLAG(PF) | FLAG(SF) | FLAG(ZF) } // #34 [ref=1x]
};
#undef FLAG
#define FLAG(VAL) uint32_t(InstRWFlags::k##VAL)
const InstRWFlags InstDB::_instFlagsTable[] = {
- InstRWFlags(FLAG(None)), // #0 [ref=1634x]
+ InstRWFlags(FLAG(None)), // #0 [ref=1693x]
InstRWFlags(FLAG(MovOp)) // #1 [ref=29x]
};
#undef FLAG
@@ -2845,164 +2921,8 @@ const InstRWFlags InstDB::_instFlagsTable[] = {
#ifndef ASMJIT_NO_TEXT
// ${NameData:Begin}
// ------------------- Automatically generated, do not edit -------------------
-const char InstDB::_nameData[] =
- "\0" "aaa\0" "aad\0" "aam\0" "aas\0" "adc\0" "adcx\0" "adox\0" "arpl\0" "bextr\0" "blcfill\0" "blci\0" "blcic\0"
- "blcmsk\0" "blcs\0" "blsfill\0" "blsi\0" "blsic\0" "blsmsk\0" "blsr\0" "bndcl\0" "bndcn\0" "bndcu\0" "bndldx\0"
- "bndmk\0" "bndmov\0" "bndstx\0" "bound\0" "bsf\0" "bsr\0" "bswap\0" "bt\0" "btc\0" "btr\0" "bts\0" "bzhi\0" "cbw\0"
- "cdq\0" "cdqe\0" "clac\0" "clc\0" "cld\0" "cldemote\0" "clflush\0" "clflushopt\0" "clgi\0" "cli\0" "clrssbsy\0"
- "clts\0" "clui\0" "clwb\0" "clzero\0" "cmc\0" "cmova\0" "cmovae\0" "cmovc\0" "cmovg\0" "cmovge\0" "cmovl\0"
- "cmovle\0" "cmovna\0" "cmovnae\0" "cmovnc\0" "cmovng\0" "cmovnge\0" "cmovnl\0" "cmovnle\0" "cmovno\0" "cmovnp\0"
- "cmovns\0" "cmovnz\0" "cmovo\0" "cmovp\0" "cmovpe\0" "cmovpo\0" "cmovs\0" "cmovz\0" "cmp\0" "cmps\0" "cmpxchg\0"
- "cmpxchg16b\0" "cmpxchg8b\0" "cpuid\0" "cqo\0" "crc32\0" "cvtpd2pi\0" "cvtpi2pd\0" "cvtpi2ps\0" "cvtps2pi\0"
- "cvttpd2pi\0" "cvttps2pi\0" "cwd\0" "cwde\0" "daa\0" "das\0" "endbr32\0" "endbr64\0" "enqcmd\0" "enqcmds\0" "f2xm1\0"
- "fabs\0" "faddp\0" "fbld\0" "fbstp\0" "fchs\0" "fclex\0" "fcmovb\0" "fcmovbe\0" "fcmove\0" "fcmovnb\0" "fcmovnbe\0"
- "fcmovne\0" "fcmovnu\0" "fcmovu\0" "fcom\0" "fcomi\0" "fcomip\0" "fcomp\0" "fcompp\0" "fcos\0" "fdecstp\0" "fdiv\0"
- "fdivp\0" "fdivr\0" "fdivrp\0" "femms\0" "ffree\0" "fiadd\0" "ficom\0" "ficomp\0" "fidiv\0" "fidivr\0" "fild\0"
- "fimul\0" "fincstp\0" "finit\0" "fist\0" "fistp\0" "fisttp\0" "fisub\0" "fisubr\0" "fld\0" "fld1\0" "fldcw\0"
- "fldenv\0" "fldl2e\0" "fldl2t\0" "fldlg2\0" "fldln2\0" "fldpi\0" "fldz\0" "fmulp\0" "fnclex\0" "fninit\0" "fnop\0"
- "fnsave\0" "fnstcw\0" "fnstenv\0" "fnstsw\0" "fpatan\0" "fprem\0" "fprem1\0" "fptan\0" "frndint\0" "frstor\0"
- "fsave\0" "fscale\0" "fsin\0" "fsincos\0" "fsqrt\0" "fst\0" "fstcw\0" "fstenv\0" "fstp\0" "fstsw\0" "fsubp\0"
- "fsubrp\0" "ftst\0" "fucom\0" "fucomi\0" "fucomip\0" "fucomp\0" "fucompp\0" "fwait\0" "fxam\0" "fxch\0" "fxrstor\0"
- "fxrstor64\0" "fxsave\0" "fxsave64\0" "fxtract\0" "fyl2x\0" "fyl2xp1\0" "getsec\0" "hlt\0" "hreset\0" "inc\0"
- "incsspd\0" "incsspq\0" "insertq\0" "int3\0" "into\0" "invept\0" "invlpg\0" "invlpga\0" "invpcid\0" "invvpid\0"
- "iretd\0" "iretq\0" "ja\0" "jae\0" "jb\0" "jbe\0" "jc\0" "je\0" "jecxz\0" "jg\0" "jge\0" "jl\0" "jle\0" "jna\0"
- "jnae\0" "jnb\0" "jnbe\0" "jnc\0" "jne\0" "jng\0" "jnge\0" "jnl\0" "jnle\0" "jno\0" "jnp\0" "jns\0" "jnz\0" "jo\0"
- "jp\0" "jpe\0" "jpo\0" "js\0" "jz\0" "kaddb\0" "kaddd\0" "kaddq\0" "kaddw\0" "kandb\0" "kandd\0" "kandnb\0"
- "kandnd\0" "kandnq\0" "kandnw\0" "kandq\0" "kandw\0" "kmovb\0" "kmovw\0" "knotb\0" "knotd\0" "knotq\0" "knotw\0"
- "korb\0" "kord\0" "korq\0" "kortestb\0" "kortestd\0" "kortestq\0" "kortestw\0" "korw\0" "kshiftlb\0" "kshiftld\0"
- "kshiftlq\0" "kshiftlw\0" "kshiftrb\0" "kshiftrd\0" "kshiftrq\0" "kshiftrw\0" "ktestb\0" "ktestd\0" "ktestq\0"
- "ktestw\0" "kunpckbw\0" "kunpckdq\0" "kunpckwd\0" "kxnorb\0" "kxnord\0" "kxnorq\0" "kxnorw\0" "kxorb\0" "kxord\0"
- "kxorq\0" "kxorw\0" "lahf\0" "lar\0" "lcall\0" "lds\0" "ldtilecfg\0" "lea\0" "leave\0" "les\0" "lfence\0" "lfs\0"
- "lgdt\0" "lgs\0" "lidt\0" "ljmp\0" "lldt\0" "llwpcb\0" "lmsw\0" "lods\0" "loop\0" "loope\0" "loopne\0" "lsl\0"
- "ltr\0" "lwpins\0" "lwpval\0" "lzcnt\0" "mcommit\0" "mfence\0" "monitorx\0" "movabs\0" "movdir64b\0" "movdiri\0"
- "movdq2q\0" "movnti\0" "movntq\0" "movntsd\0" "movntss\0" "movq2dq\0" "movsx\0" "movsxd\0" "movzx\0" "mulx\0"
- "mwaitx\0" "neg\0" "not\0" "out\0" "outs\0" "pavgusb\0" "pconfig\0" "pdep\0" "pext\0" "pf2id\0" "pf2iw\0" "pfacc\0"
- "pfadd\0" "pfcmpeq\0" "pfcmpge\0" "pfcmpgt\0" "pfmax\0" "pfmin\0" "pfmul\0" "pfnacc\0" "pfpnacc\0" "pfrcp\0"
- "pfrcpit1\0" "pfrcpit2\0" "pfrcpv\0" "pfrsqit1\0" "pfrsqrt\0" "pfrsqrtv\0" "pfsub\0" "pfsubr\0" "pi2fd\0" "pi2fw\0"
- "pmulhrw\0" "pop\0" "popa\0" "popad\0" "popcnt\0" "popf\0" "popfd\0" "popfq\0" "prefetch\0" "prefetchnta\0"
- "prefetcht0\0" "prefetcht1\0" "prefetcht2\0" "prefetchw\0" "prefetchwt1\0" "pshufw\0" "psmash\0" "pswapd\0"
- "ptwrite\0" "push\0" "pusha\0" "pushad\0" "pushf\0" "pushfd\0" "pushfq\0" "pvalidate\0" "rcl\0" "rcr\0" "rdfsbase\0"
- "rdgsbase\0" "rdmsr\0" "rdpid\0" "rdpkru\0" "rdpmc\0" "rdpru\0" "rdrand\0" "rdseed\0" "rdsspd\0" "rdsspq\0" "rdtsc\0"
- "rdtscp\0" "retf\0" "rmpadjust\0" "rmpupdate\0" "rol\0" "ror\0" "rorx\0" "rsm\0" "rstorssp\0" "sahf\0" "sal\0"
- "sar\0" "sarx\0" "saveprevssp\0" "sbb\0" "scas\0" "senduipi\0" "serialize\0" "seta\0" "setae\0" "setb\0" "setbe\0"
- "setc\0" "sete\0" "setg\0" "setge\0" "setl\0" "setle\0" "setna\0" "setnae\0" "setnb\0" "setnbe\0" "setnc\0" "setne\0"
- "setng\0" "setnge\0" "setnl\0" "setnle\0" "setno\0" "setnp\0" "setns\0" "setnz\0" "seto\0" "setp\0" "setpe\0"
- "setpo\0" "sets\0" "setssbsy\0" "setz\0" "sfence\0" "sgdt\0" "sha1msg1\0" "sha1msg2\0" "sha1nexte\0" "sha1rnds4\0"
- "sha256msg1\0" "sha256msg2\0" "sha256rnds2\0" "shl\0" "shlx\0" "shr\0" "shrd\0" "shrx\0" "sidt\0" "skinit\0" "sldt\0"
- "slwpcb\0" "smsw\0" "stac\0" "stc\0" "stgi\0" "sti\0" "stos\0" "str\0" "sttilecfg\0" "swapgs\0" "syscall\0"
- "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" "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 },
+const InstNameIndex InstDB::instNameIndex = {{
+ { Inst::kIdAaa , Inst::kIdAxor + 1 },
{ Inst::kIdBextr , Inst::kIdBzhi + 1 },
{ Inst::kIdCall , Inst::kIdCwde + 1 },
{ Inst::kIdDaa , Inst::kIdDpps + 1 },
@@ -3028,6 +2948,1761 @@ const InstDB::InstNameIndex InstDB::instNameIndex[26] = {
{ Inst::kIdXabort , Inst::kIdXtest + 1 },
{ Inst::kIdNone , Inst::kIdNone + 1 },
{ Inst::kIdNone , Inst::kIdNone + 1 }
+}, uint16_t(17)};
+
+const char InstDB::_instNameStringTable[] =
+ "vgf2p8affineinvqbvaeskeygenassistvbroadcastf32x464x264x4i32x2i32x4i32x8i64x2i64x"
+ "4vpbroadcastmb2w2dvbcstnebf162p128i128vcvtne2ps2vcvtneebf16vcvtneobf16vfmaddsub1"
+ "32ph213pd213ph213ps231pd231ph231psvfmsubadd132vpmultishiftvscatterpf0dqpdqps1dpd"
+ "1dps1qpd1qpsvcvtneps2vextracvextractfvgatherpf0vp2intersecttcmmimfp16tcmmrlfp16s"
+ "h2pssdph2psvfnmadd132213sd213sh213ss231sd231sh231ssvfnmsub132vinservinsertfvpshu"
+ "fbitqvsha512rndprefetchitntawt1saveprevsssha256rndtileloaddtilereleavaesdeclvaes"
+ "enclvcompressvcvttpd2uqqvcvttph2uvcvttps2uvcvttsd2uvcvttsh2uvcvttss2uvfixupimmvf"
+ "madd132vfmsub132vmaskmovdqvpcompressvpconflictvphminposuvpmadd52hluqvpscatterqdv"
+ "punpckhqlqdqvrndscalemsg1msg2clflushopcmpnbexcmpnlexcmpxchg16t0t2tilestorev4fnma"
+ "ddssvcvtpd2uvcvtph2psudqvcvtps2phvcvtsd2uvcvtsh2uvcvtss2uvcvtudq2vcvtuqq2vcvtusi"
+ "2vfcmaddcvfpclassvgetmanmulbvp4dpwssvpclmuvpcmpestrvpcmpistrvperm2fvpermil2vpgat"
+ "hervpmacssdqvpmadcsswubswvpmaskmovpternlogbwwdlbwldqlwdvrsqrt1428pd28ps28sd28ssv"
+ "shufvshuffvzeroupxsaveoptcmpbexcmplexcmpnbxcmpnlxcmpnoxcmpnpxcmpnsxcmpnzx8bfxrst"
+ "orldtilecfmovdir64pvalidarmpadjurmpupdaserialisha1nexsha1rndssttilecftdpbf16tdpf"
+ "p16v4fmadvaddsubvblendmvpdvcvtdq2uwvcvtqq2vcvtsi2vcvtuwvdbpsadvdpbf16vexpanvfcmu"
+ "lccphcshvgetexpvmovdqau16u32u64vmovmskvmovntvmovshdvmovsldvpackssdwbvpackuswbvpb"
+ "lendmdvpdpbssudsvpdpbusvpdpwssvpdpwus2pdvpermtvpexpanvphaddubwqdqhvpmovmskvpmovs"
+ "xbvpmovusqwvpmovzxbvpmulhrvptestnmqvreducevscalefvsm3rndvsm4rndsvunpckhlpdlpsxre"
+ "sldtrs64xsusldtrcldemoclrssbscmpbxcmplxcmpoxcmppxcmpsxcmpzxcvtpifcmovfxsavekorte"
+ "stkshiftrbkunpckmonitorpfrcpipfrsqirtvrdfsbrdgsbsspseamcalsenduisetssbssysesysex"
+ "vcvtwvfmulvldmxcsvmlaundupu8vmovhvmovlhvmpsadvmresumvpadduvpaligngtbgtdgtqgtw2b2"
+ "qbdbqvphsubvplzcnb2md2mq2mw2mvpopcnvpshldvqvpshrdvwhwvpsubuvrangevrcp14vroundsdv"
+ "sm4keyvstmxcsvucomiallwbnoinwrfsbwrgsbc64blcfiblsficmovnendbrenqcmnufdecsfincsfn"
+ "stefrndfsincfucomfyl2xincsspqinvlinvlpinvpcinvvpmcommmovq2pavgupfcmpepfpnaptwris"
+ "eamoseamrsyscsysretdpbutlbsyvaesivaligvandnvcomivfrczvhadvhsubvmclevmgexvmmcvmov"
+ "avmovuvmptvmwrivpandvpextrwvpinsvpmaxvpminvprolvprorvpsadvpsigvpslvpsllvpsravpsr"
+ "lvsqrvtes";
+
+
+const uint32_t InstDB::_instNameIndexTable[] = {
+ 0x80000000, // Small ''.
+ 0x80000421, // Small 'aaa'.
+ 0x80001021, // Small 'aad'.
+ 0x80021021, // Small 'aadd'.
+ 0x80003421, // Small 'aam'.
+ 0x80023821, // Small 'aand'.
+ 0x80004C21, // Small 'aas'.
+ 0x80000C81, // Small 'adc'.
+ 0x800C0C81, // Small 'adcx'.
+ 0x80001081, // Small 'add'.
+ 0x80481081, // Small 'addpd'.
+ 0x81381081, // Small 'addps'.
+ 0x80499081, // Small 'addsd'.
+ 0x81399081, // Small 'addss'.
+ 0x20A76099, // Large 'addsub|pd'.
+ 0x207D6099, // Large 'addsub|ps'.
+ 0x800C3C81, // Small 'adox'.
+ 0x86524CA1, // Small 'aesdec'.
+ 0x302871D5, // Large 'aesdecl|ast'.
+ 0x86E2CCA1, // Small 'aesenc'.
+ 0x302871DD, // Large 'aesencl|ast'.
+ 0x86D4CCA1, // Small 'aesimc'.
+ 0x0000F012, // Large 'aeskeygenassist'.
+ 0x800011C1, // Small 'and'.
+ 0x800711C1, // Small 'andn'.
+ 0x890711C1, // Small 'andnpd'.
+ 0xA70711C1, // Small 'andnps'.
+ 0x804811C1, // Small 'andpd'.
+ 0x813811C1, // Small 'andps'.
+ 0x800049E1, // Small 'aor'.
+ 0x80064241, // Small 'arpl'.
+ 0x80093F01, // Small 'axor'.
+ 0x812A60A2, // Small 'bextr'.
+ 0x26F45709, // Large 'blcfi|ll'.
+ 0x80048D82, // Small 'blci'.
+ 0x80348D82, // Small 'blcic'.
+ 0x97368D82, // Small 'blcmsk'.
+ 0x80098D82, // Small 'blcs'.
+ 0x20A75471, // Large 'blend|pd'.
+ 0x207D5471, // Large 'blend|ps'.
+ 0x34775471, // Large 'blend|vpd'.
+ 0x318B5471, // Large 'blend|vps'.
+ 0x26F4570E, // Large 'blsfi|ll'.
+ 0x8004CD82, // Small 'blsi'.
+ 0x8034CD82, // Small 'blsic'.
+ 0x9736CD82, // Small 'blsmsk'.
+ 0x80094D82, // Small 'blsr'.
+ 0x80C191C2, // Small 'bndcl'.
+ 0x80E191C2, // Small 'bndcn'.
+ 0x815191C2, // Small 'bndcu'.
+ 0xB04611C2, // Small 'bndldx'.
+ 0x80B691C2, // Small 'bndmk'.
+ 0xACF691C2, // Small 'bndmov'.
+ 0xB14991C2, // Small 'bndstx'.
+ 0x804755E2, // Small 'bound'.
+ 0x80001A62, // Small 'bsf'.
+ 0x80004A62, // Small 'bsr'.
+ 0x8100DE62, // Small 'bswap'.
+ 0x80000282, // Small 'bt'.
+ 0x80000E82, // Small 'btc'.
+ 0x80004A82, // Small 'btr'.
+ 0x80004E82, // Small 'bts'.
+ 0x8004A342, // Small 'bzhi'.
+ 0x80063023, // Small 'call'.
+ 0x80005C43, // Small 'cbw'.
+ 0x80004483, // Small 'cdq'.
+ 0x8002C483, // Small 'cdqe'.
+ 0x80018583, // Small 'clac'.
+ 0x80000D83, // Small 'clc'.
+ 0x80001183, // Small 'cld'.
+ 0x20DF65B0, // Large 'cldemo|te'.
+ 0x0000729D, // Large 'clflush'.
+ 0x1020929D, // Large 'clflushop|t'.
+ 0x80049D83, // Small 'clgi'.
+ 0x80002583, // Small 'cli'.
+ 0x101775B6, // Large 'clrssbs|y'.
+ 0x8009D183, // Small 'clts'.
+ 0x8004D583, // Small 'clui'.
+ 0x80015D83, // Small 'clwb'.
+ 0x9F22E983, // Small 'clzero'.
+ 0x80000DA3, // Small 'cmc'.
+ 0x801B3DA3, // Small 'cmova'.
+ 0x8A1B3DA3, // Small 'cmovae'.
+ 0x802B3DA3, // Small 'cmovb'.
+ 0x8A2B3DA3, // Small 'cmovbe'.
+ 0x803B3DA3, // Small 'cmovc'.
+ 0x805B3DA3, // Small 'cmove'.
+ 0x807B3DA3, // Small 'cmovg'.
+ 0x8A7B3DA3, // Small 'cmovge'.
+ 0x80CB3DA3, // Small 'cmovl'.
+ 0x8ACB3DA3, // Small 'cmovle'.
+ 0x82EB3DA3, // Small 'cmovna'.
+ 0x20125713, // Large 'cmovn|ae'.
+ 0x84EB3DA3, // Small 'cmovnb'.
+ 0x22AA5713, // Large 'cmovn|be'.
+ 0x86EB3DA3, // Small 'cmovnc'.
+ 0x8AEB3DA3, // Small 'cmovne'.
+ 0x8EEB3DA3, // Small 'cmovng'.
+ 0x20185713, // Large 'cmovn|ge'.
+ 0x98EB3DA3, // Small 'cmovnl'.
+ 0x21C45713, // Large 'cmovn|le'.
+ 0x9EEB3DA3, // Small 'cmovno'.
+ 0xA0EB3DA3, // Small 'cmovnp'.
+ 0xA6EB3DA3, // Small 'cmovns'.
+ 0xB4EB3DA3, // Small 'cmovnz'.
+ 0x80FB3DA3, // Small 'cmovo'.
+ 0x810B3DA3, // Small 'cmovp'.
+ 0x8B0B3DA3, // Small 'cmovpe'.
+ 0x9F0B3DA3, // Small 'cmovpo'.
+ 0x813B3DA3, // Small 'cmovs'.
+ 0x81AB3DA3, // Small 'cmovz'.
+ 0x800041A3, // Small 'cmp'.
+ 0x309963D9, // Large 'cmpbex|add'.
+ 0x309955BD, // Large 'cmpbx|add'.
+ 0x309963DF, // Large 'cmplex|add'.
+ 0x309955C2, // Large 'cmplx|add'.
+ 0x309972A6, // Large 'cmpnbex|add'.
+ 0x309963E5, // Large 'cmpnbx|add'.
+ 0x309972AD, // Large 'cmpnlex|add'.
+ 0x309963EB, // Large 'cmpnlx|add'.
+ 0x309963F1, // Large 'cmpnox|add'.
+ 0x309963F7, // Large 'cmpnpx|add'.
+ 0x309963FD, // Large 'cmpnsx|add'.
+ 0x30996403, // Large 'cmpnzx|add'.
+ 0x309955C7, // Large 'cmpox|add'.
+ 0x804841A3, // Small 'cmppd'.
+ 0x813841A3, // Small 'cmpps'.
+ 0x309955CC, // Large 'cmppx|add'.
+ 0x8009C1A3, // Small 'cmps'.
+ 0x8049C1A3, // Small 'cmpsd'.
+ 0x8139C1A3, // Small 'cmpss'.
+ 0x309955D1, // Large 'cmpsx|add'.
+ 0x000072B4, // Large 'cmpxchg'.
+ 0x101092B4, // Large 'cmpxchg16|b'.
+ 0x240972B4, // Large 'cmpxchg|8b'.
+ 0x309955D6, // Large 'cmpzx|add'.
+ 0x8934B5E3, // Small 'comisd'.
+ 0xA734B5E3, // Small 'comiss'.
+ 0x8044D603, // Small 'cpuid'.
+ 0x80003E23, // Small 'cqo'.
+ 0x81DF0E43, // Small 'crc32'.
+ 0x20A7647B, // Large 'cvtdq2|pd'.
+ 0x207D647B, // Large 'cvtdq2|ps'.
+ 0x20E562D5, // Large 'cvtpd2|dq'.
+ 0x222A62D5, // Large 'cvtpd2|pi'.
+ 0x207D62D5, // Large 'cvtpd2|ps'.
+ 0x352555DB, // Large 'cvtpi|2pd'.
+ 0x307C55DB, // Large 'cvtpi|2ps'.
+ 0x20E562E9, // Large 'cvtps2|dq'.
+ 0x102672E9, // Large 'cvtps2p|d'.
+ 0x100972E9, // Large 'cvtps2p|i'.
+ 0x201D62F2, // Large 'cvtsd2|si'.
+ 0x201C62F2, // Large 'cvtsd2|ss'.
+ 0x2144648B, // Large 'cvtsi2|sd'.
+ 0x201C648B, // Large 'cvtsi2|ss'.
+ 0x21446302, // Large 'cvtss2|sd'.
+ 0x201D6302, // Large 'cvtss2|si'.
+ 0x20E571EE, // Large 'cvttpd2|dq'.
+ 0x222A71EE, // Large 'cvttpd2|pi'.
+ 0x20E57202, // Large 'cvttps2|dq'.
+ 0x222A7202, // Large 'cvttps2|pi'.
+ 0x201D720B, // Large 'cvttsd2|si'.
+ 0x201D721D, // Large 'cvttss2|si'.
+ 0x800012E3, // Small 'cwd'.
+ 0x800292E3, // Small 'cwde'.
+ 0x80000424, // Small 'daa'.
+ 0x80004C24, // Small 'das'.
+ 0x80000CA4, // Small 'dec'.
+ 0x80005924, // Small 'div'.
+ 0x80485924, // Small 'divpd'.
+ 0x81385924, // Small 'divps'.
+ 0x8049D924, // Small 'divsd'.
+ 0x8139D924, // Small 'divss'.
+ 0x80024204, // Small 'dppd'.
+ 0x8009C204, // Small 'dpps'.
+ 0x8009B5A5, // Small 'emms'.
+ 0x202C5718, // Large 'endbr|32'.
+ 0x20305718, // Large 'endbr|64'.
+ 0x88D1C5C5, // Small 'enqcmd'.
+ 0x209B571D, // Large 'enqcm|ds'.
+ 0x8122D1C5, // Small 'enter'.
+ 0x207D710D, // Large 'extract|ps'.
+ 0x81195305, // Small 'extrq'.
+ 0x81C6E3A6, // Small 'f2xm1'.
+ 0x80098826, // Small 'fabs'.
+ 0x80021026, // Small 'fadd'.
+ 0x81021026, // Small 'faddp'.
+ 0x80023046, // Small 'fbld'.
+ 0x810A4C46, // Small 'fbstp'.
+ 0x8009A066, // Small 'fchs'.
+ 0x8182B066, // Small 'fclex'.
+ 0x8567B466, // Small 'fcmovb'.
+ 0x22AA55E0, // Large 'fcmov|be'.
+ 0x8B67B466, // Small 'fcmove'.
+ 0x22A955E0, // Large 'fcmov|nb'.
+ 0x32A955E0, // Large 'fcmov|nbe'.
+ 0x200A55E0, // Large 'fcmov|ne'.
+ 0x272255E0, // Large 'fcmov|nu'.
+ 0xAB67B466, // Small 'fcmovu'.
+ 0x8006BC66, // Small 'fcom'.
+ 0x8096BC66, // Small 'fcomi'.
+ 0xA096BC66, // Small 'fcomip'.
+ 0x8106BC66, // Small 'fcomp'.
+ 0xA106BC66, // Small 'fcompp'.
+ 0x8009BC66, // Small 'fcos'.
+ 0x21F15724, // Large 'fdecs|tp'.
+ 0x800B2486, // Small 'fdiv'.
+ 0x810B2486, // Small 'fdivp'.
+ 0x812B2486, // Small 'fdivr'.
+ 0xA12B2486, // Small 'fdivrp'.
+ 0x8136B4A6, // Small 'femms'.
+ 0x8052C8C6, // Small 'ffree'.
+ 0x80420526, // Small 'fiadd'.
+ 0x80D78D26, // Small 'ficom'.
+ 0xA0D78D26, // Small 'ficomp'.
+ 0x81649126, // Small 'fidiv'.
+ 0xA5649126, // Small 'fidivr'.
+ 0x80023126, // Small 'fild'.
+ 0x80CAB526, // Small 'fimul'.
+ 0x21F15729, // Large 'fincs|tp'.
+ 0x8144B926, // Small 'finit'.
+ 0x800A4D26, // Small 'fist'.
+ 0x810A4D26, // Small 'fistp'.
+ 0xA14A4D26, // Small 'fisttp'.
+ 0x802ACD26, // Small 'fisub'.
+ 0xA42ACD26, // Small 'fisubr'.
+ 0x80001186, // Small 'fld'.
+ 0x800E1186, // Small 'fld1'.
+ 0x81719186, // Small 'fldcw'.
+ 0xACE29186, // Small 'fldenv'.
+ 0x8BD61186, // Small 'fldl2e'.
+ 0xA9D61186, // Small 'fldl2t'.
+ 0xBA761186, // Small 'fldlg2'.
+ 0xBAE61186, // Small 'fldln2'.
+ 0x80981186, // Small 'fldpi'.
+ 0x800D1186, // Small 'fldz'.
+ 0x800655A6, // Small 'fmul'.
+ 0x810655A6, // Small 'fmulp'.
+ 0xB0560DC6, // Small 'fnclex'.
+ 0xA89725C6, // Small 'fninit'.
+ 0x80083DC6, // Small 'fnop'.
+ 0x8B60CDC6, // Small 'fnsave'.
+ 0xAE3A4DC6, // Small 'fnstcw'.
+ 0x200D572E, // Large 'fnste|nv'.
+ 0xAF3A4DC6, // Small 'fnstsw'.
+ 0x9C1A0606, // Small 'fpatan'.
+ 0x80D2CA06, // Small 'fprem'.
+ 0xB8D2CA06, // Small 'fprem1'.
+ 0x80E0D206, // Small 'fptan'.
+ 0x31224733, // Large 'frnd|int'.
+ 0xA4FA4E46, // Small 'frstor'.
+ 0x805B0666, // Small 'fsave'.
+ 0x8AC08E66, // Small 'fscale'.
+ 0x80072666, // Small 'fsin'.
+ 0x22655737, // Large 'fsinc|os'.
+ 0x81494666, // Small 'fsqrt'.
+ 0x80005266, // Small 'fst'.
+ 0x8171D266, // Small 'fstcw'.
+ 0xACE2D266, // Small 'fstenv'.
+ 0x80085266, // Small 'fstp'.
+ 0x8179D266, // Small 'fstsw'.
+ 0x80015666, // Small 'fsub'.
+ 0x81015666, // Small 'fsubp'.
+ 0x81215666, // Small 'fsubr'.
+ 0xA1215666, // Small 'fsubrp'.
+ 0x800A4E86, // Small 'ftst'.
+ 0x80D78EA6, // Small 'fucom'.
+ 0x92D78EA6, // Small 'fucomi'.
+ 0x260C573C, // Large 'fucom|ip'.
+ 0xA0D78EA6, // Small 'fucomp'.
+ 0x25CE573C, // Large 'fucom|pp'.
+ 0x814486E6, // Small 'fwait'.
+ 0x80068706, // Small 'fxam'.
+ 0x80040F06, // Small 'fxch'.
+ 0x0000740B, // Large 'fxrstor'.
+ 0x2030740B, // Large 'fxrstor|64'.
+ 0x8B60CF06, // Small 'fxsave'.
+ 0x203065E5, // Large 'fxsave|64'.
+ 0x510F240B, // Large 'fx|tract'.
+ 0x818EB326, // Small 'fyl2x'.
+ 0x206E5741, // Large 'fyl2x|p1'.
+ 0x8659D0A7, // Small 'getsec'.
+ 0x1010F001, // Large 'gf2p8affineinvq|b'.
+ 0x200FB001, // Large 'gf2p8affine|qb'.
+ 0x43385001, // Large 'gf2p8|mulb'.
+ 0x89021028, // Small 'haddpd'.
+ 0xA7021028, // Small 'haddps'.
+ 0x80005188, // Small 'hlt'.
+ 0xA8599648, // Small 'hreset'.
+ 0x89015668, // Small 'hsubpd'.
+ 0xA7015668, // Small 'hsubps'.
+ 0x800B2489, // Small 'idiv'.
+ 0x800655A9, // Small 'imul'.
+ 0x800001C9, // Small 'in'.
+ 0x80000DC9, // Small 'inc'.
+ 0x20A75746, // Large 'incss|pd'.
+ 0x274B5746, // Large 'incss|pq'.
+ 0x80004DC9, // Small 'ins'.
+ 0x207D6184, // Large 'insert|ps'.
+ 0x100F6184, // Large 'insert|q'.
+ 0x800051C9, // Small 'int'.
+ 0x800F51C9, // Small 'int3'.
+ 0x8007D1C9, // Small 'into'.
+ 0x800259C9, // Small 'invd'.
+ 0xA902D9C9, // Small 'invept'.
+ 0x8F0659C9, // Small 'invlpg'.
+ 0x336C474D, // Large 'invl|pga'.
+ 0x23995751, // Large 'invlp|gb'.
+ 0x24265756, // Large 'invpc|id'.
+ 0x2426575B, // Large 'invvp|id'.
+ 0x800A1649, // Small 'iret'.
+ 0x804A1649, // Small 'iretd'.
+ 0x811A1649, // Small 'iretq'.
+ 0x8000002A, // Small 'ja'.
+ 0x8000142A, // Small 'jae'.
+ 0x8000004A, // Small 'jb'.
+ 0x8000144A, // Small 'jbe'.
+ 0x8000006A, // Small 'jc'.
+ 0x800000AA, // Small 'je'.
+ 0x81AC0CAA, // Small 'jecxz'.
+ 0x800000EA, // Small 'jg'.
+ 0x800014EA, // Small 'jge'.
+ 0x8000018A, // Small 'jl'.
+ 0x8000158A, // Small 'jle'.
+ 0x800041AA, // Small 'jmp'.
+ 0x800005CA, // Small 'jna'.
+ 0x800285CA, // Small 'jnae'.
+ 0x800009CA, // Small 'jnb'.
+ 0x800289CA, // Small 'jnbe'.
+ 0x80000DCA, // Small 'jnc'.
+ 0x800015CA, // Small 'jne'.
+ 0x80001DCA, // Small 'jng'.
+ 0x80029DCA, // Small 'jnge'.
+ 0x800031CA, // Small 'jnl'.
+ 0x8002B1CA, // Small 'jnle'.
+ 0x80003DCA, // Small 'jno'.
+ 0x800041CA, // Small 'jnp'.
+ 0x80004DCA, // Small 'jns'.
+ 0x800069CA, // Small 'jnz'.
+ 0x800001EA, // Small 'jo'.
+ 0x8000020A, // Small 'jp'.
+ 0x8000160A, // Small 'jpe'.
+ 0x80003E0A, // Small 'jpo'.
+ 0x8000026A, // Small 'js'.
+ 0x8000034A, // Small 'jz'.
+ 0x8022102B, // Small 'kaddb'.
+ 0x8042102B, // Small 'kaddd'.
+ 0x8112102B, // Small 'kaddq'.
+ 0x8172102B, // Small 'kaddw'.
+ 0x8022382B, // Small 'kandb'.
+ 0x8042382B, // Small 'kandd'.
+ 0x84E2382B, // Small 'kandnb'.
+ 0x88E2382B, // Small 'kandnd'.
+ 0xA2E2382B, // Small 'kandnq'.
+ 0xAEE2382B, // Small 'kandnw'.
+ 0x8112382B, // Small 'kandq'.
+ 0x8172382B, // Small 'kandw'.
+ 0x802B3DAB, // Small 'kmovb'.
+ 0x804B3DAB, // Small 'kmovd'.
+ 0x811B3DAB, // Small 'kmovq'.
+ 0x817B3DAB, // Small 'kmovw'.
+ 0x802A3DCB, // Small 'knotb'.
+ 0x804A3DCB, // Small 'knotd'.
+ 0x811A3DCB, // Small 'knotq'.
+ 0x817A3DCB, // Small 'knotw'.
+ 0x800149EB, // Small 'korb'.
+ 0x800249EB, // Small 'kord'.
+ 0x8008C9EB, // Small 'korq'.
+ 0x101075EB, // Large 'kortest|b'.
+ 0x102675EB, // Large 'kortest|d'.
+ 0x100F75EB, // Large 'kortest|q'.
+ 0x105F75EB, // Large 'kortest|w'.
+ 0x800BC9EB, // Small 'korw'.
+ 0x233A65F2, // Large 'kshift|lb'.
+ 0x23A165F2, // Large 'kshift|ld'.
+ 0x228865F2, // Large 'kshift|lq'.
+ 0x23A465F2, // Large 'kshift|lw'.
+ 0x25F865F2, // Large 'kshift|rb'.
+ 0x102675F2, // Large 'kshiftr|d'.
+ 0x100F75F2, // Large 'kshiftr|q'.
+ 0x105F75F2, // Large 'kshiftr|w'.
+ 0x8549968B, // Small 'ktestb'.
+ 0x8949968B, // Small 'ktestd'.
+ 0xA349968B, // Small 'ktestq'.
+ 0xAF49968B, // Small 'ktestw'.
+ 0x239A65FA, // Large 'kunpck|bw'.
+ 0x20E565FA, // Large 'kunpck|dq'.
+ 0x239C65FA, // Large 'kunpck|wd'.
+ 0x8527BB0B, // Small 'kxnorb'.
+ 0x8927BB0B, // Small 'kxnord'.
+ 0xA327BB0B, // Small 'kxnorq'.
+ 0xAF27BB0B, // Small 'kxnorw'.
+ 0x80293F0B, // Small 'kxorb'.
+ 0x80493F0B, // Small 'kxord'.
+ 0x81193F0B, // Small 'kxorq'.
+ 0x81793F0B, // Small 'kxorw'.
+ 0x8003202C, // Small 'lahf'.
+ 0x8000482C, // Small 'lar'.
+ 0x80C6046C, // Small 'lcall'.
+ 0x8158908C, // Small 'lddqu'.
+ 0x1023664B, // Large 'ldmxcs|r'.
+ 0x80004C8C, // Small 'lds'.
+ 0x10018412, // Large 'ldtilecf|g'.
+ 0x800004AC, // Small 'lea'.
+ 0x805B04AC, // Small 'leave'.
+ 0x80004CAC, // Small 'les'.
+ 0x8A3714CC, // Small 'lfence'.
+ 0x80004CCC, // Small 'lfs'.
+ 0x800A10EC, // Small 'lgdt'.
+ 0x80004CEC, // Small 'lgs'.
+ 0x800A112C, // Small 'lidt'.
+ 0x8008354C, // Small 'ljmp'.
+ 0x800A118C, // Small 'lldt'.
+ 0x84385D8C, // Small 'llwpcb'.
+ 0x800BCDAC, // Small 'lmsw'.
+ 0x800991EC, // Small 'lods'.
+ 0x80083DEC, // Small 'loop'.
+ 0x80583DEC, // Small 'loope'.
+ 0x8AE83DEC, // Small 'loopne'.
+ 0x8000326C, // Small 'lsl'.
+ 0x80004E6C, // Small 'lss'.
+ 0x80004A8C, // Small 'ltr'.
+ 0xA6E4C2EC, // Small 'lwpins'.
+ 0x981B42EC, // Small 'lwpval'.
+ 0x81470F4C, // Small 'lzcnt'.
+ 0x109D9241, // Large 'maskmovdq|u'.
+ 0x100F7241, // Large 'maskmov|q'.
+ 0x8048602D, // Small 'maxpd'.
+ 0x8138602D, // Small 'maxps'.
+ 0x8049E02D, // Small 'maxsd'.
+ 0x8139E02D, // Small 'maxss'.
+ 0x21925760, // Large 'mcomm|it'.
+ 0x8A3714CD, // Small 'mfence'.
+ 0x8048392D, // Small 'minpd'.
+ 0x8138392D, // Small 'minps'.
+ 0x8049B92D, // Small 'minsd'.
+ 0x8139B92D, // Small 'minss'.
+ 0x00007600, // Large 'monitor'.
+ 0x102E7600, // Large 'monitor|x'.
+ 0x800059ED, // Small 'mov'.
+ 0xA620D9ED, // Small 'movabs'.
+ 0x8900D9ED, // Small 'movapd'.
+ 0xA700D9ED, // Small 'movaps'.
+ 0x805159ED, // Small 'movbe'.
+ 0x800259ED, // Small 'movd'.
+ 0x36574245, // Large 'movd|dup'.
+ 0x1010841A, // Large 'movdir64|b'.
+ 0x1009641A, // Large 'movdir|i'.
+ 0x268F5245, // Large 'movdq|2q'.
+ 0x831259ED, // Small 'movdqa'.
+ 0xAB1259ED, // Small 'movdqu'.
+ 0x359A465D, // Large 'movh|lps'.
+ 0x890459ED, // Small 'movhpd'.
+ 0xA70459ED, // Small 'movhps'.
+ 0x207D5662, // Large 'movlh|ps'.
+ 0x890659ED, // Small 'movlpd'.
+ 0xA70659ED, // Small 'movlps'.
+ 0x20A764D0, // Large 'movmsk|pd'.
+ 0x207D64D0, // Large 'movmsk|ps'.
+ 0x20E554D7, // Large 'movnt|dq'.
+ 0x34C354D7, // Large 'movnt|dqa'.
+ 0x934759ED, // Small 'movnti'.
+ 0x20A754D7, // Large 'movnt|pd'.
+ 0x207D54D7, // Large 'movnt|ps'.
+ 0xA34759ED, // Small 'movntq'.
+ 0x214454D7, // Large 'movnt|sd'.
+ 0x201C54D7, // Large 'movnt|ss'.
+ 0x8008D9ED, // Small 'movq'.
+ 0x20E55765, // Large 'movq2|dq'.
+ 0x8009D9ED, // Small 'movs'.
+ 0x8049D9ED, // Small 'movsd'.
+ 0x222964DD, // Large 'movshd|up'.
+ 0x222964E4, // Large 'movsld|up'.
+ 0x8139D9ED, // Small 'movss'.
+ 0x8189D9ED, // Small 'movsx'.
+ 0x8989D9ED, // Small 'movsxd'.
+ 0x890AD9ED, // Small 'movupd'.
+ 0xA70AD9ED, // Small 'movups'.
+ 0x818D59ED, // Small 'movzx'.
+ 0x239A5668, // Large 'mpsad|bw'.
+ 0x800032AD, // Small 'mul'.
+ 0x804832AD, // Small 'mulpd'.
+ 0x813832AD, // Small 'mulps'.
+ 0x8049B2AD, // Small 'mulsd'.
+ 0x8139B2AD, // Small 'mulss'.
+ 0x800C32AD, // Small 'mulx'.
+ 0x814486ED, // Small 'mwait'.
+ 0xB14486ED, // Small 'mwaitx'.
+ 0x80001CAE, // Small 'neg'.
+ 0x800041EE, // Small 'nop'.
+ 0x800051EE, // Small 'not'.
+ 0x8000024F, // Small 'or'.
+ 0x8002424F, // Small 'orpd'.
+ 0x8009C24F, // Small 'orps'.
+ 0x800052AF, // Small 'out'.
+ 0x8009D2AF, // Small 'outs'.
+ 0x80298830, // Small 'pabsb'.
+ 0x80498830, // Small 'pabsd'.
+ 0x81798830, // Small 'pabsw'.
+ 0x000084EB, // Large 'packssdw'.
+ 0x24F264EB, // Large 'packss|wb'.
+ 0x24F164F5, // Large 'packus|dw'.
+ 0x000084F5, // Large 'packuswb'.
+ 0x80221030, // Small 'paddb'.
+ 0x80421030, // Small 'paddd'.
+ 0x81121030, // Small 'paddq'.
+ 0x85321030, // Small 'paddsb'.
+ 0xAF321030, // Small 'paddsw'.
+ 0x25BA5675, // Large 'paddu|sb'.
+ 0x23835675, // Large 'paddu|sw'.
+ 0x81721030, // Small 'paddw'.
+ 0x1023667B, // Large 'palign|r'.
+ 0x80023830, // Small 'pand'.
+ 0x80E23830, // Small 'pandn'.
+ 0x8059D430, // Small 'pause'.
+ 0x8023D830, // Small 'pavgb'.
+ 0x25BA576A, // Large 'pavgu|sb'.
+ 0x8173D830, // Small 'pavgw'.
+ 0x202164FE, // Large 'pblend|vb'.
+ 0x105F64FE, // Large 'pblend|w'.
+ 0x42885345, // Large 'pclmu|lqdq'.
+ 0x200F534B, // Large 'pcmpe|qb'.
+ 0x227D534B, // Large 'pcmpe|qd'.
+ 0x21F6534B, // Large 'pcmpe|qq'.
+ 0x2559534B, // Large 'pcmpe|qw'.
+ 0x1009834B, // Large 'pcmpestr|i'.
+ 0x105C834B, // Large 'pcmpestr|m'.
+ 0x368142A5, // Large 'pcmp|gtb'.
+ 0x368442A5, // Large 'pcmp|gtd'.
+ 0x368742A5, // Large 'pcmp|gtq'.
+ 0x368A42A5, // Large 'pcmp|gtw'.
+ 0x10098354, // Large 'pcmpistr|i'.
+ 0x105C8354, // Large 'pcmpistr|m'.
+ 0x267E5255, // Large 'pconf|ig'.
+ 0x80081490, // Small 'pdep'.
+ 0x800A60B0, // Small 'pext'.
+ 0x852A60B0, // Small 'pextrb'.
+ 0x892A60B0, // Small 'pextrd'.
+ 0xA32A60B0, // Small 'pextrq'.
+ 0xAF2A60B0, // Small 'pextrw'.
+ 0x8044F4D0, // Small 'pf2id'.
+ 0x8174F4D0, // Small 'pf2iw'.
+ 0x803184D0, // Small 'pfacc'.
+ 0x804204D0, // Small 'pfadd'.
+ 0x100F676F, // Large 'pfcmpe|q'.
+ 0x2018576F, // Large 'pfcmp|ge'.
+ 0x2681576F, // Large 'pfcmp|gt'.
+ 0x8180B4D0, // Small 'pfmax'.
+ 0x80E4B4D0, // Small 'pfmin'.
+ 0x80CAB4D0, // Small 'pfmul'.
+ 0x8630B8D0, // Small 'pfnacc'.
+ 0x24B15775, // Large 'pfpna|cc'.
+ 0x8101C8D0, // Small 'pfrcp'.
+ 0x21AD6607, // Large 'pfrcpi|t1'.
+ 0x22BF6607, // Large 'pfrcpi|t2'.
+ 0xAD01C8D0, // Small 'pfrcpv'.
+ 0x21AD660D, // Large 'pfrsqi|t1'.
+ 0x2188560D, // Large 'pfrsq|rt'.
+ 0x3613560D, // Large 'pfrsq|rtv'.
+ 0x802ACCD0, // Small 'pfsub'.
+ 0xA42ACCD0, // Small 'pfsubr'.
+ 0x88420510, // Small 'phaddd'.
+ 0x23835536, // Large 'phadd|sw'.
+ 0xAE420510, // Small 'phaddw'.
+ 0x105F925F, // Large 'phminposu|w'.
+ 0x882ACD10, // Small 'phsubd'.
+ 0x23835696, // Large 'phsub|sw'.
+ 0xAE2ACD10, // Small 'phsubw'.
+ 0x80437530, // Small 'pi2fd'.
+ 0x81737530, // Small 'pi2fw'.
+ 0x8529B930, // Small 'pinsrb'.
+ 0x8929B930, // Small 'pinsrd'.
+ 0xA329B930, // Small 'pinsrq'.
+ 0xAF29B930, // Small 'pinsrw'.
+ 0x43855269, // Large 'pmadd|ubsw'.
+ 0x239C5269, // Large 'pmadd|wd'.
+ 0x853C05B0, // Small 'pmaxsb'.
+ 0x893C05B0, // Small 'pmaxsd'.
+ 0xAF3C05B0, // Small 'pmaxsw'.
+ 0x855C05B0, // Small 'pmaxub'.
+ 0x895C05B0, // Small 'pmaxud'.
+ 0xAF5C05B0, // Small 'pmaxuw'.
+ 0x853725B0, // Small 'pminsb'.
+ 0x893725B0, // Small 'pminsd'.
+ 0xAF3725B0, // Small 'pminsw'.
+ 0x855725B0, // Small 'pminub'.
+ 0x895725B0, // Small 'pminud'.
+ 0xAF5725B0, // Small 'pminuw'.
+ 0x10107543, // Large 'pmovmsk|b'.
+ 0x1026754B, // Large 'pmovsxb|d'.
+ 0x100F754B, // Large 'pmovsxb|q'.
+ 0x105F754B, // Large 'pmovsxb|w'.
+ 0x20E5654B, // Large 'pmovsx|dq'.
+ 0x239C654B, // Large 'pmovsx|wd'.
+ 0x253D654B, // Large 'pmovsx|wq'.
+ 0x1026755C, // Large 'pmovzxb|d'.
+ 0x100F755C, // Large 'pmovzxb|q'.
+ 0x105F755C, // Large 'pmovzxb|w'.
+ 0x20E5655C, // Large 'pmovzx|dq'.
+ 0x239C655C, // Large 'pmovzx|wd'.
+ 0x253D655C, // Large 'pmovzx|wq'.
+ 0xA24655B0, // Small 'pmuldq'.
+ 0x23836564, // Large 'pmulhr|sw'.
+ 0x105F6564, // Large 'pmulhr|w'.
+ 0x24815564, // Large 'pmulh|uw'.
+ 0xAE8655B0, // Small 'pmulhw'.
+ 0x88C655B0, // Small 'pmulld'.
+ 0xAEC655B0, // Small 'pmullw'.
+ 0x32E540CF, // Large 'pmul|udq'.
+ 0x800041F0, // Small 'pop'.
+ 0x8000C1F0, // Small 'popa'.
+ 0x8040C1F0, // Small 'popad'.
+ 0xA8E1C1F0, // Small 'popcnt'.
+ 0x800341F0, // Small 'popf'.
+ 0x804341F0, // Small 'popfd'.
+ 0x811341F0, // Small 'popfq'.
+ 0x800049F0, // Small 'por'.
+ 0x0000819F, // Large 'prefetch'.
+ 0x10E4A19F, // Large 'prefetchit|0'.
+ 0x106BA19F, // Large 'prefetchit|1'.
+ 0x31A9819F, // Large 'prefetch|nta'.
+ 0x22BD819F, // Large 'prefetch|t0'.
+ 0x21AD819F, // Large 'prefetch|t1'.
+ 0x22BF819F, // Large 'prefetch|t2'.
+ 0x105F819F, // Large 'prefetch|w'.
+ 0x31AC819F, // Large 'prefetch|wt1'.
+ 0xAE220670, // Small 'psadbw'.
+ 0x846AA270, // Small 'pshufb'.
+ 0x886AA270, // Small 'pshufd'.
+ 0x26C3518C, // Large 'pshuf|hw'.
+ 0x23A4518C, // Large 'pshuf|lw'.
+ 0xAE6AA270, // Small 'pshufw'.
+ 0x84E3A670, // Small 'psignb'.
+ 0x88E3A670, // Small 'psignd'.
+ 0xAEE3A670, // Small 'psignw'.
+ 0x80463270, // Small 'pslld'.
+ 0xA2463270, // Small 'pslldq'.
+ 0x81163270, // Small 'psllq'.
+ 0x81763270, // Small 'psllw'.
+ 0x9130B670, // Small 'psmash'.
+ 0x8040CA70, // Small 'psrad'.
+ 0x8170CA70, // Small 'psraw'.
+ 0x80464A70, // Small 'psrld'.
+ 0xA2464A70, // Small 'psrldq'.
+ 0x81164A70, // Small 'psrlq'.
+ 0x81764A70, // Small 'psrlw'.
+ 0x80215670, // Small 'psubb'.
+ 0x80415670, // Small 'psubd'.
+ 0x81115670, // Small 'psubq'.
+ 0x85315670, // Small 'psubsb'.
+ 0xAF315670, // Small 'psubsw'.
+ 0x25BA56C6, // Large 'psubu|sb'.
+ 0x238356C6, // Large 'psubu|sw'.
+ 0x81715670, // Small 'psubw'.
+ 0x8900DE70, // Small 'pswapd'.
+ 0x81499690, // Small 'ptest'.
+ 0x20DF577A, // Large 'ptwri|te'.
+ 0x239A7280, // Large 'punpckh|bw'.
+ 0x20E57280, // Large 'punpckh|dq'.
+ 0x20E58280, // Large 'punpckhq|dq'.
+ 0x239C7280, // Large 'punpckh|wd'.
+ 0x339E6280, // Large 'punpck|lbw'.
+ 0x33A16280, // Large 'punpck|ldq'.
+ 0x42886280, // Large 'punpck|lqdq'.
+ 0x33A46280, // Large 'punpck|lwd'.
+ 0x80044EB0, // Small 'push'.
+ 0x80144EB0, // Small 'pusha'.
+ 0x88144EB0, // Small 'pushad'.
+ 0x80644EB0, // Small 'pushf'.
+ 0x88644EB0, // Small 'pushfd'.
+ 0xA2644EB0, // Small 'pushfq'.
+ 0x20DF7422, // Large 'pvalida|te'.
+ 0x80093F10, // Small 'pxor'.
+ 0x80003072, // Small 'rcl'.
+ 0x81384072, // Small 'rcpps'.
+ 0x8139C072, // Small 'rcpss'.
+ 0x80004872, // Small 'rcr'.
+ 0x34365616, // Large 'rdfsb|ase'.
+ 0x3436561B, // Large 'rdgsb|ase'.
+ 0x8129B492, // Small 'rdmsr'.
+ 0x8044C092, // Small 'rdpid'.
+ 0xAB25C092, // Small 'rdpkru'.
+ 0x8036C092, // Small 'rdpmc'.
+ 0x81594092, // Small 'rdpru'.
+ 0x88E0C892, // Small 'rdrand'.
+ 0x8852CC92, // Small 'rdseed'.
+ 0x8909CC92, // Small 'rdsspd'.
+ 0xA309CC92, // Small 'rdsspq'.
+ 0x8039D092, // Small 'rdtsc'.
+ 0xA039D092, // Small 'rdtscp'.
+ 0x800050B2, // Small 'ret'.
+ 0x800350B2, // Small 'retf'.
+ 0x201F7429, // Large 'rmpadju|st'.
+ 0x20DF7430, // Large 'rmpupda|te'.
+ 0x800031F2, // Small 'rol'.
+ 0x800049F2, // Small 'ror'.
+ 0x800C49F2, // Small 'rorx'.
+ 0x20A756D8, // Large 'round|pd'.
+ 0x207D56D8, // Large 'round|ps'.
+ 0x000076D8, // Large 'roundsd'.
+ 0x101466D8, // Large 'rounds|s'.
+ 0x80003672, // Small 'rsm'.
+ 0x207D53A8, // Large 'rsqrt|ps'.
+ 0x201C53A8, // Large 'rsqrt|ss'.
+ 0x3620540D, // Large 'rstor|ssp'.
+ 0x80032033, // Small 'sahf'.
+ 0x80003033, // Small 'sal'.
+ 0x80004833, // Small 'sar'.
+ 0x800C4833, // Small 'sarx'.
+ 0x1004A1AF, // Large 'saveprevss|p'.
+ 0x80000853, // Small 'sbb'.
+ 0x80098473, // Small 'scas'.
+ 0x10D27623, // Large 'seamcal|l'.
+ 0x207D577F, // Large 'seamo|ps'.
+ 0x21A35784, // Large 'seamr|et'.
+ 0x222A662A, // Large 'sendui|pi'.
+ 0x23CB7437, // Large 'seriali|ze'.
+ 0x8000D0B3, // Small 'seta'.
+ 0x8050D0B3, // Small 'setae'.
+ 0x800150B3, // Small 'setb'.
+ 0x805150B3, // Small 'setbe'.
+ 0x8001D0B3, // Small 'setc'.
+ 0x8002D0B3, // Small 'sete'.
+ 0x8003D0B3, // Small 'setg'.
+ 0x8053D0B3, // Small 'setge'.
+ 0x800650B3, // Small 'setl'.
+ 0x805650B3, // Small 'setle'.
+ 0x801750B3, // Small 'setna'.
+ 0x8A1750B3, // Small 'setnae'.
+ 0x802750B3, // Small 'setnb'.
+ 0x8A2750B3, // Small 'setnbe'.
+ 0x803750B3, // Small 'setnc'.
+ 0x805750B3, // Small 'setne'.
+ 0x807750B3, // Small 'setng'.
+ 0x8A7750B3, // Small 'setnge'.
+ 0x80C750B3, // Small 'setnl'.
+ 0x8AC750B3, // Small 'setnle'.
+ 0x80F750B3, // Small 'setno'.
+ 0x810750B3, // Small 'setnp'.
+ 0x813750B3, // Small 'setns'.
+ 0x81A750B3, // Small 'setnz'.
+ 0x8007D0B3, // Small 'seto'.
+ 0x800850B3, // Small 'setp'.
+ 0x805850B3, // Small 'setpe'.
+ 0x80F850B3, // Small 'setpo'.
+ 0x8009D0B3, // Small 'sets'.
+ 0x10177630, // Large 'setssbs|y'.
+ 0x800D50B3, // Small 'setz'.
+ 0x8A3714D3, // Small 'sfence'.
+ 0x800A10F3, // Small 'sgdt'.
+ 0x4295443E, // Large 'sha1|msg1'.
+ 0x4299443E, // Large 'sha1|msg2'.
+ 0x20DF743E, // Large 'sha1nex|te'.
+ 0x102F8445, // Large 'sha1rnds|4'.
+ 0x429561B9, // Large 'sha256|msg1'.
+ 0x429961B9, // Large 'sha256|msg2'.
+ 0x207E91B9, // Large 'sha256rnd|s2'.
+ 0x80003113, // Small 'shl'.
+ 0x80023113, // Small 'shld'.
+ 0x800C3113, // Small 'shlx'.
+ 0x80004913, // Small 'shr'.
+ 0x80024913, // Small 'shrd'.
+ 0x800C4913, // Small 'shrx'.
+ 0x89035513, // Small 'shufpd'.
+ 0xA7035513, // Small 'shufps'.
+ 0x800A1133, // Small 'sidt'.
+ 0xA8972573, // Small 'skinit'.
+ 0x800A1193, // Small 'sldt'.
+ 0x84385D93, // Small 'slwpcb'.
+ 0x800BCDB3, // Small 'smsw'.
+ 0x890A4A33, // Small 'sqrtpd'.
+ 0xA70A4A33, // Small 'sqrtps'.
+ 0x893A4A33, // Small 'sqrtsd'.
+ 0xA73A4A33, // Small 'sqrtss'.
+ 0x80018693, // Small 'stac'.
+ 0x80000E93, // Small 'stc'.
+ 0x80001293, // Small 'std'.
+ 0x80049E93, // Small 'stgi'.
+ 0x80002693, // Small 'sti'.
+ 0x102366E7, // Large 'stmxcs|r'.
+ 0x8009BE93, // Small 'stos'.
+ 0x80004A93, // Small 'str'.
+ 0x1001844D, // Large 'sttilecf|g'.
+ 0x8004D693, // Small 'stui'.
+ 0x80000AB3, // Small 'sub'.
+ 0x80480AB3, // Small 'subpd'.
+ 0x81380AB3, // Small 'subps'.
+ 0x80498AB3, // Small 'subsd'.
+ 0x81398AB3, // Small 'subss'.
+ 0xA67806F3, // Small 'swapgs'.
+ 0x36F34789, // Large 'sysc|all'.
+ 0x41234637, // Large 'syse|nter'.
+ 0x2192563B, // Large 'sysex|it'.
+ 0x3192563B, // Large 'sysex|itq'.
+ 0xA8594F33, // Small 'sysret'.
+ 0x2193578D, // Large 'sysre|tq'.
+ 0x86B9B794, // Small 't1mskc'.
+ 0x207DA12B, // Large 'tcmmimfp16|ps'.
+ 0x207DA135, // Large 'tcmmrlfp16|ps'.
+ 0x98C08C94, // Small 'tdcall'.
+ 0x207D7455, // Large 'tdpbf16|ps'.
+ 0x31434455, // Large 'tdpb|ssd'.
+ 0x32E44455, // Large 'tdpb|sud'.
+ 0x21445792, // Large 'tdpbu|sd'.
+ 0x22E55792, // Large 'tdpbu|ud'.
+ 0x207D745C, // Large 'tdpfp16|ps'.
+ 0x800A4CB4, // Small 'test'.
+ 0x935A4CB4, // Small 'testui'.
+ 0x000091C2, // Large 'tileloadd'.
+ 0x21AD91C2, // Large 'tileloadd|t1'.
+ 0x212791CB, // Large 'tilerelea|se'.
+ 0x102692C1, // Large 'tilestore|d'.
+ 0x43CB41C2, // Large 'tile|zero'.
+ 0x21E15797, // Large 'tlbsy|nc'.
+ 0x8B3A8614, // Small 'tpause'.
+ 0x81470F54, // Small 'tzcnt'.
+ 0x80B9B754, // Small 'tzmsk'.
+ 0x214456EE, // Large 'ucomi|sd'.
+ 0x201C56EE, // Large 'ucomi|ss'.
+ 0x80006C95, // Small 'ud0'.
+ 0x80007095, // Small 'ud1'.
+ 0x80007495, // Small 'ud2'.
+ 0x8142C935, // Small 'uiret'.
+ 0x7600109D, // Large 'u|monitor'.
+ 0xA890DDB5, // Small 'umwait'.
+ 0x20A76281, // Large 'unpckh|pd'.
+ 0x207D6281, // Large 'unpckh|ps'.
+ 0x35975281, // Large 'unpck|lpd'.
+ 0x359A5281, // Large 'unpck|lps'.
+ 0x30F16463, // Large 'v4fmad|dps'.
+ 0x32D16463, // Large 'v4fmad|dss'.
+ 0x30F172CA, // Large 'v4fnmad|dps'.
+ 0x32D172CA, // Large 'v4fnmad|dss'.
+ 0x89021036, // Small 'vaddpd'.
+ 0x91021036, // Small 'vaddph'.
+ 0xA7021036, // Small 'vaddps'.
+ 0x89321036, // Small 'vaddsd'.
+ 0x91321036, // Small 'vaddsh'.
+ 0xA7321036, // Small 'vaddss'.
+ 0x20A77469, // Large 'vaddsub|pd'.
+ 0x207D7469, // Large 'vaddsub|ps'.
+ 0x000071D4, // Large 'vaesdec'.
+ 0x302881D4, // Large 'vaesdecl|ast'.
+ 0x000071DC, // Large 'vaesenc'.
+ 0x302881DC, // Large 'vaesencl|ast'.
+ 0x2626579C, // Large 'vaesi|mc'.
+ 0x1020F011, // Large 'vaeskeygenassis|t'.
+ 0x219D57A1, // Large 'valig|nd'.
+ 0x271E57A1, // Large 'valig|nq'.
+ 0x20A757A6, // Large 'vandn|pd'.
+ 0x207D57A6, // Large 'vandn|ps'.
+ 0x89023836, // Small 'vandpd'.
+ 0xA7023836, // Small 'vandps'.
+ 0x1014D062, // Large 'vbcstnebf162p|s'.
+ 0x513F7062, // Large 'vbcstne|sh2ps'.
+ 0x20A77470, // Large 'vblendm|pd'.
+ 0x207D7470, // Large 'vblendm|ps'.
+ 0x20A76470, // Large 'vblend|pd'.
+ 0x207D6470, // Large 'vblend|ps'.
+ 0x34776470, // Large 'vblend|vpd'.
+ 0x318B6470, // Large 'vblend|vps'.
+ 0x306FB021, // Large 'vbroadcastf|128'.
+ 0x1003E021, // Large 'vbroadcastf32x|2'.
+ 0x102FE021, // Large 'vbroadcastf32x|4'.
+ 0x1005E021, // Large 'vbroadcastf32x|8'.
+ 0x4030B021, // Large 'vbroadcastf|64x2'.
+ 0x4034B021, // Large 'vbroadcastf|64x4'.
+ 0x4072A021, // Large 'vbroadcast|i128'.
+ 0x5038A021, // Large 'vbroadcast|i32x2'.
+ 0x503DA021, // Large 'vbroadcast|i32x4'.
+ 0x5042A021, // Large 'vbroadcast|i32x8'.
+ 0x5047A021, // Large 'vbroadcast|i64x2'.
+ 0x504CA021, // Large 'vbroadcast|i64x4'.
+ 0x2144A021, // Large 'vbroadcast|sd'.
+ 0x201CA021, // Large 'vbroadcast|ss'.
+ 0x89083476, // Small 'vcmppd'.
+ 0x91083476, // Small 'vcmpph'.
+ 0xA7083476, // Small 'vcmpps'.
+ 0x89383476, // Small 'vcmpsd'.
+ 0x91383476, // Small 'vcmpsh'.
+ 0xA7383476, // Small 'vcmpss'.
+ 0x214457AB, // Large 'vcomi|sd'.
+ 0x20D557AB, // Large 'vcomi|sh'.
+ 0x201C57AB, // Large 'vcomi|ss'.
+ 0x20A791E4, // Large 'vcompress|pd'.
+ 0x207D91E4, // Large 'vcompress|ps'.
+ 0x20A7747A, // Large 'vcvtdq2|pd'.
+ 0x20A2747A, // Large 'vcvtdq2|ph'.
+ 0x207D747A, // Large 'vcvtdq2|ps'.
+ 0x4069A076, // Large 'vcvtne2ps2|bf16'.
+ 0x307CB080, // Large 'vcvtneebf16|2ps'.
+ 0x51467080, // Large 'vcvtnee|ph2ps'.
+ 0x307CB08B, // Large 'vcvtneobf16|2ps'.
+ 0x5146708B, // Large 'vcvtneo|ph2ps'.
+ 0x406990FC, // Large 'vcvtneps2|bf16'.
+ 0x20E572D4, // Large 'vcvtpd2|dq'.
+ 0x20A272D4, // Large 'vcvtpd2|ph'.
+ 0x207D72D4, // Large 'vcvtpd2|ps'.
+ 0x21F672D4, // Large 'vcvtpd2|qq'.
+ 0x20E582D4, // Large 'vcvtpd2u|dq'.
+ 0x21F682D4, // Large 'vcvtpd2u|qq'.
+ 0x20E572DC, // Large 'vcvtph2|dq'.
+ 0x102682DC, // Large 'vcvtph2p|d'.
+ 0x000092DC, // Large 'vcvtph2ps'.
+ 0x102E92DC, // Large 'vcvtph2ps|x'.
+ 0x21F672DC, // Large 'vcvtph2|qq'.
+ 0x32E572DC, // Large 'vcvtph2|udq'.
+ 0x31F572DC, // Large 'vcvtph2|uqq'.
+ 0x248172DC, // Large 'vcvtph2|uw'.
+ 0x105F72DC, // Large 'vcvtph2|w'.
+ 0x20E572E8, // Large 'vcvtps2|dq'.
+ 0x102682E8, // Large 'vcvtps2p|d'.
+ 0x000092E8, // Large 'vcvtps2ph'.
+ 0x102E92E8, // Large 'vcvtps2ph|x'.
+ 0x21F672E8, // Large 'vcvtps2|qq'.
+ 0x32E572E8, // Large 'vcvtps2|udq'.
+ 0x31F572E8, // Large 'vcvtps2|uqq'.
+ 0x20A77483, // Large 'vcvtqq2|pd'.
+ 0x20A27483, // Large 'vcvtqq2|ph'.
+ 0x207D7483, // Large 'vcvtqq2|ps'.
+ 0x20D572F1, // Large 'vcvtsd2|sh'.
+ 0x201D72F1, // Large 'vcvtsd2|si'.
+ 0x201C72F1, // Large 'vcvtsd2|ss'.
+ 0x201D82F1, // Large 'vcvtsd2u|si'.
+ 0x214472F9, // Large 'vcvtsh2|sd'.
+ 0x201D72F9, // Large 'vcvtsh2|si'.
+ 0x201C72F9, // Large 'vcvtsh2|ss'.
+ 0x201D82F9, // Large 'vcvtsh2u|si'.
+ 0x2144748A, // Large 'vcvtsi2|sd'.
+ 0x20D5748A, // Large 'vcvtsi2|sh'.
+ 0x201C748A, // Large 'vcvtsi2|ss'.
+ 0x21447301, // Large 'vcvtss2|sd'.
+ 0x20D57301, // Large 'vcvtss2|sh'.
+ 0x201D7301, // Large 'vcvtss2|si'.
+ 0x201D8301, // Large 'vcvtss2u|si'.
+ 0x20E581ED, // Large 'vcvttpd2|dq'.
+ 0x21F681ED, // Large 'vcvttpd2|qq'.
+ 0x20E591ED, // Large 'vcvttpd2u|dq'.
+ 0x21F691ED, // Large 'vcvttpd2u|qq'.
+ 0x20E581F8, // Large 'vcvttph2|dq'.
+ 0x21F681F8, // Large 'vcvttph2|qq'.
+ 0x20E591F8, // Large 'vcvttph2u|dq'.
+ 0x21F691F8, // Large 'vcvttph2u|qq'.
+ 0x105F91F8, // Large 'vcvttph2u|w'.
+ 0x105F81F8, // Large 'vcvttph2|w'.
+ 0x20E58201, // Large 'vcvttps2|dq'.
+ 0x21F68201, // Large 'vcvttps2|qq'.
+ 0x20E59201, // Large 'vcvttps2u|dq'.
+ 0x21F69201, // Large 'vcvttps2u|qq'.
+ 0x201D820A, // Large 'vcvttsd2|si'.
+ 0x201D920A, // Large 'vcvttsd2u|si'.
+ 0x201D8213, // Large 'vcvttsh2|si'.
+ 0x201D9213, // Large 'vcvttsh2u|si'.
+ 0x201D821C, // Large 'vcvttss2|si'.
+ 0x201D921C, // Large 'vcvttss2u|si'.
+ 0x20A78309, // Large 'vcvtudq2|pd'.
+ 0x20A28309, // Large 'vcvtudq2|ph'.
+ 0x207D8309, // Large 'vcvtudq2|ps'.
+ 0x20A78311, // Large 'vcvtuqq2|pd'.
+ 0x20A28311, // Large 'vcvtuqq2|ph'.
+ 0x207D8311, // Large 'vcvtuqq2|ps'.
+ 0x21448319, // Large 'vcvtusi2|sd'.
+ 0x20D58319, // Large 'vcvtusi2|sh'.
+ 0x201C8319, // Large 'vcvtusi2|ss'.
+ 0x30A16491, // Large 'vcvtuw|2ph'.
+ 0x30A15640, // Large 'vcvtw|2ph'.
+ 0x239A7497, // Large 'vdbpsad|bw'.
+ 0x890B2496, // Small 'vdivpd'.
+ 0x910B2496, // Small 'vdivph'.
+ 0xA70B2496, // Small 'vdivps'.
+ 0x893B2496, // Small 'vdivsd'.
+ 0x913B2496, // Small 'vdivsh'.
+ 0xA73B2496, // Small 'vdivss'.
+ 0x207D749E, // Large 'vdpbf16|ps'.
+ 0x80484096, // Small 'vdppd'.
+ 0x81384096, // Small 'vdpps'.
+ 0x800948B6, // Small 'verr'.
+ 0x800BC8B6, // Small 'verw'.
+ 0x352544A5, // Large 'vexp|2pd'.
+ 0x307C44A5, // Large 'vexp|2ps'.
+ 0x30ED64A5, // Large 'vexpan|dpd'.
+ 0x30F164A5, // Large 'vexpan|dps'.
+ 0x306F910C, // Large 'vextractf|128'.
+ 0x602A7105, // Large 'vextrac|tf32x4'.
+ 0x4043910C, // Large 'vextractf|32x8'.
+ 0x4030910C, // Large 'vextractf|64x2'.
+ 0x4034910C, // Large 'vextractf|64x4'.
+ 0x4072810C, // Large 'vextract|i128'.
+ 0x503D810C, // Large 'vextract|i32x4'.
+ 0x5042810C, // Large 'vextract|i32x8'.
+ 0x5047810C, // Large 'vextract|i64x2'.
+ 0x504C810C, // Large 'vextract|i64x4'.
+ 0x207D810C, // Large 'vextract|ps'.
+ 0x20A28321, // Large 'vfcmaddc|ph'.
+ 0x20D58321, // Large 'vfcmaddc|sh'.
+ 0x20A274AB, // Large 'vfcmulc|ph'.
+ 0x20D574AB, // Large 'vfcmulc|sh'.
+ 0x20A79225, // Large 'vfixupimm|pd'.
+ 0x207D9225, // Large 'vfixupimm|ps'.
+ 0x21449225, // Large 'vfixupimm|sd'.
+ 0x201C9225, // Large 'vfixupimm|ss'.
+ 0x20A7922E, // Large 'vfmadd132|pd'.
+ 0x20A2922E, // Large 'vfmadd132|ph'.
+ 0x207D922E, // Large 'vfmadd132|ps'.
+ 0x2144922E, // Large 'vfmadd132|sd'.
+ 0x20D5922E, // Large 'vfmadd132|sh'.
+ 0x201C922E, // Large 'vfmadd132|ss'.
+ 0x50A46096, // Large 'vfmadd|213pd'.
+ 0x50A96096, // Large 'vfmadd|213ph'.
+ 0x50AE6096, // Large 'vfmadd|213ps'.
+ 0x51556096, // Large 'vfmadd|213sd'.
+ 0x515A6096, // Large 'vfmadd|213sh'.
+ 0x515F6096, // Large 'vfmadd|213ss'.
+ 0x50B36096, // Large 'vfmadd|231pd'.
+ 0x50B86096, // Large 'vfmadd|231ph'.
+ 0x50BD6096, // Large 'vfmadd|231ps'.
+ 0x51646096, // Large 'vfmadd|231sd'.
+ 0x51696096, // Large 'vfmadd|231sh'.
+ 0x516E6096, // Large 'vfmadd|231ss'.
+ 0x34B26096, // Large 'vfmadd|cph'.
+ 0x34B56096, // Large 'vfmadd|csh'.
+ 0x20A76096, // Large 'vfmadd|pd'.
+ 0x207D6096, // Large 'vfmadd|ps'.
+ 0x10267096, // Large 'vfmadds|d'.
+ 0x10147096, // Large 'vfmadds|s'.
+ 0x1026D096, // Large 'vfmaddsub132p|d'.
+ 0x10A3D096, // Large 'vfmaddsub132p|h'.
+ 0x1014D096, // Large 'vfmaddsub132p|s'.
+ 0x50A49096, // Large 'vfmaddsub|213pd'.
+ 0x50A99096, // Large 'vfmaddsub|213ph'.
+ 0x50AE9096, // Large 'vfmaddsub|213ps'.
+ 0x50B39096, // Large 'vfmaddsub|231pd'.
+ 0x50B89096, // Large 'vfmaddsub|231ph'.
+ 0x50BD9096, // Large 'vfmaddsub|231ps'.
+ 0x20A79096, // Large 'vfmaddsub|pd'.
+ 0x207D9096, // Large 'vfmaddsub|ps'.
+ 0x20A79237, // Large 'vfmsub132|pd'.
+ 0x20A29237, // Large 'vfmsub132|ph'.
+ 0x207D9237, // Large 'vfmsub132|ps'.
+ 0x21449237, // Large 'vfmsub132|sd'.
+ 0x20D59237, // Large 'vfmsub132|sh'.
+ 0x201C9237, // Large 'vfmsub132|ss'.
+ 0x50A460C2, // Large 'vfmsub|213pd'.
+ 0x50A960C2, // Large 'vfmsub|213ph'.
+ 0x50AE60C2, // Large 'vfmsub|213ps'.
+ 0x515560C2, // Large 'vfmsub|213sd'.
+ 0x515A60C2, // Large 'vfmsub|213sh'.
+ 0x515F60C2, // Large 'vfmsub|213ss'.
+ 0x50B360C2, // Large 'vfmsub|231pd'.
+ 0x50B860C2, // Large 'vfmsub|231ph'.
+ 0x50BD60C2, // Large 'vfmsub|231ps'.
+ 0x516460C2, // Large 'vfmsub|231sd'.
+ 0x516960C2, // Large 'vfmsub|231sh'.
+ 0x516E60C2, // Large 'vfmsub|231ss'.
+ 0x20A7C0C2, // Large 'vfmsubadd132|pd'.
+ 0x20A2C0C2, // Large 'vfmsubadd132|ph'.
+ 0x207DC0C2, // Large 'vfmsubadd132|ps'.
+ 0x50A490C2, // Large 'vfmsubadd|213pd'.
+ 0x50A990C2, // Large 'vfmsubadd|213ph'.
+ 0x50AE90C2, // Large 'vfmsubadd|213ps'.
+ 0x50B390C2, // Large 'vfmsubadd|231pd'.
+ 0x50B890C2, // Large 'vfmsubadd|231ph'.
+ 0x50BD90C2, // Large 'vfmsubadd|231ps'.
+ 0x20A790C2, // Large 'vfmsubadd|pd'.
+ 0x207D90C2, // Large 'vfmsubadd|ps'.
+ 0x20A760C2, // Large 'vfmsub|pd'.
+ 0x207D60C2, // Large 'vfmsub|ps'.
+ 0x214460C2, // Large 'vfmsub|sd'.
+ 0x201C60C2, // Large 'vfmsub|ss'.
+ 0x34B25645, // Large 'vfmul|cph'.
+ 0x34B55645, // Large 'vfmul|csh'.
+ 0x20A7A14B, // Large 'vfnmadd132|pd'.
+ 0x20A2A14B, // Large 'vfnmadd132|ph'.
+ 0x207DA14B, // Large 'vfnmadd132|ps'.
+ 0x2144A14B, // Large 'vfnmadd132|sd'.
+ 0x20D5A14B, // Large 'vfnmadd132|sh'.
+ 0x201CA14B, // Large 'vfnmadd132|ss'.
+ 0x50A4714B, // Large 'vfnmadd|213pd'.
+ 0x50A9714B, // Large 'vfnmadd|213ph'.
+ 0x50AE714B, // Large 'vfnmadd|213ps'.
+ 0x5155714B, // Large 'vfnmadd|213sd'.
+ 0x515A714B, // Large 'vfnmadd|213sh'.
+ 0x515F714B, // Large 'vfnmadd|213ss'.
+ 0x50B3714B, // Large 'vfnmadd|231pd'.
+ 0x50B8714B, // Large 'vfnmadd|231ph'.
+ 0x50BD714B, // Large 'vfnmadd|231ps'.
+ 0x5164714B, // Large 'vfnmadd|231sd'.
+ 0x5169714B, // Large 'vfnmadd|231sh'.
+ 0x516E714B, // Large 'vfnmadd|231ss'.
+ 0x20A7714B, // Large 'vfnmadd|pd'.
+ 0x207D714B, // Large 'vfnmadd|ps'.
+ 0x2144714B, // Large 'vfnmadd|sd'.
+ 0x201C714B, // Large 'vfnmadd|ss'.
+ 0x20A7A173, // Large 'vfnmsub132|pd'.
+ 0x20A2A173, // Large 'vfnmsub132|ph'.
+ 0x207DA173, // Large 'vfnmsub132|ps'.
+ 0x2144A173, // Large 'vfnmsub132|sd'.
+ 0x20D5A173, // Large 'vfnmsub132|sh'.
+ 0x201CA173, // Large 'vfnmsub132|ss'.
+ 0x50A47173, // Large 'vfnmsub|213pd'.
+ 0x50A97173, // Large 'vfnmsub|213ph'.
+ 0x50AE7173, // Large 'vfnmsub|213ps'.
+ 0x51557173, // Large 'vfnmsub|213sd'.
+ 0x515A7173, // Large 'vfnmsub|213sh'.
+ 0x515F7173, // Large 'vfnmsub|213ss'.
+ 0x50B37173, // Large 'vfnmsub|231pd'.
+ 0x50B87173, // Large 'vfnmsub|231ph'.
+ 0x50BD7173, // Large 'vfnmsub|231ps'.
+ 0x51647173, // Large 'vfnmsub|231sd'.
+ 0x51697173, // Large 'vfnmsub|231sh'.
+ 0x516E7173, // Large 'vfnmsub|231ss'.
+ 0x20A77173, // Large 'vfnmsub|pd'.
+ 0x207D7173, // Large 'vfnmsub|ps'.
+ 0x21447173, // Large 'vfnmsub|sd'.
+ 0x201C7173, // Large 'vfnmsub|ss'.
+ 0x20A78329, // Large 'vfpclass|pd'.
+ 0x20A28329, // Large 'vfpclass|ph'.
+ 0x207D8329, // Large 'vfpclass|ps'.
+ 0x21448329, // Large 'vfpclass|sd'.
+ 0x20D58329, // Large 'vfpclass|sh'.
+ 0x201C8329, // Large 'vfpclass|ss'.
+ 0x20A757B0, // Large 'vfrcz|pd'.
+ 0x207D57B0, // Large 'vfrcz|ps'.
+ 0x214457B0, // Large 'vfrcz|sd'.
+ 0x201C57B0, // Large 'vfrcz|ss'.
+ 0x30ED7115, // Large 'vgather|dpd'.
+ 0x30F17115, // Large 'vgather|dps'.
+ 0x30EDA115, // Large 'vgatherpf0|dpd'.
+ 0x30F1A115, // Large 'vgatherpf0|dps'.
+ 0x30E6A115, // Large 'vgatherpf0|qpd'.
+ 0x30E9A115, // Large 'vgatherpf0|qps'.
+ 0x40EC9115, // Large 'vgatherpf|1dpd'.
+ 0x40F09115, // Large 'vgatherpf|1dps'.
+ 0x40F49115, // Large 'vgatherpf|1qpd'.
+ 0x40F89115, // Large 'vgatherpf|1qps'.
+ 0x30E67115, // Large 'vgather|qpd'.
+ 0x30E97115, // Large 'vgather|qps'.
+ 0x20A774B8, // Large 'vgetexp|pd'.
+ 0x20A274B8, // Large 'vgetexp|ph'.
+ 0x207D74B8, // Large 'vgetexp|ps'.
+ 0x214474B8, // Large 'vgetexp|sd'.
+ 0x20D574B8, // Large 'vgetexp|sh'.
+ 0x201C74B8, // Large 'vgetexp|ss'.
+ 0x31F17331, // Large 'vgetman|tpd'.
+ 0x31FC7331, // Large 'vgetman|tph'.
+ 0x32057331, // Large 'vgetman|tps'.
+ 0x320E7331, // Large 'vgetman|tsd'.
+ 0x32177331, // Large 'vgetman|tsh'.
+ 0x32207331, // Large 'vgetman|tss'.
+ 0x200FF000, // Large 'vgf2p8affineinv|qb'.
+ 0x200FC000, // Large 'vgf2p8affine|qb'.
+ 0x43386000, // Large 'vgf2p8|mulb'.
+ 0x30ED47B5, // Large 'vhad|dpd'.
+ 0x30F147B5, // Large 'vhad|dps'.
+ 0x20A757B9, // Large 'vhsub|pd'.
+ 0x207D57B9, // Large 'vhsub|ps'.
+ 0x306F8183, // Large 'vinsertf|128'.
+ 0x602A617D, // Large 'vinser|tf32x4'.
+ 0x40438183, // Large 'vinsertf|32x8'.
+ 0x40308183, // Large 'vinsertf|64x2'.
+ 0x40348183, // Large 'vinsertf|64x4'.
+ 0x40727183, // Large 'vinsert|i128'.
+ 0x503D7183, // Large 'vinsert|i32x4'.
+ 0x50427183, // Large 'vinsert|i32x8'.
+ 0x50477183, // Large 'vinsert|i64x2'.
+ 0x504C7183, // Large 'vinsert|i64x4'.
+ 0x207D7183, // Large 'vinsert|ps'.
+ 0xAB121196, // Small 'vlddqu'.
+ 0x1023764A, // Large 'vldmxcs|r'.
+ 0x109DA240, // Large 'vmaskmovdq|u'.
+ 0x20A78240, // Large 'vmaskmov|pd'.
+ 0x207D8240, // Large 'vmaskmov|ps'.
+ 0x890C05B6, // Small 'vmaxpd'.
+ 0x910C05B6, // Small 'vmaxph'.
+ 0xA70C05B6, // Small 'vmaxps'.
+ 0x893C05B6, // Small 'vmaxsd'.
+ 0x913C05B6, // Small 'vmaxsh'.
+ 0xA73C05B6, // Small 'vmaxss'.
+ 0x98C08DB6, // Small 'vmcall'.
+ 0x242857BE, // Large 'vmcle|ar'.
+ 0x86EA99B6, // Small 'vmfunc'.
+ 0x219257C3, // Large 'vmgex|it'.
+ 0x890725B6, // Small 'vminpd'.
+ 0x910725B6, // Small 'vminph'.
+ 0xA70725B6, // Small 'vminps'.
+ 0x893725B6, // Small 'vminsd'.
+ 0x913725B6, // Small 'vminsh'.
+ 0xA73725B6, // Small 'vminss'.
+ 0x21A56651, // Large 'vmlaun|ch'.
+ 0x8817B1B6, // Small 'vmload'.
+ 0x36F347C8, // Large 'vmmc|all'.
+ 0x20A757CC, // Large 'vmova|pd'.
+ 0x207D57CC, // Large 'vmova|ps'.
+ 0x804B3DB6, // Small 'vmovd'.
+ 0x365754BF, // Large 'vmovd|dup'.
+ 0x000074BF, // Large 'vmovdqa'.
+ 0x202C74BF, // Large 'vmovdqa|32'.
+ 0x203074BF, // Large 'vmovdqa|64'.
+ 0x109D64BF, // Large 'vmovdq|u'.
+ 0x34C664BF, // Large 'vmovdq|u16'.
+ 0x34C964BF, // Large 'vmovdq|u32'.
+ 0x34CC64BF, // Large 'vmovdq|u64'.
+ 0x265A64BF, // Large 'vmovdq|u8'.
+ 0x359A565C, // Large 'vmovh|lps'.
+ 0x20A7565C, // Large 'vmovh|pd'.
+ 0x207D565C, // Large 'vmovh|ps'.
+ 0x207D6661, // Large 'vmovlh|ps'.
+ 0x20A75661, // Large 'vmovl|pd'.
+ 0x207D5661, // Large 'vmovl|ps'.
+ 0x20A774CF, // Large 'vmovmsk|pd'.
+ 0x207D74CF, // Large 'vmovmsk|ps'.
+ 0x20E564D6, // Large 'vmovnt|dq'.
+ 0x34C364D6, // Large 'vmovnt|dqa'.
+ 0x20A764D6, // Large 'vmovnt|pd'.
+ 0x207D64D6, // Large 'vmovnt|ps'.
+ 0x811B3DB6, // Small 'vmovq'.
+ 0x893B3DB6, // Small 'vmovsd'.
+ 0x913B3DB6, // Small 'vmovsh'.
+ 0x222974DC, // Large 'vmovshd|up'.
+ 0x222974E3, // Large 'vmovsld|up'.
+ 0xA73B3DB6, // Small 'vmovss'.
+ 0x343344BF, // Large 'vmov|upd'.
+ 0x207D57D1, // Large 'vmovu|ps'.
+ 0x817B3DB6, // Small 'vmovw'.
+ 0x239A6667, // Large 'vmpsad|bw'.
+ 0x341147D6, // Large 'vmpt|rld'.
+ 0x340D47D6, // Large 'vmpt|rst'.
+ 0x8812C9B6, // Small 'vmread'.
+ 0x100B766D, // Large 'vmresum|e'.
+ 0x80EAC9B6, // Small 'vmrun'.
+ 0x8B60CDB6, // Small 'vmsave'.
+ 0x890655B6, // Small 'vmulpd'.
+ 0x910655B6, // Small 'vmulph'.
+ 0xA70655B6, // Small 'vmulps'.
+ 0x893655B6, // Small 'vmulsd'.
+ 0x913655B6, // Small 'vmulsh'.
+ 0xA73655B6, // Small 'vmulss'.
+ 0x20DF57DA, // Large 'vmwri|te'.
+ 0x8C67E1B6, // Small 'vmxoff'.
+ 0x80E7E1B6, // Small 'vmxon'.
+ 0x804849F6, // Small 'vorpd'.
+ 0x813849F6, // Small 'vorps'.
+ 0x1026C11F, // Large 'vp2intersect|d'.
+ 0x100FC11F, // Large 'vp2intersect|q'.
+ 0x1026833C, // Large 'vp4dpwss|d'.
+ 0x209B833C, // Large 'vp4dpwss|ds'.
+ 0x85310616, // Small 'vpabsb'.
+ 0x89310616, // Small 'vpabsd'.
+ 0xA3310616, // Small 'vpabsq'.
+ 0xAF310616, // Small 'vpabsw'.
+ 0x105F84EA, // Large 'vpackssd|w'.
+ 0x24F274EA, // Large 'vpackss|wb'.
+ 0x34F064F4, // Large 'vpacku|sdw'.
+ 0x34FA64F4, // Large 'vpacku|swb'.
+ 0x84420616, // Small 'vpaddb'.
+ 0x88420616, // Small 'vpaddd'.
+ 0xA2420616, // Small 'vpaddq'.
+ 0x25BA5674, // Large 'vpadd|sb'.
+ 0x23835674, // Large 'vpadd|sw'.
+ 0x25BA6674, // Large 'vpaddu|sb'.
+ 0x23836674, // Large 'vpaddu|sw'.
+ 0xAE420616, // Small 'vpaddw'.
+ 0x1023767A, // Large 'vpalign|r'.
+ 0x80470616, // Small 'vpand'.
+ 0x88470616, // Small 'vpandd'.
+ 0x9C470616, // Small 'vpandn'.
+ 0x219D57DF, // Large 'vpand|nd'.
+ 0x271E57DF, // Large 'vpand|nq'.
+ 0xA2470616, // Small 'vpandq'.
+ 0x847B0616, // Small 'vpavgb'.
+ 0xAE7B0616, // Small 'vpavgw'.
+ 0x102674FD, // Large 'vpblend|d'.
+ 0x205C74FD, // Large 'vpblend|mb'.
+ 0x250474FD, // Large 'vpblend|md'.
+ 0x100F84FD, // Large 'vpblendm|q'.
+ 0x105F84FD, // Large 'vpblendm|w'.
+ 0x202174FD, // Large 'vpblend|vb'.
+ 0x105F74FD, // Large 'vpblend|w'.
+ 0x1010B051, // Large 'vpbroadcast|b'.
+ 0x1026B051, // Large 'vpbroadcast|d'.
+ 0x100FE051, // Large 'vpbroadcastmb2|q'.
+ 0x305FC051, // Large 'vpbroadcastm|w2d'.
+ 0x100FB051, // Large 'vpbroadcast|q'.
+ 0x105FB051, // Large 'vpbroadcast|w'.
+ 0x42886344, // Large 'vpclmu|lqdq'.
+ 0xACF68E16, // Small 'vpcmov'.
+ 0x85068E16, // Small 'vpcmpb'.
+ 0x89068E16, // Small 'vpcmpd'.
+ 0x200F634A, // Large 'vpcmpe|qb'.
+ 0x227D634A, // Large 'vpcmpe|qd'.
+ 0x21F6634A, // Large 'vpcmpe|qq'.
+ 0x2559634A, // Large 'vpcmpe|qw'.
+ 0x1009934A, // Large 'vpcmpestr|i'.
+ 0x105C934A, // Large 'vpcmpestr|m'.
+ 0x3681534A, // Large 'vpcmp|gtb'.
+ 0x3684534A, // Large 'vpcmp|gtd'.
+ 0x3687534A, // Large 'vpcmp|gtq'.
+ 0x368A534A, // Large 'vpcmp|gtw'.
+ 0x10099353, // Large 'vpcmpistr|i'.
+ 0x105C9353, // Large 'vpcmpistr|m'.
+ 0xA3068E16, // Small 'vpcmpq'.
+ 0x209D534A, // Large 'vpcmp|ub'.
+ 0x22E5534A, // Large 'vpcmp|ud'.
+ 0x21F5534A, // Large 'vpcmp|uq'.
+ 0x2481534A, // Large 'vpcmp|uw'.
+ 0xAF068E16, // Small 'vpcmpw'.
+ 0x84D78E16, // Small 'vpcomb'.
+ 0x88D78E16, // Small 'vpcomd'.
+ 0x1010A24A, // Large 'vpcompress|b'.
+ 0x1026A24A, // Large 'vpcompress|d'.
+ 0x100FA24A, // Large 'vpcompress|q'.
+ 0x105FA24A, // Large 'vpcompress|w'.
+ 0xA2D78E16, // Small 'vpcomq'.
+ 0x209D524A, // Large 'vpcom|ub'.
+ 0x22E5524A, // Large 'vpcom|ud'.
+ 0x21F5524A, // Large 'vpcom|uq'.
+ 0x2481524A, // Large 'vpcom|uw'.
+ 0xAED78E16, // Small 'vpcomw'.
+ 0x1026A254, // Large 'vpconflict|d'.
+ 0x100FA254, // Large 'vpconflict|q'.
+ 0x10267506, // Large 'vpdpbss|d'.
+ 0x209B7506, // Large 'vpdpbss|ds'.
+ 0x22E56506, // Large 'vpdpbs|ud'.
+ 0x350D6506, // Large 'vpdpbs|uds'.
+ 0x10267510, // Large 'vpdpbus|d'.
+ 0x209B7510, // Large 'vpdpbus|ds'.
+ 0x22E56510, // Large 'vpdpbu|ud'.
+ 0x350D6510, // Large 'vpdpbu|uds'.
+ 0x10267517, // Large 'vpdpwss|d'.
+ 0x209B7517, // Large 'vpdpwss|ds'.
+ 0x22E56517, // Large 'vpdpws|ud'.
+ 0x350D6517, // Large 'vpdpws|uds'.
+ 0x1026751E, // Large 'vpdpwus|d'.
+ 0x209B751E, // Large 'vpdpwus|ds'.
+ 0x22E5651E, // Large 'vpdpwu|ud'.
+ 0x350D651E, // Large 'vpdpwu|uds'.
+ 0x306F735C, // Large 'vperm2f|128'.
+ 0x4072635C, // Large 'vperm2|i128'.
+ 0x84D91616, // Small 'vpermb'.
+ 0x88D91616, // Small 'vpermd'.
+ 0x268D6363, // Large 'vpermi|2b'.
+ 0x20606363, // Large 'vpermi|2d'.
+ 0x35256363, // Large 'vpermi|2pd'.
+ 0x307C6363, // Large 'vpermi|2ps'.
+ 0x268F6363, // Large 'vpermi|2q'.
+ 0x205E6363, // Large 'vpermi|2w'.
+ 0x20A78363, // Large 'vpermil2|pd'.
+ 0x207D8363, // Large 'vpermil2|ps'.
+ 0x20A77363, // Large 'vpermil|pd'.
+ 0x207D7363, // Large 'vpermil|ps'.
+ 0x20A7535C, // Large 'vperm|pd'.
+ 0x207D535C, // Large 'vperm|ps'.
+ 0xA2D91616, // Small 'vpermq'.
+ 0x268D6528, // Large 'vpermt|2b'.
+ 0x20606528, // Large 'vpermt|2d'.
+ 0x35256528, // Large 'vpermt|2pd'.
+ 0x307C6528, // Large 'vpermt|2ps'.
+ 0x268F6528, // Large 'vpermt|2q'.
+ 0x205E6528, // Large 'vpermt|2w'.
+ 0xAED91616, // Small 'vpermw'.
+ 0x2498752E, // Large 'vpexpan|db'.
+ 0x209A752E, // Large 'vpexpan|dd'.
+ 0x20E5752E, // Large 'vpexpan|dq'.
+ 0x24F1752E, // Large 'vpexpan|dw'.
+ 0x35F7452E, // Large 'vpex|trb'.
+ 0x261657E4, // Large 'vpext|rd'.
+ 0x227C57E4, // Large 'vpext|rq'.
+ 0x27E957E4, // Large 'vpext|rw'.
+ 0x209A836B, // Large 'vpgather|dd'.
+ 0x20E5836B, // Large 'vpgather|dq'.
+ 0x227D836B, // Large 'vpgather|qd'.
+ 0x21F6836B, // Large 'vpgather|qq'.
+ 0x26916535, // Large 'vphadd|bd'.
+ 0x26936535, // Large 'vphadd|bq'.
+ 0x239A6535, // Large 'vphadd|bw'.
+ 0x10266535, // Large 'vphadd|d'.
+ 0x20E56535, // Large 'vphadd|dq'.
+ 0x23836535, // Large 'vphadd|sw'.
+ 0x10268535, // Large 'vphaddub|d'.
+ 0x100F8535, // Large 'vphaddub|q'.
+ 0x105F8535, // Large 'vphaddub|w'.
+ 0x20E57535, // Large 'vphaddu|dq'.
+ 0x239C7535, // Large 'vphaddu|wd'.
+ 0x253D7535, // Large 'vphaddu|wq'.
+ 0x105F6535, // Large 'vphadd|w'.
+ 0x239C6535, // Large 'vphadd|wd'.
+ 0x253D6535, // Large 'vphadd|wq'.
+ 0x105FA25E, // Large 'vphminposu|w'.
+ 0x239A6695, // Large 'vphsub|bw'.
+ 0x10266695, // Large 'vphsub|d'.
+ 0x20E56695, // Large 'vphsub|dq'.
+ 0x23836695, // Large 'vphsub|sw'.
+ 0x105F6695, // Large 'vphsub|w'.
+ 0x239C6695, // Large 'vphsub|wd'.
+ 0x25F857EB, // Large 'vpins|rb'.
+ 0x261657EB, // Large 'vpins|rd'.
+ 0x227C57EB, // Large 'vpins|rq'.
+ 0x27E957EB, // Large 'vpins|rw'.
+ 0x2455669B, // Large 'vplzcn|td'.
+ 0x2193669B, // Large 'vplzcn|tq'.
+ 0x209A6373, // Large 'vpmacs|dd'.
+ 0x353F6373, // Large 'vpmacs|dqh'.
+ 0x33A26373, // Large 'vpmacs|dql'.
+ 0x10268373, // Large 'vpmacssd|d'.
+ 0x10A39373, // Large 'vpmacssdq|h'.
+ 0x10D29373, // Large 'vpmacssdq|l'.
+ 0x239C7373, // Large 'vpmacss|wd'.
+ 0x239B7373, // Large 'vpmacss|ww'.
+ 0x239C6373, // Large 'vpmacs|wd'.
+ 0x239B6373, // Large 'vpmacs|ww'.
+ 0x1026937C, // Large 'vpmadcssw|d'.
+ 0x239C737C, // Large 'vpmadcs|wd'.
+ 0x21F59268, // Large 'vpmadd52h|uq'.
+ 0x32718268, // Large 'vpmadd52|luq'.
+ 0x43856268, // Large 'vpmadd|ubsw'.
+ 0x239C6268, // Large 'vpmadd|wd'.
+ 0x62434268, // Large 'vpma|skmovd'.
+ 0x200E8389, // Large 'vpmaskmo|vq'.
+ 0x25BA57F0, // Large 'vpmax|sb'.
+ 0x214457F0, // Large 'vpmax|sd'.
+ 0x23A957F0, // Large 'vpmax|sq'.
+ 0x238357F0, // Large 'vpmax|sw'.
+ 0x209D57F0, // Large 'vpmax|ub'.
+ 0x22E557F0, // Large 'vpmax|ud'.
+ 0x21F557F0, // Large 'vpmax|uq'.
+ 0x248157F0, // Large 'vpmax|uw'.
+ 0x25BA57F5, // Large 'vpmin|sb'.
+ 0x214457F5, // Large 'vpmin|sd'.
+ 0x23A957F5, // Large 'vpmin|sq'.
+ 0x238357F5, // Large 'vpmin|sw'.
+ 0x209D57F5, // Large 'vpmin|ub'.
+ 0x22E557F5, // Large 'vpmin|ud'.
+ 0x21F557F5, // Large 'vpmin|uq'.
+ 0x248157F5, // Large 'vpmin|uw'.
+ 0x36A15542, // Large 'vpmov|b2m'.
+ 0x36A45542, // Large 'vpmov|d2m'.
+ 0x24985542, // Large 'vpmov|db'.
+ 0x24F15542, // Large 'vpmov|dw'.
+ 0x268D6542, // Large 'vpmovm|2b'.
+ 0x20606542, // Large 'vpmovm|2d'.
+ 0x268F6542, // Large 'vpmovm|2q'.
+ 0x205E6542, // Large 'vpmovm|2w'.
+ 0x10108542, // Large 'vpmovmsk|b'.
+ 0x36A75542, // Large 'vpmov|q2m'.
+ 0x200F5542, // Large 'vpmov|qb'.
+ 0x227D5542, // Large 'vpmov|qd'.
+ 0x25595542, // Large 'vpmov|qw'.
+ 0x2498654A, // Large 'vpmovs|db'.
+ 0x24F1654A, // Large 'vpmovs|dw'.
+ 0x200F654A, // Large 'vpmovs|qb'.
+ 0x227D654A, // Large 'vpmovs|qd'.
+ 0x2559654A, // Large 'vpmovs|qw'.
+ 0x24F2654A, // Large 'vpmovs|wb'.
+ 0x1026854A, // Large 'vpmovsxb|d'.
+ 0x100F854A, // Large 'vpmovsxb|q'.
+ 0x105F854A, // Large 'vpmovsxb|w'.
+ 0x20E5754A, // Large 'vpmovsx|dq'.
+ 0x239C754A, // Large 'vpmovsx|wd'.
+ 0x253D754A, // Large 'vpmovsx|wq'.
+ 0x24987552, // Large 'vpmovus|db'.
+ 0x24F17552, // Large 'vpmovus|dw'.
+ 0x200F7552, // Large 'vpmovus|qb'.
+ 0x227D7552, // Large 'vpmovus|qd'.
+ 0x25597552, // Large 'vpmovus|qw'.
+ 0x24F27552, // Large 'vpmovus|wb'.
+ 0x36AA5542, // Large 'vpmov|w2m'.
+ 0x24F25542, // Large 'vpmov|wb'.
+ 0x1026855B, // Large 'vpmovzxb|d'.
+ 0x100F855B, // Large 'vpmovzxb|q'.
+ 0x105F855B, // Large 'vpmovzxb|w'.
+ 0x20E5755B, // Large 'vpmovzx|dq'.
+ 0x239C755B, // Large 'vpmovzx|wd'.
+ 0x253D755B, // Large 'vpmovzx|wq'.
+ 0x20E550CE, // Large 'vpmul|dq'.
+ 0x23837563, // Large 'vpmulhr|sw'.
+ 0x24816563, // Large 'vpmulh|uw'.
+ 0x105F6563, // Large 'vpmulh|w'.
+ 0x23A150CE, // Large 'vpmul|ld'.
+ 0x228850CE, // Large 'vpmul|lq'.
+ 0x23A450CE, // Large 'vpmul|lw'.
+ 0x200FC0CE, // Large 'vpmultishift|qb'.
+ 0x32E550CE, // Large 'vpmul|udq'.
+ 0x268266AD, // Large 'vpopcn|tb'.
+ 0x245566AD, // Large 'vpopcn|td'.
+ 0x219366AD, // Large 'vpopcn|tq'.
+ 0x264366AD, // Large 'vpopcn|tw'.
+ 0x80093E16, // Small 'vpor'.
+ 0x80493E16, // Small 'vpord'.
+ 0x81193E16, // Small 'vporq'.
+ 0x9B22C216, // Small 'vpperm'.
+ 0x88C7CA16, // Small 'vprold'.
+ 0xA2C7CA16, // Small 'vprolq'.
+ 0x224757FA, // Large 'vprol|vd'.
+ 0x200E57FA, // Large 'vprol|vq'.
+ 0x8927CA16, // Small 'vprord'.
+ 0xA327CA16, // Small 'vprorq'.
+ 0x224757FF, // Large 'vpror|vd'.
+ 0x200E57FF, // Large 'vpror|vq'.
+ 0x8547CA16, // Small 'vprotb'.
+ 0x8947CA16, // Small 'vprotd'.
+ 0xA347CA16, // Small 'vprotq'.
+ 0xAF47CA16, // Small 'vprotw'.
+ 0x239A5804, // Large 'vpsad|bw'.
+ 0x209A9274, // Large 'vpscatter|dd'.
+ 0x20E59274, // Large 'vpscatter|dq'.
+ 0x227D9274, // Large 'vpscatter|qd'.
+ 0x100FA274, // Large 'vpscatterq|q'.
+ 0x84144E16, // Small 'vpshab'.
+ 0x88144E16, // Small 'vpshad'.
+ 0xA2144E16, // Small 'vpshaq'.
+ 0xAE144E16, // Small 'vpshaw'.
+ 0x84C44E16, // Small 'vpshlb'.
+ 0x88C44E16, // Small 'vpshld'.
+ 0x102666B3, // Large 'vpshld|d'.
+ 0x100F66B3, // Large 'vpshld|q'.
+ 0x349D56B3, // Large 'vpshl|dvd'.
+ 0x36B856B3, // Large 'vpshl|dvq'.
+ 0x105F76B3, // Large 'vpshldv|w'.
+ 0x105F66B3, // Large 'vpshld|w'.
+ 0xA2C44E16, // Small 'vpshlq'.
+ 0xAEC44E16, // Small 'vpshlw'.
+ 0x102666BB, // Large 'vpshrd|d'.
+ 0x100F66BB, // Large 'vpshrd|q'.
+ 0x349D56BB, // Large 'vpshr|dvd'.
+ 0x36B856BB, // Large 'vpshr|dvq'.
+ 0x36C056BB, // Large 'vpshr|dvw'.
+ 0x105F66BB, // Large 'vpshrd|w'.
+ 0x0000718B, // Large 'vpshufb'.
+ 0x205CA18B, // Large 'vpshufbitq|mb'.
+ 0x1026618B, // Large 'vpshuf|d'.
+ 0x26C3618B, // Large 'vpshuf|hw'.
+ 0x23A4618B, // Large 'vpshuf|lw'.
+ 0x22A95809, // Large 'vpsig|nb'.
+ 0x219D5809, // Large 'vpsig|nd'.
+ 0x26FB5809, // Large 'vpsig|nw'.
+ 0x88C64E16, // Small 'vpslld'.
+ 0x33A1480E, // Large 'vpsl|ldq'.
+ 0xA2C64E16, // Small 'vpsllq'.
+ 0x22475812, // Large 'vpsll|vd'.
+ 0x200E5812, // Large 'vpsll|vq'.
+ 0x26C15812, // Large 'vpsll|vw'.
+ 0xAEC64E16, // Small 'vpsllw'.
+ 0x88194E16, // Small 'vpsrad'.
+ 0xA2194E16, // Small 'vpsraq'.
+ 0x22475817, // Large 'vpsra|vd'.
+ 0x200E5817, // Large 'vpsra|vq'.
+ 0x26C15817, // Large 'vpsra|vw'.
+ 0xAE194E16, // Small 'vpsraw'.
+ 0x88C94E16, // Small 'vpsrld'.
+ 0x33A14817, // Large 'vpsr|ldq'.
+ 0xA2C94E16, // Small 'vpsrlq'.
+ 0x2247581C, // Large 'vpsrl|vd'.
+ 0x200E581C, // Large 'vpsrl|vq'.
+ 0x26C1581C, // Large 'vpsrl|vw'.
+ 0xAEC94E16, // Small 'vpsrlw'.
+ 0x842ACE16, // Small 'vpsubb'.
+ 0x882ACE16, // Small 'vpsubd'.
+ 0xA22ACE16, // Small 'vpsubq'.
+ 0x25BA56C5, // Large 'vpsub|sb'.
+ 0x238356C5, // Large 'vpsub|sw'.
+ 0x25BA66C5, // Large 'vpsubu|sb'.
+ 0x238366C5, // Large 'vpsubu|sw'.
+ 0xAE2ACE16, // Small 'vpsubw'.
+ 0x10269391, // Large 'vpternlog|d'.
+ 0x100F9391, // Large 'vpternlog|q'.
+ 0xA932D216, // Small 'vptest'.
+ 0x205C656A, // Large 'vptest|mb'.
+ 0x2504656A, // Large 'vptest|md'.
+ 0x2571656A, // Large 'vptest|mq'.
+ 0x26A9656A, // Large 'vptest|mw'.
+ 0x205C756A, // Large 'vptestn|mb'.
+ 0x2504756A, // Large 'vptestn|md'.
+ 0x2571756A, // Large 'vptestn|mq'.
+ 0x105F856A, // Large 'vptestnm|w'.
+ 0x239A827F, // Large 'vpunpckh|bw'.
+ 0x20E5827F, // Large 'vpunpckh|dq'.
+ 0x20E5927F, // Large 'vpunpckhq|dq'.
+ 0x239C827F, // Large 'vpunpckh|wd'.
+ 0x339E727F, // Large 'vpunpck|lbw'.
+ 0x33A1727F, // Large 'vpunpck|ldq'.
+ 0x4288727F, // Large 'vpunpck|lqdq'.
+ 0x33A4727F, // Large 'vpunpck|lwd'.
+ 0x8127E216, // Small 'vpxor'.
+ 0x8927E216, // Small 'vpxord'.
+ 0xA327E216, // Small 'vpxorq'.
+ 0x20A766CB, // Large 'vrange|pd'.
+ 0x207D66CB, // Large 'vrange|ps'.
+ 0x214466CB, // Large 'vrange|sd'.
+ 0x201C66CB, // Large 'vrange|ss'.
+ 0x20A766D1, // Large 'vrcp14|pd'.
+ 0x207D66D1, // Large 'vrcp14|ps'.
+ 0x214466D1, // Large 'vrcp14|sd'.
+ 0x201C66D1, // Large 'vrcp14|ss'.
+ 0x43AF46D1, // Large 'vrcp|28pd'.
+ 0x43B346D1, // Large 'vrcp|28ps'.
+ 0x43B746D1, // Large 'vrcp|28sd'.
+ 0x43BB46D1, // Large 'vrcp|28ss'.
+ 0x91080E56, // Small 'vrcpph'.
+ 0xA7080E56, // Small 'vrcpps'.
+ 0x91380E56, // Small 'vrcpsh'.
+ 0xA7380E56, // Small 'vrcpss'.
+ 0x20A77573, // Large 'vreduce|pd'.
+ 0x20A27573, // Large 'vreduce|ph'.
+ 0x207D7573, // Large 'vreduce|ps'.
+ 0x21447573, // Large 'vreduce|sd'.
+ 0x20D57573, // Large 'vreduce|sh'.
+ 0x201C7573, // Large 'vreduce|ss'.
+ 0x20A7928C, // Large 'vrndscale|pd'.
+ 0x20A2928C, // Large 'vrndscale|ph'.
+ 0x207D928C, // Large 'vrndscale|ps'.
+ 0x2144928C, // Large 'vrndscale|sd'.
+ 0x20D5928C, // Large 'vrndscale|sh'.
+ 0x201C928C, // Large 'vrndscale|ss'.
+ 0x30ED56D7, // Large 'vroun|dpd'.
+ 0x30F156D7, // Large 'vroun|dps'.
+ 0x36DC56D7, // Large 'vroun|dsd'.
+ 0x101476D7, // Large 'vrounds|s'.
+ 0x20A783A7, // Large 'vrsqrt14|pd'.
+ 0x207D83A7, // Large 'vrsqrt14|ps'.
+ 0x214483A7, // Large 'vrsqrt14|sd'.
+ 0x201C83A7, // Large 'vrsqrt14|ss'.
+ 0x43AF63A7, // Large 'vrsqrt|28pd'.
+ 0x43B363A7, // Large 'vrsqrt|28ps'.
+ 0x43B763A7, // Large 'vrsqrt|28sd'.
+ 0x43BB63A7, // Large 'vrsqrt|28ss'.
+ 0x20A263A7, // Large 'vrsqrt|ph'.
+ 0x207D63A7, // Large 'vrsqrt|ps'.
+ 0x20D563A7, // Large 'vrsqrt|sh'.
+ 0x201C63A7, // Large 'vrsqrt|ss'.
+ 0x20A7757A, // Large 'vscalef|pd'.
+ 0x20A2757A, // Large 'vscalef|ph'.
+ 0x207D757A, // Large 'vscalef|ps'.
+ 0x2144757A, // Large 'vscalef|sd'.
+ 0x20D5757A, // Large 'vscalef|sh'.
+ 0x201C757A, // Large 'vscalef|ss'.
+ 0x30ED80DA, // Large 'vscatter|dpd'.
+ 0x30F180DA, // Large 'vscatter|dps'.
+ 0x20A7C0DA, // Large 'vscatterpf0d|pd'.
+ 0x207DC0DA, // Large 'vscatterpf0d|ps'.
+ 0x30E6B0DA, // Large 'vscatterpf0|qpd'.
+ 0x30E9B0DA, // Large 'vscatterpf0|qps'.
+ 0x40ECA0DA, // Large 'vscatterpf|1dpd'.
+ 0x40F0A0DA, // Large 'vscatterpf|1dps'.
+ 0x40F4A0DA, // Large 'vscatterpf|1qpd'.
+ 0x40F8A0DA, // Large 'vscatterpf|1qps'.
+ 0x30E680DA, // Large 'vscatter|qpd'.
+ 0x30E980DA, // Large 'vscatter|qps'.
+ 0x42957195, // Large 'vsha512|msg1'.
+ 0x42997195, // Large 'vsha512|msg2'.
+ 0x207EA195, // Large 'vsha512rnd|s2'.
+ 0x502B53BF, // Large 'vshuf|f32x4'.
+ 0x403063C4, // Large 'vshuff|64x2'.
+ 0x503D53BF, // Large 'vshuf|i32x4'.
+ 0x504753BF, // Large 'vshuf|i64x2'.
+ 0x20A753BF, // Large 'vshuf|pd'.
+ 0x207D53BF, // Large 'vshuf|ps'.
+ 0x42954581, // Large 'vsm3|msg1'.
+ 0x42994581, // Large 'vsm3|msg2'.
+ 0x207E7581, // Large 'vsm3rnd|s2'.
+ 0x102F76DF, // Large 'vsm4key|4'.
+ 0x102F8588, // Large 'vsm4rnds|4'.
+ 0x31F14821, // Large 'vsqr|tpd'.
+ 0x31FC4821, // Large 'vsqr|tph'.
+ 0x32054821, // Large 'vsqr|tps'.
+ 0x320E4821, // Large 'vsqr|tsd'.
+ 0x32174821, // Large 'vsqr|tsh'.
+ 0x32204821, // Large 'vsqr|tss'.
+ 0x102376E6, // Large 'vstmxcs|r'.
+ 0x89015676, // Small 'vsubpd'.
+ 0x91015676, // Small 'vsubph'.
+ 0xA7015676, // Small 'vsubps'.
+ 0x89315676, // Small 'vsubsd'.
+ 0x91315676, // Small 'vsubsh'.
+ 0xA7315676, // Small 'vsubss'.
+ 0x31F14825, // Large 'vtes|tpd'.
+ 0x32054825, // Large 'vtes|tps'.
+ 0x214466ED, // Large 'vucomi|sd'.
+ 0x20D566ED, // Large 'vucomi|sh'.
+ 0x201C66ED, // Large 'vucomi|ss'.
+ 0x20A77590, // Large 'vunpckh|pd'.
+ 0x207D7590, // Large 'vunpckh|ps'.
+ 0x35976590, // Large 'vunpck|lpd'.
+ 0x359A6590, // Large 'vunpck|lps'.
+ 0x89093F16, // Small 'vxorpd'.
+ 0xA7093F16, // Small 'vxorps'.
+ 0x36F353CA, // Large 'vzero|all'.
+ 0x335D73CA, // Large 'vzeroup|per'.
+ 0x89672457, // Small 'wbinvd'.
+ 0x224766F6, // Large 'wbnoin|vd'.
+ 0x343656FC, // Large 'wrfsb|ase'.
+ 0x34365701, // Large 'wrgsb|ase'.
+ 0x8129B657, // Small 'wrmsr'.
+ 0x8049CE57, // Small 'wrssd'.
+ 0x8119CE57, // Small 'wrssq'.
+ 0x8939D657, // Small 'wrussd'.
+ 0xA339D657, // Small 'wrussq'.
+ 0xA9278838, // Small 'xabort'.
+ 0x80021038, // Small 'xadd'.
+ 0x9C939458, // Small 'xbegin'.
+ 0x8003A078, // Small 'xchg'.
+ 0x800238B8, // Small 'xend'.
+ 0xAC2A14F8, // Small 'xgetbv'.
+ 0x802A0598, // Small 'xlatb'.
+ 0x800049F8, // Small 'xor'.
+ 0x804849F8, // Small 'xorpd'.
+ 0x813849F8, // Small 'xorps'.
+ 0x1015859D, // Large 'xresldtr|k'.
+ 0xA4FA4E58, // Small 'xrstor'.
+ 0x2030640C, // Large 'xrstor|64'.
+ 0x1014640C, // Large 'xrstor|s'.
+ 0x35A5640C, // Large 'xrstor|s64'.
+ 0x805B0678, // Small 'xsave'.
+ 0x203053D1, // Large 'xsave|64'.
+ 0x865B0678, // Small 'xsavec'.
+ 0x370653D1, // Large 'xsave|c64'.
+ 0x000083D1, // Large 'xsaveopt'.
+ 0x203083D1, // Large 'xsaveopt|64'.
+ 0xA65B0678, // Small 'xsaves'.
+ 0x35A553D1, // Large 'xsave|s64'.
+ 0xAC2A1678, // Small 'xsetbv'.
+ 0x101585A8, // Large 'xsusldtr|k'.
+ 0x81499698 // Small 'xtest'.
};
// ----------------------------------------------------------------------------
// ${NameData:End}
@@ -3054,515 +4729,573 @@ const InstDB::InstSignature InstDB::_instSignatureTable[] = {
ROW(2, 1, 1, 0, 9 , 10 , 0 , 0 , 0 , 0 ), // {r8lo|r8hi|m8, i8|u8}
ROW(2, 1, 1, 0, 11 , 12 , 0 , 0 , 0 , 0 ), // {r16|m16, i16|u16}
ROW(2, 1, 1, 0, 13 , 14 , 0 , 0 , 0 , 0 ), // {r32|m32, i32|u32}
- ROW(2, 0, 1, 0, 15 , 16 , 0 , 0 , 0 , 0 ), // {r64|m64|mem, i32}
+ ROW(2, 0, 1, 0, 15 , 16 , 0 , 0 , 0 , 0 ), // {r64|m64, i32}
ROW(2, 0, 1, 0, 8 , 17 , 0 , 0 , 0 , 0 ), // {r64, i64|u64|m64|mem|sreg|creg|dreg}
ROW(2, 1, 1, 0, 2 , 18 , 0 , 0 , 0 , 0 ), // {r8lo|r8hi, m8|mem}
ROW(2, 1, 1, 0, 4 , 19 , 0 , 0 , 0 , 0 ), // {r16, m16|mem|sreg}
ROW(2, 1, 1, 0, 6 , 20 , 0 , 0 , 0 , 0 ), // {r32, m32|mem|sreg}
ROW(2, 1, 1, 0, 21 , 22 , 0 , 0 , 0 , 0 ), // {m16|mem, sreg}
+ ROW(2, 1, 1, 0, 21 , 22 , 0 , 0 , 0 , 0 ), // {m16|mem, sreg}
+ ROW(2, 0, 1, 0, 21 , 22 , 0 , 0 , 0 , 0 ), // {m16|mem, sreg}
ROW(2, 1, 1, 0, 22 , 21 , 0 , 0 , 0 , 0 ), // {sreg, m16|mem}
+ ROW(2, 1, 1, 0, 22 , 21 , 0 , 0 , 0 , 0 ), // {sreg, m16|mem}
+ ROW(2, 0, 1, 0, 22 , 21 , 0 , 0 , 0 , 0 ), // {sreg, m16|mem}
ROW(2, 1, 0, 0, 6 , 23 , 0 , 0 , 0 , 0 ), // {r32, creg|dreg}
ROW(2, 1, 0, 0, 23 , 6 , 0 , 0 , 0 , 0 ), // {creg|dreg, r32}
- ROW(2, 1, 1, 0, 9 , 10 , 0 , 0 , 0 , 0 ), // #16 {r8lo|r8hi|m8, i8|u8}
+ ROW(2, 1, 1, 0, 9 , 10 , 0 , 0 , 0 , 0 ), // #20 {r8lo|r8hi|m8, i8|u8}
ROW(2, 1, 1, 0, 11 , 12 , 0 , 0 , 0 , 0 ), // {r16|m16, i16|u16}
ROW(2, 1, 1, 0, 13 , 14 , 0 , 0 , 0 , 0 ), // {r32|m32, i32|u32}
- ROW(2, 0, 1, 0, 15 , 24 , 0 , 0 , 0 , 0 ), // {r64|m64|mem, i32|r64}
- ROW(2, 1, 1, 0, 25 , 26 , 0 , 0 , 0 , 0 ), // {r16|m16|r32|m32|r64|m64|mem, i8}
- ROW(2, 1, 1, 0, 1 , 2 , 0 , 0 , 0 , 0 ), // {r8lo|r8hi|m8|mem, r8lo|r8hi}
+ ROW(2, 0, 1, 0, 15 , 24 , 0 , 0 , 0 , 0 ), // {r64|m64, i32|i8}
+ ROW(2, 1, 1, 0, 25 , 26 , 0 , 0 , 0 , 0 ), // {r16|m16|r32|m32, i8}
+ ROW(2, 1, 1, 0, 1 , 2 , 0 , 0 , 0 , 0 ), // #25 {r8lo|r8hi|m8|mem, r8lo|r8hi}
ROW(2, 1, 1, 0, 27 , 4 , 0 , 0 , 0 , 0 ), // {r16|m16|mem, r16}
- ROW(2, 1, 1, 0, 28 , 6 , 0 , 0 , 0 , 0 ), // #23 {r32|m32|mem, r32}
+ ROW(2, 1, 1, 0, 28 , 6 , 0 , 0 , 0 , 0 ), // #27 {r32|m32|mem, r32}
+ ROW(2, 0, 1, 0, 29 , 8 , 0 , 0 , 0 , 0 ), // #28 {r64|m64|mem, r64}
ROW(2, 1, 1, 0, 2 , 18 , 0 , 0 , 0 , 0 ), // {r8lo|r8hi, m8|mem}
ROW(2, 1, 1, 0, 4 , 21 , 0 , 0 , 0 , 0 ), // {r16, m16|mem}
- ROW(2, 1, 1, 0, 6 , 29 , 0 , 0 , 0 , 0 ), // {r32, m32|mem}
- ROW(2, 0, 1, 0, 8 , 30 , 0 , 0 , 0 , 0 ), // {r64, m64|mem}
- ROW(2, 1, 1, 0, 31 , 10 , 0 , 0 , 0 , 0 ), // #28 {r8lo|r8hi|m8|r16|m16|r32|m32|r64|m64|mem, i8|u8}
+ ROW(2, 1, 1, 0, 6 , 30 , 0 , 0 , 0 , 0 ), // {r32, m32|mem}
+ ROW(2, 0, 1, 0, 8 , 31 , 0 , 0 , 0 , 0 ), // {r64, m64|mem}
+ ROW(2, 1, 1, 0, 32 , 10 , 0 , 0 , 0 , 0 ), // #33 {r8lo|r8hi|m8|r16|m16|r32|m32, i8|u8}
ROW(2, 1, 1, 0, 11 , 12 , 0 , 0 , 0 , 0 ), // {r16|m16, i16|u16}
ROW(2, 1, 1, 0, 13 , 14 , 0 , 0 , 0 , 0 ), // {r32|m32, i32|u32}
- ROW(2, 0, 1, 0, 8 , 32 , 0 , 0 , 0 , 0 ), // {r64, u32|i32|r64|m64|mem}
- ROW(2, 0, 1, 0, 30 , 24 , 0 , 0 , 0 , 0 ), // {m64|mem, i32|r64}
+ ROW(2, 0, 1, 0, 8 , 33 , 0 , 0 , 0 , 0 ), // {r64, u32|i32|i8|u8|r64|m64|mem}
+ ROW(2, 0, 1, 0, 34 , 35 , 0 , 0 , 0 , 0 ), // {m64, i32|i8|u8}
ROW(2, 1, 1, 0, 1 , 2 , 0 , 0 , 0 , 0 ), // {r8lo|r8hi|m8|mem, r8lo|r8hi}
ROW(2, 1, 1, 0, 27 , 4 , 0 , 0 , 0 , 0 ), // {r16|m16|mem, r16}
ROW(2, 1, 1, 0, 28 , 6 , 0 , 0 , 0 , 0 ), // {r32|m32|mem, r32}
+ ROW(2, 0, 1, 0, 31 , 8 , 0 , 0 , 0 , 0 ), // {m64|mem, r64}
ROW(2, 1, 1, 0, 2 , 18 , 0 , 0 , 0 , 0 ), // {r8lo|r8hi, m8|mem}
ROW(2, 1, 1, 0, 4 , 21 , 0 , 0 , 0 , 0 ), // {r16, m16|mem}
- ROW(2, 1, 1, 0, 6 , 29 , 0 , 0 , 0 , 0 ), // {r32, m32|mem}
- ROW(2, 1, 1, 1, 33 , 1 , 0 , 0 , 0 , 0 ), // #39 {<ax>, r8lo|r8hi|m8|mem}
- ROW(3, 1, 1, 2, 34 , 33 , 27 , 0 , 0 , 0 ), // {<dx>, <ax>, r16|m16|mem}
- ROW(3, 1, 1, 2, 35 , 36 , 28 , 0 , 0 , 0 ), // {<edx>, <eax>, r32|m32|mem}
- ROW(3, 0, 1, 2, 37 , 38 , 15 , 0 , 0 , 0 ), // {<rdx>, <rax>, r64|m64|mem}
- ROW(2, 1, 1, 0, 4 , 39 , 0 , 0 , 0 , 0 ), // {r16, r16|m16|mem|i8|i16}
- ROW(2, 1, 1, 0, 6 , 40 , 0 , 0 , 0 , 0 ), // {r32, r32|m32|mem|i8|i32}
- ROW(2, 0, 1, 0, 8 , 41 , 0 , 0 , 0 , 0 ), // {r64, r64|m64|mem|i8|i32}
+ ROW(2, 1, 1, 0, 6 , 30 , 0 , 0 , 0 , 0 ), // {r32, m32|mem}
+ ROW(2, 1, 1, 1, 36 , 1 , 0 , 0 , 0 , 0 ), // #45 {<ax>, r8lo|r8hi|m8|mem}
+ ROW(3, 1, 1, 2, 37 , 36 , 27 , 0 , 0 , 0 ), // {<dx>, <ax>, r16|m16|mem}
+ ROW(3, 1, 1, 2, 38 , 39 , 28 , 0 , 0 , 0 ), // {<edx>, <eax>, r32|m32|mem}
+ ROW(3, 0, 1, 2, 40 , 41 , 29 , 0 , 0 , 0 ), // {<rdx>, <rax>, r64|m64|mem}
+ ROW(2, 1, 1, 0, 4 , 27 , 0 , 0 , 0 , 0 ), // #49 {r16, r16|m16|mem}
+ ROW(2, 1, 1, 0, 6 , 28 , 0 , 0 , 0 , 0 ), // #50 {r32, r32|m32|mem}
+ ROW(2, 0, 1, 0, 8 , 29 , 0 , 0 , 0 , 0 ), // {r64, r64|m64|mem}
ROW(3, 1, 1, 0, 4 , 27 , 42 , 0 , 0 , 0 ), // {r16, r16|m16|mem, i8|i16|u16}
ROW(3, 1, 1, 0, 6 , 28 , 43 , 0 , 0 , 0 ), // {r32, r32|m32|mem, i8|i32|u32}
- ROW(3, 0, 1, 0, 8 , 15 , 44 , 0 , 0 , 0 ), // {r64, r64|m64|mem, i8|i32}
- ROW(2, 0, 1, 0, 8 , 45 , 0 , 0 , 0 , 0 ), // #49 {r64, i64|u64}
- ROW(2, 0, 1, 0, 46 , 18 , 0 , 0 , 0 , 0 ), // {al, m8|mem}
- ROW(2, 0, 1, 0, 47 , 21 , 0 , 0 , 0 , 0 ), // {ax, m16|mem}
- ROW(2, 0, 1, 0, 48 , 29 , 0 , 0 , 0 , 0 ), // {eax, m32|mem}
- ROW(2, 0, 1, 0, 49 , 30 , 0 , 0 , 0 , 0 ), // {rax, m64|mem}
- ROW(2, 0, 1, 0, 18 , 46 , 0 , 0 , 0 , 0 ), // {m8|mem, al}
- ROW(2, 0, 1, 0, 21 , 47 , 0 , 0 , 0 , 0 ), // {m16|mem, ax}
- ROW(2, 0, 1, 0, 29 , 48 , 0 , 0 , 0 , 0 ), // {m32|mem, eax}
- ROW(2, 0, 1, 0, 30 , 49 , 0 , 0 , 0 , 0 ), // {m64|mem, rax}
- ROW(2, 1, 1, 0, 1 , 2 , 0 , 0 , 0 , 0 ), // #58 {r8lo|r8hi|m8|mem, r8lo|r8hi}
- ROW(2, 1, 1, 0, 27 , 4 , 0 , 0 , 0 , 0 ), // {r16|m16|mem, r16}
- ROW(2, 1, 1, 0, 28 , 6 , 0 , 0 , 0 , 0 ), // {r32|m32|mem, r32}
- ROW(2, 0, 1, 0, 15 , 8 , 0 , 0 , 0 , 0 ), // #61 {r64|m64|mem, r64}
- ROW(2, 1, 1, 0, 2 , 18 , 0 , 0 , 0 , 0 ), // {r8lo|r8hi, m8|mem}
- ROW(2, 1, 1, 0, 4 , 21 , 0 , 0 , 0 , 0 ), // {r16, m16|mem}
- ROW(2, 1, 1, 0, 6 , 29 , 0 , 0 , 0 , 0 ), // {r32, m32|mem}
- ROW(2, 0, 1, 0, 8 , 30 , 0 , 0 , 0 , 0 ), // {r64, m64|mem}
- ROW(2, 1, 1, 0, 9 , 10 , 0 , 0 , 0 , 0 ), // #66 {r8lo|r8hi|m8, i8|u8}
+ ROW(3, 0, 1, 0, 8 , 29 , 24 , 0 , 0 , 0 ), // {r64, r64|m64|mem, i8|i32}
+ ROW(2, 0, 1, 0, 8 , 44 , 0 , 0 , 0 , 0 ), // #55 {r64, i64|u64}
+ ROW(2, 1, 1, 0, 45 , 18 , 0 , 0 , 0 , 0 ), // {al, m8|mem}
+ ROW(2, 1, 1, 0, 46 , 21 , 0 , 0 , 0 , 0 ), // {ax, m16|mem}
+ ROW(2, 1, 1, 0, 47 , 30 , 0 , 0 , 0 , 0 ), // {eax, m32|mem}
+ ROW(2, 0, 1, 0, 48 , 31 , 0 , 0 , 0 , 0 ), // {rax, m64|mem}
+ ROW(2, 1, 1, 0, 18 , 45 , 0 , 0 , 0 , 0 ), // {m8|mem, al}
+ ROW(2, 1, 1, 0, 21 , 46 , 0 , 0 , 0 , 0 ), // {m16|mem, ax}
+ ROW(2, 1, 1, 0, 30 , 47 , 0 , 0 , 0 , 0 ), // {m32|mem, eax}
+ ROW(2, 0, 1, 0, 31 , 48 , 0 , 0 , 0 , 0 ), // {m64|mem, rax}
+ ROW(2, 1, 1, 0, 9 , 10 , 0 , 0 , 0 , 0 ), // #64 {r8lo|r8hi|m8, i8|u8}
ROW(2, 1, 1, 0, 11 , 12 , 0 , 0 , 0 , 0 ), // {r16|m16, i16|u16}
ROW(2, 1, 1, 0, 13 , 14 , 0 , 0 , 0 , 0 ), // {r32|m32, i32|u32}
- ROW(2, 0, 1, 0, 15 , 24 , 0 , 0 , 0 , 0 ), // {r64|m64|mem, i32|r64}
+ ROW(2, 0, 1, 0, 15 , 16 , 0 , 0 , 0 , 0 ), // {r64|m64, i32}
ROW(2, 1, 1, 0, 1 , 2 , 0 , 0 , 0 , 0 ), // {r8lo|r8hi|m8|mem, r8lo|r8hi}
ROW(2, 1, 1, 0, 27 , 4 , 0 , 0 , 0 , 0 ), // {r16|m16|mem, r16}
ROW(2, 1, 1, 0, 28 , 6 , 0 , 0 , 0 , 0 ), // {r32|m32|mem, r32}
- ROW(2, 1, 1, 0, 4 , 21 , 0 , 0 , 0 , 0 ), // #73 {r16, m16|mem}
- ROW(2, 1, 1, 0, 6 , 29 , 0 , 0 , 0 , 0 ), // {r32, m32|mem}
- ROW(2, 0, 1, 0, 8 , 30 , 0 , 0 , 0 , 0 ), // {r64, m64|mem}
+ ROW(2, 0, 1, 0, 29 , 8 , 0 , 0 , 0 , 0 ), // {r64|m64|mem, r64}
+ ROW(2, 1, 1, 0, 49 , 50 , 0 , 0 , 0 , 0 ), // #72 {xmm, xmm|m128|mem}
+ ROW(2, 1, 1, 0, 51 , 49 , 0 , 0 , 0 , 0 ), // #73 {m128|mem, xmm}
+ ROW(2, 1, 1, 0, 52 , 53 , 0 , 0 , 0 , 0 ), // {ymm, ymm|m256|mem}
+ ROW(2, 1, 1, 0, 54 , 52 , 0 , 0 , 0 , 0 ), // {m256|mem, ymm}
+ ROW(2, 1, 1, 0, 51 , 49 , 0 , 0 , 0 , 0 ), // {m128|mem, xmm}
+ ROW(2, 1, 1, 0, 54 , 52 , 0 , 0 , 0 , 0 ), // {m256|mem, ymm}
+ ROW(2, 1, 1, 0, 55 , 56 , 0 , 0 , 0 , 0 ), // #78 {zmm, zmm|m512|mem}
+ ROW(2, 1, 1, 0, 57 , 55 , 0 , 0 , 0 , 0 ), // {m512|mem, zmm}
+ ROW(2, 1, 1, 0, 31 , 49 , 0 , 0 , 0 , 0 ), // #80 {m64|mem, xmm}
+ ROW(2, 1, 1, 0, 49 , 31 , 0 , 0 , 0 , 0 ), // {xmm, m64|mem}
+ ROW(3, 1, 1, 0, 49 , 49 , 49 , 0 , 0 , 0 ), // #82 {xmm, xmm, xmm}
+ ROW(3, 1, 1, 0, 49 , 49 , 49 , 0 , 0 , 0 ), // {xmm, xmm, xmm}
+ ROW(2, 1, 1, 0, 31 , 49 , 0 , 0 , 0 , 0 ), // {m64|mem, xmm}
+ ROW(2, 1, 1, 0, 49 , 31 , 0 , 0 , 0 , 0 ), // {xmm, m64|mem}
+ ROW(3, 1, 1, 0, 49 , 49 , 49 , 0 , 0 , 0 ), // {xmm, xmm, xmm}
+ ROW(3, 1, 1, 0, 49 , 49 , 49 , 0 , 0 , 0 ), // {xmm, xmm, xmm}
+ ROW(2, 1, 1, 0, 30 , 49 , 0 , 0 , 0 , 0 ), // #88 {m32|mem, xmm}
+ ROW(2, 1, 1, 0, 49 , 30 , 0 , 0 , 0 , 0 ), // {xmm, m32|mem}
+ ROW(3, 1, 1, 0, 49 , 49 , 49 , 0 , 0 , 0 ), // {xmm, xmm, xmm}
+ ROW(3, 1, 1, 0, 49 , 49 , 49 , 0 , 0 , 0 ), // {xmm, xmm, xmm}
+ ROW(2, 1, 1, 0, 30 , 49 , 0 , 0 , 0 , 0 ), // {m32|mem, xmm}
+ ROW(2, 1, 1, 0, 49 , 30 , 0 , 0 , 0 , 0 ), // {xmm, m32|mem}
+ ROW(3, 1, 1, 0, 49 , 49 , 49 , 0 , 0 , 0 ), // {xmm, xmm, xmm}
+ ROW(3, 1, 1, 0, 49 , 49 , 49 , 0 , 0 , 0 ), // {xmm, xmm, xmm}
+ ROW(3, 1, 1, 0, 49 , 49 , 58 , 0 , 0 , 0 ), // #96 {xmm, xmm, xmm|m128|mem|i8|u8}
+ ROW(3, 1, 1, 0, 49 , 51 , 10 , 0 , 0 , 0 ), // {xmm, m128|mem, i8|u8}
+ ROW(3, 1, 1, 0, 52 , 52 , 59 , 0 , 0 , 0 ), // {ymm, ymm, ymm|m256|mem|i8|u8}
+ ROW(3, 1, 1, 0, 52 , 54 , 10 , 0 , 0 , 0 ), // {ymm, m256|mem, i8|u8}
+ ROW(3, 1, 1, 0, 55 , 55 , 60 , 0 , 0 , 0 ), // {zmm, zmm, zmm|m512|mem|i8|u8}
+ ROW(3, 1, 1, 0, 49 , 51 , 10 , 0 , 0 , 0 ), // {xmm, m128|mem, i8|u8}
+ ROW(3, 1, 1, 0, 52 , 54 , 10 , 0 , 0 , 0 ), // {ymm, m256|mem, i8|u8}
+ ROW(3, 1, 1, 0, 55 , 57 , 10 , 0 , 0 , 0 ), // {zmm, m512|mem, i8|u8}
+ ROW(2, 1, 1, 0, 4 , 21 , 0 , 0 , 0 , 0 ), // #104 {r16, m16|mem}
+ ROW(2, 1, 1, 0, 6 , 30 , 0 , 0 , 0 , 0 ), // {r32, m32|mem}
+ ROW(2, 0, 1, 0, 8 , 31 , 0 , 0 , 0 , 0 ), // {r64, m64|mem}
ROW(2, 1, 1, 0, 21 , 4 , 0 , 0 , 0 , 0 ), // {m16|mem, r16}
- ROW(2, 1, 1, 0, 29 , 6 , 0 , 0 , 0 , 0 ), // #77 {m32|mem, r32}
- ROW(2, 0, 1, 0, 30 , 8 , 0 , 0 , 0 , 0 ), // {m64|mem, r64}
- ROW(2, 1, 1, 0, 50 , 51 , 0 , 0 , 0 , 0 ), // #79 {xmm, xmm|m128|mem}
- ROW(2, 1, 1, 0, 52 , 50 , 0 , 0 , 0 , 0 ), // #80 {m128|mem, xmm}
- ROW(2, 1, 1, 0, 53 , 54 , 0 , 0 , 0 , 0 ), // {ymm, ymm|m256|mem}
- ROW(2, 1, 1, 0, 55 , 53 , 0 , 0 , 0 , 0 ), // {m256|mem, ymm}
- ROW(2, 1, 1, 0, 56 , 57 , 0 , 0 , 0 , 0 ), // #83 {zmm, zmm|m512|mem}
- ROW(2, 1, 1, 0, 58 , 56 , 0 , 0 , 0 , 0 ), // {m512|mem, zmm}
- ROW(3, 1, 1, 0, 50 , 50 , 59 , 0 , 0 , 0 ), // #85 {xmm, xmm, xmm|m128|mem|i8|u8}
- ROW(3, 1, 1, 0, 50 , 52 , 10 , 0 , 0 , 0 ), // {xmm, m128|mem, i8|u8}
- ROW(3, 1, 1, 0, 53 , 53 , 60 , 0 , 0 , 0 ), // {ymm, ymm, ymm|m256|mem|i8|u8}
- ROW(3, 1, 1, 0, 53 , 55 , 10 , 0 , 0 , 0 ), // {ymm, m256|mem, i8|u8}
- ROW(3, 1, 1, 0, 56 , 56 , 61 , 0 , 0 , 0 ), // {zmm, zmm, zmm|m512|mem|i8|u8}
- ROW(3, 1, 1, 0, 56 , 58 , 10 , 0 , 0 , 0 ), // {zmm, m512|mem, i8|u8}
- ROW(3, 1, 1, 0, 50 , 50 , 59 , 0 , 0 , 0 ), // #91 {xmm, xmm, i8|u8|xmm|m128|mem}
- ROW(3, 1, 1, 0, 53 , 53 , 59 , 0 , 0 , 0 ), // {ymm, ymm, i8|u8|xmm|m128|mem}
- ROW(3, 1, 1, 0, 50 , 52 , 10 , 0 , 0 , 0 ), // {xmm, m128|mem, i8|u8}
- ROW(3, 1, 1, 0, 53 , 55 , 10 , 0 , 0 , 0 ), // {ymm, m256|mem, i8|u8}
- ROW(3, 1, 1, 0, 56 , 56 , 59 , 0 , 0 , 0 ), // {zmm, zmm, xmm|m128|mem|i8|u8}
- ROW(3, 1, 1, 0, 56 , 58 , 10 , 0 , 0 , 0 ), // {zmm, m512|mem, i8|u8}
- ROW(3, 1, 1, 0, 50 , 50 , 59 , 0 , 0 , 0 ), // #97 {xmm, xmm, xmm|m128|mem|i8|u8}
- ROW(3, 1, 1, 0, 50 , 52 , 10 , 0 , 0 , 0 ), // {xmm, m128|mem, i8|u8}
- ROW(3, 1, 1, 0, 53 , 53 , 59 , 0 , 0 , 0 ), // {ymm, ymm, xmm|m128|mem|i8|u8}
- ROW(3, 1, 1, 0, 53 , 55 , 10 , 0 , 0 , 0 ), // {ymm, m256|mem, i8|u8}
- ROW(3, 1, 1, 0, 56 , 56 , 59 , 0 , 0 , 0 ), // {zmm, zmm, xmm|m128|mem|i8|u8}
- ROW(3, 1, 1, 0, 56 , 58 , 10 , 0 , 0 , 0 ), // {zmm, m512|mem, i8|u8}
- ROW(2, 1, 1, 0, 62 , 63 , 0 , 0 , 0 , 0 ), // #103 {mm, mm|m64|mem|r64}
- ROW(2, 1, 1, 0, 15 , 64 , 0 , 0 , 0 , 0 ), // {m64|mem|r64, mm|xmm}
- ROW(2, 0, 1, 0, 50 , 15 , 0 , 0 , 0 , 0 ), // {xmm, r64|m64|mem}
- ROW(2, 1, 1, 0, 50 , 65 , 0 , 0 , 0 , 0 ), // #106 {xmm, xmm|m64|mem}
- ROW(2, 1, 1, 0, 30 , 50 , 0 , 0 , 0 , 0 ), // #107 {m64|mem, xmm}
- ROW(0, 1, 1, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #108 {}
- ROW(1, 1, 1, 0, 66 , 0 , 0 , 0 , 0 , 0 ), // {r16|m16|r32|m32|r64|m64}
+ ROW(2, 1, 1, 0, 30 , 6 , 0 , 0 , 0 , 0 ), // #108 {m32|mem, r32}
+ ROW(2, 0, 1, 0, 31 , 8 , 0 , 0 , 0 , 0 ), // {m64|mem, r64}
+ ROW(0, 1, 1, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #110 {}
+ ROW(1, 1, 1, 0, 25 , 0 , 0 , 0 , 0 , 0 ), // {r16|m16|r32|m32}
+ ROW(1, 0, 1, 0, 15 , 0 , 0 , 0 , 0 , 0 ), // {r64|m64}
ROW(2, 1, 1, 0, 27 , 4 , 0 , 0 , 0 , 0 ), // {r16|m16|mem, r16}
ROW(2, 1, 1, 0, 28 , 6 , 0 , 0 , 0 , 0 ), // {r32|m32|mem, r32}
- ROW(2, 1, 1, 0, 15 , 8 , 0 , 0 , 0 , 0 ), // {r64|m64|mem, r64}
- ROW(3, 1, 1, 0, 50 , 67 , 50 , 0 , 0 , 0 ), // #113 {xmm, vm32x, xmm}
- ROW(3, 1, 1, 0, 53 , 68 , 53 , 0 , 0 , 0 ), // {ymm, vm32y, ymm}
- ROW(2, 1, 1, 0, 50 , 67 , 0 , 0 , 0 , 0 ), // {xmm, vm32x}
- ROW(2, 1, 1, 0, 53 , 68 , 0 , 0 , 0 , 0 ), // {ymm, vm32y}
- ROW(2, 1, 1, 0, 56 , 69 , 0 , 0 , 0 , 0 ), // {zmm, vm32z}
- ROW(3, 1, 1, 0, 50 , 70 , 50 , 0 , 0 , 0 ), // #118 {xmm, vm64x, xmm}
- ROW(3, 1, 1, 0, 53 , 71 , 53 , 0 , 0 , 0 ), // {ymm, vm64y, ymm}
- ROW(2, 1, 1, 0, 50 , 70 , 0 , 0 , 0 , 0 ), // {xmm, vm64x}
- ROW(2, 1, 1, 0, 53 , 71 , 0 , 0 , 0 , 0 ), // {ymm, vm64y}
- ROW(2, 1, 1, 0, 56 , 72 , 0 , 0 , 0 , 0 ), // {zmm, vm64z}
- ROW(2, 1, 1, 0, 25 , 10 , 0 , 0 , 0 , 0 ), // #123 {r16|m16|r32|m32|r64|m64|mem, i8|u8}
+ ROW(2, 0, 1, 0, 29 , 8 , 0 , 0 , 0 , 0 ), // {r64|m64|mem, r64}
+ ROW(2, 1, 1, 0, 49 , 50 , 0 , 0 , 0 , 0 ), // #116 {xmm, xmm|m128|mem}
+ ROW(2, 1, 1, 0, 51 , 49 , 0 , 0 , 0 , 0 ), // {m128|mem, xmm}
+ ROW(2, 1, 1, 0, 52 , 53 , 0 , 0 , 0 , 0 ), // {ymm, ymm|m256|mem}
+ ROW(2, 1, 1, 0, 54 , 52 , 0 , 0 , 0 , 0 ), // {m256|mem, ymm}
+ ROW(2, 1, 1, 0, 55 , 56 , 0 , 0 , 0 , 0 ), // {zmm, zmm|m512|mem}
+ ROW(2, 1, 1, 0, 57 , 55 , 0 , 0 , 0 , 0 ), // {m512|mem, zmm}
+ ROW(3, 1, 1, 0, 49 , 49 , 58 , 0 , 0 , 0 ), // #122 {xmm, xmm, i8|u8|xmm|m128|mem}
+ ROW(3, 1, 1, 0, 52 , 52 , 58 , 0 , 0 , 0 ), // {ymm, ymm, i8|u8|xmm|m128|mem}
+ ROW(3, 1, 1, 0, 49 , 51 , 10 , 0 , 0 , 0 ), // {xmm, m128|mem, i8|u8}
+ ROW(3, 1, 1, 0, 52 , 54 , 10 , 0 , 0 , 0 ), // {ymm, m256|mem, i8|u8}
+ ROW(3, 1, 1, 0, 55 , 55 , 58 , 0 , 0 , 0 ), // {zmm, zmm, xmm|m128|mem|i8|u8}
+ ROW(3, 1, 1, 0, 55 , 57 , 10 , 0 , 0 , 0 ), // {zmm, m512|mem, i8|u8}
+ ROW(3, 1, 1, 0, 49 , 49 , 58 , 0 , 0 , 0 ), // #128 {xmm, xmm, xmm|m128|mem|i8|u8}
+ ROW(3, 1, 1, 0, 49 , 51 , 10 , 0 , 0 , 0 ), // {xmm, m128|mem, i8|u8}
+ ROW(3, 1, 1, 0, 52 , 52 , 58 , 0 , 0 , 0 ), // {ymm, ymm, xmm|m128|mem|i8|u8}
+ ROW(3, 1, 1, 0, 52 , 54 , 10 , 0 , 0 , 0 ), // {ymm, m256|mem, i8|u8}
+ ROW(3, 1, 1, 0, 55 , 55 , 58 , 0 , 0 , 0 ), // {zmm, zmm, xmm|m128|mem|i8|u8}
+ ROW(3, 1, 1, 0, 55 , 57 , 10 , 0 , 0 , 0 ), // {zmm, m512|mem, i8|u8}
+ ROW(2, 1, 1, 0, 25 , 10 , 0 , 0 , 0 , 0 ), // #134 {r16|m16|r32|m32, i8|u8}
+ ROW(2, 0, 1, 0, 15 , 10 , 0 , 0 , 0 , 0 ), // {r64|m64, i8|u8}
ROW(2, 1, 1, 0, 27 , 4 , 0 , 0 , 0 , 0 ), // {r16|m16|mem, r16}
ROW(2, 1, 1, 0, 28 , 6 , 0 , 0 , 0 , 0 ), // {r32|m32|mem, r32}
- ROW(2, 0, 1, 0, 15 , 8 , 0 , 0 , 0 , 0 ), // {r64|m64|mem, r64}
- ROW(2, 1, 1, 2, 73 , 74 , 0 , 0 , 0 , 0 ), // #127 {<ds:[m8|memBase|zsi]>, <es:[m8|memBase|zdi]>}
- ROW(2, 1, 1, 2, 75 , 76 , 0 , 0 , 0 , 0 ), // {<ds:[m16|memBase|zsi]>, <es:[m16|memBase|zdi]>}
- ROW(2, 1, 1, 2, 77 , 78 , 0 , 0 , 0 , 0 ), // {<ds:[m32|memBase|zsi]>, <es:[m32|memBase|zdi]>}
- ROW(2, 0, 1, 2, 79 , 80 , 0 , 0 , 0 , 0 ), // {<ds:[m64|memBase|zsi]>, <es:[m64|memBase|zdi]>}
- ROW(3, 1, 1, 1, 1 , 2 , 81 , 0 , 0 , 0 ), // #131 {r8lo|r8hi|m8|mem, r8lo|r8hi, <al>}
- ROW(3, 1, 1, 1, 27 , 4 , 33 , 0 , 0 , 0 ), // {r16|m16|mem, r16, <ax>}
- ROW(3, 1, 1, 1, 28 , 6 , 36 , 0 , 0 , 0 ), // {r32|m32|mem, r32, <eax>}
- ROW(3, 0, 1, 1, 15 , 8 , 38 , 0 , 0 , 0 ), // {r64|m64|mem, r64, <rax>}
- ROW(2, 1, 1, 2, 81 , 82 , 0 , 0 , 0 , 0 ), // #135 {<al>, <ds:[m8|memBase|zsi|mem]>}
- ROW(2, 1, 1, 2, 33 , 83 , 0 , 0 , 0 , 0 ), // {<ax>, <ds:[m16|memBase|zsi|mem]>}
- ROW(2, 1, 1, 2, 36 , 84 , 0 , 0 , 0 , 0 ), // {<eax>, <ds:[m32|memBase|zsi|mem]>}
- ROW(2, 0, 1, 2, 38 , 85 , 0 , 0 , 0 , 0 ), // {<rax>, <ds:[m64|memBase|zsi|mem]>}
- ROW(2, 1, 1, 2, 74 , 73 , 0 , 0 , 0 , 0 ), // #139 {<es:[m8|memBase|zdi]>, <ds:[m8|memBase|zsi]>}
- ROW(2, 1, 1, 2, 76 , 75 , 0 , 0 , 0 , 0 ), // {<es:[m16|memBase|zdi]>, <ds:[m16|memBase|zsi]>}
- ROW(2, 1, 1, 2, 78 , 77 , 0 , 0 , 0 , 0 ), // {<es:[m32|memBase|zdi]>, <ds:[m32|memBase|zsi]>}
- ROW(2, 0, 1, 2, 80 , 79 , 0 , 0 , 0 , 0 ), // {<es:[m64|memBase|zdi]>, <ds:[m64|memBase|zsi]>}
- ROW(1, 1, 1, 0, 86 , 0 , 0 , 0 , 0 , 0 ), // #143 {r16|m16|r64|m64}
+ ROW(2, 0, 1, 0, 29 , 8 , 0 , 0 , 0 , 0 ), // {r64|m64|mem, r64}
+ ROW(2, 1, 1, 0, 61 , 62 , 0 , 0 , 0 , 0 ), // #139 {mm, mm|m64|mem}
+ ROW(2, 0, 1, 0, 63 , 29 , 0 , 0 , 0 , 0 ), // {mm|xmm, r64|m64|mem}
+ ROW(2, 1, 1, 0, 31 , 63 , 0 , 0 , 0 , 0 ), // {m64|mem, mm|xmm}
+ ROW(2, 0, 1, 0, 29 , 63 , 0 , 0 , 0 , 0 ), // {r64|m64|mem, mm|xmm}
+ ROW(2, 1, 1, 0, 49 , 64 , 0 , 0 , 0 , 0 ), // #143 {xmm, xmm|m64|mem}
+ ROW(1, 1, 1, 0, 11 , 0 , 0 , 0 , 0 , 0 ), // #144 {r16|m16}
ROW(1, 1, 0, 0, 13 , 0 , 0 , 0 , 0 , 0 ), // {r32|m32}
- ROW(1, 1, 0, 0, 87 , 0 , 0 , 0 , 0 , 0 ), // {ds|es|ss}
- ROW(1, 1, 1, 0, 88 , 0 , 0 , 0 , 0 , 0 ), // {fs|gs}
- ROW(1, 1, 1, 0, 89 , 0 , 0 , 0 , 0 , 0 ), // #147 {r16|m16|r64|m64|i8|i16|i32}
- ROW(1, 1, 0, 0, 90 , 0 , 0 , 0 , 0 , 0 ), // {r32|m32|i32|u32}
- ROW(1, 1, 0, 0, 91 , 0 , 0 , 0 , 0 , 0 ), // {cs|ss|ds|es}
- ROW(1, 1, 1, 0, 88 , 0 , 0 , 0 , 0 , 0 ), // {fs|gs}
- ROW(2, 1, 1, 2, 81 , 92 , 0 , 0 , 0 , 0 ), // #151 {<al>, <es:[m8|memBase|zdi|mem]>}
- ROW(2, 1, 1, 2, 33 , 93 , 0 , 0 , 0 , 0 ), // {<ax>, <es:[m16|memBase|zdi|mem]>}
- ROW(2, 1, 1, 2, 36 , 94 , 0 , 0 , 0 , 0 ), // {<eax>, <es:[m32|memBase|zdi|mem]>}
- ROW(2, 0, 1, 2, 38 , 95 , 0 , 0 , 0 , 0 ), // {<rax>, <es:[m64|memBase|zdi|mem]>}
- ROW(2, 1, 1, 2, 92 , 81 , 0 , 0 , 0 , 0 ), // #155 {<es:[m8|memBase|zdi|mem]>, <al>}
- ROW(2, 1, 1, 2, 93 , 33 , 0 , 0 , 0 , 0 ), // {<es:[m16|memBase|zdi|mem]>, <ax>}
- ROW(2, 1, 1, 2, 94 , 36 , 0 , 0 , 0 , 0 ), // {<es:[m32|memBase|zdi|mem]>, <eax>}
- ROW(2, 0, 1, 2, 95 , 38 , 0 , 0 , 0 , 0 ), // {<es:[m64|memBase|zdi|mem]>, <rax>}
- ROW(4, 1, 1, 0, 50 , 50 , 50 , 51 , 0 , 0 ), // #159 {xmm, xmm, xmm, xmm|m128|mem}
- ROW(4, 1, 1, 0, 50 , 50 , 52 , 50 , 0 , 0 ), // {xmm, xmm, m128|mem, xmm}
- ROW(4, 1, 1, 0, 53 , 53 , 53 , 54 , 0 , 0 ), // {ymm, ymm, ymm, ymm|m256|mem}
- ROW(4, 1, 1, 0, 53 , 53 , 55 , 53 , 0 , 0 ), // {ymm, ymm, m256|mem, ymm}
- ROW(3, 1, 1, 0, 50 , 67 , 50 , 0 , 0 , 0 ), // #163 {xmm, vm32x, xmm}
- ROW(3, 1, 1, 0, 53 , 67 , 53 , 0 , 0 , 0 ), // {ymm, vm32x, ymm}
- ROW(2, 1, 1, 0, 96 , 67 , 0 , 0 , 0 , 0 ), // {xmm|ymm, vm32x}
- ROW(2, 1, 1, 0, 56 , 68 , 0 , 0 , 0 , 0 ), // {zmm, vm32y}
- ROW(3, 1, 1, 0, 52 , 50 , 50 , 0 , 0 , 0 ), // #167 {m128|mem, xmm, xmm}
- ROW(3, 1, 1, 0, 55 , 53 , 53 , 0 , 0 , 0 ), // {m256|mem, ymm, ymm}
- ROW(3, 1, 1, 0, 50 , 50 , 52 , 0 , 0 , 0 ), // {xmm, xmm, m128|mem}
- ROW(3, 1, 1, 0, 53 , 53 , 55 , 0 , 0 , 0 ), // {ymm, ymm, m256|mem}
- ROW(5, 1, 1, 0, 50 , 50 , 51 , 50 , 97 , 0 ), // #171 {xmm, xmm, xmm|m128|mem, xmm, i4|u4}
- ROW(5, 1, 1, 0, 50 , 50 , 50 , 52 , 97 , 0 ), // {xmm, xmm, xmm, m128|mem, i4|u4}
- ROW(5, 1, 1, 0, 53 , 53 , 54 , 53 , 97 , 0 ), // {ymm, ymm, ymm|m256|mem, ymm, i4|u4}
- ROW(5, 1, 1, 0, 53 , 53 , 53 , 55 , 97 , 0 ), // {ymm, ymm, ymm, m256|mem, i4|u4}
- ROW(3, 1, 1, 0, 53 , 54 , 10 , 0 , 0 , 0 ), // #175 {ymm, ymm|m256|mem, i8|u8}
- ROW(3, 1, 1, 0, 53 , 53 , 54 , 0 , 0 , 0 ), // {ymm, ymm, ymm|m256|mem}
- ROW(3, 1, 1, 0, 56 , 56 , 61 , 0 , 0 , 0 ), // {zmm, zmm, zmm|m512|mem|i8|u8}
- ROW(3, 1, 1, 0, 56 , 58 , 10 , 0 , 0 , 0 ), // {zmm, m512|mem, i8|u8}
- ROW(2, 1, 1, 0, 4 , 27 , 0 , 0 , 0 , 0 ), // #179 {r16, r16|m16|mem}
- ROW(2, 1, 1, 0, 6 , 28 , 0 , 0 , 0 , 0 ), // #180 {r32, r32|m32|mem}
- ROW(2, 0, 1, 0, 8 , 15 , 0 , 0 , 0 , 0 ), // {r64, r64|m64|mem}
- ROW(1, 1, 1, 0, 98 , 0 , 0 , 0 , 0 , 0 ), // #182 {m32|m64}
- ROW(2, 1, 1, 0, 99 , 100, 0 , 0 , 0 , 0 ), // {st0, st}
- ROW(2, 1, 1, 0, 100, 99 , 0 , 0 , 0 , 0 ), // {st, st0}
- ROW(2, 1, 1, 0, 4 , 29 , 0 , 0 , 0 , 0 ), // #185 {r16, m32|mem}
- ROW(2, 1, 1, 0, 6 , 101, 0 , 0 , 0 , 0 ), // {r32, m48|mem}
- ROW(2, 0, 1, 0, 8 , 102, 0 , 0 , 0 , 0 ), // {r64, m80|mem}
- ROW(3, 1, 1, 0, 27 , 4 , 103, 0 , 0 , 0 ), // #188 {r16|m16|mem, r16, cl|i8|u8}
- ROW(3, 1, 1, 0, 28 , 6 , 103, 0 , 0 , 0 ), // {r32|m32|mem, r32, cl|i8|u8}
- ROW(3, 0, 1, 0, 15 , 8 , 103, 0 , 0 , 0 ), // {r64|m64|mem, r64, cl|i8|u8}
- ROW(3, 1, 1, 0, 50 , 50 , 51 , 0 , 0 , 0 ), // #191 {xmm, xmm, xmm|m128|mem}
- ROW(3, 1, 1, 0, 53 , 53 , 54 , 0 , 0 , 0 ), // #192 {ymm, ymm, ymm|m256|mem}
- ROW(3, 1, 1, 0, 56 , 56 , 57 , 0 , 0 , 0 ), // {zmm, zmm, zmm|m512|mem}
- ROW(4, 1, 1, 0, 50 , 50 , 51 , 10 , 0 , 0 ), // #194 {xmm, xmm, xmm|m128|mem, i8|u8}
- ROW(4, 1, 1, 0, 53 , 53 , 54 , 10 , 0 , 0 ), // #195 {ymm, ymm, ymm|m256|mem, i8|u8}
- ROW(4, 1, 1, 0, 56 , 56 , 57 , 10 , 0 , 0 ), // {zmm, zmm, zmm|m512|mem, i8|u8}
- 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(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 ), // #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 ), // #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(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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 , 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(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, 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 ), // #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 ), // #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 , 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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 , 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 ), // #331 {r16, r8lo|r8hi|m8}
- ROW(2, 1, 1, 0, 139, 140, 0 , 0 , 0 , 0 ), // {r32|r64, r8lo|r8hi|m8|r16|m16}
- 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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 ), // #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 , 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 ), // #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 ), // #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 ), // #367 {m64|mem, xmm}
- ROW(3, 1, 1, 0, 50 , 50 , 30 , 0 , 0 , 0 ), // {xmm, xmm, m64|mem}
- 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 ), // #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 ), // #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 ), // #377 {vm32x, xmm|ymm}
- ROW(2, 1, 1, 0, 68 , 56 , 0 , 0 , 0 , 0 ), // {vm32y, zmm}
- 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 ), // #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 ), // #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>}
+ ROW(1, 0, 1, 0, 15 , 0 , 0 , 0 , 0 , 0 ), // {r64|m64}
+ ROW(1, 1, 0, 0, 65 , 0 , 0 , 0 , 0 , 0 ), // {ds|es|ss}
+ ROW(1, 1, 1, 0, 66 , 0 , 0 , 0 , 0 , 0 ), // {fs|gs}
+ ROW(1, 1, 1, 0, 67 , 0 , 0 , 0 , 0 , 0 ), // #149 {r16|m16|i8|i16}
+ ROW(1, 1, 0, 0, 68 , 0 , 0 , 0 , 0 , 0 ), // {r32|m32|i32|u32}
+ ROW(1, 0, 1, 0, 69 , 0 , 0 , 0 , 0 , 0 ), // {r64|m64|i32}
+ ROW(1, 1, 0, 0, 70 , 0 , 0 , 0 , 0 , 0 ), // {cs|ss|ds|es}
+ ROW(1, 1, 1, 0, 66 , 0 , 0 , 0 , 0 , 0 ), // {fs|gs}
+ ROW(3, 1, 1, 0, 49 , 71 , 49 , 0 , 0 , 0 ), // #154 {xmm, vm32x, xmm}
+ ROW(3, 1, 1, 0, 52 , 72 , 52 , 0 , 0 , 0 ), // {ymm, vm32y, ymm}
+ ROW(2, 1, 1, 0, 49 , 71 , 0 , 0 , 0 , 0 ), // {xmm, vm32x}
+ ROW(2, 1, 1, 0, 52 , 72 , 0 , 0 , 0 , 0 ), // {ymm, vm32y}
+ ROW(2, 1, 1, 0, 55 , 73 , 0 , 0 , 0 , 0 ), // {zmm, vm32z}
+ ROW(3, 1, 1, 0, 49 , 74 , 49 , 0 , 0 , 0 ), // #159 {xmm, vm64x, xmm}
+ ROW(3, 1, 1, 0, 52 , 75 , 52 , 0 , 0 , 0 ), // {ymm, vm64y, ymm}
+ ROW(2, 1, 1, 0, 49 , 74 , 0 , 0 , 0 , 0 ), // {xmm, vm64x}
+ ROW(2, 1, 1, 0, 52 , 75 , 0 , 0 , 0 , 0 ), // {ymm, vm64y}
+ ROW(2, 1, 1, 0, 55 , 76 , 0 , 0 , 0 , 0 ), // {zmm, vm64z}
+ ROW(2, 1, 1, 0, 51 , 49 , 0 , 0 , 0 , 0 ), // #164 {m128|mem, xmm}
+ ROW(2, 1, 1, 0, 54 , 52 , 0 , 0 , 0 , 0 ), // {m256|mem, ymm}
+ ROW(2, 1, 1, 0, 51 , 49 , 0 , 0 , 0 , 0 ), // {m128|mem, xmm}
+ ROW(2, 1, 1, 0, 54 , 52 , 0 , 0 , 0 , 0 ), // {m256|mem, ymm}
+ ROW(2, 1, 1, 0, 57 , 55 , 0 , 0 , 0 , 0 ), // {m512|mem, zmm}
+ ROW(2, 1, 1, 0, 49 , 51 , 0 , 0 , 0 , 0 ), // #169 {xmm, m128|mem}
+ ROW(2, 1, 1, 0, 52 , 54 , 0 , 0 , 0 , 0 ), // {ymm, m256|mem}
+ ROW(2, 1, 1, 0, 49 , 51 , 0 , 0 , 0 , 0 ), // {xmm, m128|mem}
+ ROW(2, 1, 1, 0, 52 , 54 , 0 , 0 , 0 , 0 ), // {ymm, m256|mem}
+ ROW(2, 1, 1, 0, 55 , 57 , 0 , 0 , 0 , 0 ), // {zmm, m512|mem}
+ ROW(2, 0, 1, 0, 29 , 49 , 0 , 0 , 0 , 0 ), // #174 {r64|m64|mem, xmm}
+ ROW(2, 1, 1, 0, 49 , 64 , 0 , 0 , 0 , 0 ), // {xmm, xmm|m64|mem}
+ ROW(2, 0, 1, 0, 49 , 29 , 0 , 0 , 0 , 0 ), // {xmm, r64|m64|mem}
+ ROW(2, 1, 1, 0, 31 , 49 , 0 , 0 , 0 , 0 ), // {m64|mem, xmm}
+ ROW(2, 1, 1, 0, 31 , 49 , 0 , 0 , 0 , 0 ), // {m64|mem, xmm}
+ ROW(2, 1, 1, 0, 77 , 78 , 0 , 0 , 0 , 0 ), // #179 {ds:[memBase|zsi|m8], es:[memBase|zdi|m8]}
+ ROW(2, 1, 1, 0, 79 , 80 , 0 , 0 , 0 , 0 ), // {ds:[memBase|zsi|m16], es:[memBase|zdi|m16]}
+ ROW(2, 1, 1, 0, 81 , 82 , 0 , 0 , 0 , 0 ), // {ds:[memBase|zsi|m32], es:[memBase|zdi|m32]}
+ ROW(2, 0, 1, 0, 83 , 84 , 0 , 0 , 0 , 0 ), // {ds:[memBase|zsi|m64], es:[memBase|zdi|m64]}
+ ROW(3, 1, 1, 1, 1 , 2 , 85 , 0 , 0 , 0 ), // #183 {r8lo|r8hi|m8|mem, r8lo|r8hi, <al>}
+ ROW(3, 1, 1, 1, 27 , 4 , 36 , 0 , 0 , 0 ), // {r16|m16|mem, r16, <ax>}
+ ROW(3, 1, 1, 1, 28 , 6 , 39 , 0 , 0 , 0 ), // {r32|m32|mem, r32, <eax>}
+ ROW(3, 0, 1, 1, 29 , 8 , 41 , 0 , 0 , 0 ), // {r64|m64|mem, r64, <rax>}
+ ROW(2, 1, 1, 0, 86 , 87 , 0 , 0 , 0 , 0 ), // #187 {k, k|m64|mem}
+ ROW(2, 0, 1, 0, 86 , 8 , 0 , 0 , 0 , 0 ), // {k, r64}
+ ROW(2, 1, 1, 0, 31 , 86 , 0 , 0 , 0 , 0 ), // {m64|mem, k}
+ ROW(2, 0, 1, 0, 8 , 86 , 0 , 0 , 0 , 0 ), // {r64, k}
+ ROW(2, 1, 1, 0, 45 , 88 , 0 , 0 , 0 , 0 ), // #191 {al, ds:[memBase|zsi|m8|mem]}
+ ROW(2, 1, 1, 0, 46 , 89 , 0 , 0 , 0 , 0 ), // {ax, ds:[memBase|zsi|m16|mem]}
+ ROW(2, 1, 1, 0, 47 , 90 , 0 , 0 , 0 , 0 ), // {eax, ds:[memBase|zsi|m32|mem]}
+ ROW(2, 0, 1, 0, 48 , 91 , 0 , 0 , 0 , 0 ), // {rax, ds:[memBase|zsi|m64|mem]}
+ ROW(2, 1, 1, 0, 78 , 77 , 0 , 0 , 0 , 0 ), // #195 {es:[memBase|zdi|m8], ds:[memBase|zsi|m8]}
+ ROW(2, 1, 1, 0, 80 , 79 , 0 , 0 , 0 , 0 ), // {es:[memBase|zdi|m16], ds:[memBase|zsi|m16]}
+ ROW(2, 1, 1, 0, 82 , 81 , 0 , 0 , 0 , 0 ), // {es:[memBase|zdi|m32], ds:[memBase|zsi|m32]}
+ ROW(2, 0, 1, 0, 84 , 83 , 0 , 0 , 0 , 0 ), // {es:[memBase|zdi|m64], ds:[memBase|zsi|m64]}
+ ROW(2, 1, 1, 0, 45 , 92 , 0 , 0 , 0 , 0 ), // #199 {al, es:[memBase|zdi|m8|mem]}
+ ROW(2, 1, 1, 0, 46 , 93 , 0 , 0 , 0 , 0 ), // {ax, es:[memBase|zdi|m16|mem]}
+ ROW(2, 1, 1, 0, 47 , 94 , 0 , 0 , 0 , 0 ), // {eax, es:[memBase|zdi|m32|mem]}
+ ROW(2, 0, 1, 0, 48 , 95 , 0 , 0 , 0 , 0 ), // {rax, es:[memBase|zdi|m64|mem]}
+ ROW(2, 1, 1, 0, 92 , 45 , 0 , 0 , 0 , 0 ), // #203 {es:[memBase|zdi|m8|mem], al}
+ ROW(2, 1, 1, 0, 93 , 46 , 0 , 0 , 0 , 0 ), // {es:[memBase|zdi|m16|mem], ax}
+ ROW(2, 1, 1, 0, 94 , 47 , 0 , 0 , 0 , 0 ), // {es:[memBase|zdi|m32|mem], eax}
+ ROW(2, 0, 1, 0, 95 , 48 , 0 , 0 , 0 , 0 ), // {es:[memBase|zdi|m64|mem], rax}
+ ROW(4, 1, 1, 0, 49 , 49 , 49 , 50 , 0 , 0 ), // #207 {xmm, xmm, xmm, xmm|m128|mem}
+ ROW(4, 1, 1, 0, 49 , 49 , 51 , 49 , 0 , 0 ), // {xmm, xmm, m128|mem, xmm}
+ ROW(4, 1, 1, 0, 52 , 52 , 52 , 53 , 0 , 0 ), // {ymm, ymm, ymm, ymm|m256|mem}
+ ROW(4, 1, 1, 0, 52 , 52 , 54 , 52 , 0 , 0 ), // {ymm, ymm, m256|mem, ymm}
+ ROW(3, 1, 1, 0, 49 , 71 , 49 , 0 , 0 , 0 ), // #211 {xmm, vm32x, xmm}
+ ROW(3, 1, 1, 0, 52 , 71 , 52 , 0 , 0 , 0 ), // {ymm, vm32x, ymm}
+ ROW(2, 1, 1, 0, 96 , 71 , 0 , 0 , 0 , 0 ), // {xmm|ymm, vm32x}
+ ROW(2, 1, 1, 0, 55 , 72 , 0 , 0 , 0 , 0 ), // {zmm, vm32y}
+ ROW(3, 1, 1, 0, 51 , 49 , 49 , 0 , 0 , 0 ), // #215 {m128|mem, xmm, xmm}
+ ROW(3, 1, 1, 0, 54 , 52 , 52 , 0 , 0 , 0 ), // {m256|mem, ymm, ymm}
+ ROW(3, 1, 1, 0, 49 , 49 , 51 , 0 , 0 , 0 ), // {xmm, xmm, m128|mem}
+ ROW(3, 1, 1, 0, 52 , 52 , 54 , 0 , 0 , 0 ), // {ymm, ymm, m256|mem}
+ ROW(2, 1, 1, 0, 31 , 49 , 0 , 0 , 0 , 0 ), // #219 {m64|mem, xmm}
+ ROW(3, 1, 1, 0, 49 , 49 , 31 , 0 , 0 , 0 ), // {xmm, xmm, m64|mem}
+ ROW(2, 1, 1, 0, 31 , 49 , 0 , 0 , 0 , 0 ), // {m64|mem, xmm}
+ ROW(3, 1, 1, 0, 49 , 49 , 31 , 0 , 0 , 0 ), // {xmm, xmm, m64|mem}
+ ROW(2, 1, 1, 0, 21 , 49 , 0 , 0 , 0 , 0 ), // #223 {m16|mem, xmm}
+ ROW(2, 1, 1, 0, 49 , 21 , 0 , 0 , 0 , 0 ), // {xmm, m16|mem}
+ ROW(3, 1, 1, 0, 49 , 49 , 49 , 0 , 0 , 0 ), // {xmm, xmm, xmm}
+ ROW(3, 1, 1, 0, 49 , 49 , 49 , 0 , 0 , 0 ), // {xmm, xmm, xmm}
+ ROW(5, 1, 1, 0, 49 , 49 , 50 , 49 , 97 , 0 ), // #227 {xmm, xmm, xmm|m128|mem, xmm, i4|u4}
+ ROW(5, 1, 1, 0, 49 , 49 , 49 , 51 , 97 , 0 ), // {xmm, xmm, xmm, m128|mem, i4|u4}
+ ROW(5, 1, 1, 0, 52 , 52 , 53 , 52 , 97 , 0 ), // {ymm, ymm, ymm|m256|mem, ymm, i4|u4}
+ ROW(5, 1, 1, 0, 52 , 52 , 52 , 54 , 97 , 0 ), // {ymm, ymm, ymm, m256|mem, i4|u4}
+ ROW(3, 1, 1, 0, 52 , 53 , 10 , 0 , 0 , 0 ), // #231 {ymm, ymm|m256|mem, i8|u8}
+ ROW(3, 1, 1, 0, 52 , 52 , 53 , 0 , 0 , 0 ), // {ymm, ymm, ymm|m256|mem}
+ ROW(3, 1, 1, 0, 55 , 55 , 60 , 0 , 0 , 0 ), // {zmm, zmm, zmm|m512|mem|i8|u8}
+ ROW(3, 1, 1, 0, 55 , 57 , 10 , 0 , 0 , 0 ), // {zmm, m512|mem, i8|u8}
+ ROW(1, 1, 0, 0, 98 , 0 , 0 , 0 , 0 , 0 ), // #235 {rel16|r16|m16|mem|r32|m32}
+ ROW(1, 1, 1, 0, 99 , 0 , 0 , 0 , 0 , 0 ), // #236 {rel32}
+ ROW(1, 0, 1, 0, 29 , 0 , 0 , 0 , 0 , 0 ), // {r64|m64|mem}
+ ROW(1, 1, 0, 0, 100, 0 , 0 , 0 , 0 , 0 ), // #238 {r16|r32}
+ ROW(1, 1, 1, 0, 32 , 0 , 0 , 0 , 0 , 0 ), // #239 {r8lo|r8hi|m8|r16|m16|r32|m32}
+ ROW(1, 0, 1, 0, 15 , 0 , 0 , 0 , 0 , 0 ), // {r64|m64}
+ ROW(1, 1, 1, 0, 101, 0 , 0 , 0 , 0 , 0 ), // #241 {m32|m64}
+ ROW(2, 1, 1, 0, 102, 103, 0 , 0 , 0 , 0 ), // {st0, st}
+ ROW(2, 1, 1, 0, 103, 102, 0 , 0 , 0 , 0 ), // {st, st0}
+ ROW(1, 1, 1, 0, 104, 0 , 0 , 0 , 0 , 0 ), // #244 {rel8|rel32}
+ ROW(1, 1, 0, 0, 105, 0 , 0 , 0 , 0 , 0 ), // {rel16|r32|m32}
+ ROW(1, 0, 1, 0, 15 , 0 , 0 , 0 , 0 , 0 ), // {r64|m64}
+ ROW(2, 1, 0, 0, 106, 107, 0 , 0 , 0 , 0 ), // #247 {i16, i16|i32}
+ ROW(1, 1, 1, 0, 108, 0 , 0 , 0 , 0 , 0 ), // {m32|mem|m48}
+ ROW(1, 0, 1, 0, 109, 0 , 0 , 0 , 0 , 0 ), // {m80|mem}
+ ROW(2, 1, 1, 0, 4 , 30 , 0 , 0 , 0 , 0 ), // #250 {r16, m32|mem}
+ ROW(2, 1, 1, 0, 6 , 110, 0 , 0 , 0 , 0 ), // {r32, m48|mem}
+ ROW(2, 0, 1, 0, 8 , 109, 0 , 0 , 0 , 0 ), // {r64, m80|mem}
+ ROW(2, 1, 1, 0, 4 , 27 , 0 , 0 , 0 , 0 ), // #253 {r16, r16|m16|mem}
+ ROW(2, 1, 1, 0, 6 , 111, 0 , 0 , 0 , 0 ), // {r32, r32|m16|mem}
+ ROW(2, 0, 1, 0, 8 , 111, 0 , 0 , 0 , 0 ), // {r64, r32|m16|mem}
+ ROW(2, 1, 1, 0, 4 , 9 , 0 , 0 , 0 , 0 ), // #256 {r16, r8lo|r8hi|m8}
+ ROW(2, 1, 1, 0, 6 , 112, 0 , 0 , 0 , 0 ), // {r32, r8lo|r8hi|m8|r16|m16}
+ ROW(2, 0, 1, 0, 8 , 113, 0 , 0 , 0 , 0 ), // {r64, r8lo|m8|r16|m16}
+ ROW(3, 1, 1, 0, 27 , 4 , 114, 0 , 0 , 0 ), // #259 {r16|m16|mem, r16, cl|i8|u8}
+ ROW(3, 1, 1, 0, 28 , 6 , 114, 0 , 0 , 0 ), // {r32|m32|mem, r32, cl|i8|u8}
+ ROW(3, 0, 1, 0, 29 , 8 , 114, 0 , 0 , 0 ), // {r64|m64|mem, r64, cl|i8|u8}
+ ROW(3, 1, 1, 0, 49 , 49 , 50 , 0 , 0 , 0 ), // #262 {xmm, xmm, xmm|m128|mem}
+ ROW(3, 1, 1, 0, 52 , 52 , 53 , 0 , 0 , 0 ), // #263 {ymm, ymm, ymm|m256|mem}
+ ROW(3, 1, 1, 0, 55 , 55 , 56 , 0 , 0 , 0 ), // {zmm, zmm, zmm|m512|mem}
+ ROW(4, 1, 1, 0, 49 , 49 , 50 , 10 , 0 , 0 ), // #265 {xmm, xmm, xmm|m128|mem, i8|u8}
+ ROW(4, 1, 1, 0, 52 , 52 , 53 , 10 , 0 , 0 ), // #266 {ymm, ymm, ymm|m256|mem, i8|u8}
+ ROW(4, 1, 1, 0, 55 , 55 , 56 , 10 , 0 , 0 ), // {zmm, zmm, zmm|m512|mem, i8|u8}
+ ROW(4, 1, 1, 0, 115, 49 , 50 , 10 , 0 , 0 ), // #268 {xmm|k, xmm, xmm|m128|mem, i8|u8}
+ ROW(4, 1, 1, 0, 116, 52 , 53 , 10 , 0 , 0 ), // {ymm|k, ymm, ymm|m256|mem, i8|u8}
+ ROW(4, 1, 1, 0, 86 , 55 , 56 , 10 , 0 , 0 ), // {k, zmm, zmm|m512|mem, i8|u8}
+ ROW(4, 1, 1, 0, 86 , 49 , 50 , 10 , 0 , 0 ), // #271 {k, xmm, xmm|m128|mem, i8|u8}
+ ROW(4, 1, 1, 0, 86 , 52 , 53 , 10 , 0 , 0 ), // {k, ymm, ymm|m256|mem, i8|u8}
+ ROW(4, 1, 1, 0, 86 , 55 , 56 , 10 , 0 , 0 ), // {k, zmm, zmm|m512|mem, i8|u8}
+ ROW(2, 1, 1, 0, 50 , 49 , 0 , 0 , 0 , 0 ), // #274 {xmm|m128|mem, xmm}
+ ROW(2, 1, 1, 0, 53 , 52 , 0 , 0 , 0 , 0 ), // {ymm|m256|mem, ymm}
+ ROW(2, 1, 1, 0, 56 , 55 , 0 , 0 , 0 , 0 ), // {zmm|m512|mem, zmm}
+ ROW(2, 1, 1, 0, 49 , 64 , 0 , 0 , 0 , 0 ), // #277 {xmm, xmm|m64|mem}
+ ROW(2, 1, 1, 0, 52 , 50 , 0 , 0 , 0 , 0 ), // {ymm, xmm|m128|mem}
+ ROW(2, 1, 1, 0, 55 , 53 , 0 , 0 , 0 , 0 ), // {zmm, ymm|m256|mem}
+ ROW(2, 1, 1, 0, 49 , 50 , 0 , 0 , 0 , 0 ), // #280 {xmm, xmm|m128|mem}
+ ROW(2, 1, 1, 0, 52 , 53 , 0 , 0 , 0 , 0 ), // {ymm, ymm|m256|mem}
+ ROW(2, 1, 1, 0, 55 , 56 , 0 , 0 , 0 , 0 ), // {zmm, zmm|m512|mem}
+ ROW(2, 1, 1, 0, 49 , 117, 0 , 0 , 0 , 0 ), // #283 {xmm, xmm|m32|mem}
+ ROW(2, 1, 1, 0, 52 , 64 , 0 , 0 , 0 , 0 ), // {ymm, xmm|m64|mem}
+ ROW(2, 1, 1, 0, 55 , 50 , 0 , 0 , 0 , 0 ), // {zmm, xmm|m128|mem}
+ ROW(3, 1, 1, 0, 64 , 49 , 10 , 0 , 0 , 0 ), // #286 {xmm|m64|mem, xmm, i8|u8}
+ ROW(3, 1, 1, 0, 50 , 52 , 10 , 0 , 0 , 0 ), // #287 {xmm|m128|mem, ymm, i8|u8}
+ ROW(3, 1, 1, 0, 53 , 55 , 10 , 0 , 0 , 0 ), // #288 {ymm|m256|mem, zmm, i8|u8}
+ ROW(3, 1, 1, 0, 49 , 118, 49 , 0 , 0 , 0 ), // #289 {xmm, vm64x|vm64y, xmm}
+ ROW(2, 1, 1, 0, 49 , 118, 0 , 0 , 0 , 0 ), // {xmm, vm64x|vm64y}
+ ROW(2, 1, 1, 0, 52 , 76 , 0 , 0 , 0 , 0 ), // {ymm, vm64z}
+ ROW(3, 1, 1, 0, 49 , 50 , 10 , 0 , 0 , 0 ), // #292 {xmm, xmm|m128|mem, i8|u8}
+ ROW(3, 1, 1, 0, 52 , 53 , 10 , 0 , 0 , 0 ), // {ymm, ymm|m256|mem, i8|u8}
+ ROW(3, 1, 1, 0, 55 , 56 , 10 , 0 , 0 , 0 ), // {zmm, zmm|m512|mem, i8|u8}
+ ROW(2, 1, 1, 0, 49 , 64 , 0 , 0 , 0 , 0 ), // #295 {xmm, xmm|m64|mem}
+ ROW(2, 1, 1, 0, 52 , 53 , 0 , 0 , 0 , 0 ), // {ymm, ymm|m256|mem}
+ ROW(2, 1, 1, 0, 55 , 56 , 0 , 0 , 0 , 0 ), // {zmm, zmm|m512|mem}
+ ROW(4, 1, 1, 0, 86 , 86 , 49 , 50 , 0 , 0 ), // #298 {k, k, xmm, xmm|m128|mem}
+ ROW(4, 1, 1, 0, 86 , 86 , 52 , 53 , 0 , 0 ), // {k, k, ymm, ymm|m256|mem}
+ ROW(4, 1, 1, 0, 86 , 86 , 55 , 56 , 0 , 0 ), // {k, k, zmm, zmm|m512|mem}
+ ROW(3, 1, 1, 0, 115, 49 , 50 , 0 , 0 , 0 ), // #301 {xmm|k, xmm, xmm|m128|mem}
+ ROW(3, 1, 1, 0, 116, 52 , 53 , 0 , 0 , 0 ), // {ymm|k, ymm, ymm|m256|mem}
+ ROW(3, 1, 1, 0, 86 , 55 , 56 , 0 , 0 , 0 ), // {k, zmm, zmm|m512|mem}
+ ROW(2, 1, 1, 0, 117, 49 , 0 , 0 , 0 , 0 ), // #304 {xmm|m32|mem, xmm}
+ ROW(2, 1, 1, 0, 64 , 52 , 0 , 0 , 0 , 0 ), // {xmm|m64|mem, ymm}
+ ROW(2, 1, 1, 0, 50 , 55 , 0 , 0 , 0 , 0 ), // {xmm|m128|mem, zmm}
+ ROW(2, 1, 1, 0, 64 , 49 , 0 , 0 , 0 , 0 ), // #307 {xmm|m64|mem, xmm}
+ ROW(2, 1, 1, 0, 50 , 52 , 0 , 0 , 0 , 0 ), // {xmm|m128|mem, ymm}
+ ROW(2, 1, 1, 0, 53 , 55 , 0 , 0 , 0 , 0 ), // {ymm|m256|mem, zmm}
+ ROW(2, 1, 1, 0, 119, 49 , 0 , 0 , 0 , 0 ), // #310 {xmm|m16|mem, xmm}
+ ROW(2, 1, 1, 0, 117, 52 , 0 , 0 , 0 , 0 ), // {xmm|m32|mem, ymm}
+ ROW(2, 1, 1, 0, 64 , 55 , 0 , 0 , 0 , 0 ), // {xmm|m64|mem, zmm}
+ ROW(2, 1, 1, 0, 49 , 119, 0 , 0 , 0 , 0 ), // #313 {xmm, xmm|m16|mem}
+ ROW(2, 1, 1, 0, 52 , 117, 0 , 0 , 0 , 0 ), // {ymm, xmm|m32|mem}
+ ROW(2, 1, 1, 0, 55 , 64 , 0 , 0 , 0 , 0 ), // {zmm, xmm|m64|mem}
+ ROW(2, 1, 1, 0, 71 , 49 , 0 , 0 , 0 , 0 ), // #316 {vm32x, xmm}
+ ROW(2, 1, 1, 0, 72 , 52 , 0 , 0 , 0 , 0 ), // {vm32y, ymm}
+ ROW(2, 1, 1, 0, 73 , 55 , 0 , 0 , 0 , 0 ), // {vm32z, zmm}
+ ROW(2, 1, 1, 0, 74 , 49 , 0 , 0 , 0 , 0 ), // #319 {vm64x, xmm}
+ ROW(2, 1, 1, 0, 75 , 52 , 0 , 0 , 0 , 0 ), // {vm64y, ymm}
+ ROW(2, 1, 1, 0, 76 , 55 , 0 , 0 , 0 , 0 ), // {vm64z, zmm}
+ ROW(3, 1, 1, 0, 86 , 49 , 50 , 0 , 0 , 0 ), // #322 {k, xmm, xmm|m128|mem}
+ ROW(3, 1, 1, 0, 86 , 52 , 53 , 0 , 0 , 0 ), // {k, ymm, ymm|m256|mem}
+ ROW(3, 1, 1, 0, 86 , 55 , 56 , 0 , 0 , 0 ), // {k, zmm, zmm|m512|mem}
+ ROW(3, 1, 1, 0, 6 , 6 , 28 , 0 , 0 , 0 ), // #325 {r32, r32, r32|m32|mem}
+ ROW(3, 0, 1, 0, 8 , 8 , 29 , 0 , 0 , 0 ), // {r64, r64, r64|m64|mem}
+ ROW(3, 1, 1, 0, 6 , 28 , 6 , 0 , 0 , 0 ), // #327 {r32, r32|m32|mem, r32}
+ ROW(3, 0, 1, 0, 8 , 29 , 8 , 0 , 0 , 0 ), // {r64, r64|m64|mem, r64}
+ ROW(2, 1, 0, 0, 120, 28 , 0 , 0 , 0 , 0 ), // #329 {bnd, r32|m32|mem}
+ ROW(2, 0, 1, 0, 120, 29 , 0 , 0 , 0 , 0 ), // {bnd, r64|m64|mem}
+ ROW(2, 1, 1, 0, 120, 121, 0 , 0 , 0 , 0 ), // #331 {bnd, bnd|mem}
+ ROW(2, 1, 1, 0, 122, 120, 0 , 0 , 0 , 0 ), // {mem, bnd}
+ ROW(2, 1, 0, 0, 4 , 30 , 0 , 0 , 0 , 0 ), // #333 {r16, m32|mem}
+ ROW(2, 1, 0, 0, 6 , 31 , 0 , 0 , 0 , 0 ), // {r32, m64|mem}
+ ROW(1, 1, 1, 0, 100, 0 , 0 , 0 , 0 , 0 ), // #335 {r16|r32}
+ ROW(1, 0, 1, 0, 8 , 0 , 0 , 0 , 0 , 0 ), // #336 {r64}
+ ROW(3, 1, 1, 0, 30 , 6 , 6 , 0 , 0 , 0 ), // #337 {m32|mem, r32, r32}
+ ROW(3, 0, 1, 0, 31 , 8 , 8 , 0 , 0 , 0 ), // {m64|mem, r64, r64}
+ ROW(2, 1, 1, 0, 6 , 32 , 0 , 0 , 0 , 0 ), // #339 {r32, r8lo|r8hi|m8|r16|m16|r32|m32}
+ ROW(2, 0, 1, 0, 8 , 123, 0 , 0 , 0 , 0 ), // {r64, r8lo|m8|r64|m64}
+ ROW(2, 1, 1, 0, 6 , 64 , 0 , 0 , 0 , 0 ), // #341 {r32, xmm|m64|mem}
+ ROW(2, 0, 1, 0, 8 , 64 , 0 , 0 , 0 , 0 ), // {r64, xmm|m64|mem}
+ ROW(2, 1, 1, 0, 49 , 28 , 0 , 0 , 0 , 0 ), // #343 {xmm, r32|m32|mem}
+ ROW(2, 0, 1, 0, 49 , 29 , 0 , 0 , 0 , 0 ), // {xmm, r64|m64|mem}
+ ROW(2, 0, 1, 0, 49 , 29 , 0 , 0 , 0 , 0 ), // #345 {xmm, r64|m64|mem}
+ ROW(2, 1, 1, 0, 49 , 28 , 0 , 0 , 0 , 0 ), // {xmm, r32|m32|mem}
+ ROW(2, 1, 1, 0, 6 , 117, 0 , 0 , 0 , 0 ), // #347 {r32, xmm|m32|mem}
+ ROW(2, 0, 1, 0, 8 , 117, 0 , 0 , 0 , 0 ), // {r64, xmm|m32|mem}
+ ROW(2, 0, 1, 0, 8 , 117, 0 , 0 , 0 , 0 ), // #349 {r64, xmm|m32|mem}
+ ROW(2, 1, 1, 0, 6 , 117, 0 , 0 , 0 , 0 ), // {r32, xmm|m32|mem}
+ ROW(2, 1, 0, 0, 124, 57 , 0 , 0 , 0 , 0 ), // #351 {es:[mem|m512|memBase], m512|mem}
+ ROW(2, 0, 1, 0, 124, 57 , 0 , 0 , 0 , 0 ), // {es:[mem|m512|memBase], m512|mem}
+ ROW(3, 1, 1, 0, 49 , 10 , 10 , 0 , 0 , 0 ), // #353 {xmm, i8|u8, i8|u8}
+ ROW(2, 1, 1, 0, 49 , 49 , 0 , 0 , 0 , 0 ), // #354 {xmm, xmm}
+ ROW(0, 1, 1, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #355 {}
+ ROW(1, 1, 1, 0, 103, 0 , 0 , 0 , 0 , 0 ), // #356 {st}
+ ROW(0, 1, 1, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #357 {}
+ ROW(1, 1, 1, 0, 125, 0 , 0 , 0 , 0 , 0 ), // #358 {m32|m64|st}
+ ROW(2, 1, 1, 0, 49 , 49 , 0 , 0 , 0 , 0 ), // #359 {xmm, xmm}
+ ROW(4, 1, 1, 0, 49 , 49 , 10 , 10 , 0 , 0 ), // {xmm, xmm, i8|u8, i8|u8}
+ ROW(2, 1, 0, 0, 6 , 51 , 0 , 0 , 0 , 0 ), // #361 {r32, m128|mem}
+ ROW(2, 0, 1, 0, 8 , 51 , 0 , 0 , 0 , 0 ), // {r64, m128|mem}
+ ROW(2, 1, 0, 2, 39 , 126, 0 , 0 , 0 , 0 ), // #363 {<eax>, <ecx>}
+ ROW(2, 0, 1, 2, 127, 126, 0 , 0 , 0 , 0 ), // {<eax|rax>, <ecx>}
+ ROW(3, 1, 0, 3, 39 , 38 , 126, 0 , 0 , 0 ), // #365 {<eax>, <edx>, <ecx>}
+ ROW(3, 0, 1, 3, 127, 38 , 126, 0 , 0 , 0 ), // {<eax|rax>, <edx>, <ecx>}
+ ROW(2, 1, 0, 1, 128, 129, 0 , 0 , 0 , 0 ), // #367 {<cx|ecx>, rel8}
+ ROW(2, 0, 1, 1, 130, 129, 0 , 0 , 0 , 0 ), // {<ecx|rcx>, rel8}
+ ROW(2, 1, 1, 0, 86 , 131, 0 , 0 , 0 , 0 ), // #369 {k, k|m8|mem|r32}
+ ROW(2, 1, 1, 0, 132, 86 , 0 , 0 , 0 , 0 ), // {m8|mem|r32, k}
+ ROW(2, 1, 1, 0, 86 , 133, 0 , 0 , 0 , 0 ), // #371 {k, k|m32|mem|r32}
+ ROW(2, 1, 1, 0, 28 , 86 , 0 , 0 , 0 , 0 ), // {m32|mem|r32, k}
+ ROW(2, 1, 1, 0, 86 , 134, 0 , 0 , 0 , 0 ), // #373 {k, k|m16|mem|r32}
+ ROW(2, 1, 1, 0, 111, 86 , 0 , 0 , 0 , 0 ), // {m16|mem|r32, k}
+ ROW(2, 1, 0, 0, 4 , 30 , 0 , 0 , 0 , 0 ), // #375 {r16, m32|mem}
+ ROW(2, 1, 0, 0, 6 , 110, 0 , 0 , 0 , 0 ), // {r32, m48|mem}
+ ROW(2, 1, 1, 0, 100, 135, 0 , 0 , 0 , 0 ), // #377 {r16|r32, mem|m8|m16|m32|m48|m64|m80|m128|m256|m512|m1024}
+ ROW(2, 0, 1, 0, 8 , 135, 0 , 0 , 0 , 0 ), // {r64, mem|m8|m16|m32|m48|m64|m80|m128|m256|m512|m1024}
+ ROW(1, 1, 1, 0, 6 , 0 , 0 , 0 , 0 , 0 ), // #379 {r32}
+ ROW(1, 0, 1, 0, 8 , 0 , 0 , 0 , 0 , 0 ), // {r64}
+ ROW(3, 1, 1, 0, 6 , 28 , 14 , 0 , 0 , 0 ), // #381 {r32, r32|m32|mem, i32|u32}
+ ROW(3, 0, 1, 0, 8 , 28 , 14 , 0 , 0 , 0 ), // {r64, r32|m32|mem, i32|u32}
+ ROW(2, 1, 1, 0, 63 , 28 , 0 , 0 , 0 , 0 ), // #383 {mm|xmm, r32|m32|mem}
+ ROW(2, 1, 1, 0, 28 , 63 , 0 , 0 , 0 , 0 ), // {r32|m32|mem, mm|xmm}
+ ROW(2, 1, 1, 0, 124, 57 , 0 , 0 , 0 , 0 ), // #385 {es:[mem|m512|memBase], m512|mem}
+ ROW(2, 1, 1, 0, 124, 57 , 0 , 0 , 0 , 0 ), // {es:[mem|m512|memBase], m512|mem}
+ ROW(2, 1, 1, 0, 49 , 64 , 0 , 0 , 0 , 0 ), // #387 {xmm, xmm|m64|mem}
+ ROW(2, 1, 1, 0, 31 , 49 , 0 , 0 , 0 , 0 ), // {m64|mem, xmm}
+ ROW(2, 1, 1, 0, 49 , 117, 0 , 0 , 0 , 0 ), // #389 {xmm, xmm|m32|mem}
+ ROW(2, 1, 1, 0, 30 , 49 , 0 , 0 , 0 , 0 ), // {m32|mem, xmm}
+ ROW(2, 0, 1, 0, 4 , 27 , 0 , 0 , 0 , 0 ), // #391 {r16, r16|m16|mem}
+ ROW(2, 0, 1, 0, 136, 28 , 0 , 0 , 0 , 0 ), // {r32|r64, r32|m32|mem}
+ ROW(4, 1, 1, 1, 6 , 6 , 28 , 38 , 0 , 0 ), // #393 {r32, r32, r32|m32|mem, <edx>}
+ ROW(4, 0, 1, 1, 8 , 8 , 29 , 40 , 0 , 0 ), // {r64, r64, r64|m64|mem, <rdx>}
+ ROW(2, 1, 1, 0, 61 , 62 , 0 , 0 , 0 , 0 ), // #395 {mm, mm|m64|mem}
+ ROW(2, 1, 1, 0, 49 , 50 , 0 , 0 , 0 , 0 ), // {xmm, xmm|m128|mem}
+ ROW(3, 1, 1, 0, 61 , 62 , 10 , 0 , 0 , 0 ), // #397 {mm, mm|m64|mem, i8|u8}
+ ROW(3, 1, 1, 0, 49 , 50 , 10 , 0 , 0 , 0 ), // {xmm, xmm|m128|mem, i8|u8}
+ ROW(3, 1, 1, 0, 6 , 63 , 10 , 0 , 0 , 0 ), // #399 {r32, mm|xmm, i8|u8}
+ ROW(3, 1, 1, 0, 21 , 49 , 10 , 0 , 0 , 0 ), // {m16|mem, xmm, i8|u8}
+ ROW(2, 1, 1, 0, 61 , 137, 0 , 0 , 0 , 0 ), // #401 {mm, i8|u8|mm|m64|mem}
+ ROW(2, 1, 1, 0, 49 , 58 , 0 , 0 , 0 , 0 ), // {xmm, i8|u8|xmm|m128|mem}
+ ROW(1, 1, 1, 0, 28 , 0 , 0 , 0 , 0 , 0 ), // #403 {r32|m32|mem}
+ ROW(1, 0, 1, 0, 29 , 0 , 0 , 0 , 0 , 0 ), // {r64|m64|mem}
+ ROW(2, 1, 1, 0, 61 , 138, 0 , 0 , 0 , 0 ), // #405 {mm, mm|m32|mem}
+ ROW(2, 1, 1, 0, 49 , 50 , 0 , 0 , 0 , 0 ), // {xmm, xmm|m128|mem}
+ ROW(2, 1, 1, 0, 32 , 114, 0 , 0 , 0 , 0 ), // #407 {r8lo|r8hi|m8|r16|m16|r32|m32, cl|i8|u8}
+ ROW(2, 0, 1, 0, 15 , 114, 0 , 0 , 0 , 0 ), // {r64|m64, cl|i8|u8}
+ ROW(1, 1, 0, 0, 6 , 0 , 0 , 0 , 0 , 0 ), // #409 {r32}
+ ROW(1, 0, 1, 0, 8 , 0 , 0 , 0 , 0 , 0 ), // {r64}
+ ROW(0, 1, 1, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #411 {}
+ ROW(1, 1, 1, 0, 139, 0 , 0 , 0 , 0 , 0 ), // {u16}
+ ROW(3, 1, 1, 0, 6 , 28 , 10 , 0 , 0 , 0 ), // #413 {r32, r32|m32|mem, i8|u8}
+ ROW(3, 0, 1, 0, 8 , 29 , 10 , 0 , 0 , 0 ), // {r64, r64|m64|mem, i8|u8}
+ ROW(1, 1, 1, 0, 140, 0 , 0 , 0 , 0 , 0 ), // #415 {r16|m16|mem|r32}
+ ROW(1, 0, 1, 0, 141, 0 , 0 , 0 , 0 , 0 ), // {r64|m16|mem}
+ ROW(1, 1, 0, 0, 142, 0 , 0 , 0 , 0 , 0 ), // #417 {ds:[mem|memBase]}
+ ROW(1, 0, 1, 0, 142, 0 , 0 , 0 , 0 , 0 ), // {ds:[mem|memBase]}
+ ROW(4, 1, 1, 0, 49 , 49 , 50 , 49 , 0 , 0 ), // #419 {xmm, xmm, xmm|m128|mem, xmm}
+ ROW(4, 1, 1, 0, 52 , 52 , 53 , 52 , 0 , 0 ), // {ymm, ymm, ymm|m256|mem, ymm}
+ ROW(2, 1, 1, 0, 49 , 143, 0 , 0 , 0 , 0 ), // #421 {xmm, xmm|m128|ymm|m256}
+ ROW(2, 1, 1, 0, 52 , 56 , 0 , 0 , 0 , 0 ), // {ymm, zmm|m512|mem}
+ ROW(2, 1, 1, 0, 6 , 119, 0 , 0 , 0 , 0 ), // #423 {r32, xmm|m16|mem}
+ ROW(2, 0, 1, 0, 8 , 119, 0 , 0 , 0 , 0 ), // {r64, xmm|m16|mem}
+ ROW(3, 1, 1, 0, 49 , 49 , 28 , 0 , 0 , 0 ), // #425 {xmm, xmm, r32|m32|mem}
+ ROW(3, 0, 1, 0, 49 , 49 , 29 , 0 , 0 , 0 ), // {xmm, xmm, r64|m64|mem}
+ ROW(3, 1, 1, 0, 49 , 49 , 13 , 0 , 0 , 0 ), // #427 {xmm, xmm, r32|m32}
+ ROW(3, 0, 1, 0, 49 , 49 , 15 , 0 , 0 , 0 ), // {xmm, xmm, r64|m64}
+ ROW(4, 1, 1, 0, 49 , 49 , 49 , 64 , 0 , 0 ), // #429 {xmm, xmm, xmm, xmm|m64|mem}
+ ROW(4, 1, 1, 0, 49 , 49 , 31 , 49 , 0 , 0 ), // {xmm, xmm, m64|mem, xmm}
+ ROW(4, 1, 1, 0, 49 , 49 , 49 , 117, 0 , 0 ), // #431 {xmm, xmm, xmm, xmm|m32|mem}
+ ROW(4, 1, 1, 0, 49 , 49 , 30 , 49 , 0 , 0 ), // {xmm, xmm, m32|mem, xmm}
+ ROW(4, 1, 1, 0, 52 , 52 , 50 , 10 , 0 , 0 ), // #433 {ymm, ymm, xmm|m128|mem, i8|u8}
+ ROW(4, 1, 1, 0, 55 , 55 , 50 , 10 , 0 , 0 ), // {zmm, zmm, xmm|m128|mem, i8|u8}
+ ROW(1, 1, 0, 1, 39 , 0 , 0 , 0 , 0 , 0 ), // #435 {<eax>}
+ ROW(1, 0, 1, 1, 41 , 0 , 0 , 0 , 0 , 0 ), // #436 {<rax>}
+ ROW(2, 1, 1, 0, 28 , 49 , 0 , 0 , 0 , 0 ), // #437 {r32|m32|mem, xmm}
+ ROW(2, 1, 1, 0, 49 , 28 , 0 , 0 , 0 , 0 ), // {xmm, r32|m32|mem}
+ ROW(2, 1, 1, 0, 111, 49 , 0 , 0 , 0 , 0 ), // #439 {r32|m16|mem, xmm}
+ ROW(2, 1, 1, 0, 49 , 111, 0 , 0 , 0 , 0 ), // {xmm, r32|m16|mem}
+ ROW(2, 1, 0, 0, 28 , 6 , 0 , 0 , 0 , 0 ), // #441 {r32|m32|mem, r32}
+ ROW(2, 0, 1, 0, 29 , 8 , 0 , 0 , 0 , 0 ), // {r64|m64|mem, r64}
+ ROW(2, 1, 0, 0, 6 , 28 , 0 , 0 , 0 , 0 ), // #443 {r32, r32|m32|mem}
+ ROW(2, 0, 1, 0, 8 , 29 , 0 , 0 , 0 , 0 ), // {r64, r64|m64|mem}
+ ROW(2, 1, 1, 0, 144, 64 , 0 , 0 , 0 , 0 ), // #445 {xmm|ymm|zmm, xmm|m64|mem}
+ ROW(2, 0, 1, 0, 144, 8 , 0 , 0 , 0 , 0 ), // {xmm|ymm|zmm, r64}
+ ROW(3, 1, 1, 0, 49 , 49 , 58 , 0 , 0 , 0 ), // #447 {xmm, xmm, xmm|m128|mem|i8|u8}
+ ROW(3, 1, 1, 0, 49 , 51 , 145, 0 , 0 , 0 ), // {xmm, m128|mem, i8|u8|xmm}
+ ROW(2, 1, 1, 0, 71 , 96 , 0 , 0 , 0 , 0 ), // #449 {vm32x, xmm|ymm}
+ ROW(2, 1, 1, 0, 72 , 55 , 0 , 0 , 0 , 0 ), // {vm32y, zmm}
+ ROW(2, 1, 1, 0, 118, 49 , 0 , 0 , 0 , 0 ), // #451 {vm64x|vm64y, xmm}
+ ROW(2, 1, 1, 0, 76 , 52 , 0 , 0 , 0 , 0 ), // {vm64z, ymm}
+ ROW(3, 1, 1, 0, 49 , 49 , 50 , 0 , 0 , 0 ), // #453 {xmm, xmm, xmm|m128|mem}
+ ROW(3, 1, 1, 0, 49 , 51 , 49 , 0 , 0 , 0 ), // {xmm, m128|mem, xmm}
+ ROW(1, 1, 0, 1, 36 , 0 , 0 , 0 , 0 , 0 ), // #455 {<ax>}
+ ROW(2, 1, 0, 1, 36 , 10 , 0 , 0 , 0 , 0 ), // #456 {<ax>, i8|u8}
+ ROW(2, 1, 0, 0, 27 , 4 , 0 , 0 , 0 , 0 ), // #457 {r16|m16|mem, r16}
+ ROW(3, 1, 1, 1, 49 , 50 , 146, 0 , 0 , 0 ), // #458 {xmm, xmm|m128|mem, <xmm0>}
+ ROW(2, 1, 1, 0, 120, 147, 0 , 0 , 0 , 0 ), // #459 {bnd, mib}
+ ROW(2, 1, 1, 0, 120, 122, 0 , 0 , 0 , 0 ), // #460 {bnd, mem}
+ ROW(2, 1, 1, 0, 147, 120, 0 , 0 , 0 , 0 ), // #461 {mib, bnd}
+ ROW(1, 1, 1, 1, 36 , 0 , 0 , 0 , 0 , 0 ), // #462 {<ax>}
+ ROW(2, 1, 1, 2, 38 , 39 , 0 , 0 , 0 , 0 ), // #463 {<edx>, <eax>}
+ ROW(1, 1, 1, 0, 122, 0 , 0 , 0 , 0 , 0 ), // #464 {mem}
+ ROW(1, 1, 1, 0, 31 , 0 , 0 , 0 , 0 , 0 ), // #465 {m64|mem}
+ ROW(0, 0, 1, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #466 {}
+ ROW(1, 1, 1, 1, 148, 0 , 0 , 0 , 0 , 0 ), // #467 {<ds:[mem|m512|memBase|zax]>}
+ ROW(3, 1, 1, 0, 49 , 64 , 10 , 0 , 0 , 0 ), // #468 {xmm, xmm|m64|mem, i8|u8}
+ ROW(3, 1, 1, 0, 49 , 117, 10 , 0 , 0 , 0 ), // #469 {xmm, xmm|m32|mem, i8|u8}
+ ROW(5, 0, 1, 4, 51 , 40 , 41 , 149, 150, 0 ), // #470 {m128|mem, <rdx>, <rax>, <rcx>, <rbx>}
+ ROW(5, 1, 1, 4, 31 , 38 , 39 , 126, 151, 0 ), // #471 {m64|mem, <edx>, <eax>, <ecx>, <ebx>}
+ ROW(4, 1, 1, 4, 39 , 151, 126, 38 , 0 , 0 ), // #472 {<eax>, <ebx>, <ecx>, <edx>}
+ ROW(2, 0, 1, 2, 40 , 41 , 0 , 0 , 0 , 0 ), // #473 {<rdx>, <rax>}
+ ROW(2, 1, 1, 0, 61 , 50 , 0 , 0 , 0 , 0 ), // #474 {mm, xmm|m128|mem}
+ ROW(2, 1, 1, 0, 49 , 62 , 0 , 0 , 0 , 0 ), // #475 {xmm, mm|m64|mem}
+ ROW(2, 1, 1, 0, 61 , 64 , 0 , 0 , 0 , 0 ), // #476 {mm, xmm|m64|mem}
+ ROW(2, 1, 1, 2, 37 , 36 , 0 , 0 , 0 , 0 ), // #477 {<dx>, <ax>}
+ ROW(1, 1, 1, 1, 39 , 0 , 0 , 0 , 0 , 0 ), // #478 {<eax>}
+ ROW(2, 1, 1, 0, 12 , 10 , 0 , 0 , 0 , 0 ), // #479 {i16|u16, i8|u8}
+ ROW(3, 1, 1, 0, 28 , 49 , 10 , 0 , 0 , 0 ), // #480 {r32|m32|mem, xmm, i8|u8}
+ ROW(1, 1, 1, 0, 109, 0 , 0 , 0 , 0 , 0 ), // #481 {m80|mem}
+ ROW(1, 1, 1, 0, 152, 0 , 0 , 0 , 0 , 0 ), // #482 {m16|m32}
+ ROW(1, 1, 1, 0, 153, 0 , 0 , 0 , 0 , 0 ), // #483 {m16|m32|m64}
+ ROW(1, 1, 1, 0, 154, 0 , 0 , 0 , 0 , 0 ), // #484 {m32|m64|m80|st}
+ ROW(1, 1, 1, 0, 21 , 0 , 0 , 0 , 0 , 0 ), // #485 {m16|mem}
+ ROW(1, 1, 1, 0, 155, 0 , 0 , 0 , 0 , 0 ), // #486 {ax|m16|mem}
+ ROW(1, 0, 1, 0, 122, 0 , 0 , 0 , 0 , 0 ), // #487 {mem}
+ ROW(2, 1, 1, 1, 10 , 39 , 0 , 0 , 0 , 0 ), // #488 {i8|u8, <eax>}
+ ROW(2, 1, 1, 0, 156, 157, 0 , 0 , 0 , 0 ), // #489 {al|ax|eax, i8|u8|dx}
+ ROW(2, 1, 1, 0, 158, 159, 0 , 0 , 0 , 0 ), // #490 {es:[memBase|zdi|m8|m16|m32], dx}
+ ROW(1, 1, 1, 0, 10 , 0 , 0 , 0 , 0 , 0 ), // #491 {i8|u8}
+ ROW(0, 1, 0, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #492 {}
+ ROW(3, 1, 1, 0, 86 , 86 , 86 , 0 , 0 , 0 ), // #493 {k, k, k}
+ ROW(2, 1, 1, 0, 86 , 86 , 0 , 0 , 0 , 0 ), // #494 {k, k}
+ ROW(3, 1, 1, 0, 86 , 86 , 10 , 0 , 0 , 0 ), // #495 {k, k, i8|u8}
+ ROW(1, 1, 1, 1, 160, 0 , 0 , 0 , 0 , 0 ), // #496 {<ah>}
+ ROW(1, 1, 1, 0, 30 , 0 , 0 , 0 , 0 , 0 ), // #497 {m32|mem}
+ ROW(1, 0, 1, 0, 57 , 0 , 0 , 0 , 0 , 0 ), // #498 {m512|mem}
+ ROW(1, 1, 1, 0, 27 , 0 , 0 , 0 , 0 , 0 ), // #499 {r16|m16|mem}
+ ROW(3, 1, 1, 1, 49 , 49 , 161, 0 , 0 , 0 ), // #500 {xmm, xmm, <ds:[mem|m128|memBase|zdi]>}
+ ROW(3, 1, 1, 1, 61 , 61 , 162, 0 , 0 , 0 ), // #501 {mm, mm, <ds:[mem|m64|memBase|zdi]>}
+ ROW(3, 1, 1, 3, 163, 126, 38 , 0 , 0 , 0 ), // #502 {<ds:[mem|memBase|zax]>, <ecx>, <edx>}
+ ROW(2, 1, 1, 0, 61 , 49 , 0 , 0 , 0 , 0 ), // #503 {mm, xmm}
+ ROW(2, 1, 1, 0, 6 , 49 , 0 , 0 , 0 , 0 ), // #504 {r32, xmm}
+ ROW(2, 1, 1, 0, 31 , 61 , 0 , 0 , 0 , 0 ), // #505 {m64|mem, mm}
+ ROW(2, 1, 1, 0, 49 , 61 , 0 , 0 , 0 , 0 ), // #506 {xmm, mm}
+ ROW(2, 1, 1, 2, 39 , 126, 0 , 0 , 0 , 0 ), // #507 {<eax>, <ecx>}
+ ROW(3, 1, 1, 3, 39 , 126, 151, 0 , 0 , 0 ), // #508 {<eax>, <ecx>, <ebx>}
+ ROW(2, 1, 1, 0, 164, 156, 0 , 0 , 0 , 0 ), // #509 {u8|dx, al|ax|eax}
+ ROW(2, 1, 1, 0, 159, 165, 0 , 0 , 0 , 0 ), // #510 {dx, ds:[memBase|zsi|m8|m16|m32]}
+ ROW(6, 1, 1, 3, 49 , 50 , 10 , 126, 39 , 38 ), // #511 {xmm, xmm|m128|mem, i8|u8, <ecx>, <eax>, <edx>}
+ ROW(6, 1, 1, 3, 49 , 50 , 10 , 146, 39 , 38 ), // #512 {xmm, xmm|m128|mem, i8|u8, <xmm0>, <eax>, <edx>}
+ ROW(4, 1, 1, 1, 49 , 50 , 10 , 126, 0 , 0 ), // #513 {xmm, xmm|m128|mem, i8|u8, <ecx>}
+ ROW(4, 1, 1, 1, 49 , 50 , 10 , 146, 0 , 0 ), // #514 {xmm, xmm|m128|mem, i8|u8, <xmm0>}
+ ROW(3, 1, 1, 0, 132, 49 , 10 , 0 , 0 , 0 ), // #515 {r32|m8|mem, xmm, i8|u8}
+ ROW(3, 0, 1, 0, 29 , 49 , 10 , 0 , 0 , 0 ), // #516 {r64|m64|mem, xmm, i8|u8}
+ ROW(3, 1, 1, 0, 49 , 132, 10 , 0 , 0 , 0 ), // #517 {xmm, r32|m8|mem, i8|u8}
+ ROW(3, 1, 1, 0, 49 , 28 , 10 , 0 , 0 , 0 ), // #518 {xmm, r32|m32|mem, i8|u8}
+ ROW(3, 0, 1, 0, 49 , 29 , 10 , 0 , 0 , 0 ), // #519 {xmm, r64|m64|mem, i8|u8}
+ ROW(3, 1, 1, 0, 63 , 111, 10 , 0 , 0 , 0 ), // #520 {mm|xmm, r32|m16|mem, i8|u8}
+ ROW(2, 1, 1, 0, 6 , 63 , 0 , 0 , 0 , 0 ), // #521 {r32, mm|xmm}
+ ROW(2, 1, 1, 0, 49 , 10 , 0 , 0 , 0 , 0 ), // #522 {xmm, i8|u8}
+ ROW(1, 0, 1, 0, 136, 0 , 0 , 0 , 0 , 0 ), // #523 {r32|r64}
+ ROW(3, 1, 1, 3, 38 , 39 , 126, 0 , 0 , 0 ), // #524 {<edx>, <eax>, <ecx>}
+ ROW(1, 1, 1, 0, 1 , 0 , 0 , 0 , 0 , 0 ), // #525 {r8lo|r8hi|m8|mem}
+ ROW(3, 0, 1, 0, 166, 166, 166, 0 , 0 , 0 ), // #526 {tmm, tmm, tmm}
+ ROW(2, 0, 1, 0, 166, 167, 0 , 0 , 0 , 0 ), // #527 {tmm, tmem}
+ ROW(2, 0, 1, 0, 167, 166, 0 , 0 , 0 , 0 ), // #528 {tmem, tmm}
+ ROW(1, 0, 1, 0, 166, 0 , 0 , 0 , 0 , 0 ), // #529 {tmm}
+ ROW(3, 1, 1, 2, 6 , 38 , 39 , 0 , 0 , 0 ), // #530 {r32, <edx>, <eax>}
+ ROW(6, 1, 1, 0, 55 , 55 , 55 , 55 , 55 , 51 ), // #531 {zmm, zmm, zmm, zmm, zmm, m128|mem}
+ ROW(6, 1, 1, 0, 49 , 49 , 49 , 49 , 49 , 51 ), // #532 {xmm, xmm, xmm, xmm, xmm, m128|mem}
+ ROW(3, 1, 1, 0, 49 , 49 , 64 , 0 , 0 , 0 ), // #533 {xmm, xmm, xmm|m64|mem}
+ ROW(3, 1, 1, 0, 49 , 49 , 119, 0 , 0 , 0 ), // #534 {xmm, xmm, xmm|m16|mem}
+ ROW(3, 1, 1, 0, 49 , 49 , 117, 0 , 0 , 0 ), // #535 {xmm, xmm, xmm|m32|mem}
+ ROW(2, 1, 1, 0, 96 , 21 , 0 , 0 , 0 , 0 ), // #536 {xmm|ymm, m16|mem}
+ ROW(2, 1, 1, 0, 52 , 51 , 0 , 0 , 0 , 0 ), // #537 {ymm, m128|mem}
+ ROW(2, 1, 1, 0, 168, 64 , 0 , 0 , 0 , 0 ), // #538 {ymm|zmm, xmm|m64|mem}
+ ROW(2, 1, 1, 0, 168, 51 , 0 , 0 , 0 , 0 ), // #539 {ymm|zmm, m128|mem}
+ ROW(2, 1, 1, 0, 55 , 54 , 0 , 0 , 0 , 0 ), // #540 {zmm, m256|mem}
+ ROW(2, 1, 1, 0, 144, 117, 0 , 0 , 0 , 0 ), // #541 {xmm|ymm|zmm, m32|mem|xmm}
+ ROW(4, 1, 1, 0, 115, 49 , 64 , 10 , 0 , 0 ), // #542 {xmm|k, xmm, xmm|m64|mem, i8|u8}
+ ROW(4, 1, 1, 0, 86 , 49 , 119, 10 , 0 , 0 ), // #543 {k, xmm, xmm|m16|mem, i8|u8}
+ ROW(4, 1, 1, 0, 115, 49 , 117, 10 , 0 , 0 ), // #544 {xmm|k, xmm, xmm|m32|mem, i8|u8}
+ ROW(2, 1, 1, 0, 49 , 169, 0 , 0 , 0 , 0 ), // #545 {xmm, xmm|m128|ymm|m256|zmm|m512}
+ ROW(3, 1, 1, 0, 50 , 168, 10 , 0 , 0 , 0 ), // #546 {xmm|m128|mem, ymm|zmm, i8|u8}
+ ROW(4, 1, 1, 0, 49 , 49 , 64 , 10 , 0 , 0 ), // #547 {xmm, xmm, xmm|m64|mem, i8|u8}
+ ROW(4, 1, 1, 0, 49 , 49 , 117, 10 , 0 , 0 ), // #548 {xmm, xmm, xmm|m32|mem, i8|u8}
+ ROW(3, 1, 1, 0, 86 , 169, 10 , 0 , 0 , 0 ), // #549 {k, xmm|m128|ymm|m256|zmm|m512, i8|u8}
+ ROW(3, 1, 1, 0, 86 , 64 , 10 , 0 , 0 , 0 ), // #550 {k, xmm|m64|mem, i8|u8}
+ ROW(3, 1, 1, 0, 86 , 119, 10 , 0 , 0 , 0 ), // #551 {k, xmm|m16|mem, i8|u8}
+ ROW(3, 1, 1, 0, 86 , 117, 10 , 0 , 0 , 0 ), // #552 {k, xmm|m32|mem, i8|u8}
+ ROW(1, 1, 1, 0, 72 , 0 , 0 , 0 , 0 , 0 ), // #553 {vm32y}
+ ROW(1, 1, 1, 0, 73 , 0 , 0 , 0 , 0 , 0 ), // #554 {vm32z}
+ ROW(1, 1, 1, 0, 76 , 0 , 0 , 0 , 0 , 0 ), // #555 {vm64z}
+ ROW(4, 1, 1, 0, 49 , 49 , 119, 10 , 0 , 0 ), // #556 {xmm, xmm, xmm|m16|mem, i8|u8}
+ ROW(4, 1, 1, 0, 55 , 55 , 53 , 10 , 0 , 0 ), // #557 {zmm, zmm, ymm|m256|mem, i8|u8}
+ ROW(2, 1, 1, 0, 6 , 96 , 0 , 0 , 0 , 0 ), // #558 {r32, xmm|ymm}
+ ROW(2, 1, 1, 0, 144, 170, 0 , 0 , 0 , 0 ), // #559 {xmm|ymm|zmm, xmm|m8|mem|r32}
+ ROW(2, 1, 1, 0, 144, 171, 0 , 0 , 0 , 0 ), // #560 {xmm|ymm|zmm, xmm|m32|mem|r32}
+ ROW(2, 1, 1, 0, 144, 86 , 0 , 0 , 0 , 0 ), // #561 {xmm|ymm|zmm, k}
+ ROW(2, 1, 1, 0, 144, 172, 0 , 0 , 0 , 0 ), // #562 {xmm|ymm|zmm, xmm|m16|mem|r32}
+ ROW(3, 1, 1, 0, 111, 49 , 10 , 0 , 0 , 0 ), // #563 {r32|m16|mem, xmm, i8|u8}
+ ROW(4, 1, 1, 0, 49 , 49 , 132, 10 , 0 , 0 ), // #564 {xmm, xmm, r32|m8|mem, i8|u8}
+ ROW(4, 1, 1, 0, 49 , 49 , 28 , 10 , 0 , 0 ), // #565 {xmm, xmm, r32|m32|mem, i8|u8}
+ ROW(4, 0, 1, 0, 49 , 49 , 29 , 10 , 0 , 0 ), // #566 {xmm, xmm, r64|m64|mem, i8|u8}
+ ROW(4, 1, 1, 0, 49 , 49 , 111, 10 , 0 , 0 ), // #567 {xmm, xmm, r32|m16|mem, i8|u8}
+ ROW(2, 1, 1, 0, 86 , 144, 0 , 0 , 0 , 0 ), // #568 {k, xmm|ymm|zmm}
+ ROW(2, 1, 1, 0, 52 , 49 , 0 , 0 , 0 , 0 ), // #569 {ymm, xmm}
+ ROW(2, 1, 1, 0, 52 , 52 , 0 , 0 , 0 , 0 ), // #570 {ymm, ymm}
+ ROW(3, 1, 1, 0, 52 , 52 , 49 , 0 , 0 , 0 ), // #571 {ymm, ymm, xmm}
+ ROW(3, 1, 1, 2, 122, 38 , 39 , 0 , 0 , 0 ), // #572 {mem, <edx>, <eax>}
+ ROW(3, 0, 1, 2, 122, 38 , 39 , 0 , 0 , 0 ) // #573 {mem, <edx>, <eax>}
};
#undef ROW
@@ -3584,7 +5317,7 @@ const InstDB::OpSignature InstDB::_opSignatureTable[] = {
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(RegGpq) | 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),
@@ -3593,27 +5326,26 @@ const InstDB::OpSignature InstDB::_opSignatureTable[] = {
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) | F(ImmI32), 0x00),
+ ROW(F(RegGpw) | F(RegGpd) | F(Mem16) | F(Mem32), 0x00),
ROW(F(ImmI8), 0x00),
ROW(F(RegGpw) | F(MemUnspecified) | F(Mem16), 0x00),
ROW(F(RegGpd) | F(MemUnspecified) | F(Mem32), 0x00),
+ ROW(F(RegGpq) | F(MemUnspecified) | F(Mem64), 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(RegGpbLo) | F(RegGpbHi) | F(RegGpw) | F(RegGpd) | F(Mem8) | F(Mem16) | F(Mem32), 0x00),
+ ROW(F(RegGpq) | F(MemUnspecified) | F(Mem64) | F(ImmI8) | F(ImmU8) | F(ImmI32) | F(ImmU32), 0x00),
+ ROW(F(Mem64), 0x00),
+ ROW(F(ImmI8) | F(ImmU8) | F(ImmI32), 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),
@@ -3632,99 +5364,96 @@ const InstDB::OpSignature InstDB::_opSignatureTable[] = {
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(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(RegSReg), 0x1A),
+ ROW(F(RegSReg), 0x60),
+ ROW(F(RegGpw) | F(Mem16) | F(ImmI8) | F(ImmI16), 0x00),
+ ROW(F(RegGpd) | F(Mem32) | F(ImmI32) | F(ImmU32), 0x00),
+ ROW(F(RegGpq) | F(Mem64) | F(ImmI32), 0x00),
+ ROW(F(RegSReg), 0x1E),
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(Mem8) | F(FlagMemBase) | F(FlagMemDs), 0x40),
+ ROW(F(Mem8) | F(FlagMemBase) | F(FlagMemEs), 0x80),
+ ROW(F(Mem16) | F(FlagMemBase) | F(FlagMemDs), 0x40),
+ ROW(F(Mem16) | F(FlagMemBase) | F(FlagMemEs), 0x80),
+ ROW(F(Mem32) | F(FlagMemBase) | F(FlagMemDs), 0x40),
+ ROW(F(Mem32) | F(FlagMemBase) | F(FlagMemEs), 0x80),
+ ROW(F(Mem64) | F(FlagMemBase) | F(FlagMemDs), 0x40),
+ ROW(F(Mem64) | F(FlagMemBase) | F(FlagMemEs), 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(RegKReg), 0x00),
+ ROW(F(RegKReg) | F(MemUnspecified) | F(Mem64), 0x00),
+ ROW(F(MemUnspecified) | F(Mem8) | F(FlagMemBase) | F(FlagMemDs), 0x40),
+ ROW(F(MemUnspecified) | F(Mem16) | F(FlagMemBase) | F(FlagMemDs), 0x40),
+ ROW(F(MemUnspecified) | F(Mem32) | F(FlagMemBase) | F(FlagMemDs), 0x40),
+ ROW(F(MemUnspecified) | F(Mem64) | F(FlagMemBase) | F(FlagMemDs), 0x40),
+ ROW(F(MemUnspecified) | F(Mem8) | F(FlagMemBase) | F(FlagMemEs), 0x80),
+ ROW(F(MemUnspecified) | F(Mem16) | F(FlagMemBase) | F(FlagMemEs), 0x80),
+ ROW(F(MemUnspecified) | F(Mem32) | F(FlagMemBase) | F(FlagMemEs), 0x80),
+ ROW(F(MemUnspecified) | F(Mem64) | F(FlagMemBase) | F(FlagMemEs), 0x80),
ROW(F(RegXmm) | F(RegYmm), 0x00),
ROW(F(ImmI4) | F(ImmU4), 0x00),
+ ROW(F(RegGpw) | F(RegGpd) | F(MemUnspecified) | F(Mem16) | F(Mem32) | F(ImmI32) | F(ImmI64) | F(Rel32), 0x00),
+ ROW(F(ImmI32) | F(ImmI64) | F(Rel32), 0x00),
+ ROW(F(RegGpw) | F(RegGpd), 0x00),
ROW(F(Mem32) | F(Mem64), 0x00),
ROW(F(RegSt), 0x01),
ROW(F(RegSt), 0x00),
- ROW(F(MemUnspecified) | F(Mem48), 0x00),
+ ROW(F(ImmI32) | F(ImmI64) | F(Rel8) | F(Rel32), 0x00),
+ ROW(F(RegGpd) | F(Mem32) | F(ImmI32) | F(ImmI64) | F(Rel32), 0x00),
+ ROW(F(ImmI16), 0x00),
+ ROW(F(ImmI16) | F(ImmI32), 0x00),
+ ROW(F(MemUnspecified) | F(Mem32) | F(Mem48), 0x00),
ROW(F(MemUnspecified) | F(Mem80), 0x00),
+ ROW(F(MemUnspecified) | F(Mem48), 0x00),
+ ROW(F(RegGpd) | F(MemUnspecified) | F(Mem16), 0x00),
+ ROW(F(RegGpbLo) | F(RegGpbHi) | F(RegGpw) | F(Mem8) | F(Mem16), 0x00),
+ ROW(F(RegGpbLo) | F(RegGpw) | F(Mem8) | F(Mem16), 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(RegGpbLo) | F(RegGpq) | F(Mem8) | F(Mem64), 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(MemUnspecified) | F(Mem8) | F(Mem16) | F(Mem32) | F(Mem48) | F(Mem64) | F(Mem80) | F(Mem128) | F(Mem256) | F(Mem512) | F(Mem1024), 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(RegGpw) | F(RegGpd) | F(MemUnspecified) | F(Mem16), 0x00),
+ ROW(F(RegGpq) | F(MemUnspecified) | F(Mem16), 0x00),
+ ROW(F(MemUnspecified) | F(FlagMemBase) | F(FlagMemDs), 0x00),
ROW(F(RegXmm) | F(RegYmm) | F(Mem128) | F(Mem256), 0x00),
+ ROW(F(RegXmm) | F(RegYmm) | F(RegZmm), 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),
@@ -3739,12 +5468,9 @@ const InstDB::OpSignature InstDB::_opSignatureTable[] = {
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),
@@ -3762,302 +5488,311 @@ const InstDB::OpSignature InstDB::_opSignatureTable[] = {
// ${InstRWInfoTable:Begin}
// ------------------- Automatically generated, do not edit -------------------
const uint8_t InstDB::rwInfoIndexA[Inst::_kIdCount] = {
- 0, 0, 1, 1, 0, 2, 3, 2, 4, 4, 5, 6, 4, 4, 3, 4, 4, 4, 4, 7, 0, 2, 0, 4, 4, 4,
- 4, 8, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 10, 10, 10, 11, 11, 12, 13,
- 14, 9, 9, 0, 15, 16, 16, 16, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 3, 3, 3, 3, 18, 0, 0, 19, 0, 0, 0, 0, 0, 20, 21, 0, 22, 23, 24, 7, 25,
- 25, 25, 24, 26, 7, 24, 27, 28, 29, 30, 31, 32, 33, 25, 25, 7, 27, 28, 33, 34,
- 0, 0, 0, 0, 35, 4, 4, 5, 6, 0, 0, 0, 0, 0, 36, 36, 0, 0, 37, 0, 0, 38, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 38, 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, 38, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 38,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 0, 39, 4,
- 4, 35, 40, 41, 0, 0, 0, 42, 0, 37, 0, 0, 0, 0, 43, 0, 44, 43, 43, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 45, 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, 46, 47, 48, 49, 50, 51,
- 52, 53, 0, 0, 0, 54, 55, 56, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 55, 56, 57, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 0, 59, 0, 60, 0, 61, 0, 60, 0, 60, 0, 60,
- 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, 75, 7, 7, 76, 77,
- 9, 66, 66, 77, 0, 35, 4, 4, 5, 6, 0, 78, 0, 0, 79, 0, 2, 4, 4, 80, 81, 9, 9,
- 9, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 0, 3, 82, 3, 0, 0, 0, 3, 3,
- 4, 3, 0, 0, 3, 3, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 83, 27, 27, 82, 82, 82, 82, 82,
- 82, 82, 82, 82, 82, 27, 82, 82, 82, 27, 27, 82, 82, 82, 3, 3, 3, 84, 3, 3, 3,
- 27, 27, 0, 0, 0, 0, 3, 3, 4, 4, 3, 3, 4, 4, 4, 4, 3, 3, 4, 4, 85, 86, 87, 24,
- 24, 24, 86, 86, 87, 24, 24, 24, 86, 4, 3, 82, 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, 88, 3, 3, 0, 3, 3,
- 3, 88, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 27, 89, 0, 3, 3, 4, 3, 90, 90, 4, 90, 0,
- 0, 0, 0, 0, 0, 0, 3, 91, 7, 92, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 0, 0,
- 0, 0, 0, 91, 91, 0, 0, 0, 0, 0, 0, 7, 92, 0, 0, 91, 91, 0, 0, 2, 94, 0, 0, 0,
+ 0, 0, 1, 2, 1, 2, 0, 3, 4, 3, 5, 5, 6, 7, 5, 5, 4, 5, 5, 5, 5, 8, 0, 3, 0, 5,
+ 5, 5, 5, 2, 9, 2, 0, 10, 10, 10, 10, 10, 0, 0, 0, 0, 10, 10, 10, 10, 10, 11, 11,
+ 11, 12, 12, 13, 14, 15, 10, 10, 0, 16, 17, 17, 17, 0, 0, 0, 18, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 21, 22, 0, 23, 24, 25, 8, 26, 26,
+ 26, 25, 27, 8, 25, 28, 29, 30, 31, 32, 33, 34, 26, 26, 8, 28, 29, 34, 35, 0,
+ 0, 0, 0, 36, 5, 5, 6, 7, 0, 0, 0, 0, 0, 37, 37, 0, 0, 38, 0, 0, 39, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 0, 39, 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, 39, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 0, 39, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 0, 40, 5, 5, 36,
+ 41, 42, 0, 0, 0, 43, 0, 38, 0, 0, 0, 0, 44, 0, 45, 0, 44, 44, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 46, 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, 47, 48, 49, 50, 51, 52, 53,
+ 54, 0, 0, 0, 55, 56, 57, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 56, 57, 58, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0, 60, 0, 2, 0, 61, 0, 2, 0, 2, 0, 2, 0, 0,
+ 0, 0, 0, 62, 63, 63, 63, 59, 2, 0, 0, 0, 10, 0, 0, 5, 5, 6, 7, 0, 0, 5, 5, 6,
+ 7, 0, 0, 64, 65, 66, 66, 67, 48, 25, 37, 67, 53, 66, 66, 68, 69, 69, 70, 71,
+ 71, 72, 72, 60, 60, 67, 60, 60, 71, 71, 73, 49, 53, 74, 75, 8, 8, 76, 77, 10,
+ 66, 66, 77, 0, 36, 5, 5, 6, 7, 0, 78, 0, 0, 79, 0, 3, 5, 5, 80, 81, 10, 10, 10,
+ 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 0, 4, 82, 4, 0, 0, 0, 4, 4, 5,
+ 4, 0, 0, 4, 4, 5, 4, 0, 0, 0, 0, 0, 0, 0, 0, 83, 28, 28, 82, 82, 82, 82, 82, 82,
+ 82, 82, 82, 82, 28, 82, 82, 82, 28, 28, 82, 82, 82, 4, 4, 4, 84, 4, 4, 4, 28,
+ 28, 0, 0, 0, 0, 4, 4, 5, 5, 4, 4, 5, 5, 5, 5, 4, 4, 5, 5, 85, 86, 87, 25, 25,
+ 25, 86, 86, 87, 25, 25, 25, 86, 5, 4, 82, 4, 4, 5, 4, 4, 0, 0, 0, 10, 0, 0,
+ 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 88, 4, 4, 0, 4,
+ 4, 4, 88, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 28, 89, 0, 4, 4, 5, 4, 90, 90, 5, 90,
+ 0, 0, 0, 0, 0, 0, 0, 4, 91, 8, 92, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93,
+ 0, 0, 0, 0, 0, 91, 91, 0, 0, 0, 0, 0, 0, 8, 92, 0, 0, 91, 91, 0, 0, 3, 94, 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, 91, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 7, 7, 26, 92, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 2, 4, 4, 5, 6, 0, 0, 0, 0, 0,
- 0, 0, 9, 0, 0, 0, 0, 0, 15, 0, 96, 96, 0, 97, 0, 0, 9, 9, 20, 21, 98, 98, 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, 99, 28, 100, 101, 100, 101, 99, 28, 100, 101,
- 100, 101, 102, 103, 0, 0, 0, 0, 0, 0, 20, 104, 21, 105, 105, 106, 77, 9, 0, 77,
- 107, 108, 107, 9, 107, 9, 109, 110, 106, 109, 110, 109, 110, 9, 9, 9, 106,
- 0, 77, 106, 9, 106, 9, 108, 107, 0, 28, 0, 28, 0, 111, 0, 111, 0, 0, 0, 0, 0,
- 33, 33, 107, 9, 107, 9, 109, 110, 109, 110, 9, 9, 9, 106, 9, 106, 28, 28, 111,
- 111, 33, 33, 106, 77, 9, 9, 108, 107, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 112, 112, 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, 5, 5, 5, 0, 5, 5, 0, 91, 0, 0, 91, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 8, 8, 27, 92, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 3, 5, 5, 6, 7, 0,
+ 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 96, 96, 0, 97, 0, 0,
+ 0, 10, 10, 21, 22, 98, 98, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 99, 99, 0, 0, 0, 0, 0, 0, 100, 29,
+ 101, 102, 101, 102, 100, 29, 101, 102, 101, 102, 103, 104, 0, 0, 0, 0, 0, 0,
+ 21, 105, 22, 106, 106, 107, 77, 10, 0, 67, 67, 67, 67, 77, 108, 109, 108, 10,
+ 108, 10, 110, 111, 107, 110, 111, 110, 111, 10, 10, 10, 107, 0, 77, 107, 10,
+ 107, 10, 109, 108, 0, 29, 0, 29, 0, 112, 0, 112, 0, 0, 0, 0, 0, 34, 34, 108,
+ 10, 108, 10, 110, 111, 110, 111, 10, 10, 10, 107, 10, 107, 29, 29, 112, 112, 34,
+ 34, 107, 77, 10, 10, 109, 108, 0, 0, 0, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 113, 113, 10, 10, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 27, 113, 60, 60,
- 0, 0, 0, 0, 0, 0, 0, 0, 60, 114, 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, 0, 0, 10, 10, 28, 114, 2, 2, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2, 115, 10, 10, 10, 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, 115, 115, 47, 116, 115, 115, 115, 115, 115,
- 115, 115, 115, 0, 117, 117, 0, 71, 71, 118, 119, 67, 67, 67, 67, 120, 71, 121,
- 9, 9, 73, 115, 115, 49, 0, 0, 0, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 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, 123, 33, 124, 124, 28, 125, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, 105, 105, 105, 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, 114, 60, 7, 7, 7,
- 0, 7, 0, 7, 7, 7, 7, 7, 7, 0, 7, 7, 84, 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, 116, 116, 48, 117, 116, 116, 116, 116,
+ 116, 116, 116, 116, 0, 118, 118, 0, 71, 71, 119, 120, 67, 67, 67, 67, 121, 71,
+ 122, 10, 10, 73, 116, 116, 50, 0, 0, 0, 106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123,
+ 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 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, 124, 34, 125, 125, 29, 126, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 106,
+ 106, 106, 0, 0, 0, 0, 0, 0, 10, 10, 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, 126, 126, 127, 128, 124, 124, 124, 124, 85, 126, 129, 128,
- 127, 127, 128, 129, 128, 127, 128, 130, 131, 106, 106, 106, 130, 127, 128,
- 129, 128, 127, 128, 126, 128, 130, 131, 106, 106, 106, 130, 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,
- 132, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 10, 10, 10, 10, 0, 0, 0, 0, 2, 2, 115, 2, 8, 8, 8, 0, 8, 0, 8, 8, 8, 8, 8, 8,
+ 0, 8, 8, 84, 8, 0, 8, 0, 0, 8, 0, 0, 0, 0, 10, 10, 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, 127,
+ 127, 128, 129, 125, 125, 125, 125, 85, 127, 130, 129, 128, 128, 129, 130,
+ 129, 128, 129, 131, 132, 107, 107, 107, 131, 128, 129, 130, 129, 128, 129, 127,
+ 129, 131, 132, 107, 107, 107, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 67, 133, 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, 122, 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, 112, 112, 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, 112, 112, 0, 0, 9, 9, 0, 0, 0,
- 0, 0, 0, 0, 0, 67, 67, 0, 0, 0, 0, 0, 0, 0, 0, 67, 132, 0, 0, 0, 0, 0, 0, 9,
- 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 122, 20, 104, 21, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 133, 134, 133, 134, 0, 135, 0, 136, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 10, 10, 0, 0, 113, 113, 0, 0, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 10, 10, 0, 0, 113, 113, 0, 0, 10, 10, 0, 0, 0, 0, 0, 0, 0,
+ 0, 67, 67, 0, 0, 0, 0, 0, 0, 0, 0, 67, 133, 134, 135, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123, 123, 21, 105, 22,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 137, 136, 137, 0, 138, 0, 139, 0,
+ 0, 0, 3, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
const uint8_t InstDB::rwInfoIndexB[Inst::_kIdCount] = {
- 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 0, 0,
- 0, 0, 4, 0, 0, 0, 0, 0, 5, 5, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 7, 0, 0, 0, 0, 4, 8, 1, 0, 9, 0, 0, 0, 10, 10, 10, 0, 0, 11, 0, 0, 10, 12,
- 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, 5, 5, 0, 13, 14, 15, 16, 17, 0, 0, 18, 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, 19, 1, 1, 20, 21, 0, 0,
- 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 22, 23, 0, 0, 24, 25, 26, 27, 0, 0, 25, 25, 25,
- 25, 25, 25, 25, 25, 28, 29, 29, 28, 0, 0, 0, 24, 25, 24, 25, 0, 25, 24, 24, 24,
- 24, 24, 24, 24, 0, 0, 30, 30, 30, 24, 24, 28, 0, 31, 10, 0, 0, 0, 0, 0, 0, 24,
- 25, 0, 0, 0, 32, 33, 32, 34, 0, 0, 0, 0, 0, 10, 32, 0, 0, 0, 0, 35, 33, 32,
- 35, 34, 24, 25, 24, 25, 0, 29, 29, 29, 29, 0, 0, 0, 25, 10, 10, 32, 32, 0, 0,
- 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 21, 36, 0, 20, 37, 38, 0, 39, 40, 0, 0, 0, 0,
- 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 43, 44, 41, 42, 41, 42, 43,
- 44, 43, 44, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 43, 0, 0, 0, 0, 44, 45, 46, 47,
- 48, 45, 46, 47, 48, 0, 0, 0, 0, 49, 50, 51, 41, 42, 43, 44, 41, 42, 43, 44, 52,
- 0, 24, 0, 53, 0, 54, 0, 0, 0, 0, 0, 10, 0, 10, 24, 55, 56, 55, 0, 0, 0, 0,
- 0, 0, 55, 57, 57, 0, 58, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 60, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0,
+ 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 5, 5, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 4, 8, 1, 0, 9, 0, 0, 0, 10, 10, 10, 0, 0, 11, 0,
+ 0, 10, 12, 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, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 5, 5, 13, 0, 14, 15, 13, 16, 17, 18, 13, 0, 0, 19, 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, 20, 1, 1, 21, 22, 0, 0, 0,
+ 0, 5, 5, 0, 0, 0, 0, 0, 0, 23, 24, 0, 0, 25, 26, 27, 28, 0, 0, 26, 26, 26, 26,
+ 26, 26, 26, 26, 29, 30, 30, 29, 0, 0, 0, 25, 26, 25, 26, 0, 26, 25, 25, 25,
+ 25, 25, 25, 25, 0, 0, 31, 31, 31, 25, 25, 29, 0, 32, 10, 0, 0, 0, 0, 0, 0, 25,
+ 26, 0, 0, 0, 33, 34, 33, 35, 0, 0, 0, 0, 0, 10, 33, 0, 0, 0, 0, 36, 34, 33, 36,
+ 35, 25, 26, 25, 26, 0, 30, 30, 30, 30, 0, 0, 0, 26, 10, 10, 33, 33, 0, 0, 0,
+ 20, 5, 5, 0, 0, 0, 0, 0, 0, 0, 22, 37, 0, 21, 38, 39, 0, 40, 41, 0, 0, 0, 0,
+ 0, 10, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 45, 46, 43, 44, 43, 44,
+ 45, 46, 45, 46, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 45, 0, 0, 0, 0, 46, 47, 48,
+ 49, 50, 47, 48, 49, 50, 0, 0, 0, 0, 51, 52, 53, 43, 44, 45, 46, 43, 44, 45, 46,
+ 54, 0, 25, 0, 55, 0, 56, 0, 0, 0, 0, 0, 10, 0, 10, 25, 57, 58, 57, 0, 0, 0,
+ 0, 0, 0, 57, 59, 59, 0, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 62, 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, 61, 0, 0, 61, 0, 0, 0, 0, 0, 5, 62, 0, 0, 0, 0, 63, 0, 64, 20, 65, 20, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0,
- 6, 5, 5, 0, 0, 0, 0, 67, 68, 0, 0, 0, 0, 69, 70, 0, 3, 3, 71, 22, 72, 73, 0,
+ 0, 0, 63, 0, 0, 63, 0, 0, 0, 0, 0, 5, 64, 0, 0, 0, 0, 65, 0, 66, 21, 67, 21,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0,
+ 0, 6, 5, 5, 0, 0, 0, 0, 69, 70, 0, 0, 0, 0, 71, 72, 0, 3, 3, 73, 23, 74, 75,
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, 74, 39, 75, 76, 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, 77, 0, 0, 0, 0, 0, 0, 0, 10,
- 10, 10, 10, 10, 10, 10, 0, 0, 2, 2, 2, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 81, 80, 81, 81, 81, 80, 80, 82, 83, 0, 84,
- 0, 0, 0, 0, 0, 0, 85, 2, 2, 86, 87, 0, 0, 0, 11, 88, 0, 0, 4, 0, 0, 0, 89, 0,
- 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,
- 90, 90, 90, 90, 90, 90, 90, 90, 90, 0, 90, 0, 32, 0, 0, 0, 5, 0, 0, 6, 0, 91,
- 4, 0, 91, 4, 5, 5, 32, 19, 92, 80, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 0, 92,
- 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 95, 95, 95, 95, 0, 0, 0, 0,
- 0, 0, 96, 97, 0, 0, 0, 0, 0, 0, 0, 0, 56, 97, 0, 0, 0, 0, 98, 99, 98, 99, 3,
- 3, 3, 100, 101, 102, 3, 3, 3, 3, 3, 3, 0, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 103,
- 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 104, 3, 105, 106, 107, 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,
- 108, 0, 0, 0, 0, 0, 0, 0, 109, 0, 110, 0, 111, 0, 111, 0, 112, 113, 114, 115,
- 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, 0,
- 0, 0, 0, 112, 113, 114, 0, 0, 3, 3, 3, 3, 100, 111, 102, 3, 117, 3, 55, 55,
- 0, 0, 0, 0, 118, 119, 120, 119, 120, 118, 119, 120, 119, 120, 22, 121, 122, 121,
- 122, 121, 121, 123, 124, 121, 121, 121, 125, 126, 127, 121, 121, 121, 125,
- 126, 127, 121, 121, 121, 125, 126, 127, 121, 122, 128, 128, 129, 130, 121, 121,
- 121, 121, 121, 121, 121, 121, 121, 128, 128, 121, 121, 121, 125, 131, 127, 121,
- 121, 121, 125, 131, 127, 121, 121, 121, 125, 131, 127, 121, 121, 121, 121,
- 121, 121, 121, 121, 121, 128, 128, 128, 128, 129, 130, 121, 122, 121, 121, 121,
- 125, 126, 127, 121, 121, 121, 125, 126, 127, 121, 121, 121, 125, 126, 127,
- 128, 128, 129, 130, 121, 121, 121, 125, 131, 127, 121, 121, 121, 125, 131, 127,
- 121, 121, 121, 132, 131, 133, 128, 128, 129, 130, 134, 134, 134, 78, 135, 136,
- 0, 0, 0, 0, 137, 138, 10, 10, 10, 10, 10, 10, 10, 10, 138, 139, 0, 0, 0, 140,
- 141, 142, 85, 85, 85, 140, 141, 142, 3, 3, 3, 3, 3, 3, 3, 143, 144, 145, 144,
- 145, 143, 144, 145, 144, 145, 102, 0, 53, 58, 146, 146, 3, 3, 3, 100, 101,
- 102, 0, 147, 0, 3, 3, 3, 100, 101, 102, 0, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 149, 150, 150, 151, 152, 152, 0, 0, 0, 0, 0, 0, 0, 153, 154, 0, 0, 155,
- 0, 0, 0, 3, 11, 147, 0, 0, 156, 148, 3, 3, 3, 100, 101, 102, 0, 11, 3, 3, 157,
- 157, 158, 158, 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, 103, 3, 0, 0, 0, 0, 0, 0, 3, 128, 104, 104, 3,
- 3, 3, 3, 67, 68, 3, 3, 3, 3, 69, 70, 104, 104, 104, 104, 104, 104, 117, 117, 0,
- 0, 0, 0, 117, 117, 117, 117, 117, 117, 0, 0, 121, 121, 121, 121, 159, 159, 3,
- 3, 3, 121, 3, 3, 121, 121, 128, 128, 160, 160, 160, 3, 160, 3, 121, 121, 121,
- 121, 121, 3, 0, 0, 0, 0, 71, 22, 72, 161, 138, 137, 139, 138, 0, 0, 0, 3, 0,
- 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 0, 3, 3, 0, 162, 102, 100, 101, 0, 0,
- 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 121, 121, 3, 3, 146,
- 146, 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, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 3, 3, 3, 164, 85, 85,
- 3, 3, 85, 85, 3, 3, 165, 165, 165, 165, 3, 0, 0, 0, 0, 165, 165, 165, 165, 165,
- 165, 3, 3, 121, 121, 121, 3, 165, 165, 3, 3, 121, 121, 121, 3, 3, 104, 85, 85,
- 85, 3, 3, 3, 166, 167, 166, 3, 3, 3, 168, 166, 169, 3, 3, 3, 168, 166, 167,
- 166, 3, 3, 3, 168, 3, 3, 3, 3, 3, 3, 3, 3, 121, 121, 0, 104, 104, 104, 104, 104,
- 104, 104, 104, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 140, 142, 0, 0, 140,
- 142, 0, 0, 140, 142, 0, 0, 141, 142, 85, 85, 85, 140, 141, 142, 85, 85, 85, 140,
- 141, 142, 85, 85, 140, 142, 0, 0, 140, 142, 0, 0, 140, 142, 0, 0, 141, 142,
- 3, 3, 3, 100, 101, 102, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 3, 3, 3,
- 3, 3, 3, 0, 0, 0, 140, 141, 142, 93, 3, 3, 3, 100, 101, 102, 0, 0, 0, 0, 0, 3,
- 3, 3, 3, 3, 3, 0, 0, 0, 0, 56, 56, 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0,
- 0, 0, 0, 171, 171, 171, 171, 172, 172, 172, 172, 172, 172, 172, 172, 170, 0,
- 0
+ 0, 0, 0, 0, 76, 40, 77, 78, 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, 79, 0, 0, 0, 0, 0, 0, 0,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 2, 2, 2, 80, 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,
+ 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 81, 82, 81, 82, 82, 82, 81, 81, 83,
+ 84, 0, 85, 0, 0, 0, 0, 0, 0, 86, 2, 2, 87, 88, 0, 0, 0, 11, 89, 0, 0, 4, 0, 0,
+ 0, 0, 0, 0, 90, 0, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 0, 91, 0, 33, 0, 0,
+ 0, 5, 0, 0, 6, 0, 92, 4, 0, 92, 4, 5, 5, 33, 20, 93, 81, 93, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 94, 0, 93, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 96, 0,
+ 96, 96, 96, 96, 96, 96, 0, 0, 0, 0, 0, 0, 97, 0, 98, 0, 0, 0, 0, 0, 0, 0, 0, 10,
+ 98, 0, 0, 0, 0, 99, 100, 99, 100, 3, 3, 3, 101, 102, 103, 3, 3, 3, 3, 3, 3,
+ 0, 2, 3, 3, 3, 3, 3, 3, 0, 0, 3, 3, 3, 3, 104, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 3, 105, 3, 106, 107, 108, 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, 0, 0, 0, 0, 109, 0, 0, 0, 0, 0,
+ 0, 0, 110, 0, 111, 0, 112, 0, 112, 0, 113, 114, 115, 116, 117, 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, 114,
+ 115, 0, 0, 3, 3, 3, 3, 101, 112, 103, 3, 118, 3, 57, 57, 0, 0, 0, 0, 119, 120,
+ 121, 120, 121, 119, 120, 121, 120, 121, 23, 122, 123, 122, 123, 124, 124, 125,
+ 126, 124, 124, 124, 127, 128, 129, 124, 124, 124, 127, 128, 129, 124, 124,
+ 124, 127, 128, 129, 122, 123, 130, 130, 131, 132, 124, 124, 124, 124, 124, 124,
+ 124, 124, 124, 130, 130, 124, 124, 124, 127, 133, 129, 124, 124, 124, 127, 133,
+ 129, 124, 124, 124, 127, 133, 129, 124, 124, 124, 124, 124, 124, 124, 124,
+ 124, 130, 130, 130, 130, 131, 132, 122, 123, 124, 124, 124, 127, 128, 129, 124,
+ 124, 124, 127, 128, 129, 124, 124, 124, 127, 128, 129, 130, 130, 131, 132,
+ 124, 124, 124, 127, 133, 129, 124, 124, 124, 127, 133, 129, 124, 124, 124, 134,
+ 133, 135, 130, 130, 131, 132, 136, 136, 136, 80, 137, 138, 0, 0, 0, 0, 139,
+ 140, 10, 10, 10, 10, 10, 10, 10, 10, 140, 141, 0, 0, 0, 142, 143, 144, 86, 86,
+ 86, 142, 143, 144, 3, 3, 3, 3, 3, 3, 3, 145, 146, 147, 146, 147, 145, 146, 147,
+ 146, 147, 103, 0, 55, 60, 148, 148, 3, 3, 3, 101, 102, 103, 0, 149, 0, 0, 3,
+ 3, 3, 101, 102, 103, 0, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 151, 152,
+ 152, 153, 154, 154, 0, 0, 0, 0, 0, 0, 0, 155, 156, 0, 0, 157, 0, 0, 0, 3, 11,
+ 149, 0, 0, 158, 150, 3, 3, 3, 101, 102, 103, 0, 0, 11, 3, 3, 159, 159, 160,
+ 160, 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, 104, 3, 0, 0, 0, 0, 0, 0, 3, 130, 105, 105, 3, 3, 3, 3, 69, 70,
+ 3, 3, 3, 3, 71, 72, 105, 105, 105, 105, 105, 105, 118, 118, 0, 0, 0, 0, 118,
+ 118, 118, 118, 118, 118, 0, 0, 124, 124, 124, 124, 124, 124, 124, 124, 124,
+ 124, 124, 124, 124, 124, 124, 124, 161, 161, 3, 3, 124, 124, 3, 3, 124, 124, 130,
+ 130, 162, 162, 162, 3, 162, 124, 124, 124, 124, 124, 124, 3, 0, 0, 0, 0, 73,
+ 23, 74, 163, 140, 139, 141, 140, 0, 0, 0, 3, 0, 3, 0, 0, 0, 0, 0, 0, 3, 0,
+ 0, 0, 0, 3, 0, 3, 3, 0, 164, 103, 101, 102, 0, 0, 165, 165, 165, 165, 165, 165,
+ 165, 165, 165, 165, 165, 165, 124, 124, 3, 3, 148, 148, 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, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 0, 0, 0, 0, 3, 3, 3, 166, 86, 86, 3, 3, 86, 86, 3, 3, 167, 167,
+ 167, 167, 3, 0, 0, 0, 0, 167, 167, 167, 167, 167, 167, 3, 3, 124, 124, 124,
+ 3, 167, 167, 3, 3, 124, 124, 124, 3, 3, 105, 86, 86, 86, 3, 3, 3, 168, 169, 168,
+ 3, 3, 3, 170, 168, 171, 3, 3, 3, 170, 168, 169, 168, 3, 3, 3, 170, 3, 3, 3,
+ 3, 3, 3, 3, 3, 172, 172, 0, 105, 105, 105, 105, 105, 105, 105, 105, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 142, 144, 0, 0, 142, 144, 0, 0, 142, 144, 0, 0,
+ 143, 144, 86, 86, 86, 142, 143, 144, 86, 86, 86, 142, 143, 144, 86, 86, 142, 144,
+ 0, 0, 142, 144, 0, 0, 142, 144, 0, 0, 143, 144, 3, 3, 3, 101, 102, 103, 0,
+ 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 173, 3, 3, 3, 3, 3, 3, 174, 174,
+ 174, 3, 3, 0, 0, 0, 142, 143, 144, 94, 3, 3, 3, 101, 102, 103, 0, 0, 0, 0,
+ 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 58, 58, 175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 0,
+ 0, 0, 0, 0, 176, 176, 176, 176, 177, 177, 177, 177, 177, 177, 177, 177, 175,
+ 0, 0
};
const InstDB::RWInfo InstDB::rwInfoA[] = {
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #0 [ref=1007x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #0 [ref=1054x]
{ 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]
- { InstDB::RWInfo::kCategoryGeneric , 3 , { 4 , 5 , 0 , 0 , 0 , 0 } }, // #4 [ref=55x]
- { InstDB::RWInfo::kCategoryGeneric , 4 , { 6 , 7 , 0 , 0 , 0 , 0 } }, // #5 [ref=6x]
- { 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=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]
- { InstDB::RWInfo::kCategoryGeneric , 8 , { 15, 5 , 0 , 0 , 0 , 0 } }, // #13 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 3 , 3 , 0 , 0 , 0 , 0 } }, // #14 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 10, { 3 , 3 , 0 , 0 , 0 , 0 } }, // #15 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 10, { 2 , 3 , 0 , 0 , 0 , 0 } }, // #16 [ref=3x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 16, 17, 0 , 0 , 0 , 0 } }, // #17 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 1 , { 3 , 3 , 0 , 0 , 0 , 0 } }, // #18 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 20, 21, 0 , 0 , 0 , 0 } }, // #19 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 4 , { 7 , 7 , 0 , 0 , 0 , 0 } }, // #20 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 5 , { 9 , 9 , 0 , 0 , 0 , 0 } }, // #21 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 33, 34, 0 , 0 , 0 , 0 } }, // #22 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 14, { 2 , 3 , 0 , 0 , 0 , 0 } }, // #23 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 4 , { 10, 7 , 0 , 0 , 0 , 0 } }, // #24 [ref=10x]
- { InstDB::RWInfo::kCategoryGeneric , 3 , { 35, 5 , 0 , 0 , 0 , 0 } }, // #25 [ref=5x]
- { InstDB::RWInfo::kCategoryGeneric , 4 , { 36, 7 , 0 , 0 , 0 , 0 } }, // #26 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 4 , { 35, 7 , 0 , 0 , 0 , 0 } }, // #27 [ref=11x]
- { InstDB::RWInfo::kCategoryGeneric , 4 , { 11, 7 , 0 , 0 , 0 , 0 } }, // #28 [ref=9x]
- { InstDB::RWInfo::kCategoryGeneric , 4 , { 37, 7 , 0 , 0 , 0 , 0 } }, // #29 [ref=1x]
- { 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=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]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 4 , 5 , 0 , 0 , 0 , 0 } }, // #37 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 45, 46, 0 , 0 , 0 , 0 } }, // #38 [ref=6x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 0 , 50, 0 , 0 , 0 , 0 } }, // #39 [ref=1x]
- { InstDB::RWInfo::kCategoryImul , 2 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #40 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 51, 52, 0 , 0 , 0 , 0 } }, // #41 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 54, 52, 0 , 0 , 0 , 0 } }, // #42 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 13, { 3 , 5 , 0 , 0 , 0 , 0 } }, // #43 [ref=3x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 22, 29, 0 , 0 , 0 , 0 } }, // #44 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 55, 0 , 0 , 0 , 0 , 0 } }, // #45 [ref=1x]
- { 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=3x]
- { InstDB::RWInfo::kCategoryGeneric , 25, { 35, 7 , 0 , 0 , 0 , 0 } }, // #48 [ref=2x]
- { 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]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 48, 13, 0 , 0 , 0 , 0 } }, // #53 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 40, 40, 0 , 0 , 0 , 0 } }, // #54 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 9 , 9 , 0 , 0 , 0 , 0 } }, // #55 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 7 , 7 , 0 , 0 , 0 , 0 } }, // #56 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 13, 13, 0 , 0 , 0 , 0 } }, // #57 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 27, { 11, 3 , 0 , 0 , 0 , 0 } }, // #58 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 13, { 10, 5 , 0 , 0 , 0 , 0 } }, // #59 [ref=5x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 2 , 3 , 0 , 0 , 0 , 0 } }, // #60 [ref=11x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 2 , 3 , 0 , 0 , 0 , 0 } }, // #2 [ref=15x]
+ { InstDB::RWInfo::kCategoryGeneric , 1 , { 2 , 3 , 0 , 0 , 0 , 0 } }, // #3 [ref=7x]
+ { InstDB::RWInfo::kCategoryGeneric , 2 , { 2 , 3 , 0 , 0 , 0 , 0 } }, // #4 [ref=96x]
+ { InstDB::RWInfo::kCategoryGeneric , 3 , { 4 , 5 , 0 , 0 , 0 , 0 } }, // #5 [ref=55x]
+ { InstDB::RWInfo::kCategoryGeneric , 4 , { 6 , 7 , 0 , 0 , 0 , 0 } }, // #6 [ref=6x]
+ { InstDB::RWInfo::kCategoryGeneric , 5 , { 8 , 9 , 0 , 0 , 0 , 0 } }, // #7 [ref=6x]
+ { InstDB::RWInfo::kCategoryGeneric , 3 , { 10, 5 , 0 , 0 , 0 , 0 } }, // #8 [ref=26x]
+ { InstDB::RWInfo::kCategoryGeneric , 7 , { 12, 13, 0 , 0 , 0 , 0 } }, // #9 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 2 , { 11, 3 , 0 , 0 , 0 , 0 } }, // #10 [ref=75x]
+ { InstDB::RWInfo::kCategoryGeneric , 2 , { 5 , 3 , 0 , 0 , 0 , 0 } }, // #11 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 8 , { 10, 3 , 0 , 0 , 0 , 0 } }, // #12 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 9 , { 10, 5 , 0 , 0 , 0 , 0 } }, // #13 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 8 , { 15, 5 , 0 , 0 , 0 , 0 } }, // #14 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 3 , 3 , 0 , 0 , 0 , 0 } }, // #15 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 10, { 3 , 3 , 0 , 0 , 0 , 0 } }, // #16 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 10, { 2 , 3 , 0 , 0 , 0 , 0 } }, // #17 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 16, 17, 0 , 0 , 0 , 0 } }, // #18 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 1 , { 3 , 3 , 0 , 0 , 0 , 0 } }, // #19 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 14, { 20, 21, 0 , 0 , 0 , 0 } }, // #20 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 4 , { 7 , 7 , 0 , 0 , 0 , 0 } }, // #21 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 5 , { 9 , 9 , 0 , 0 , 0 , 0 } }, // #22 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 33, 34, 0 , 0 , 0 , 0 } }, // #23 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 16, { 2 , 3 , 0 , 0 , 0 , 0 } }, // #24 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 4 , { 10, 7 , 0 , 0 , 0 , 0 } }, // #25 [ref=10x]
+ { InstDB::RWInfo::kCategoryGeneric , 3 , { 35, 5 , 0 , 0 , 0 , 0 } }, // #26 [ref=5x]
+ { InstDB::RWInfo::kCategoryGeneric , 4 , { 36, 7 , 0 , 0 , 0 , 0 } }, // #27 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 4 , { 35, 7 , 0 , 0 , 0 , 0 } }, // #28 [ref=11x]
+ { InstDB::RWInfo::kCategoryGeneric , 4 , { 11, 7 , 0 , 0 , 0 , 0 } }, // #29 [ref=9x]
+ { InstDB::RWInfo::kCategoryGeneric , 4 , { 37, 7 , 0 , 0 , 0 , 0 } }, // #30 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 16, { 36, 3 , 0 , 0 , 0 , 0 } }, // #31 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 16, { 37, 3 , 0 , 0 , 0 , 0 } }, // #32 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 5 , { 36, 9 , 0 , 0 , 0 , 0 } }, // #33 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 5 , { 11, 9 , 0 , 0 , 0 , 0 } }, // #34 [ref=7x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 38, 39, 0 , 0 , 0 , 0 } }, // #35 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 17, { 1 , 40, 0 , 0 , 0 , 0 } }, // #36 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 13, { 43, 44, 0 , 0 , 0 , 0 } }, // #37 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 4 , 5 , 0 , 0 , 0 , 0 } }, // #38 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 46, 47, 0 , 0 , 0 , 0 } }, // #39 [ref=6x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 0 , 51, 0 , 0 , 0 , 0 } }, // #40 [ref=1x]
+ { InstDB::RWInfo::kCategoryImul , 2 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #41 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 52, 53, 0 , 0 , 0 , 0 } }, // #42 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 14, { 55, 53, 0 , 0 , 0 , 0 } }, // #43 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 15, { 3 , 5 , 0 , 0 , 0 , 0 } }, // #44 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 22, 29, 0 , 0 , 0 , 0 } }, // #45 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 57, 0 , 0 , 0 , 0 , 0 } }, // #46 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 23, { 58, 40, 0 , 0 , 0 , 0 } }, // #47 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 24, { 45, 9 , 0 , 0 , 0 , 0 } }, // #48 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 25, { 35, 7 , 0 , 0 , 0 , 0 } }, // #49 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 26, { 49, 13, 0 , 0 , 0 , 0 } }, // #50 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 58, 40, 0 , 0 , 0 , 0 } }, // #51 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 45, 9 , 0 , 0 , 0 , 0 } }, // #52 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 35, 7 , 0 , 0 , 0 , 0 } }, // #53 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 49, 13, 0 , 0 , 0 , 0 } }, // #54 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 40, 40, 0 , 0 , 0 , 0 } }, // #55 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 9 , 9 , 0 , 0 , 0 , 0 } }, // #56 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 7 , 7 , 0 , 0 , 0 , 0 } }, // #57 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 13, 13, 0 , 0 , 0 , 0 } }, // #58 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 27, { 11, 3 , 0 , 0 , 0 , 0 } }, // #59 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 15, { 10, 5 , 0 , 0 , 0 , 0 } }, // #60 [ref=5x]
{ InstDB::RWInfo::kCategoryGeneric , 8 , { 11, 3 , 0 , 0 , 0 , 0 } }, // #61 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 51, 20, 0 , 0 , 0 , 0 } }, // #62 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 58, 0 , 0 , 0 , 0 , 0 } }, // #63 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 52, 20, 0 , 0 , 0 , 0 } }, // #62 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 60, 0 , 0 , 0 , 0 , 0 } }, // #63 [ref=3x]
{ InstDB::RWInfo::kCategoryMov , 29, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #64 [ref=1x]
{ InstDB::RWInfo::kCategoryMovabs , 0 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #65 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 30, { 10, 5 , 0 , 0 , 0 , 0 } }, // #66 [ref=6x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 11, 3 , 0 , 0 , 0 , 0 } }, // #67 [ref=14x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 36, 61, 0 , 0 , 0 , 0 } }, // #68 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 11, 3 , 0 , 0 , 0 , 0 } }, // #67 [ref=18x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 36, 64, 0 , 0 , 0 , 0 } }, // #68 [ref=1x]
{ InstDB::RWInfo::kCategoryMovh64 , 12, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #69 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 62, 7 , 0 , 0 , 0 , 0 } }, // #70 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 65, 7 , 0 , 0 , 0 , 0 } }, // #70 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 12, { 35, 7 , 0 , 0 , 0 , 0 } }, // #71 [ref=7x]
- { 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 , 0 , { 58, 5 , 0 , 0 , 0 , 0 } }, // #72 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 28, { 45, 9 , 0 , 0 , 0 , 0 } }, // #73 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 14, { 66, 20, 0 , 0 , 0 , 0 } }, // #74 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 31, { 35, 7 , 0 , 0 , 0 , 0 } }, // #75 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 33, { 44, 9 , 0 , 0 , 0 , 0 } }, // #76 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 14, { 11, 3 , 0 , 0 , 0 , 0 } }, // #77 [ref=6x]
+ { InstDB::RWInfo::kCategoryGeneric , 33, { 45, 9 , 0 , 0 , 0 , 0 } }, // #76 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 16, { 11, 3 , 0 , 0 , 0 , 0 } }, // #77 [ref=6x]
{ InstDB::RWInfo::kCategoryGeneric , 0 , { 17, 29, 0 , 0 , 0 , 0 } }, // #78 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 11, { 3 , 3 , 0 , 0 , 0 , 0 } }, // #79 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 52, 22, 0 , 0 , 0 , 0 } }, // #80 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 52, 66, 0 , 0 , 0 , 0 } }, // #81 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 53, 22, 0 , 0 , 0 , 0 } }, // #80 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 14, { 53, 69, 0 , 0 , 0 , 0 } }, // #81 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 4 , { 26, 7 , 0 , 0 , 0 , 0 } }, // #82 [ref=18x]
{ InstDB::RWInfo::kCategoryGeneric , 36, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #83 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 3 , { 69, 5 , 0 , 0 , 0 , 0 } }, // #84 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 3 , { 72, 5 , 0 , 0 , 0 , 0 } }, // #84 [ref=2x]
{ InstDB::RWInfo::kCategoryVmov1_8 , 0 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #85 [ref=2x]
{ InstDB::RWInfo::kCategoryGeneric , 5 , { 10, 9 , 0 , 0 , 0 , 0 } }, // #86 [ref=4x]
{ InstDB::RWInfo::kCategoryGeneric , 27, { 10, 13, 0 , 0 , 0 , 0 } }, // #87 [ref=2x]
{ InstDB::RWInfo::kCategoryGeneric , 0 , { 4 , 0 , 0 , 0 , 0 , 0 } }, // #88 [ref=2x]
{ InstDB::RWInfo::kCategoryGeneric , 3 , { 5 , 5 , 0 , 0 , 0 , 0 } }, // #89 [ref=1x]
{ InstDB::RWInfo::kCategoryPunpcklxx , 38, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #90 [ref=3x]
- { InstDB::RWInfo::kCategoryGeneric , 10, { 2 , 71, 0 , 0 , 0 , 0 } }, // #91 [ref=8x]
+ { InstDB::RWInfo::kCategoryGeneric , 10, { 2 , 73, 0 , 0 , 0 , 0 } }, // #91 [ref=8x]
{ InstDB::RWInfo::kCategoryGeneric , 5 , { 37, 9 , 0 , 0 , 0 , 0 } }, // #92 [ref=3x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 16, 50, 0 , 0 , 0 , 0 } }, // #93 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 16, 51, 0 , 0 , 0 , 0 } }, // #93 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 0 , { 22, 21, 0 , 0 , 0 , 0 } }, // #94 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 63, 22, 0 , 0 , 0 , 0 } }, // #95 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 8 , { 74, 3 , 0 , 0 , 0 , 0 } }, // #96 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 8 , { 11, 43, 0 , 0 , 0 , 0 } }, // #97 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 5 , { 53, 9 , 0 , 0 , 0 , 0 } }, // #98 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 13, { 80, 5 , 0 , 0 , 0 , 0 } }, // #99 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 13, { 11, 5 , 0 , 0 , 0 , 0 } }, // #100 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 43, { 74, 81, 0 , 0 , 0 , 0 } }, // #101 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 44, { 11, 7 , 0 , 0 , 0 , 0 } }, // #102 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 45, { 11, 9 , 0 , 0 , 0 , 0 } }, // #103 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 27, { 13, 13, 0 , 0 , 0 , 0 } }, // #104 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 11, { 11, 3 , 0 , 0 , 0 , 0 } }, // #105 [ref=7x]
- { InstDB::RWInfo::kCategoryVmov2_1 , 46, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #106 [ref=14x]
- { InstDB::RWInfo::kCategoryVmov1_2 , 14, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #107 [ref=7x]
- { InstDB::RWInfo::kCategoryGeneric , 14, { 10, 3 , 0 , 0 , 0 , 0 } }, // #108 [ref=3x]
- { InstDB::RWInfo::kCategoryGeneric , 46, { 11, 3 , 0 , 0 , 0 , 0 } }, // #109 [ref=5x]
- { InstDB::RWInfo::kCategoryGeneric , 47, { 11, 5 , 0 , 0 , 0 , 0 } }, // #110 [ref=5x]
- { InstDB::RWInfo::kCategoryGeneric , 27, { 11, 5 , 0 , 0 , 0 , 0 } }, // #111 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 51, { 74, 43, 0 , 0 , 0 , 0 } }, // #112 [ref=6x]
- { InstDB::RWInfo::kCategoryGeneric , 5 , { 44, 9 , 0 , 0 , 0 , 0 } }, // #113 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 18, { 2 , 3 , 0 , 0 , 0 , 0 } }, // #114 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 58, { 11, 3 , 0 , 0 , 0 , 0 } }, // #115 [ref=12x]
- { InstDB::RWInfo::kCategoryVmovddup , 38, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #116 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 12, { 35, 61, 0 , 0 , 0 , 0 } }, // #117 [ref=2x]
- { InstDB::RWInfo::kCategoryVmovmskpd , 0 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #118 [ref=1x]
- { InstDB::RWInfo::kCategoryVmovmskps , 0 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #119 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 59, { 35, 7 , 0 , 0 , 0 , 0 } }, // #120 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 21, { 48, 13, 0 , 0 , 0 , 0 } }, // #121 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 2 , { 3 , 3 , 0 , 0 , 0 , 0 } }, // #122 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 15, { 11, 40, 0 , 0 , 0 , 0 } }, // #123 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 11, 7 , 0 , 0 , 0 , 0 } }, // #124 [ref=6x]
- { InstDB::RWInfo::kCategoryGeneric , 27, { 11, 13, 0 , 0 , 0 , 0 } }, // #125 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 35, 3 , 0 , 0 , 0 , 0 } }, // #126 [ref=4x]
- { InstDB::RWInfo::kCategoryVmov1_4 , 62, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #127 [ref=6x]
- { InstDB::RWInfo::kCategoryVmov1_2 , 48, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #128 [ref=9x]
- { InstDB::RWInfo::kCategoryVmov1_8 , 63, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #129 [ref=3x]
- { InstDB::RWInfo::kCategoryVmov4_1 , 47, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #130 [ref=4x]
- { InstDB::RWInfo::kCategoryVmov8_1 , 64, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #131 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 18, { 11, 3 , 0 , 0 , 0 , 0 } }, // #132 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 17, { 44, 9 , 0 , 0 , 0 , 0 } }, // #133 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 35, { 35, 7 , 0 , 0 , 0 , 0 } }, // #134 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 11, { 2 , 2 , 0 , 0 , 0 , 0 } }, // #135 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 58, { 2 , 2 , 0 , 0 , 0 , 0 } } // #136 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 66, 22, 0 , 0 , 0 , 0 } }, // #95 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 8 , { 43, 3 , 0 , 0 , 0 , 0 } }, // #96 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 8 , { 11, 44, 0 , 0 , 0 , 0 } }, // #97 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 5 , { 54, 9 , 0 , 0 , 0 , 0 } }, // #98 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 21, { 11, 13, 0 , 0 , 0 , 0 } }, // #99 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 15, { 81, 5 , 0 , 0 , 0 , 0 } }, // #100 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 15, { 11, 5 , 0 , 0 , 0 , 0 } }, // #101 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 43, { 43, 82, 0 , 0 , 0 , 0 } }, // #102 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 44, { 11, 7 , 0 , 0 , 0 , 0 } }, // #103 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 45, { 11, 9 , 0 , 0 , 0 , 0 } }, // #104 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 27, { 13, 13, 0 , 0 , 0 , 0 } }, // #105 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 11, { 11, 3 , 0 , 0 , 0 , 0 } }, // #106 [ref=7x]
+ { InstDB::RWInfo::kCategoryVmov2_1 , 46, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #107 [ref=14x]
+ { InstDB::RWInfo::kCategoryVmov1_2 , 16, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #108 [ref=7x]
+ { InstDB::RWInfo::kCategoryGeneric , 16, { 10, 3 , 0 , 0 , 0 , 0 } }, // #109 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 46, { 11, 3 , 0 , 0 , 0 , 0 } }, // #110 [ref=5x]
+ { InstDB::RWInfo::kCategoryGeneric , 47, { 11, 5 , 0 , 0 , 0 , 0 } }, // #111 [ref=5x]
+ { InstDB::RWInfo::kCategoryGeneric , 27, { 11, 5 , 0 , 0 , 0 , 0 } }, // #112 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 51, { 43, 44, 0 , 0 , 0 , 0 } }, // #113 [ref=6x]
+ { InstDB::RWInfo::kCategoryGeneric , 5 , { 45, 9 , 0 , 0 , 0 , 0 } }, // #114 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 14, { 2 , 3 , 0 , 0 , 0 , 0 } }, // #115 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 58, { 11, 3 , 0 , 0 , 0 , 0 } }, // #116 [ref=12x]
+ { InstDB::RWInfo::kCategoryVmovddup , 38, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #117 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 12, { 35, 64, 0 , 0 , 0 , 0 } }, // #118 [ref=2x]
+ { InstDB::RWInfo::kCategoryVmovmskpd , 0 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #119 [ref=1x]
+ { InstDB::RWInfo::kCategoryVmovmskps , 0 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #120 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 59, { 35, 7 , 0 , 0 , 0 , 0 } }, // #121 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 21, { 49, 13, 0 , 0 , 0 , 0 } }, // #122 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 2 , { 3 , 3 , 0 , 0 , 0 , 0 } }, // #123 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 17, { 11, 40, 0 , 0 , 0 , 0 } }, // #124 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 11, 7 , 0 , 0 , 0 , 0 } }, // #125 [ref=6x]
+ { InstDB::RWInfo::kCategoryGeneric , 27, { 11, 13, 0 , 0 , 0 , 0 } }, // #126 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 35, 3 , 0 , 0 , 0 , 0 } }, // #127 [ref=4x]
+ { InstDB::RWInfo::kCategoryVmov1_4 , 62, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #128 [ref=6x]
+ { InstDB::RWInfo::kCategoryVmov1_2 , 48, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #129 [ref=9x]
+ { InstDB::RWInfo::kCategoryVmov1_8 , 63, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #130 [ref=3x]
+ { InstDB::RWInfo::kCategoryVmov4_1 , 47, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #131 [ref=4x]
+ { InstDB::RWInfo::kCategoryVmov8_1 , 64, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #132 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 14, { 11, 3 , 0 , 0 , 0 , 0 } }, // #133 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 90, 5 , 0 , 0 , 0 , 0 } }, // #134 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 90, 82, 0 , 0 , 0 , 0 } }, // #135 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 18, { 45, 9 , 0 , 0 , 0 , 0 } }, // #136 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 35, { 35, 7 , 0 , 0 , 0 , 0 } }, // #137 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 11, { 2 , 2 , 0 , 0 , 0 , 0 } }, // #138 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 58, { 2 , 2 , 0 , 0 , 0 , 0 } } // #139 [ref=1x]
};
const InstDB::RWInfo InstDB::rwInfoB[] = {
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #0 [ref=773x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #0 [ref=791x]
{ 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=193x]
@@ -4067,201 +5802,206 @@ const InstDB::RWInfo InstDB::rwInfoB[] = {
{ InstDB::RWInfo::kCategoryGeneric , 0 , { 2 , 0 , 0 , 0 , 0 , 0 } }, // #7 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 11, { 3 , 0 , 0 , 0 , 0 , 0 } }, // #8 [ref=2x]
{ InstDB::RWInfo::kCategoryGeneric , 0 , { 18, 0 , 0 , 0 , 0 , 0 } }, // #9 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 8 , { 3 , 0 , 0 , 0 , 0 , 0 } }, // #10 [ref=34x]
+ { InstDB::RWInfo::kCategoryGeneric , 8 , { 3 , 0 , 0 , 0 , 0 , 0 } }, // #10 [ref=37x]
{ InstDB::RWInfo::kCategoryGeneric , 12, { 7 , 0 , 0 , 0 , 0 , 0 } }, // #11 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 19, 0 , 0 , 0 , 0 , 0 } }, // #12 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 4 , { 6 , 7 , 0 , 0 , 0 , 0 } }, // #13 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 5 , { 8 , 9 , 0 , 0 , 0 , 0 } }, // #14 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 11, { 2 , 3 , 22, 0 , 0 , 0 } }, // #15 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 13, { 4 , 23, 18, 24, 25, 0 } }, // #16 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 12, { 26, 27, 28, 29, 30, 0 } }, // #17 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 28, 31, 32, 16, 0 , 0 } }, // #18 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 28, 0 , 0 , 0 , 0 , 0 } }, // #19 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 10, { 2 , 0 , 0 , 0 , 0 , 0 } }, // #20 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 6 , { 41, 42, 3 , 0 , 0 , 0 } }, // #21 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 17, { 44, 5 , 0 , 0 , 0 , 0 } }, // #22 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 4 , 0 , 0 , 0 , 0 , 0 } }, // #23 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 18, { 3 , 0 , 0 , 0 , 0 , 0 } }, // #24 [ref=17x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 45, 0 , 0 , 0 , 0 , 0 } }, // #25 [ref=16x]
- { InstDB::RWInfo::kCategoryGeneric , 19, { 46, 0 , 0 , 0 , 0 , 0 } }, // #26 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 13, { 19, 0 , 0 , 0 , 0 , 0 } }, // #12 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 2 , 2 , 3 , 0 , 0 , 0 } }, // #13 [ref=16x]
+ { InstDB::RWInfo::kCategoryGeneric , 4 , { 6 , 7 , 0 , 0 , 0 , 0 } }, // #14 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 5 , { 8 , 9 , 0 , 0 , 0 , 0 } }, // #15 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 11, { 2 , 3 , 22, 0 , 0 , 0 } }, // #16 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 15, { 4 , 23, 18, 24, 25, 0 } }, // #17 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 12, { 26, 27, 28, 29, 30, 0 } }, // #18 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 28, 31, 32, 16, 0 , 0 } }, // #19 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 28, 0 , 0 , 0 , 0 , 0 } }, // #20 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 10, { 2 , 0 , 0 , 0 , 0 , 0 } }, // #21 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 6 , { 41, 42, 3 , 0 , 0 , 0 } }, // #22 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 18, { 45, 5 , 0 , 0 , 0 , 0 } }, // #23 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 4 , 0 , 0 , 0 , 0 , 0 } }, // #24 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 14, { 3 , 0 , 0 , 0 , 0 , 0 } }, // #25 [ref=17x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 46, 0 , 0 , 0 , 0 , 0 } }, // #26 [ref=16x]
{ InstDB::RWInfo::kCategoryGeneric , 19, { 47, 0 , 0 , 0 , 0 , 0 } }, // #27 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 20, { 3 , 0 , 0 , 0 , 0 , 0 } }, // #28 [ref=3x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 46, 0 , 0 , 0 , 0 , 0 } }, // #29 [ref=6x]
- { InstDB::RWInfo::kCategoryGeneric , 18, { 11, 0 , 0 , 0 , 0 , 0 } }, // #30 [ref=3x]
- { InstDB::RWInfo::kCategoryGeneric , 21, { 13, 0 , 0 , 0 , 0 , 0 } }, // #31 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 8 , { 11, 0 , 0 , 0 , 0 , 0 } }, // #32 [ref=8x]
- { InstDB::RWInfo::kCategoryGeneric , 21, { 48, 0 , 0 , 0 , 0 , 0 } }, // #33 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 7 , { 49, 0 , 0 , 0 , 0 , 0 } }, // #34 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 20, { 11, 0 , 0 , 0 , 0 , 0 } }, // #35 [ref=2x]
- { InstDB::RWInfo::kCategoryImul , 22, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #36 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 53, 0 , 0 , 0 , 0 , 0 } }, // #37 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 26, 0 , 0 , 0 , 0 , 0 } }, // #38 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 5 , { 4 , 9 , 0 , 0 , 0 , 0 } }, // #39 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 4 , 5 , 0 , 0 , 0 , 0 } }, // #40 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 56, 40, 40, 0 , 0 , 0 } }, // #41 [ref=6x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 44, 9 , 9 , 0 , 0 , 0 } }, // #42 [ref=6x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 35, 7 , 7 , 0 , 0 , 0 } }, // #43 [ref=6x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 48, 13, 13, 0 , 0 , 0 } }, // #44 [ref=6x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 56, 40, 0 , 0 , 0 , 0 } }, // #45 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 44, 9 , 0 , 0 , 0 , 0 } }, // #46 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 35, 7 , 0 , 0 , 0 , 0 } }, // #47 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 48, 13, 0 , 0 , 0 , 0 } }, // #48 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 48, 40, 40, 0 , 0 , 0 } }, // #49 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 35, 9 , 9 , 0 , 0 , 0 } }, // #50 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 44, 13, 13, 0 , 0 , 0 } }, // #51 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 57, 0 , 0 , 0 , 0 , 0 } }, // #52 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 28, { 9 , 0 , 0 , 0 , 0 , 0 } }, // #53 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 16, { 43, 0 , 0 , 0 , 0 , 0 } }, // #54 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 7 , { 13, 0 , 0 , 0 , 0 , 0 } }, // #55 [ref=5x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 3 , 0 , 0 , 0 , 0 , 0 } }, // #56 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 5 , { 3 , 9 , 0 , 0 , 0 , 0 } }, // #57 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 5 , 5 , 59, 0 , 0 , 0 } }, // #58 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 7 , 7 , 59, 0 , 0 , 0 } }, // #59 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 19, 29, 60, 0 , 0 , 0 } }, // #60 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 32, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #61 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 6 , { 64, 42, 3 , 0 , 0 , 0 } }, // #62 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 6 , { 11, 11, 3 , 65, 0 , 0 } }, // #63 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 17, 29, 30, 0 , 0 , 0 } }, // #64 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 10, { 3 , 0 , 0 , 0 , 0 , 0 } }, // #65 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 2 , { 2 , 3 , 0 , 0 , 0 , 0 } }, // #66 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 3 , { 5 , 5 , 0 , 67, 17, 60 } }, // #67 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 3 , { 5 , 5 , 0 , 68, 17, 60 } }, // #68 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 3 , { 5 , 5 , 0 , 67, 0 , 0 } }, // #69 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 3 , { 5 , 5 , 0 , 68, 0 , 0 } }, // #70 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 34, { 56, 5 , 0 , 0 , 0 , 0 } }, // #71 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 35, { 35, 5 , 0 , 0 , 0 , 0 } }, // #72 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 37, { 48, 3 , 0 , 0 , 0 , 0 } }, // #73 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 15, { 4 , 40, 0 , 0 , 0 , 0 } }, // #74 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 4 , { 4 , 7 , 0 , 0 , 0 , 0 } }, // #75 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 27, { 2 , 13, 0 , 0 , 0 , 0 } }, // #76 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 10, { 70, 0 , 0 , 0 , 0 , 0 } }, // #77 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 4 , { 35, 7 , 0 , 0 , 0 , 0 } }, // #78 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 10, { 65, 0 , 0 , 0 , 0 , 0 } }, // #79 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 11, 0 , 0 , 0 , 0 , 0 } }, // #80 [ref=6x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 16, 50, 29, 0 , 0 , 0 } }, // #81 [ref=5x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 44, 0 , 0 , 0 , 0 , 0 } }, // #82 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 35, 0 , 0 , 0 , 0 , 0 } }, // #83 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 16, 50, 67, 0 , 0 , 0 } }, // #84 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 2 , { 11, 3 , 0 , 0 , 0 , 0 } }, // #85 [ref=19x]
- { InstDB::RWInfo::kCategoryGeneric , 4 , { 36, 7 , 0 , 0 , 0 , 0 } }, // #86 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 5 , { 37, 9 , 0 , 0 , 0 , 0 } }, // #87 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 72, 0 , 0 , 0 , 0 , 0 } }, // #88 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 7 , 0 , 0 , 0 , 0 , 0 } }, // #89 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 34, { 73, 0 , 0 , 0 , 0 , 0 } }, // #90 [ref=30x]
- { InstDB::RWInfo::kCategoryGeneric , 11, { 2 , 3 , 71, 0 , 0 , 0 } }, // #91 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 39, { 11, 0 , 0 , 0 , 0 , 0 } }, // #92 [ref=3x]
- { InstDB::RWInfo::kCategoryGeneric , 28, { 44, 0 , 0 , 0 , 0 , 0 } }, // #93 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 16, { 74, 0 , 0 , 0 , 0 , 0 } }, // #94 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 75, 43, 43, 0 , 0 , 0 } }, // #95 [ref=5x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 74, 0 , 0 , 0 , 0 , 0 } }, // #96 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 9 , 60, 17, 0 , 0 , 0 } }, // #97 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 13, { 75, 76, 77, 77, 77, 5 } }, // #98 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 13, { 4 , 78, 79, 79, 79, 5 } }, // #99 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 40, { 10, 5 , 7 , 0 , 0 , 0 } }, // #100 [ref=8x]
- { InstDB::RWInfo::kCategoryGeneric , 41, { 10, 5 , 13, 0 , 0 , 0 } }, // #101 [ref=7x]
- { InstDB::RWInfo::kCategoryGeneric , 42, { 10, 5 , 9 , 0 , 0 , 0 } }, // #102 [ref=9x]
- { InstDB::RWInfo::kCategoryGeneric , 6 , { 11, 3 , 3 , 3 , 0 , 0 } }, // #103 [ref=3x]
- { InstDB::RWInfo::kCategoryGeneric , 6 , { 35, 3 , 3 , 0 , 0 , 0 } }, // #104 [ref=18x]
- { InstDB::RWInfo::kCategoryGeneric , 40, { 11, 5 , 7 , 0 , 0 , 0 } }, // #105 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 41, { 35, 13, 13, 0 , 0 , 0 } }, // #106 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 42, { 11, 5 , 9 , 0 , 0 , 0 } }, // #107 [ref=1x]
- { InstDB::RWInfo::kCategoryVmov1_2 , 48, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #108 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 40, { 10, 5 , 5 , 0 , 0 , 0 } }, // #109 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 40, { 10, 82, 7 , 0 , 0 , 0 } }, // #110 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 41, { 10, 5 , 5 , 0 , 0 , 0 } }, // #111 [ref=3x]
- { InstDB::RWInfo::kCategoryGeneric , 49, { 10, 61, 3 , 0 , 0 , 0 } }, // #112 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 49, { 10, 3 , 3 , 0 , 0 , 0 } }, // #113 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 49, { 10, 82, 3 , 0 , 0 , 0 } }, // #114 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 42, { 10, 61, 9 , 0 , 0 , 0 } }, // #115 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 42, { 10, 5 , 5 , 0 , 0 , 0 } }, // #116 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 50, { 10, 5 , 5 , 0 , 0 , 0 } }, // #117 [ref=9x]
- { InstDB::RWInfo::kCategoryGeneric , 52, { 10, 81, 0 , 0 , 0 , 0 } }, // #118 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 52, { 10, 3 , 0 , 0 , 0 , 0 } }, // #119 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 53, { 80, 43, 0 , 0 , 0 , 0 } }, // #120 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 6 , { 2 , 3 , 3 , 0 , 0 , 0 } }, // #121 [ref=82x]
- { InstDB::RWInfo::kCategoryGeneric , 42, { 4 , 5 , 5 , 0 , 0 , 0 } }, // #122 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 40, { 4 , 61, 7 , 0 , 0 , 0 } }, // #123 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 42, { 4 , 82, 9 , 0 , 0 , 0 } }, // #124 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 40, { 6 , 7 , 7 , 0 , 0 , 0 } }, // #125 [ref=11x]
- { InstDB::RWInfo::kCategoryGeneric , 41, { 4 , 5 , 5 , 0 , 0 , 0 } }, // #126 [ref=6x]
- { InstDB::RWInfo::kCategoryGeneric , 42, { 8 , 9 , 9 , 0 , 0 , 0 } }, // #127 [ref=11x]
- { InstDB::RWInfo::kCategoryGeneric , 54, { 11, 3 , 3 , 3 , 0 , 0 } }, // #128 [ref=15x]
- { InstDB::RWInfo::kCategoryGeneric , 55, { 35, 7 , 7 , 7 , 0 , 0 } }, // #129 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 56, { 44, 9 , 9 , 9 , 0 , 0 } }, // #130 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 41, { 4 , 5 , 13, 0 , 0 , 0 } }, // #131 [ref=6x]
- { InstDB::RWInfo::kCategoryGeneric , 40, { 26, 7 , 7 , 0 , 0 , 0 } }, // #132 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 42, { 53, 9 , 9 , 0 , 0 , 0 } }, // #133 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 14, { 35, 3 , 0 , 0 , 0 , 0 } }, // #134 [ref=3x]
- { InstDB::RWInfo::kCategoryGeneric , 27, { 35, 13, 0 , 0 , 0 , 0 } }, // #135 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 5 , { 35, 9 , 0 , 0 , 0 , 0 } }, // #136 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 8 , { 2 , 3 , 2 , 0 , 0 , 0 } }, // #137 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 2 , 3 , 2 , 0 , 0 , 0 } }, // #138 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 18, { 4 , 3 , 4 , 0 , 0 , 0 } }, // #139 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 40, { 10, 61, 7 , 0 , 0 , 0 } }, // #140 [ref=11x]
- { InstDB::RWInfo::kCategoryGeneric , 41, { 10, 83, 13, 0 , 0 , 0 } }, // #141 [ref=7x]
- { InstDB::RWInfo::kCategoryGeneric , 42, { 10, 82, 9 , 0 , 0 , 0 } }, // #142 [ref=13x]
- { InstDB::RWInfo::kCategoryGeneric , 50, { 80, 81, 5 , 0 , 0 , 0 } }, // #143 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 50, { 11, 3 , 5 , 0 , 0 , 0 } }, // #144 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 57, { 74, 43, 81, 0 , 0 , 0 } }, // #145 [ref=4x]
- { InstDB::RWInfo::kCategoryVmaskmov , 0 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #146 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 12, { 35, 0 , 0 , 0 , 0 , 0 } }, // #147 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 22, 0 , 0 , 0 , 0 , 0 } }, // #148 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 10, 61, 61, 0 , 0 , 0 } }, // #149 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 12, { 10, 7 , 7 , 0 , 0 , 0 } }, // #150 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 10, 7 , 7 , 0 , 0 , 0 } }, // #151 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 12, { 10, 61, 7 , 0 , 0 , 0 } }, // #152 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 10, 61, 7 , 0 , 0 , 0 } }, // #153 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 10, 83, 13, 0 , 0 , 0 } }, // #154 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 10, 82, 9 , 0 , 0 , 0 } }, // #155 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 84, 0 , 0 , 0 , 0 , 0 } }, // #156 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 60, { 85, 86, 3 , 3 , 0 , 0 } }, // #157 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 13, { 74, 76, 77, 77, 77, 5 } }, // #158 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 57, { 80, 81, 81, 0 , 0 , 0 } }, // #159 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 22, { 11, 3 , 3 , 0 , 0 , 0 } }, // #160 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 7 , { 48, 5 , 0 , 0 , 0 , 0 } }, // #161 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 61, { 10, 5 , 40, 0 , 0 , 0 } }, // #162 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 50, { 10, 5 , 5 , 5 , 0 , 0 } }, // #163 [ref=12x]
- { InstDB::RWInfo::kCategoryGeneric , 65, { 10, 5 , 5 , 5 , 0 , 0 } }, // #164 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 66, { 10, 5 , 5 , 0 , 0 , 0 } }, // #165 [ref=12x]
- { InstDB::RWInfo::kCategoryGeneric , 67, { 11, 3 , 5 , 0 , 0 , 0 } }, // #166 [ref=5x]
- { InstDB::RWInfo::kCategoryGeneric , 68, { 11, 3 , 0 , 0 , 0 , 0 } }, // #167 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 69, { 11, 3 , 5 , 0 , 0 , 0 } }, // #168 [ref=3x]
- { InstDB::RWInfo::kCategoryGeneric , 22, { 11, 3 , 5 , 0 , 0 , 0 } }, // #169 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 60, 17, 29, 0 , 0 , 0 } }, // #170 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 8 , { 3 , 60, 17, 0 , 0 , 0 } }, // #171 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 8 , { 11, 60, 17, 0 , 0 , 0 } } // #172 [ref=8x]
+ { InstDB::RWInfo::kCategoryGeneric , 19, { 48, 0 , 0 , 0 , 0 , 0 } }, // #28 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 20, { 3 , 0 , 0 , 0 , 0 , 0 } }, // #29 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 47, 0 , 0 , 0 , 0 , 0 } }, // #30 [ref=6x]
+ { InstDB::RWInfo::kCategoryGeneric , 14, { 11, 0 , 0 , 0 , 0 , 0 } }, // #31 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 21, { 13, 0 , 0 , 0 , 0 , 0 } }, // #32 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 8 , { 11, 0 , 0 , 0 , 0 , 0 } }, // #33 [ref=8x]
+ { InstDB::RWInfo::kCategoryGeneric , 21, { 49, 0 , 0 , 0 , 0 , 0 } }, // #34 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 7 , { 50, 0 , 0 , 0 , 0 , 0 } }, // #35 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 20, { 11, 0 , 0 , 0 , 0 , 0 } }, // #36 [ref=2x]
+ { InstDB::RWInfo::kCategoryImul , 22, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #37 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 54, 0 , 0 , 0 , 0 , 0 } }, // #38 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 26, 0 , 0 , 0 , 0 , 0 } }, // #39 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 5 , { 4 , 9 , 0 , 0 , 0 , 0 } }, // #40 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 4 , 5 , 0 , 0 , 0 , 0 } }, // #41 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 22, 56, 57, 0 , 0 , 0 } }, // #42 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 58, 40, 40, 0 , 0 , 0 } }, // #43 [ref=6x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 45, 9 , 9 , 0 , 0 , 0 } }, // #44 [ref=6x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 35, 7 , 7 , 0 , 0 , 0 } }, // #45 [ref=6x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 49, 13, 13, 0 , 0 , 0 } }, // #46 [ref=6x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 58, 40, 0 , 0 , 0 , 0 } }, // #47 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 45, 9 , 0 , 0 , 0 , 0 } }, // #48 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 35, 7 , 0 , 0 , 0 , 0 } }, // #49 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 49, 13, 0 , 0 , 0 , 0 } }, // #50 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 49, 40, 40, 0 , 0 , 0 } }, // #51 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 35, 9 , 9 , 0 , 0 , 0 } }, // #52 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 45, 13, 13, 0 , 0 , 0 } }, // #53 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 59, 0 , 0 , 0 , 0 , 0 } }, // #54 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 28, { 9 , 0 , 0 , 0 , 0 , 0 } }, // #55 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 13, { 44, 0 , 0 , 0 , 0 , 0 } }, // #56 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 7 , { 13, 0 , 0 , 0 , 0 , 0 } }, // #57 [ref=5x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 3 , 0 , 0 , 0 , 0 , 0 } }, // #58 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 5 , { 3 , 9 , 0 , 0 , 0 , 0 } }, // #59 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 15, { 5 , 5 , 61, 0 , 0 , 0 } }, // #60 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 12, { 7 , 7 , 62, 0 , 0 , 0 } }, // #61 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 8 , { 63, 29, 56, 0 , 0 , 0 } }, // #62 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 32, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #63 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 6 , { 67, 42, 3 , 0 , 0 , 0 } }, // #64 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 6 , { 11, 11, 3 , 68, 0 , 0 } }, // #65 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 17, 29, 30, 0 , 0 , 0 } }, // #66 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 10, { 3 , 0 , 0 , 0 , 0 , 0 } }, // #67 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 2 , { 2 , 3 , 0 , 0 , 0 , 0 } }, // #68 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 3 , { 5 , 5 , 0 , 70, 17, 56 } }, // #69 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 3 , { 5 , 5 , 0 , 71, 17, 56 } }, // #70 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 3 , { 5 , 5 , 0 , 70, 0 , 0 } }, // #71 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 3 , { 5 , 5 , 0 , 71, 0 , 0 } }, // #72 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 34, { 58, 5 , 0 , 0 , 0 , 0 } }, // #73 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 35, { 35, 5 , 0 , 0 , 0 , 0 } }, // #74 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 37, { 49, 3 , 0 , 0 , 0 , 0 } }, // #75 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 17, { 4 , 40, 0 , 0 , 0 , 0 } }, // #76 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 4 , { 4 , 7 , 0 , 0 , 0 , 0 } }, // #77 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 27, { 2 , 13, 0 , 0 , 0 , 0 } }, // #78 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 10, { 11, 0 , 0 , 0 , 0 , 0 } }, // #79 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 4 , { 35, 7 , 0 , 0 , 0 , 0 } }, // #80 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 11, 0 , 0 , 0 , 0 , 0 } }, // #81 [ref=6x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 16, 51, 29, 0 , 0 , 0 } }, // #82 [ref=5x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 45, 0 , 0 , 0 , 0 , 0 } }, // #83 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 35, 0 , 0 , 0 , 0 , 0 } }, // #84 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 16, 51, 70, 0 , 0 , 0 } }, // #85 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 2 , { 11, 3 , 0 , 0 , 0 , 0 } }, // #86 [ref=19x]
+ { InstDB::RWInfo::kCategoryGeneric , 4 , { 36, 7 , 0 , 0 , 0 , 0 } }, // #87 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 5 , { 37, 9 , 0 , 0 , 0 , 0 } }, // #88 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 74, 0 , 0 , 0 , 0 , 0 } }, // #89 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 7 , 0 , 0 , 0 , 0 , 0 } }, // #90 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 34, { 75, 0 , 0 , 0 , 0 , 0 } }, // #91 [ref=30x]
+ { InstDB::RWInfo::kCategoryGeneric , 11, { 2 , 3 , 73, 0 , 0 , 0 } }, // #92 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 39, { 11, 0 , 0 , 0 , 0 , 0 } }, // #93 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 28, { 45, 0 , 0 , 0 , 0 , 0 } }, // #94 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 13, { 43, 0 , 0 , 0 , 0 , 0 } }, // #95 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 76, 44, 44, 0 , 0 , 0 } }, // #96 [ref=8x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 43, 0 , 0 , 0 , 0 , 0 } }, // #97 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 9 , 56, 17, 0 , 0 , 0 } }, // #98 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 15, { 76, 77, 78, 78, 78, 5 } }, // #99 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 15, { 4 , 79, 80, 80, 80, 5 } }, // #100 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 40, { 10, 5 , 7 , 0 , 0 , 0 } }, // #101 [ref=8x]
+ { InstDB::RWInfo::kCategoryGeneric , 41, { 10, 5 , 13, 0 , 0 , 0 } }, // #102 [ref=7x]
+ { InstDB::RWInfo::kCategoryGeneric , 42, { 10, 5 , 9 , 0 , 0 , 0 } }, // #103 [ref=9x]
+ { InstDB::RWInfo::kCategoryGeneric , 6 , { 11, 3 , 3 , 3 , 0 , 0 } }, // #104 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 6 , { 35, 3 , 3 , 0 , 0 , 0 } }, // #105 [ref=18x]
+ { InstDB::RWInfo::kCategoryGeneric , 40, { 11, 5 , 7 , 0 , 0 , 0 } }, // #106 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 41, { 35, 13, 13, 0 , 0 , 0 } }, // #107 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 42, { 11, 5 , 9 , 0 , 0 , 0 } }, // #108 [ref=1x]
+ { InstDB::RWInfo::kCategoryVmov1_2 , 48, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #109 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 40, { 10, 5 , 5 , 0 , 0 , 0 } }, // #110 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 40, { 10, 83, 7 , 0 , 0 , 0 } }, // #111 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 41, { 10, 5 , 5 , 0 , 0 , 0 } }, // #112 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 49, { 10, 64, 3 , 0 , 0 , 0 } }, // #113 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 49, { 10, 3 , 3 , 0 , 0 , 0 } }, // #114 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 49, { 10, 83, 3 , 0 , 0 , 0 } }, // #115 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 42, { 10, 64, 9 , 0 , 0 , 0 } }, // #116 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 42, { 10, 5 , 5 , 0 , 0 , 0 } }, // #117 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 50, { 10, 5 , 5 , 0 , 0 , 0 } }, // #118 [ref=9x]
+ { InstDB::RWInfo::kCategoryGeneric , 52, { 10, 82, 0 , 0 , 0 , 0 } }, // #119 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 52, { 10, 3 , 0 , 0 , 0 , 0 } }, // #120 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 53, { 81, 44, 0 , 0 , 0 , 0 } }, // #121 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 6 , { 84, 3 , 3 , 0 , 0 , 0 } }, // #122 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 42, { 85, 5 , 5 , 0 , 0 , 0 } }, // #123 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 6 , { 2 , 3 , 3 , 0 , 0 , 0 } }, // #124 [ref=90x]
+ { InstDB::RWInfo::kCategoryGeneric , 40, { 4 , 64, 7 , 0 , 0 , 0 } }, // #125 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 42, { 4 , 83, 9 , 0 , 0 , 0 } }, // #126 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 40, { 6 , 7 , 7 , 0 , 0 , 0 } }, // #127 [ref=11x]
+ { InstDB::RWInfo::kCategoryGeneric , 41, { 4 , 5 , 5 , 0 , 0 , 0 } }, // #128 [ref=6x]
+ { InstDB::RWInfo::kCategoryGeneric , 42, { 8 , 9 , 9 , 0 , 0 , 0 } }, // #129 [ref=11x]
+ { InstDB::RWInfo::kCategoryGeneric , 54, { 11, 3 , 3 , 3 , 0 , 0 } }, // #130 [ref=15x]
+ { InstDB::RWInfo::kCategoryGeneric , 55, { 35, 7 , 7 , 7 , 0 , 0 } }, // #131 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 56, { 45, 9 , 9 , 9 , 0 , 0 } }, // #132 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 41, { 4 , 5 , 13, 0 , 0 , 0 } }, // #133 [ref=6x]
+ { InstDB::RWInfo::kCategoryGeneric , 40, { 26, 7 , 7 , 0 , 0 , 0 } }, // #134 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 42, { 54, 9 , 9 , 0 , 0 , 0 } }, // #135 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 16, { 35, 3 , 0 , 0 , 0 , 0 } }, // #136 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 27, { 35, 13, 0 , 0 , 0 , 0 } }, // #137 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 5 , { 35, 9 , 0 , 0 , 0 , 0 } }, // #138 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 8 , { 2 , 3 , 2 , 0 , 0 , 0 } }, // #139 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 2 , 3 , 2 , 0 , 0 , 0 } }, // #140 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 14, { 4 , 3 , 4 , 0 , 0 , 0 } }, // #141 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 40, { 10, 64, 7 , 0 , 0 , 0 } }, // #142 [ref=11x]
+ { InstDB::RWInfo::kCategoryGeneric , 41, { 10, 86, 13, 0 , 0 , 0 } }, // #143 [ref=7x]
+ { InstDB::RWInfo::kCategoryGeneric , 42, { 10, 83, 9 , 0 , 0 , 0 } }, // #144 [ref=13x]
+ { InstDB::RWInfo::kCategoryGeneric , 50, { 81, 82, 5 , 0 , 0 , 0 } }, // #145 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 50, { 11, 3 , 5 , 0 , 0 , 0 } }, // #146 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 57, { 43, 44, 82, 0 , 0 , 0 } }, // #147 [ref=4x]
+ { InstDB::RWInfo::kCategoryVmaskmov , 0 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #148 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 12, { 35, 0 , 0 , 0 , 0 , 0 } }, // #149 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 22, 0 , 0 , 0 , 0 , 0 } }, // #150 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 10, 64, 64, 0 , 0 , 0 } }, // #151 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 12, { 10, 7 , 7 , 0 , 0 , 0 } }, // #152 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 10, 7 , 7 , 0 , 0 , 0 } }, // #153 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 12, { 10, 64, 7 , 0 , 0 , 0 } }, // #154 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 10, 64, 7 , 0 , 0 , 0 } }, // #155 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 10, 86, 13, 0 , 0 , 0 } }, // #156 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 10, 83, 9 , 0 , 0 , 0 } }, // #157 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 87, 0 , 0 , 0 , 0 , 0 } }, // #158 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 60, { 88, 89, 3 , 3 , 0 , 0 } }, // #159 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 15, { 43, 77, 78, 78, 78, 5 } }, // #160 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 57, { 81, 82, 82, 0 , 0 , 0 } }, // #161 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 22, { 11, 3 , 3 , 0 , 0 , 0 } }, // #162 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 7 , { 49, 5 , 0 , 0 , 0 , 0 } }, // #163 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 61, { 10, 5 , 40, 0 , 0 , 0 } }, // #164 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 50, { 10, 5 , 5 , 5 , 0 , 0 } }, // #165 [ref=12x]
+ { InstDB::RWInfo::kCategoryGeneric , 65, { 10, 5 , 5 , 5 , 0 , 0 } }, // #166 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 66, { 10, 5 , 5 , 0 , 0 , 0 } }, // #167 [ref=12x]
+ { InstDB::RWInfo::kCategoryGeneric , 67, { 11, 3 , 5 , 0 , 0 , 0 } }, // #168 [ref=5x]
+ { InstDB::RWInfo::kCategoryGeneric , 68, { 11, 3 , 0 , 0 , 0 , 0 } }, // #169 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 69, { 11, 3 , 5 , 0 , 0 , 0 } }, // #170 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 22, { 11, 3 , 5 , 0 , 0 , 0 } }, // #171 [ref=1x]
+ { InstDB::RWInfo::kCategoryGenericEx , 6 , { 2 , 3 , 3 , 0 , 0 , 0 } }, // #172 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 90, 82, 5 , 0 , 0 , 0 } }, // #173 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 50, { 4 , 5 , 5 , 0 , 0 , 0 } }, // #174 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 56, 17, 29, 0 , 0 , 0 } }, // #175 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 8 , { 3 , 56, 17, 0 , 0 , 0 } }, // #176 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 8 , { 11, 56, 17, 0 , 0 , 0 } } // #177 [ref=8x]
};
const InstDB::RWInfoOp InstDB::rwInfoOp[] = {
- { 0x0000000000000000u, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kNone }, // #0 [ref=16519x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kNone }, // #0 [ref=17086x]
{ 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]
+ { 0x0000000000000000u, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kZExt }, // #2 [ref=282x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead }, // #3 [ref=1132x]
+ { 0x000000000000FFFFu, 0x000000000000FFFFu, 0xFF, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kZExt }, // #4 [ref=107x]
+ { 0x000000000000FFFFu, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead }, // #5 [ref=356x]
{ 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]
+ { 0x0000000000000000u, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt }, // #11 [ref=459x]
{ 0x0000000000000003u, 0x0000000000000003u, 0xFF, 0, { 0 }, OpRWFlags::kRW }, // #12 [ref=1x]
- { 0x0000000000000003u, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead }, // #13 [ref=63x]
+ { 0x0000000000000003u, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead }, // #13 [ref=65x]
{ 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]
+ { 0xFFFFFFFFFFFFFFFFu, 0x0000000000000000u, 0x00, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kMemPhysId }, // #19 [ref=1x]
{ 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]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x00, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kRegPhysId }, // #22 [ref=8x]
{ 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, 0x000000000000000Fu, 0x00, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kZExt | OpRWFlags::kRegPhysId }, // #28 [ref=5x]
{ 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]
@@ -4276,75 +6016,79 @@ const InstDB::RWInfoOp InstDB::rwInfoOp[] = {
{ 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]
+ { 0x0000000000000000u, 0xFFFFFFFFFFFFFFFFu, 0xFF, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt }, // #43 [ref=23x]
+ { 0xFFFFFFFFFFFFFFFFu, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead }, // #44 [ref=35x]
+ { 0x0000000000000000u, 0x000000000000000Fu, 0xFF, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt }, // #45 [ref=30x]
+ { 0x00000000000003FFu, 0x00000000000003FFu, 0xFF, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kZExt }, // #46 [ref=22x]
+ { 0x00000000000003FFu, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead }, // #47 [ref=13x]
+ { 0x0000000000000000u, 0x00000000000003FFu, 0xFF, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt }, // #48 [ref=1x]
+ { 0x0000000000000000u, 0x0000000000000003u, 0xFF, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt }, // #49 [ref=17x]
+ { 0x0000000000000000u, 0x0000000000000003u, 0x00, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kRegPhysId | OpRWFlags::kZExt }, // #50 [ref=2x]
+ { 0x0000000000000000u, 0x000000000000000Fu, 0x00, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt | OpRWFlags::kRegPhysId }, // #51 [ref=8x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x00, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kRegPhysId | OpRWFlags::kZExt }, // #52 [ref=2x]
+ { 0x0000000000000003u, 0x0000000000000000u, 0x02, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kRegPhysId }, // #53 [ref=4x]
+ { 0x000000000000000Fu, 0x000000000000000Fu, 0xFF, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kZExt }, // #54 [ref=4x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x07, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt | OpRWFlags::kMemPhysId }, // #55 [ref=1x]
+ { 0x000000000000000Fu, 0x0000000000000000u, 0x02, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kRegPhysId }, // #56 [ref=23x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x01, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kRegPhysId }, // #57 [ref=2x]
+ { 0x0000000000000000u, 0x0000000000000001u, 0xFF, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt }, // #58 [ref=14x]
+ { 0x0000000000000000u, 0x0000000000000001u, 0x00, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kRegPhysId }, // #59 [ref=1x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x01, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kRegPhysId | OpRWFlags::kZExt }, // #60 [ref=3x]
+ { 0x000000000000FFFFu, 0x000000000000FFFFu, 0x07, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kZExt | OpRWFlags::kMemPhysId }, // #61 [ref=2x]
+ { 0x00000000000000FFu, 0x00000000000000FFu, 0x07, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kZExt | OpRWFlags::kMemPhysId }, // #62 [ref=1x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x00, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kMemPhysId }, // #63 [ref=2x]
+ { 0x000000000000FF00u, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead }, // #64 [ref=23x]
+ { 0x0000000000000000u, 0x000000000000FF00u, 0xFF, 0, { 0 }, OpRWFlags::kWrite }, // #65 [ref=1x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x07, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt | OpRWFlags::kMemBaseRW | OpRWFlags::kMemBasePostModify | OpRWFlags::kMemPhysId }, // #66 [ref=2x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x02, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kRegPhysId | OpRWFlags::kZExt }, // #67 [ref=1x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x02, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kRegPhysId }, // #68 [ref=1x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x06, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kMemPhysId }, // #69 [ref=1x]
+ { 0x0000000000000000u, 0x000000000000000Fu, 0x01, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt | OpRWFlags::kRegPhysId }, // #70 [ref=5x]
+ { 0x0000000000000000u, 0x000000000000FFFFu, 0x00, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt | OpRWFlags::kRegPhysId }, // #71 [ref=4x]
+ { 0x0000000000000000u, 0x0000000000000007u, 0xFF, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt }, // #72 [ref=2x]
+ { 0x0000000000000001u, 0x0000000000000000u, 0x01, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kRegPhysId }, // #73 [ref=10x]
+ { 0x0000000000000001u, 0x0000000000000000u, 0x00, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kRegPhysId }, // #74 [ref=1x]
+ { 0x0000000000000000u, 0x0000000000000001u, 0xFF, 0, { 0 }, OpRWFlags::kWrite }, // #75 [ref=30x]
+ { 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFF, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kZExt }, // #76 [ref=10x]
+ { 0xFFFFFFFFFFFFFFFFu, 0x0000000000000000u, 0xFF, 4, { 0 }, OpRWFlags::kRead }, // #77 [ref=4x]
+ { 0xFFFFFFFFFFFFFFFFu, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kConsecutive }, // #78 [ref=12x]
+ { 0x000000000000FFFFu, 0x0000000000000000u, 0xFF, 4, { 0 }, OpRWFlags::kRead }, // #79 [ref=2x]
+ { 0x000000000000FFFFu, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kConsecutive }, // #80 [ref=6x]
+ { 0x0000000000000000u, 0x00000000FFFFFFFFu, 0xFF, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt }, // #81 [ref=10x]
+ { 0x00000000FFFFFFFFu, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead }, // #82 [ref=18x]
+ { 0x000000000000FFF0u, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead }, // #83 [ref=18x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kUnique | OpRWFlags::kZExt }, // #84 [ref=4x]
+ { 0x000000000000FFFFu, 0x000000000000FFFFu, 0xFF, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kUnique | OpRWFlags::kZExt }, // #85 [ref=4x]
+ { 0x000000000000FFFCu, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead }, // #86 [ref=8x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x00, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kZExt | OpRWFlags::kRegPhysId }, // #87 [ref=1x]
+ { 0x0000000000000000u, 0x00000000000000FFu, 0xFF, 2, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt }, // #88 [ref=2x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt | OpRWFlags::kConsecutive }, // #89 [ref=2x]
+ { 0x00000000FFFFFFFFu, 0x00000000FFFFFFFFu, 0xFF, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kZExt } // #90 [ref=3x]
};
const InstDB::RWInfoRm InstDB::rwInfoRm[] = {
- { InstDB::RWInfoRm::kCategoryNone , 0x00, 0 , 0, 0 }, // #0 [ref=1997x]
+ { InstDB::RWInfoRm::kCategoryNone , 0x00, 0 , 0, 0 }, // #0 [ref=2083x]
{ InstDB::RWInfoRm::kCategoryConsistent, 0x03, 0 , InstDB::RWInfoRm::kFlagAmbiguous, 0 }, // #1 [ref=8x]
{ 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=35x]
- { InstDB::RWInfoRm::kCategoryConsistent, 0x04, 0 , 0, 0 }, // #6 [ref=300x]
+ { InstDB::RWInfoRm::kCategoryConsistent, 0x04, 0 , 0, 0 }, // #6 [ref=314x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x01, 2 , 0, 0 }, // #7 [ref=9x]
- { InstDB::RWInfoRm::kCategoryFixed , 0x00, 0 , 0, 0 }, // #8 [ref=63x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x00, 0 , 0, 0 }, // #8 [ref=68x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x03, 0 , 0, 0 }, // #9 [ref=1x]
{ InstDB::RWInfoRm::kCategoryConsistent, 0x01, 0 , InstDB::RWInfoRm::kFlagAmbiguous, 0 }, // #10 [ref=21x]
{ 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=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, 8 , 0, 0 }, // #12 [ref=23x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x00, 64, 0, 0 }, // #13 [ref=6x]
+ { InstDB::RWInfoRm::kCategoryNone , 0x00, 0 , InstDB::RWInfoRm::kFlagAmbiguous, 0 }, // #14 [ref=30x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x00, 16, 0, 0 }, // #15 [ref=23x]
+ { InstDB::RWInfoRm::kCategoryConsistent, 0x02, 0 , InstDB::RWInfoRm::kFlagAmbiguous, 0 }, // #16 [ref=22x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x02, 1 , 0, 0 }, // #17 [ref=5x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x01, 4 , 0, 0 }, // #18 [ref=6x]
{ 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=4x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x00, 2 , 0, 0 }, // #21 [ref=6x]
{ InstDB::RWInfoRm::kCategoryConsistent, 0x06, 0 , 0, 0 }, // #22 [ref=6x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x03, 1 , 0, 0 }, // #23 [ref=1x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x03, 4 , 0, 0 }, // #24 [ref=3x]
@@ -4373,7 +6117,7 @@ const InstDB::RWInfoRm InstDB::rwInfoRm[] = {
{ InstDB::RWInfoRm::kCategoryQuarter , 0x02, 0 , 0, 0 }, // #47 [ref=9x]
{ InstDB::RWInfoRm::kCategoryHalf , 0x01, 0 , 0, 0 }, // #48 [ref=10x]
{ InstDB::RWInfoRm::kCategoryConsistent, 0x04, 0 , InstDB::RWInfoRm::kFlagAmbiguous, 0 }, // #49 [ref=6x]
- { InstDB::RWInfoRm::kCategoryFixed , 0x04, 16, 0, 0 }, // #50 [ref=27x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x04, 16, 0, 0 }, // #50 [ref=30x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x02, 64, 0, 0 }, // #51 [ref=6x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x01, 16, 0, 0 }, // #52 [ref=6x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x01, 32, 0, 0 }, // #53 [ref=4x]
@@ -4405,20 +6149,33 @@ UNIT(x86_inst_db) {
INFO("Checking validity of Inst enums");
// Cross-validate prefixes.
- 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");
+ EXPECT_EQ(uint32_t(InstOptions::kX86_Rex ), 0x40000000u)
+ .message("REX prefix must be at 0x40000000");
+
+ EXPECT_EQ(uint32_t(InstOptions::kX86_Evex), 0x00001000u)
+ .message("EVEX prefix must be at 0x00001000");
// These could be combined together to form a valid REX prefix, they must match.
- 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");
+ EXPECT_EQ(uint32_t(InstOptions::kX86_OpCodeB), uint32_t(Opcode::kB))
+ .message("Opcode::kB must match InstOptions::kX86_OpCodeB");
+
+ EXPECT_EQ(uint32_t(InstOptions::kX86_OpCodeX), uint32_t(Opcode::kX))
+ .message("Opcode::kX must match InstOptions::kX86_OpCodeX");
+
+ EXPECT_EQ(uint32_t(InstOptions::kX86_OpCodeR), uint32_t(Opcode::kR))
+ .message("Opcode::kR must match InstOptions::kX86_OpCodeR");
+
+ EXPECT_EQ(uint32_t(InstOptions::kX86_OpCodeW), uint32_t(Opcode::kW))
+ .message("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;
- EXPECT(rex_rb == 0x45, "Opcode::kR|B must form a valid REX prefix (0x45) if combined with 0x40");
- EXPECT(rex_rw == 0x4C, "Opcode::kR|W must form a valid REX prefix (0x4C) if combined with 0x40");
+ EXPECT_EQ(rex_rb, 0x45u)
+ .message("Opcode::kR|B must form a valid REX prefix (0x45) if combined with 0x40");
+
+ EXPECT_EQ(rex_rw, 0x4Cu)
+ .message("Opcode::kR|W must form a valid REX prefix (0x4C) if combined with 0x40");
}
#endif
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86instdb.h b/3rdparty/asmjit/src/asmjit/x86/x86instdb.h
index 87a286c2829..2bf7d148957 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86instdb.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86instdb.h
@@ -30,7 +30,7 @@ enum class Mode : uint8_t {
ASMJIT_DEFINE_ENUM_FLAGS(Mode)
//! Converts architecture to operation mode, see \ref Mode.
-static constexpr Mode modeFromArch(Arch arch) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr Mode modeFromArch(Arch arch) noexcept {
return arch == Arch::kX86 ? Mode::kX86 :
arch == Arch::kX64 ? Mode::kX64 : Mode::kNone;
}
@@ -348,92 +348,92 @@ struct CommonInfo {
//! \{
//! Returns instruction flags.
- inline InstFlags flags() const noexcept { return (InstFlags)_flags; }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG bool hasFlag(InstFlags flag) const noexcept { return Support::test(_flags, flag); }
//! Returns instruction AVX-512 flags.
- inline Avx512Flags avx512Flags() const noexcept { return (Avx512Flags)_avx512Flags; }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG 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(InstFlags::kFpu); }
+ ASMJIT_INLINE_NODEBUG 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(InstFlags::kMmx); }
+ ASMJIT_INLINE_NODEBUG 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(InstFlags::kVec); }
+ ASMJIT_INLINE_NODEBUG 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() & (InstFlags::kVec | InstFlags::kVex | InstFlags::kEvex)) == InstFlags::kVec; }
+ ASMJIT_INLINE_NODEBUG 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(); }
+ ASMJIT_INLINE_NODEBUG bool isAvx() const noexcept { return isVec() && isVexOrEvex(); }
//! Tests whether the instruction can be prefixed with LOCK prefix.
- inline bool hasLockPrefix() const noexcept { return hasFlag(InstFlags::kLock); }
+ ASMJIT_INLINE_NODEBUG 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(InstFlags::kRep); }
+ ASMJIT_INLINE_NODEBUG 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(InstFlags::kXAcquire); }
+ ASMJIT_INLINE_NODEBUG 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(InstFlags::kXRelease); }
+ ASMJIT_INLINE_NODEBUG 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(InstFlags::kRepIgnored); }
+ ASMJIT_INLINE_NODEBUG bool isRepIgnored() const noexcept { return hasFlag(InstFlags::kRepIgnored); }
//! Tests whether the instruction uses MIB.
- inline bool isMibOp() const noexcept { return hasFlag(InstFlags::kMib); }
+ ASMJIT_INLINE_NODEBUG bool isMibOp() const noexcept { return hasFlag(InstFlags::kMib); }
//! Tests whether the instruction uses VSIB.
- inline bool isVsibOp() const noexcept { return hasFlag(InstFlags::kVsib); }
+ ASMJIT_INLINE_NODEBUG 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(InstFlags::kTsib); }
+ ASMJIT_INLINE_NODEBUG 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(InstFlags::kVex); }
+ ASMJIT_INLINE_NODEBUG 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(InstFlags::kEvex); }
+ ASMJIT_INLINE_NODEBUG 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(InstFlags::kVex | InstFlags::kEvex); }
+ ASMJIT_INLINE_NODEBUG 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(InstFlags::kPreferEvex); }
+ ASMJIT_INLINE_NODEBUG bool preferEvex() const noexcept { return hasFlag(InstFlags::kPreferEvex); }
- 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); }
+ ASMJIT_INLINE_NODEBUG bool isEvexCompatible() const noexcept { return hasFlag(InstFlags::kEvexCompat); }
+ ASMJIT_INLINE_NODEBUG bool isEvexKRegOnly() const noexcept { return hasFlag(InstFlags::kEvexKReg); }
+ ASMJIT_INLINE_NODEBUG bool isEvexTwoOpOnly() const noexcept { return hasFlag(InstFlags::kEvexTwoOp); }
+ ASMJIT_INLINE_NODEBUG bool isEvexTransformable() const noexcept { return hasFlag(InstFlags::kEvexTransformable); }
//! Tests whether the instruction supports AVX512 masking {k}.
- inline bool hasAvx512K() const noexcept { return hasAvx512Flag(Avx512Flags::kK); }
+ ASMJIT_INLINE_NODEBUG bool hasAvx512K() const noexcept { return hasAvx512Flag(Avx512Flags::kK); }
//! Tests whether the instruction supports AVX512 zeroing {k}{z}.
- inline bool hasAvx512Z() const noexcept { return hasAvx512Flag(Avx512Flags::kZ); }
+ ASMJIT_INLINE_NODEBUG bool hasAvx512Z() const noexcept { return hasAvx512Flag(Avx512Flags::kZ); }
//! Tests whether the instruction supports AVX512 embedded-rounding {er}.
- inline bool hasAvx512ER() const noexcept { return hasAvx512Flag(Avx512Flags::kER); }
+ ASMJIT_INLINE_NODEBUG 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(Avx512Flags::kSAE); }
+ ASMJIT_INLINE_NODEBUG 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(Avx512Flags::kB16 | Avx512Flags::kB32 | Avx512Flags::kB64); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG bool hasAvx512B16() const noexcept { return hasAvx512Flag(Avx512Flags::kB16); }
//! Tests whether the instruction supports AVX512 broadcast (32-bit).
- inline bool hasAvx512B32() const noexcept { return hasAvx512Flag(Avx512Flags::kB32); }
+ ASMJIT_INLINE_NODEBUG bool hasAvx512B32() const noexcept { return hasAvx512Flag(Avx512Flags::kB32); }
//! Tests whether the instruction supports AVX512 broadcast (64-bit).
- inline bool hasAvx512B64() const noexcept { return hasAvx512Flag(Avx512Flags::kB64); }
+ ASMJIT_INLINE_NODEBUG 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 {
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG uint32_t signatureIndex() const noexcept { return _iSignatureIndex; }
+ ASMJIT_INLINE_NODEBUG uint32_t signatureCount() const noexcept { return _iSignatureCount; }
- inline const InstSignature* signatureData() const noexcept { return _instSignatureTable + _iSignatureIndex; }
- inline const InstSignature* signatureEnd() const noexcept { return _instSignatureTable + _iSignatureIndex + _iSignatureCount; }
+ ASMJIT_INLINE_NODEBUG const InstSignature* signatureData() const noexcept { return _instSignatureTable + _iSignatureIndex; }
+ ASMJIT_INLINE_NODEBUG const InstSignature* signatureEnd() const noexcept { return _instSignatureTable + _iSignatureIndex + _iSignatureCount; }
//! Returns a control flow category of the instruction.
- inline InstControlFlow controlFlow() const noexcept { return (InstControlFlow)_controlFlow; }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG InstSameRegHint sameRegHint() const noexcept { return (InstSameRegHint)_sameRegHint; }
//! \}
};
@@ -442,8 +442,8 @@ ASMJIT_VARAPI const CommonInfo _commonInfoTable[];
//! Instruction information.
struct InstInfo {
- //! Index to \ref _nameData.
- uint32_t _nameDataIndex : 14;
+ //! Reserved for future use.
+ uint32_t _reserved : 14;
//! Index to \ref _commonInfoTable.
uint32_t _commonInfoIndex : 10;
//! Index to \ref _additionalInfoTable.
@@ -462,83 +462,83 @@ struct InstInfo {
//! \{
//! Returns common information, see \ref CommonInfo.
- inline const CommonInfo& commonInfo() const noexcept { return _commonInfoTable[_commonInfoIndex]; }
+ ASMJIT_INLINE_NODEBUG const CommonInfo& commonInfo() const noexcept { return _commonInfoTable[_commonInfoIndex]; }
- //! Returns instruction flags, see \ref Flags.
- inline InstFlags flags() const noexcept { return commonInfo().flags(); }
- //! Tests whether the instruction has flag `flag`, see \ref Flags.
- inline bool hasFlag(InstFlags flag) const noexcept { return commonInfo().hasFlag(flag); }
+ //! Returns instruction flags, see \ref InstFlags.
+ ASMJIT_INLINE_NODEBUG InstFlags flags() const noexcept { return commonInfo().flags(); }
+ //! Tests whether the instruction has flag `flag`, see \ref InstFlags.
+ ASMJIT_INLINE_NODEBUG bool hasFlag(InstFlags flag) const noexcept { return commonInfo().hasFlag(flag); }
//! Returns instruction AVX-512 flags, see \ref Avx512Flags.
- inline Avx512Flags avx512Flags() const noexcept { return commonInfo().avx512Flags(); }
+ ASMJIT_INLINE_NODEBUG Avx512Flags avx512Flags() const noexcept { return commonInfo().avx512Flags(); }
//! Tests whether the instruction has an AVX-512 `flag`, see \ref Avx512Flags.
- inline bool hasAvx512Flag(Avx512Flags flag) const noexcept { return commonInfo().hasAvx512Flag(flag); }
+ ASMJIT_INLINE_NODEBUG 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(); }
+ ASMJIT_INLINE_NODEBUG bool isFpu() const noexcept { return commonInfo().isFpu(); }
//! Tests whether the instruction is MMX/3DNOW instruction that accesses MMX registers (includes EMMS and FEMMS).
- inline bool isMmx() const noexcept { return commonInfo().isMmx(); }
+ ASMJIT_INLINE_NODEBUG bool isMmx() const noexcept { return commonInfo().isMmx(); }
//! Tests whether the instruction is SSE|AVX|AVX512 instruction that accesses XMM|YMM|ZMM registers.
- inline bool isVec() const noexcept { return commonInfo().isVec(); }
+ ASMJIT_INLINE_NODEBUG bool isVec() const noexcept { return commonInfo().isVec(); }
//! Tests whether the instruction is SSE+ (SSE4.2, AES, SHA included) instruction that accesses XMM registers.
- inline bool isSse() const noexcept { return commonInfo().isSse(); }
+ ASMJIT_INLINE_NODEBUG bool isSse() const noexcept { return commonInfo().isSse(); }
//! Tests whether the instruction is AVX+ (FMA included) instruction that accesses XMM|YMM|ZMM registers.
- inline bool isAvx() const noexcept { return commonInfo().isAvx(); }
+ ASMJIT_INLINE_NODEBUG bool isAvx() const noexcept { return commonInfo().isAvx(); }
//! Tests whether the instruction can be prefixed with LOCK prefix.
- inline bool hasLockPrefix() const noexcept { return commonInfo().hasLockPrefix(); }
+ ASMJIT_INLINE_NODEBUG bool hasLockPrefix() const noexcept { return commonInfo().hasLockPrefix(); }
//! Tests whether the instruction can be prefixed with REP (REPE|REPZ) prefix.
- inline bool hasRepPrefix() const noexcept { return commonInfo().hasRepPrefix(); }
+ ASMJIT_INLINE_NODEBUG bool hasRepPrefix() const noexcept { return commonInfo().hasRepPrefix(); }
//! Tests whether the instruction can be prefixed with XACQUIRE prefix.
- inline bool hasXAcquirePrefix() const noexcept { return commonInfo().hasXAcquirePrefix(); }
+ ASMJIT_INLINE_NODEBUG bool hasXAcquirePrefix() const noexcept { return commonInfo().hasXAcquirePrefix(); }
//! Tests whether the instruction can be prefixed with XRELEASE prefix.
- inline bool hasXReleasePrefix() const noexcept { return commonInfo().hasXReleasePrefix(); }
+ ASMJIT_INLINE_NODEBUG bool hasXReleasePrefix() const noexcept { return commonInfo().hasXReleasePrefix(); }
//! Tests whether the rep prefix is supported by the instruction, but ignored (has no effect).
- inline bool isRepIgnored() const noexcept { return commonInfo().isRepIgnored(); }
+ ASMJIT_INLINE_NODEBUG bool isRepIgnored() const noexcept { return commonInfo().isRepIgnored(); }
//! Tests whether the instruction uses MIB.
- inline bool isMibOp() const noexcept { return hasFlag(InstFlags::kMib); }
+ ASMJIT_INLINE_NODEBUG bool isMibOp() const noexcept { return hasFlag(InstFlags::kMib); }
//! Tests whether the instruction uses VSIB.
- inline bool isVsibOp() const noexcept { return hasFlag(InstFlags::kVsib); }
+ ASMJIT_INLINE_NODEBUG 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(InstFlags::kVex); }
+ ASMJIT_INLINE_NODEBUG 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(InstFlags::kEvex); }
+ ASMJIT_INLINE_NODEBUG 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(InstFlags::kVex | InstFlags::kEvex); }
+ ASMJIT_INLINE_NODEBUG bool isVexOrEvex() const noexcept { return hasFlag(InstFlags::kVex | InstFlags::kEvex); }
- 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); }
+ ASMJIT_INLINE_NODEBUG bool isEvexCompatible() const noexcept { return hasFlag(InstFlags::kEvexCompat); }
+ ASMJIT_INLINE_NODEBUG bool isEvexKRegOnly() const noexcept { return hasFlag(InstFlags::kEvexKReg); }
+ ASMJIT_INLINE_NODEBUG bool isEvexTwoOpOnly() const noexcept { return hasFlag(InstFlags::kEvexTwoOp); }
+ ASMJIT_INLINE_NODEBUG bool isEvexTransformable() const noexcept { return hasFlag(InstFlags::kEvexTransformable); }
//! Tests whether the instruction supports AVX512 masking {k}.
- inline bool hasAvx512K() const noexcept { return hasAvx512Flag(Avx512Flags::kK); }
+ ASMJIT_INLINE_NODEBUG bool hasAvx512K() const noexcept { return hasAvx512Flag(Avx512Flags::kK); }
//! Tests whether the instruction supports AVX512 zeroing {k}{z}.
- inline bool hasAvx512Z() const noexcept { return hasAvx512Flag(Avx512Flags::kZ); }
+ ASMJIT_INLINE_NODEBUG bool hasAvx512Z() const noexcept { return hasAvx512Flag(Avx512Flags::kZ); }
//! Tests whether the instruction supports AVX512 embedded-rounding {er}.
- inline bool hasAvx512ER() const noexcept { return hasAvx512Flag(Avx512Flags::kER); }
+ ASMJIT_INLINE_NODEBUG 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(Avx512Flags::kSAE); }
+ ASMJIT_INLINE_NODEBUG 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(Avx512Flags::kB16 | Avx512Flags::kB32 | Avx512Flags::kB64); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG bool hasAvx512B16() const noexcept { return hasAvx512Flag(Avx512Flags::kB16); }
//! Tests whether the instruction supports AVX512 broadcast (32-bit).
- inline bool hasAvx512B32() const noexcept { return hasAvx512Flag(Avx512Flags::kB32); }
+ ASMJIT_INLINE_NODEBUG bool hasAvx512B32() const noexcept { return hasAvx512Flag(Avx512Flags::kB32); }
//! Tests whether the instruction supports AVX512 broadcast (64-bit).
- inline bool hasAvx512B64() const noexcept { return hasAvx512Flag(Avx512Flags::kB64); }
+ ASMJIT_INLINE_NODEBUG bool hasAvx512B64() const noexcept { return hasAvx512Flag(Avx512Flags::kB64); }
//! Returns a control flow category of the instruction.
- inline InstControlFlow controlFlow() const noexcept { return commonInfo().controlFlow(); }
+ ASMJIT_INLINE_NODEBUG 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(); }
+ ASMJIT_INLINE_NODEBUG 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(); }
+ ASMJIT_INLINE_NODEBUG uint32_t signatureIndex() const noexcept { return commonInfo().signatureIndex(); }
+ ASMJIT_INLINE_NODEBUG 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_INLINE_NODEBUG const InstSignature* signatureData() const noexcept { return commonInfo().signatureData(); }
+ ASMJIT_INLINE_NODEBUG const InstSignature* signatureEnd() const noexcept { return commonInfo().signatureEnd(); }
//! \}
};
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86instdb_p.h b/3rdparty/asmjit/src/asmjit/x86/x86instdb_p.h
index b8e12e16b45..cb006060832 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86instdb_p.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86instdb_p.h
@@ -6,6 +6,7 @@
#ifndef ASMJIT_X86_X86INSTDB_P_H_INCLUDED
#define ASMJIT_X86_X86INSTDB_P_H_INCLUDED
+#include "../core/instdb_p.h"
#include "../x86/x86instdb.h"
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
@@ -38,11 +39,11 @@ enum EncodingId : uint32_t {
kEncodingX86M_GPB, //!< X86 [M] (handles single-byte size).
kEncodingX86M_GPB_MulDiv, //!< X86 [M] (like GPB, handles implicit|explicit MUL|DIV|IDIV).
kEncodingX86M_Only, //!< X86 [M] (restricted to memory operand of any size).
- kEncodingX86M_Only_EDX_EAX, //!< X86 [M] (memory operand only, followed by implicit <edx> and <eax>).
+ kEncodingX86M_Only_EDX_EAX, //!< X86 [M] (memory operand only, followed by implicit `EDX` and `EAX`).
kEncodingX86M_Nop, //!< X86 [M] (special case of NOP instruction).
kEncodingX86R_Native, //!< X86 [R] (register must be either 32-bit or 64-bit depending on arch).
kEncodingX86R_FromM, //!< X86 [R] - which specifies memory address.
- kEncodingX86R32_EDX_EAX, //!< X86 [R32] followed by implicit EDX and EAX.
+ kEncodingX86R32_EDX_EAX, //!< X86 [R32] followed by implicit `EDX` and `EAX`.
kEncodingX86Rm, //!< X86 [RM] (doesn't handle single-byte size).
kEncodingX86Rm_Raw66H, //!< X86 [RM] (used by LZCNT, POPCNT, and TZCNT).
kEncodingX86Rm_NoSize, //!< X86 [RM] (doesn't add REX.W prefix if 64-bit reg is used).
@@ -126,6 +127,7 @@ enum EncodingId : uint32_t {
kEncodingVexMri, //!< VEX|EVEX [MRI].
kEncodingVexMri_Lx, //!< VEX|EVEX [MRI] (propagates VEX|EVEX.L if YMM used).
kEncodingVexMri_Vpextrw, //!< VEX|EVEX [MRI] (special case required by VPEXTRW instruction).
+ kEncodingVexMvr_Wx, //!< VEX|EVEX [MVR] (propagates VEX|EVEX.W if GPQ used).
kEncodingVexRm, //!< VEX|EVEX [RM].
kEncodingVexRm_ZDI, //!< VEX|EVEX [RM<ZDI>].
kEncodingVexRm_Wx, //!< VEX|EVEX [RM] (propagates VEX|EVEX.W if GPQ used).
@@ -200,20 +202,10 @@ struct AdditionalInfo {
inline const uint8_t* featuresEnd() const noexcept { return _features + ASMJIT_ARRAY_SIZE(_features); }
};
-// ${NameLimits:Begin}
-// ------------------- Automatically generated, do not edit -------------------
-enum : uint32_t { kMaxNameSize = 17 };
-// ----------------------------------------------------------------------------
-// ${NameLimits:End}
-
-struct InstNameIndex {
- uint16_t start;
- uint16_t end;
-};
-
struct RWInfo {
enum Category : uint8_t {
- kCategoryGeneric,
+ kCategoryGeneric = 0,
+ kCategoryGenericEx,
kCategoryMov,
kCategoryMovabs,
kCategoryImul,
@@ -295,8 +287,9 @@ extern const uint32_t _mainOpcodeTable[];
extern const uint32_t _altOpcodeTable[];
#ifndef ASMJIT_NO_TEXT
-extern const char _nameData[];
-extern const InstNameIndex instNameIndex[26];
+extern const InstNameIndex instNameIndex;
+extern const char _instNameStringTable[];
+extern const uint32_t _instNameIndexTable[];
#endif // !ASMJIT_NO_TEXT
extern const AdditionalInfo _additionalInfoTable[];
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86opcode_p.h b/3rdparty/asmjit/src/asmjit/x86/x86opcode_p.h
index 94a76f04818..ab0b13e1a50 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86opcode_p.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86opcode_p.h
@@ -45,7 +45,7 @@ struct Opcode {
//! `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
+ //! for XMM register, `L.256` 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.
//!
@@ -244,7 +244,7 @@ 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
+ // NOTE: REX.[B|X|R] are never stored within the opcode itself, they are reserved by AsmJit and 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.
@@ -280,7 +280,7 @@ 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
+ // VEX/XOP prefix can only use the first bit `L.128` or `L.256`. EVEX 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,
@@ -336,27 +336,27 @@ struct Opcode {
// Opcode Builder
// --------------
- inline uint32_t get() const noexcept { return v; }
+ ASMJIT_INLINE_NODEBUG uint32_t get() const noexcept { return v; }
- inline bool hasW() const noexcept { return (v & kW) != 0; }
- inline bool has66h() const noexcept { return (v & kPP_66) != 0; }
+ ASMJIT_INLINE_NODEBUG bool hasW() const noexcept { return (v & kW) != 0; }
+ ASMJIT_INLINE_NODEBUG bool has66h() const noexcept { return (v & kPP_66) != 0; }
- inline Opcode& add(uint32_t x) noexcept { return operator+=(x); }
+ ASMJIT_INLINE_NODEBUG Opcode& add(uint32_t x) noexcept { return operator+=(x); }
- inline Opcode& add66h() noexcept { return operator|=(kPP_66); }
+ ASMJIT_INLINE_NODEBUG Opcode& add66h() noexcept { return operator|=(kPP_66); }
template<typename T>
- inline Opcode& add66hIf(T exp) noexcept { return operator|=(uint32_t(exp) << kPP_Shift); }
+ ASMJIT_INLINE_NODEBUG Opcode& add66hIf(T exp) noexcept { return operator|=(uint32_t(exp) << kPP_Shift); }
template<typename T>
- inline Opcode& add66hBySize(T size) noexcept { return add66hIf(size == 2); }
+ ASMJIT_INLINE_NODEBUG Opcode& add66hBySize(T size) noexcept { return add66hIf(size == 2); }
- inline Opcode& addW() noexcept { return operator|=(kW); }
+ ASMJIT_INLINE_NODEBUG Opcode& addW() noexcept { return operator|=(kW); }
template<typename T>
- inline Opcode& addWIf(T exp) noexcept { return operator|=(uint32_t(exp) << kW_Shift); }
+ ASMJIT_INLINE_NODEBUG Opcode& addWIf(T exp) noexcept { return operator|=(uint32_t(exp) << kW_Shift); }
template<typename T>
- inline Opcode& addWBySize(T size) noexcept { return addWIf(size == 8); }
+ ASMJIT_INLINE_NODEBUG Opcode& addWBySize(T size) noexcept { return addWIf(size == 8); }
template<typename T>
- inline Opcode& addPrefixBySize(T size) noexcept {
+ ASMJIT_INLINE_NODEBUG Opcode& addPrefixBySize(T size) noexcept {
static const uint32_t mask[16] = {
0, // #0
0, // #1 -> nothing (already handled or not possible)
@@ -372,7 +372,7 @@ struct Opcode {
}
template<typename T>
- inline Opcode& addArithBySize(T size) noexcept {
+ ASMJIT_INLINE_NODEBUG Opcode& addArithBySize(T size) noexcept {
static const uint32_t mask[16] = {
0, // #0
0, // #1 -> nothing
@@ -387,45 +387,45 @@ struct Opcode {
return operator|=(mask[size & 0xF]);
}
- inline Opcode& forceEvex() noexcept { return operator|=(kMM_ForceEvex); }
+ ASMJIT_INLINE_NODEBUG Opcode& forceEvex() noexcept { return operator|=(kMM_ForceEvex); }
template<typename T>
- inline Opcode& forceEvexIf(T exp) noexcept { return operator|=(uint32_t(exp) << Support::ConstCTZ<uint32_t(kMM_ForceEvex)>::value); }
+ ASMJIT_INLINE_NODEBUG 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).
- inline uint32_t extractModO() const noexcept {
+ ASMJIT_INLINE_NODEBUG uint32_t extractModO() const noexcept {
return (v >> kModO_Shift) & 0x07;
}
//! Extract `RM` field (RM) from the opcode (usually specified as another opcode value).
- inline uint32_t extractModRM() const noexcept {
+ ASMJIT_INLINE_NODEBUG uint32_t extractModRM() const noexcept {
return (v >> kModRM_Shift) & 0x07;
}
//! Extract `REX` prefix from opcode combined with `options`.
- inline uint32_t extractRex(InstOptions options) const noexcept {
+ ASMJIT_INLINE_NODEBUG 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;
}
- inline uint32_t extractLLMMMMM(InstOptions options) const noexcept {
+ ASMJIT_INLINE_NODEBUG 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;
}
- 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; }
+ ASMJIT_INLINE_NODEBUG Opcode& operator=(uint32_t x) noexcept { v = x; return *this; }
+ ASMJIT_INLINE_NODEBUG Opcode& operator+=(uint32_t x) noexcept { v += x; return *this; }
+ ASMJIT_INLINE_NODEBUG Opcode& operator-=(uint32_t x) noexcept { v -= x; return *this; }
+ ASMJIT_INLINE_NODEBUG Opcode& operator&=(uint32_t x) noexcept { v &= x; return *this; }
+ ASMJIT_INLINE_NODEBUG Opcode& operator|=(uint32_t x) noexcept { v |= x; return *this; }
+ ASMJIT_INLINE_NODEBUG Opcode& operator^=(uint32_t x) noexcept { v ^= x; return *this; }
+
+ ASMJIT_INLINE_NODEBUG uint32_t operator&(uint32_t x) const noexcept { return v & x; }
+ ASMJIT_INLINE_NODEBUG uint32_t operator|(uint32_t x) const noexcept { return v | x; }
+ ASMJIT_INLINE_NODEBUG uint32_t operator^(uint32_t x) const noexcept { return v ^ x; }
+ ASMJIT_INLINE_NODEBUG uint32_t operator<<(uint32_t x) const noexcept { return v << x; }
+ ASMJIT_INLINE_NODEBUG uint32_t operator>>(uint32_t x) const noexcept { return v >> x; }
};
//! \}
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86operand.cpp b/3rdparty/asmjit/src/asmjit/x86/x86operand.cpp
index a47fec2b5b2..5ab50de570e 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86operand.cpp
+++ b/3rdparty/asmjit/src/asmjit/x86/x86operand.cpp
@@ -19,210 +19,210 @@ UNIT(x86_operand) {
Label L(1000); // Label with some ID.
INFO("Checking basic properties of built-in X86 registers");
- EXPECT(gpb(Gp::kIdAx) == al);
- EXPECT(gpb(Gp::kIdBx) == bl);
- EXPECT(gpb(Gp::kIdCx) == cl);
- EXPECT(gpb(Gp::kIdDx) == dl);
-
- EXPECT(gpb_lo(Gp::kIdAx) == al);
- EXPECT(gpb_lo(Gp::kIdBx) == bl);
- EXPECT(gpb_lo(Gp::kIdCx) == cl);
- EXPECT(gpb_lo(Gp::kIdDx) == dl);
-
- EXPECT(gpb_hi(Gp::kIdAx) == ah);
- EXPECT(gpb_hi(Gp::kIdBx) == bh);
- EXPECT(gpb_hi(Gp::kIdCx) == ch);
- EXPECT(gpb_hi(Gp::kIdDx) == dh);
-
- EXPECT(gpw(Gp::kIdAx) == ax);
- EXPECT(gpw(Gp::kIdBx) == bx);
- EXPECT(gpw(Gp::kIdCx) == cx);
- EXPECT(gpw(Gp::kIdDx) == dx);
-
- EXPECT(gpd(Gp::kIdAx) == eax);
- EXPECT(gpd(Gp::kIdBx) == ebx);
- EXPECT(gpd(Gp::kIdCx) == ecx);
- EXPECT(gpd(Gp::kIdDx) == edx);
-
- EXPECT(gpq(Gp::kIdAx) == rax);
- EXPECT(gpq(Gp::kIdBx) == rbx);
- EXPECT(gpq(Gp::kIdCx) == rcx);
- EXPECT(gpq(Gp::kIdDx) == rdx);
-
- EXPECT(gpb(Gp::kIdAx) != dl);
- EXPECT(gpw(Gp::kIdBx) != cx);
- EXPECT(gpd(Gp::kIdCx) != ebx);
- EXPECT(gpq(Gp::kIdDx) != rax);
+ EXPECT_EQ(gpb(Gp::kIdAx), al);
+ EXPECT_EQ(gpb(Gp::kIdBx), bl);
+ EXPECT_EQ(gpb(Gp::kIdCx), cl);
+ EXPECT_EQ(gpb(Gp::kIdDx), dl);
+
+ EXPECT_EQ(gpb_lo(Gp::kIdAx), al);
+ EXPECT_EQ(gpb_lo(Gp::kIdBx), bl);
+ EXPECT_EQ(gpb_lo(Gp::kIdCx), cl);
+ EXPECT_EQ(gpb_lo(Gp::kIdDx), dl);
+
+ EXPECT_EQ(gpb_hi(Gp::kIdAx), ah);
+ EXPECT_EQ(gpb_hi(Gp::kIdBx), bh);
+ EXPECT_EQ(gpb_hi(Gp::kIdCx), ch);
+ EXPECT_EQ(gpb_hi(Gp::kIdDx), dh);
+
+ EXPECT_EQ(gpw(Gp::kIdAx), ax);
+ EXPECT_EQ(gpw(Gp::kIdBx), bx);
+ EXPECT_EQ(gpw(Gp::kIdCx), cx);
+ EXPECT_EQ(gpw(Gp::kIdDx), dx);
+
+ EXPECT_EQ(gpd(Gp::kIdAx), eax);
+ EXPECT_EQ(gpd(Gp::kIdBx), ebx);
+ EXPECT_EQ(gpd(Gp::kIdCx), ecx);
+ EXPECT_EQ(gpd(Gp::kIdDx), edx);
+
+ EXPECT_EQ(gpq(Gp::kIdAx), rax);
+ EXPECT_EQ(gpq(Gp::kIdBx), rbx);
+ EXPECT_EQ(gpq(Gp::kIdCx), rcx);
+ EXPECT_EQ(gpq(Gp::kIdDx), rdx);
+
+ EXPECT_NE(gpb(Gp::kIdAx), dl);
+ EXPECT_NE(gpw(Gp::kIdBx), cx);
+ EXPECT_NE(gpd(Gp::kIdCx), ebx);
+ EXPECT_NE(gpq(Gp::kIdDx), rax);
INFO("Checking if x86::reg(...) matches built-in IDs");
- EXPECT(gpb(5) == bpl);
- EXPECT(gpw(5) == bp);
- EXPECT(gpd(5) == ebp);
- EXPECT(gpq(5) == rbp);
- EXPECT(st(5) == st5);
- EXPECT(mm(5) == mm5);
- EXPECT(k(5) == k5);
- EXPECT(cr(5) == cr5);
- EXPECT(dr(5) == dr5);
- EXPECT(xmm(5) == xmm5);
- EXPECT(ymm(5) == ymm5);
- EXPECT(zmm(5) == zmm5);
+ EXPECT_EQ(gpb(5), bpl);
+ EXPECT_EQ(gpw(5), bp);
+ EXPECT_EQ(gpd(5), ebp);
+ EXPECT_EQ(gpq(5), rbp);
+ EXPECT_EQ(st(5) , st5);
+ EXPECT_EQ(mm(5) , mm5);
+ EXPECT_EQ(k(5) , k5);
+ EXPECT_EQ(cr(5) , cr5);
+ EXPECT_EQ(dr(5) , dr5);
+ EXPECT_EQ(xmm(5), xmm5);
+ EXPECT_EQ(ymm(5), ymm5);
+ EXPECT_EQ(zmm(5), zmm5);
INFO("Checking x86::Gp register properties");
- EXPECT(Gp().isReg() == true);
- EXPECT(eax.isReg() == true);
- EXPECT(eax.id() == 0);
- EXPECT(eax.size() == 4);
- EXPECT(eax.type() == RegType::kX86_Gpd);
- EXPECT(eax.group() == RegGroup::kGp);
+ EXPECT_TRUE(Gp().isReg());
+ EXPECT_TRUE(eax.isReg());
+ EXPECT_EQ(eax.id(), 0u);
+ EXPECT_EQ(eax.size(), 4u);
+ EXPECT_EQ(eax.type(), RegType::kX86_Gpd);
+ EXPECT_EQ(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() == RegType::kX86_Xmm);
- EXPECT(xmm4.group() == RegGroup::kVec);
- EXPECT(xmm4.isVec());
+ EXPECT_TRUE(Xmm().isReg());
+ EXPECT_TRUE(xmm4.isReg());
+ EXPECT_EQ(xmm4.id(), 4u);
+ EXPECT_EQ(xmm4.size(), 16u);
+ EXPECT_EQ(xmm4.type(), RegType::kX86_Xmm);
+ EXPECT_EQ(xmm4.group(), RegGroup::kVec);
+ EXPECT_TRUE(xmm4.isVec());
INFO("Checking x86::Ymm register properties");
- EXPECT(Ymm().isReg() == true);
- EXPECT(ymm5.isReg() == true);
- EXPECT(ymm5.id() == 5);
- EXPECT(ymm5.size() == 32);
- EXPECT(ymm5.type() == RegType::kX86_Ymm);
- EXPECT(ymm5.group() == RegGroup::kVec);
- EXPECT(ymm5.isVec());
+ EXPECT_TRUE(Ymm().isReg());
+ EXPECT_TRUE(ymm5.isReg());
+ EXPECT_EQ(ymm5.id(), 5u);
+ EXPECT_EQ(ymm5.size(), 32u);
+ EXPECT_EQ(ymm5.type(), RegType::kX86_Ymm);
+ EXPECT_EQ(ymm5.group(), RegGroup::kVec);
+ EXPECT_TRUE(ymm5.isVec());
INFO("Checking x86::Zmm register properties");
- EXPECT(Zmm().isReg() == true);
- EXPECT(zmm6.isReg() == true);
- EXPECT(zmm6.id() == 6);
- EXPECT(zmm6.size() == 64);
- EXPECT(zmm6.type() == RegType::kX86_Zmm);
- EXPECT(zmm6.group() == RegGroup::kVec);
- EXPECT(zmm6.isVec());
+ EXPECT_TRUE(Zmm().isReg());
+ EXPECT_TRUE(zmm6.isReg());
+ EXPECT_EQ(zmm6.id(), 6u);
+ EXPECT_EQ(zmm6.size(), 64u);
+ EXPECT_EQ(zmm6.type(), RegType::kX86_Zmm);
+ EXPECT_EQ(zmm6.group(), RegGroup::kVec);
+ EXPECT_TRUE(zmm6.isVec());
INFO("Checking x86::Vec register properties");
- EXPECT(Vec().isReg() == true);
+ EXPECT_TRUE(Vec().isReg());
// Converts a VEC register to a type of the passed register, but keeps the ID.
- EXPECT(xmm4.cloneAs(ymm10) == ymm4);
- EXPECT(xmm4.cloneAs(zmm11) == zmm4);
- EXPECT(ymm5.cloneAs(xmm12) == xmm5);
- EXPECT(ymm5.cloneAs(zmm13) == zmm5);
- EXPECT(zmm6.cloneAs(xmm14) == xmm6);
- EXPECT(zmm6.cloneAs(ymm15) == ymm6);
+ EXPECT_EQ(xmm4.cloneAs(ymm10), ymm4);
+ EXPECT_EQ(xmm4.cloneAs(zmm11), zmm4);
+ EXPECT_EQ(ymm5.cloneAs(xmm12), xmm5);
+ EXPECT_EQ(ymm5.cloneAs(zmm13), zmm5);
+ EXPECT_EQ(zmm6.cloneAs(xmm14), xmm6);
+ EXPECT_EQ(zmm6.cloneAs(ymm15), ymm6);
- EXPECT(xmm7.xmm() == xmm7);
- EXPECT(xmm7.ymm() == ymm7);
- EXPECT(xmm7.zmm() == zmm7);
+ EXPECT_EQ(xmm7.xmm(), xmm7);
+ EXPECT_EQ(xmm7.ymm(), ymm7);
+ EXPECT_EQ(xmm7.zmm(), zmm7);
- EXPECT(ymm7.xmm() == xmm7);
- EXPECT(ymm7.ymm() == ymm7);
- EXPECT(ymm7.zmm() == zmm7);
+ EXPECT_EQ(ymm7.xmm(), xmm7);
+ EXPECT_EQ(ymm7.ymm(), ymm7);
+ EXPECT_EQ(ymm7.zmm(), zmm7);
- EXPECT(zmm7.xmm() == xmm7);
- EXPECT(zmm7.ymm() == ymm7);
- EXPECT(zmm7.zmm() == zmm7);
+ EXPECT_EQ(zmm7.xmm(), xmm7);
+ EXPECT_EQ(zmm7.ymm(), ymm7);
+ EXPECT_EQ(zmm7.zmm(), zmm7);
INFO("Checking x86::Mm register properties");
- EXPECT(Mm().isReg() == true);
- EXPECT(mm2.isReg() == true);
- EXPECT(mm2.id() == 2);
- EXPECT(mm2.size() == 8);
- EXPECT(mm2.type() == RegType::kX86_Mm);
- EXPECT(mm2.group() == RegGroup::kX86_MM);
+ EXPECT_TRUE(Mm().isReg());
+ EXPECT_TRUE(mm2.isReg());
+ EXPECT_EQ(mm2.id(), 2u);
+ EXPECT_EQ(mm2.size(), 8u);
+ EXPECT_EQ(mm2.type(), RegType::kX86_Mm);
+ EXPECT_EQ(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() == RegType::kX86_KReg);
- EXPECT(k3.group() == RegGroup::kX86_K);
+ EXPECT_TRUE(KReg().isReg());
+ EXPECT_TRUE(k3.isReg());
+ EXPECT_EQ(k3.id(), 3u);
+ EXPECT_EQ(k3.size(), 0u);
+ EXPECT_EQ(k3.type(), RegType::kX86_KReg);
+ EXPECT_EQ(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() == RegType::kX86_St);
- EXPECT(st1.group() == RegGroup::kX86_St);
+ EXPECT_TRUE(St().isReg());
+ EXPECT_TRUE(st1.isReg());
+ EXPECT_EQ(st1.id(), 1u);
+ EXPECT_EQ(st1.size(), 10u);
+ EXPECT_EQ(st1.type(), RegType::kX86_St);
+ EXPECT_EQ(st1.group(), RegGroup::kX86_St);
INFO("Checking if default constructed regs behave as expected");
- EXPECT(Reg().isValid() == false);
- EXPECT(Gp().isValid() == false);
- EXPECT(Xmm().isValid() == false);
- EXPECT(Ymm().isValid() == false);
- EXPECT(Zmm().isValid() == false);
- EXPECT(Mm().isValid() == false);
- EXPECT(KReg().isValid() == false);
- EXPECT(SReg().isValid() == false);
- EXPECT(CReg().isValid() == false);
- EXPECT(DReg().isValid() == false);
- EXPECT(St().isValid() == false);
- EXPECT(Bnd().isValid() == false);
+ EXPECT_FALSE(Reg().isValid());
+ EXPECT_FALSE(Gp().isValid());
+ EXPECT_FALSE(Xmm().isValid());
+ EXPECT_FALSE(Ymm().isValid());
+ EXPECT_FALSE(Zmm().isValid());
+ EXPECT_FALSE(Mm().isValid());
+ EXPECT_FALSE(KReg().isValid());
+ EXPECT_FALSE(SReg().isValid());
+ EXPECT_FALSE(CReg().isValid());
+ EXPECT_FALSE(DReg().isValid());
+ EXPECT_FALSE(St().isValid());
+ EXPECT_FALSE(Bnd().isValid());
INFO("Checking x86::Mem operand");
Mem m;
- EXPECT(m == Mem(), "Two default constructed x86::Mem operands must be equal");
+ EXPECT_EQ(m, Mem());
m = ptr(L);
- EXPECT(m.hasBase() == true);
- EXPECT(m.hasBaseReg() == false);
- EXPECT(m.hasBaseLabel() == true);
- EXPECT(m.hasOffset() == false);
- EXPECT(m.isOffset64Bit() == false);
- EXPECT(m.offset() == 0);
- EXPECT(m.offsetLo32() == 0);
+ EXPECT_TRUE(m.hasBase());
+ EXPECT_FALSE(m.hasBaseReg());
+ EXPECT_TRUE(m.hasBaseLabel());
+ EXPECT_FALSE(m.hasOffset());
+ EXPECT_FALSE(m.isOffset64Bit());
+ EXPECT_EQ(m.offset(), 0);
+ EXPECT_EQ(m.offsetLo32(), 0);
m = ptr(0x0123456789ABCDEFu);
- EXPECT(m.hasBase() == false);
- EXPECT(m.hasBaseReg() == false);
- EXPECT(m.hasIndex() == false);
- EXPECT(m.hasIndexReg() == false);
- EXPECT(m.hasOffset() == true);
- EXPECT(m.isOffset64Bit() == true);
- EXPECT(m.offset() == int64_t(0x0123456789ABCDEFu));
- EXPECT(m.offsetLo32() == int32_t(0x89ABCDEFu));
+ EXPECT_FALSE(m.hasBase());
+ EXPECT_FALSE(m.hasBaseReg());
+ EXPECT_FALSE(m.hasIndex());
+ EXPECT_FALSE(m.hasIndexReg());
+ EXPECT_TRUE(m.hasOffset());
+ EXPECT_TRUE(m.isOffset64Bit());
+ EXPECT_EQ(m.offset(), int64_t(0x0123456789ABCDEFu));
+ EXPECT_EQ(m.offsetLo32(), int32_t(0x89ABCDEFu));
m.addOffset(1);
- EXPECT(m.offset() == int64_t(0x0123456789ABCDF0u));
+ EXPECT_EQ(m.offset(), int64_t(0x0123456789ABCDF0u));
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));
- EXPECT(m.offsetLo32() == int32_t(0x89ABCDEFu));
+ EXPECT_FALSE(m.hasSegment());
+ EXPECT_FALSE(m.hasBase());
+ EXPECT_FALSE(m.hasBaseReg());
+ EXPECT_TRUE(m.hasIndex());
+ EXPECT_TRUE(m.hasIndexReg());
+ EXPECT_EQ(m.indexType(), rdi.type());
+ EXPECT_EQ(m.indexId(), rdi.id());
+ EXPECT_EQ(m.shift(), 3u);
+ EXPECT_TRUE(m.hasOffset());
+ EXPECT_TRUE(m.isOffset64Bit());
+ EXPECT_EQ(m.offset(), int64_t(0x0123456789ABCDEFu));
+ EXPECT_EQ(m.offsetLo32(), int32_t(0x89ABCDEFu));
m.resetIndex();
- EXPECT(m.hasIndex() == false);
- EXPECT(m.hasIndexReg() == false);
+ EXPECT_FALSE(m.hasIndex());
+ EXPECT_FALSE(m.hasIndexReg());
m = ptr(rax);
- EXPECT(m.hasBase() == true);
- EXPECT(m.hasBaseReg() == true);
- EXPECT(m.baseType() == rax.type());
- EXPECT(m.baseId() == rax.id());
- EXPECT(m.hasIndex() == false);
- EXPECT(m.hasIndexReg() == false);
- EXPECT(m.indexType() == RegType::kNone);
- EXPECT(m.indexId() == 0);
- EXPECT(m.hasOffset() == false);
- EXPECT(m.isOffset64Bit() == false);
- EXPECT(m.offset() == 0);
- EXPECT(m.offsetLo32() == 0);
+ EXPECT_TRUE(m.hasBase());
+ EXPECT_TRUE(m.hasBaseReg());
+ EXPECT_EQ(m.baseType(), rax.type());
+ EXPECT_EQ(m.baseId(), rax.id());
+ EXPECT_FALSE(m.hasIndex());
+ EXPECT_FALSE(m.hasIndexReg());
+ EXPECT_EQ(m.indexType(), RegType::kNone);
+ EXPECT_EQ(m.indexId(), 0u);
+ EXPECT_FALSE(m.hasOffset());
+ EXPECT_FALSE(m.isOffset64Bit());
+ EXPECT_EQ(m.offset(), 0);
+ EXPECT_EQ(m.offsetLo32(), 0);
m.setIndex(rsi);
- EXPECT(m.hasIndex() == true);
- EXPECT(m.hasIndexReg() == true);
- EXPECT(m.indexType() == rsi.type());
- EXPECT(m.indexId() == rsi.id());
+ EXPECT_TRUE(m.hasIndex());
+ EXPECT_TRUE(m.hasIndexReg());
+ EXPECT_EQ(m.indexType(), rsi.type());
+ EXPECT_EQ(m.indexId(), rsi.id());
}
#endif
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86operand.h b/3rdparty/asmjit/src/asmjit/x86/x86operand.h
index 037d4af4ddf..8510a9310b5 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86operand.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86operand.h
@@ -49,26 +49,26 @@ template<RegType kRegType>
struct RegTraits : public BaseRegTraits {};
//! \cond
-// <--------------------+-----+-------------------------+------------------------+---+---+------------------+
-// | 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 );
+// <--------------------+------------------------+------------------------+---+------------------+
+// | Reg-Type | Reg-Group |Sz | TypeId |
+// <--------------------+------------------------+------------------------+---+------------------+
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_Rip , RegGroup::kX86_Rip , 0 , TypeId::kVoid );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_GpbLo , RegGroup::kGp , 1 , TypeId::kInt8 );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_GpbHi , RegGroup::kGp , 1 , TypeId::kInt8 );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_Gpw , RegGroup::kGp , 2 , TypeId::kInt16 );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_Gpd , RegGroup::kGp , 4 , TypeId::kInt32 );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_Gpq , RegGroup::kGp , 8 , TypeId::kInt64 );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_Xmm , RegGroup::kVec , 16, TypeId::kInt32x4 );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_Ymm , RegGroup::kVec , 32, TypeId::kInt32x8 );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_Zmm , RegGroup::kVec , 64, TypeId::kInt32x16);
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_KReg , RegGroup::kX86_K , 0 , TypeId::kVoid );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_Mm , RegGroup::kX86_MM , 8 , TypeId::kMmx64 );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_SReg , RegGroup::kX86_SReg , 2 , TypeId::kVoid );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_CReg , RegGroup::kX86_CReg , 0 , TypeId::kVoid );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_DReg , RegGroup::kX86_DReg , 0 , TypeId::kVoid );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_St , RegGroup::kX86_St , 10, TypeId::kFloat80 );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_Bnd , RegGroup::kX86_Bnd , 16, TypeId::kVoid );
+ASMJIT_DEFINE_REG_TRAITS(RegType::kX86_Tmm , RegGroup::kX86_Tmm , 0 , TypeId::kVoid );
//! \endcond
//! Register (X86).
@@ -77,121 +77,135 @@ public:
ASMJIT_DEFINE_ABSTRACT_REG(Reg, BaseReg)
//! Tests whether the register is a GPB register (8-bit).
- inline constexpr bool isGpb() const noexcept { return size() == 1; }
+ ASMJIT_INLINE_NODEBUG constexpr bool isGpb() const noexcept { return size() == 1; }
//! Tests whether the register is a low GPB register (8-bit).
- inline constexpr bool isGpbLo() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_GpbLo>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isGpbLo() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_GpbLo>::kSignature); }
//! Tests whether the register is a high GPB register (8-bit).
- inline constexpr bool isGpbHi() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_GpbHi>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isGpbHi() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_GpbHi>::kSignature); }
//! Tests whether the register is a GPW register (16-bit).
- inline constexpr bool isGpw() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Gpw>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isGpw() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Gpw>::kSignature); }
//! Tests whether the register is a GPD register (32-bit).
- inline constexpr bool isGpd() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Gpd>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isGpd() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Gpd>::kSignature); }
//! Tests whether the register is a GPQ register (64-bit).
- inline constexpr bool isGpq() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Gpq>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isGpq() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Gpq>::kSignature); }
+
+ //! Tests whether the register is a 32-bit general purpose register, alias of \ref isGpd().
+ ASMJIT_INLINE_NODEBUG constexpr bool isGp32() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Gpd>::kSignature); }
+ //! Tests whether the register is a 64-bit general purpose register, alias of \ref isGpq()
+ ASMJIT_INLINE_NODEBUG constexpr bool isGp64() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Gpq>::kSignature); }
+
//! Tests whether the register is an XMM register (128-bit).
- inline constexpr bool isXmm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Xmm>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isXmm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Xmm>::kSignature); }
//! Tests whether the register is a YMM register (256-bit).
- inline constexpr bool isYmm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Ymm>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isYmm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Ymm>::kSignature); }
//! Tests whether the register is a ZMM register (512-bit).
- inline constexpr bool isZmm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Zmm>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isZmm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Zmm>::kSignature); }
+
+ //! Tests whether the register is a 128-bit vector register, alias of \ref isXmm().
+ ASMJIT_INLINE_NODEBUG constexpr bool isVec128() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Xmm>::kSignature); }
+ //! Tests whether the register is a 256-bit vector register, alias of \ref isYmm().
+ ASMJIT_INLINE_NODEBUG constexpr bool isVec256() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Ymm>::kSignature); }
+ //! Tests whether the register is a 512-bit vector register, alias of \ref isZmm().
+ ASMJIT_INLINE_NODEBUG constexpr bool isVec512() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Zmm>::kSignature); }
+
//! Tests whether the register is an MMX register (64-bit).
- inline constexpr bool isMm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Mm>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isMm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Mm>::kSignature); }
//! Tests whether the register is a K register (64-bit).
- inline constexpr bool isKReg() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_KReg>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isKReg() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_KReg>::kSignature); }
//! Tests whether the register is a segment register.
- inline constexpr bool isSReg() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_SReg>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isSReg() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_SReg>::kSignature); }
//! Tests whether the register is a control register.
- inline constexpr bool isCReg() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_CReg>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isCReg() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_CReg>::kSignature); }
//! Tests whether the register is a debug register.
- inline constexpr bool isDReg() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_DReg>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isDReg() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_DReg>::kSignature); }
//! Tests whether the register is an FPU register (80-bit).
- inline constexpr bool isSt() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_St>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isSt() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_St>::kSignature); }
//! Tests whether the register is a bound register.
- inline constexpr bool isBnd() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Bnd>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isBnd() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Bnd>::kSignature); }
//! Tests whether the register is a TMM register.
- inline constexpr bool isTmm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Tmm>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isTmm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Tmm>::kSignature); }
//! Tests whether the register is RIP.
- inline constexpr bool isRip() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Rip>::kSignature); }
+ ASMJIT_INLINE_NODEBUG constexpr bool isRip() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Rip>::kSignature); }
template<RegType REG_TYPE>
- inline void setRegT(uint32_t rId) noexcept {
+ ASMJIT_INLINE_NODEBUG void setRegT(uint32_t rId) noexcept {
setSignature(OperandSignature{RegTraits<REG_TYPE>::kSignature});
setId(rId);
}
- inline void setTypeAndId(RegType type, uint32_t id) noexcept {
+ ASMJIT_INLINE_NODEBUG void setTypeAndId(RegType type, uint32_t id) noexcept {
setSignature(signatureOf(type));
setId(id);
}
- 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); }
+ static ASMJIT_INLINE_NODEBUG RegGroup groupOf(RegType type) noexcept { return ArchTraits::byArch(Arch::kX86).regTypeToGroup(type); }
+ static ASMJIT_INLINE_NODEBUG TypeId typeIdOf(RegType type) noexcept { return ArchTraits::byArch(Arch::kX86).regTypeToTypeId(type); }
+ static ASMJIT_INLINE_NODEBUG OperandSignature signatureOf(RegType type) noexcept { return ArchTraits::byArch(Arch::kX86).regTypeToSignature(type); }
template<RegType REG_TYPE>
- static inline RegGroup groupOfT() noexcept { return RegGroup(RegTraits<REG_TYPE>::kGroup); }
+ static ASMJIT_INLINE_NODEBUG RegGroup groupOfT() noexcept { return RegGroup(RegTraits<REG_TYPE>::kGroup); }
template<RegType REG_TYPE>
- static inline TypeId typeIdOfT() noexcept { return TypeId(RegTraits<REG_TYPE>::kTypeId); }
+ static ASMJIT_INLINE_NODEBUG TypeId typeIdOfT() noexcept { return TypeId(RegTraits<REG_TYPE>::kTypeId); }
template<RegType REG_TYPE>
- static inline OperandSignature signatureOfT() noexcept { return OperandSignature{RegTraits<REG_TYPE>::kSignature}; }
+ static ASMJIT_INLINE_NODEBUG OperandSignature signatureOfT() noexcept { return OperandSignature{RegTraits<REG_TYPE>::kSignature}; }
- static inline OperandSignature signatureOfVecByType(TypeId typeId) noexcept {
+ static ASMJIT_INLINE_NODEBUG 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 OperandSignature signatureOfVecBySize(uint32_t size) noexcept {
+ static ASMJIT_INLINE_NODEBUG 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 {
+ static ASMJIT_INLINE_NODEBUG bool isGpb(const Operand_& op) noexcept {
// Check operand type, register group, and size. Not interested in register type.
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(); }
- static inline bool isGpbHi(const Operand_& op) noexcept { return op.as<Reg>().isGpbHi(); }
- static inline bool isGpw(const Operand_& op) noexcept { return op.as<Reg>().isGpw(); }
- static inline bool isGpd(const Operand_& op) noexcept { return op.as<Reg>().isGpd(); }
- static inline bool isGpq(const Operand_& op) noexcept { return op.as<Reg>().isGpq(); }
- static inline bool isXmm(const Operand_& op) noexcept { return op.as<Reg>().isXmm(); }
- static inline bool isYmm(const Operand_& op) noexcept { return op.as<Reg>().isYmm(); }
- static inline bool isZmm(const Operand_& op) noexcept { return op.as<Reg>().isZmm(); }
- static inline bool isMm(const Operand_& op) noexcept { return op.as<Reg>().isMm(); }
- static inline bool isKReg(const Operand_& op) noexcept { return op.as<Reg>().isKReg(); }
- static inline bool isSReg(const Operand_& op) noexcept { return op.as<Reg>().isSReg(); }
- static inline bool isCReg(const Operand_& op) noexcept { return op.as<Reg>().isCReg(); }
- static inline bool isDReg(const Operand_& op) noexcept { return op.as<Reg>().isDReg(); }
- static inline bool isSt(const Operand_& op) noexcept { return op.as<Reg>().isSt(); }
- static inline bool isBnd(const Operand_& op) noexcept { return op.as<Reg>().isBnd(); }
- static inline bool isTmm(const Operand_& op) noexcept { return op.as<Reg>().isTmm(); }
- static inline bool isRip(const Operand_& op) noexcept { return op.as<Reg>().isRip(); }
-
- static inline bool isGpb(const Operand_& op, uint32_t rId) noexcept { return isGpb(op) & (op.id() == rId); }
- static inline bool isGpbLo(const Operand_& op, uint32_t rId) noexcept { return isGpbLo(op) & (op.id() == rId); }
- static inline bool isGpbHi(const Operand_& op, uint32_t rId) noexcept { return isGpbHi(op) & (op.id() == rId); }
- static inline bool isGpw(const Operand_& op, uint32_t rId) noexcept { return isGpw(op) & (op.id() == rId); }
- static inline bool isGpd(const Operand_& op, uint32_t rId) noexcept { return isGpd(op) & (op.id() == rId); }
- static inline bool isGpq(const Operand_& op, uint32_t rId) noexcept { return isGpq(op) & (op.id() == rId); }
- static inline bool isXmm(const Operand_& op, uint32_t rId) noexcept { return isXmm(op) & (op.id() == rId); }
- static inline bool isYmm(const Operand_& op, uint32_t rId) noexcept { return isYmm(op) & (op.id() == rId); }
- static inline bool isZmm(const Operand_& op, uint32_t rId) noexcept { return isZmm(op) & (op.id() == rId); }
- static inline bool isMm(const Operand_& op, uint32_t rId) noexcept { return isMm(op) & (op.id() == rId); }
- static inline bool isKReg(const Operand_& op, uint32_t rId) noexcept { return isKReg(op) & (op.id() == rId); }
- static inline bool isSReg(const Operand_& op, uint32_t rId) noexcept { return isSReg(op) & (op.id() == rId); }
- static inline bool isCReg(const Operand_& op, uint32_t rId) noexcept { return isCReg(op) & (op.id() == rId); }
- static inline bool isDReg(const Operand_& op, uint32_t rId) noexcept { return isDReg(op) & (op.id() == rId); }
- static inline bool isSt(const Operand_& op, uint32_t rId) noexcept { return isSt(op) & (op.id() == rId); }
- static inline bool isBnd(const Operand_& op, uint32_t rId) noexcept { return isBnd(op) & (op.id() == rId); }
- static inline bool isTmm(const Operand_& op, uint32_t rId) noexcept { return isTmm(op) & (op.id() == rId); }
- static inline bool isRip(const Operand_& op, uint32_t rId) noexcept { return isRip(op) & (op.id() == rId); }
+ static ASMJIT_INLINE_NODEBUG bool isGpbLo(const Operand_& op) noexcept { return op.as<Reg>().isGpbLo(); }
+ static ASMJIT_INLINE_NODEBUG bool isGpbHi(const Operand_& op) noexcept { return op.as<Reg>().isGpbHi(); }
+ static ASMJIT_INLINE_NODEBUG bool isGpw(const Operand_& op) noexcept { return op.as<Reg>().isGpw(); }
+ static ASMJIT_INLINE_NODEBUG bool isGpd(const Operand_& op) noexcept { return op.as<Reg>().isGpd(); }
+ static ASMJIT_INLINE_NODEBUG bool isGpq(const Operand_& op) noexcept { return op.as<Reg>().isGpq(); }
+ static ASMJIT_INLINE_NODEBUG bool isXmm(const Operand_& op) noexcept { return op.as<Reg>().isXmm(); }
+ static ASMJIT_INLINE_NODEBUG bool isYmm(const Operand_& op) noexcept { return op.as<Reg>().isYmm(); }
+ static ASMJIT_INLINE_NODEBUG bool isZmm(const Operand_& op) noexcept { return op.as<Reg>().isZmm(); }
+ static ASMJIT_INLINE_NODEBUG bool isMm(const Operand_& op) noexcept { return op.as<Reg>().isMm(); }
+ static ASMJIT_INLINE_NODEBUG bool isKReg(const Operand_& op) noexcept { return op.as<Reg>().isKReg(); }
+ static ASMJIT_INLINE_NODEBUG bool isSReg(const Operand_& op) noexcept { return op.as<Reg>().isSReg(); }
+ static ASMJIT_INLINE_NODEBUG bool isCReg(const Operand_& op) noexcept { return op.as<Reg>().isCReg(); }
+ static ASMJIT_INLINE_NODEBUG bool isDReg(const Operand_& op) noexcept { return op.as<Reg>().isDReg(); }
+ static ASMJIT_INLINE_NODEBUG bool isSt(const Operand_& op) noexcept { return op.as<Reg>().isSt(); }
+ static ASMJIT_INLINE_NODEBUG bool isBnd(const Operand_& op) noexcept { return op.as<Reg>().isBnd(); }
+ static ASMJIT_INLINE_NODEBUG bool isTmm(const Operand_& op) noexcept { return op.as<Reg>().isTmm(); }
+ static ASMJIT_INLINE_NODEBUG bool isRip(const Operand_& op) noexcept { return op.as<Reg>().isRip(); }
+
+ static ASMJIT_INLINE_NODEBUG bool isGpb(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isGpb(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isGpbLo(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isGpbLo(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isGpbHi(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isGpbHi(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isGpw(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isGpw(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isGpd(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isGpd(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isGpq(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isGpq(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isXmm(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isXmm(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isYmm(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isYmm(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isZmm(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isZmm(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isMm(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isMm(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isKReg(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isKReg(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isSReg(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isSReg(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isCReg(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isCReg(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isDReg(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isDReg(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isSt(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isSt(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isBnd(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isBnd(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isTmm(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isTmm(op)) & unsigned(op.id() == rId)); }
+ static ASMJIT_INLINE_NODEBUG bool isRip(const Operand_& op, uint32_t rId) noexcept { return bool(unsigned(isRip(op)) & unsigned(op.id() == rId)); }
};
//! General purpose register (X86).
@@ -223,17 +237,17 @@ public:
};
//! Casts this register to 8-bit (LO) part.
- inline GpbLo r8() const noexcept;
+ ASMJIT_INLINE_NODEBUG GpbLo r8() const noexcept;
//! Casts this register to 8-bit (LO) part.
- inline GpbLo r8Lo() const noexcept;
+ ASMJIT_INLINE_NODEBUG GpbLo r8Lo() const noexcept;
//! Casts this register to 8-bit (HI) part.
- inline GpbHi r8Hi() const noexcept;
+ ASMJIT_INLINE_NODEBUG GpbHi r8Hi() const noexcept;
//! Casts this register to 16-bit.
- inline Gpw r16() const noexcept;
+ ASMJIT_INLINE_NODEBUG Gpw r16() const noexcept;
//! Casts this register to 32-bit.
- inline Gpd r32() const noexcept;
+ ASMJIT_INLINE_NODEBUG Gpd r32() const noexcept;
//! Casts this register to 64-bit.
- inline Gpq r64() const noexcept;
+ ASMJIT_INLINE_NODEBUG Gpq r64() const noexcept;
};
//! Vector register (XMM|YMM|ZMM) (X86).
@@ -241,14 +255,21 @@ class Vec : public Reg {
ASMJIT_DEFINE_ABSTRACT_REG(Vec, Reg)
//! Casts this register to XMM (clone).
- inline Xmm xmm() const noexcept;
- //! Casts this register to YMM.
- inline Ymm ymm() const noexcept;
- //! Casts this register to ZMM.
- inline Zmm zmm() const noexcept;
+ ASMJIT_INLINE_NODEBUG Xmm xmm() const noexcept;
+ //! Casts this register to YMM (clone).
+ ASMJIT_INLINE_NODEBUG Ymm ymm() const noexcept;
+ //! Casts this register to ZMM (clone).
+ ASMJIT_INLINE_NODEBUG Zmm zmm() const noexcept;
+
+ //! Casts this register to XMM (clone).
+ ASMJIT_INLINE_NODEBUG Vec v128() const noexcept;
+ //! Casts this register to YMM (clone).
+ ASMJIT_INLINE_NODEBUG Vec v256() const noexcept;
+ //! Casts this register to ZMM (clone).
+ ASMJIT_INLINE_NODEBUG Vec v512() const noexcept;
//! Casts this register to a register that has half the size (or XMM if it's already XMM).
- inline Vec half() const noexcept {
+ ASMJIT_INLINE_NODEBUG Vec half() const noexcept {
return Vec(type() == RegType::kX86_Zmm ? signatureOfT<RegType::kX86_Ymm>() : signatureOfT<RegType::kX86_Xmm>(), id());
}
};
@@ -300,21 +321,21 @@ class Gpq : public Gp { ASMJIT_DEFINE_FINAL_REG(Gpq, Gp, RegTraits<RegType::kX86
class Xmm : public Vec {
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()); }
+ ASMJIT_INLINE_NODEBUG Xmm half() const noexcept { return Xmm(id()); }
};
//! 256-bit YMM register (AVX+).
class Ymm : public Vec {
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()); }
+ ASMJIT_INLINE_NODEBUG Xmm half() const noexcept { return Xmm(id()); }
};
//! 512-bit ZMM register (AVX512+).
class Zmm : public Vec {
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()); }
+ ASMJIT_INLINE_NODEBUG Ymm half() const noexcept { return Ymm(id()); }
};
//! 64-bit MMX register (MMX+).
@@ -335,60 +356,61 @@ class Tmm : public Reg { ASMJIT_DEFINE_FINAL_REG(Tmm, Reg, RegTraits<RegType::kX
class Rip : public Reg { ASMJIT_DEFINE_FINAL_REG(Rip, Reg, RegTraits<RegType::kX86_Rip>) };
//! \cond
-inline GpbLo Gp::r8() const noexcept { return GpbLo(id()); }
-inline GpbLo Gp::r8Lo() const noexcept { return GpbLo(id()); }
-inline GpbHi Gp::r8Hi() const noexcept { return GpbHi(id()); }
-inline Gpw Gp::r16() const noexcept { return Gpw(id()); }
-inline Gpd Gp::r32() const noexcept { return Gpd(id()); }
-inline Gpq Gp::r64() const noexcept { return Gpq(id()); }
-inline Xmm Vec::xmm() const noexcept { return Xmm(id()); }
-inline Ymm Vec::ymm() const noexcept { return Ymm(id()); }
-inline Zmm Vec::zmm() const noexcept { return Zmm(id()); }
+ASMJIT_INLINE_NODEBUG GpbLo Gp::r8() const noexcept { return GpbLo(id()); }
+ASMJIT_INLINE_NODEBUG GpbLo Gp::r8Lo() const noexcept { return GpbLo(id()); }
+ASMJIT_INLINE_NODEBUG GpbHi Gp::r8Hi() const noexcept { return GpbHi(id()); }
+ASMJIT_INLINE_NODEBUG Gpw Gp::r16() const noexcept { return Gpw(id()); }
+ASMJIT_INLINE_NODEBUG Gpd Gp::r32() const noexcept { return Gpd(id()); }
+ASMJIT_INLINE_NODEBUG Gpq Gp::r64() const noexcept { return Gpq(id()); }
+ASMJIT_INLINE_NODEBUG Xmm Vec::xmm() const noexcept { return Xmm(id()); }
+ASMJIT_INLINE_NODEBUG Ymm Vec::ymm() const noexcept { return Ymm(id()); }
+ASMJIT_INLINE_NODEBUG Zmm Vec::zmm() const noexcept { return Zmm(id()); }
+ASMJIT_INLINE_NODEBUG Vec Vec::v128() const noexcept { return Xmm(id()); }
+ASMJIT_INLINE_NODEBUG Vec Vec::v256() const noexcept { return Ymm(id()); }
+ASMJIT_INLINE_NODEBUG Vec Vec::v512() const noexcept { return Zmm(id()); }
//! \endcond
//! \namespace asmjit::x86::regs
//!
-//! Registers provided by X86 and X64 ISAs are in both `asmjit::x86` and
-//! `asmjit::x86::regs` namespaces so they can be included with using directive.
-//! For example `using namespace asmjit::x86::regs` would include all registers,
-//! but not other X86-specific API, whereas `using namespace asmjit::x86` would
-//! include everything X86-specific.
+//! Registers provided by X86 and X64 ISAs are in both `asmjit::x86` and `asmjit::x86::regs` namespaces so they can
+//! be included with using directive. For example `using namespace asmjit::x86::regs` would include all registers,
+//! but not other X86-specific API, whereas `using namespace asmjit::x86` would include everything X86-specific.
#ifndef _DOXYGEN
namespace regs {
#endif
//! Creates an 8-bit low GPB register operand.
-static constexpr GpbLo gpb(uint32_t rId) noexcept { return GpbLo(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr GpbLo gpb(uint32_t rId) noexcept { return GpbLo(rId); }
//! Creates an 8-bit low GPB register operand.
-static constexpr GpbLo gpb_lo(uint32_t rId) noexcept { return GpbLo(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr GpbLo gpb_lo(uint32_t rId) noexcept { return GpbLo(rId); }
//! Creates an 8-bit high GPB register operand.
-static constexpr GpbHi gpb_hi(uint32_t rId) noexcept { return GpbHi(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr GpbHi gpb_hi(uint32_t rId) noexcept { return GpbHi(rId); }
//! Creates a 16-bit GPW register operand.
-static constexpr Gpw gpw(uint32_t rId) noexcept { return Gpw(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr Gpw gpw(uint32_t rId) noexcept { return Gpw(rId); }
//! Creates a 32-bit GPD register operand.
-static constexpr Gpd gpd(uint32_t rId) noexcept { return Gpd(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr Gpd gpd(uint32_t rId) noexcept { return Gpd(rId); }
//! Creates a 64-bit GPQ register operand (64-bit).
-static constexpr Gpq gpq(uint32_t rId) noexcept { return Gpq(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr Gpq gpq(uint32_t rId) noexcept { return Gpq(rId); }
//! Creates a 128-bit XMM register operand.
-static constexpr Xmm xmm(uint32_t rId) noexcept { return Xmm(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr Xmm xmm(uint32_t rId) noexcept { return Xmm(rId); }
//! Creates a 256-bit YMM register operand.
-static constexpr Ymm ymm(uint32_t rId) noexcept { return Ymm(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr Ymm ymm(uint32_t rId) noexcept { return Ymm(rId); }
//! Creates a 512-bit ZMM register operand.
-static constexpr Zmm zmm(uint32_t rId) noexcept { return Zmm(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr Zmm zmm(uint32_t rId) noexcept { return Zmm(rId); }
//! Creates a 64-bit Mm register operand.
-static constexpr Mm mm(uint32_t rId) noexcept { return Mm(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr Mm mm(uint32_t rId) noexcept { return Mm(rId); }
//! Creates a 64-bit K register operand.
-static constexpr KReg k(uint32_t rId) noexcept { return KReg(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr KReg k(uint32_t rId) noexcept { return KReg(rId); }
//! Creates a 32-bit or 64-bit control register operand.
-static constexpr CReg cr(uint32_t rId) noexcept { return CReg(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr CReg cr(uint32_t rId) noexcept { return CReg(rId); }
//! Creates a 32-bit or 64-bit debug register operand.
-static constexpr DReg dr(uint32_t rId) noexcept { return DReg(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr DReg dr(uint32_t rId) noexcept { return DReg(rId); }
//! Creates an 80-bit st register operand.
-static constexpr St st(uint32_t rId) noexcept { return St(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr St st(uint32_t rId) noexcept { return St(rId); }
//! Creates a 128-bit bound register operand.
-static constexpr Bnd bnd(uint32_t rId) noexcept { return Bnd(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr Bnd bnd(uint32_t rId) noexcept { return Bnd(rId); }
//! Creates a TMM register operand.
-static constexpr Tmm tmm(uint32_t rId) noexcept { return Tmm(rId); }
+static ASMJIT_INLINE_NODEBUG constexpr Tmm tmm(uint32_t rId) noexcept { return Tmm(rId); }
static constexpr GpbLo al = GpbLo(Gp::kIdAx);
static constexpr GpbLo bl = GpbLo(Gp::kIdBx);
@@ -723,25 +745,25 @@ public:
//! \{
//! Creates a default `Mem` operand that points to [0].
- inline constexpr Mem() noexcept
+ ASMJIT_INLINE_NODEBUG constexpr Mem() noexcept
: BaseMem() {}
- inline constexpr Mem(const Mem& other) noexcept
+ ASMJIT_INLINE_NODEBUG constexpr Mem(const Mem& other) noexcept
: BaseMem(other) {}
- inline explicit Mem(Globals::NoInit_) noexcept
+ ASMJIT_INLINE_NODEBUG explicit Mem(Globals::NoInit_) noexcept
: BaseMem(Globals::NoInit) {}
- inline constexpr Mem(const Signature& signature, uint32_t baseId, uint32_t indexId, int32_t offset) noexcept
+ ASMJIT_INLINE_NODEBUG 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
+ ASMJIT_INLINE_NODEBUG 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
+ ASMJIT_INLINE_NODEBUG 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()) |
@@ -749,13 +771,13 @@ public:
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
+ ASMJIT_INLINE_NODEBUG 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
+ ASMJIT_INLINE_NODEBUG 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()) |
@@ -763,12 +785,12 @@ public:
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
+ ASMJIT_INLINE_NODEBUG 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
+ ASMJIT_INLINE_NODEBUG 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) |
@@ -780,7 +802,7 @@ public:
//! \name Overloaded Operators
//! \{
- inline Mem& operator=(const Mem& other) noexcept = default;
+ ASMJIT_INLINE_NODEBUG Mem& operator=(const Mem& other) noexcept = default;
//! \}
@@ -788,17 +810,25 @@ public:
//! \{
//! Clones the memory operand.
- inline constexpr Mem clone() const noexcept { return Mem(*this); }
+ ASMJIT_INLINE_NODEBUG constexpr Mem clone() const noexcept { return Mem(*this); }
- //! Creates a new copy of this memory operand adjusted by `off`.
+ //! Creates a copy of this memory operand adjusted by `off`.
inline Mem cloneAdjusted(int64_t off) const noexcept {
Mem result(*this);
result.addOffset(off);
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]));
+ //! Creates a copy of this memory operand resized to `size`.
+ inline Mem cloneResized(uint32_t size) const noexcept {
+ Mem result(*this);
+ result.setSize(size);
+ return result;
+ }
+
+ //! Creates a copy of this memory operand with a broadcast `bcst`.
+ ASMJIT_INLINE_NODEBUG constexpr Mem cloneBroadcasted(Broadcast bcst) const noexcept {
+ return Mem((_signature & ~Signature{kSignatureMemBroadcastMask}) | Signature::fromValue<kSignatureMemBroadcastMask>(bcst), _baseId, _data[0], int32_t(_data[1]));
}
//! \}
@@ -809,43 +839,64 @@ public:
//! Converts memory `baseType` and `baseId` to `x86::Reg` instance.
//!
//! The memory must have a valid base register otherwise the result will be wrong.
- inline Reg baseReg() const noexcept { return Reg::fromTypeAndId(baseType(), baseId()); }
+ ASMJIT_INLINE_NODEBUG Reg baseReg() const noexcept { return Reg::fromTypeAndId(baseType(), baseId()); }
//! Converts memory `indexType` and `indexId` to `x86::Reg` instance.
//!
//! The memory must have a valid index register otherwise the result will be wrong.
- inline Reg indexReg() const noexcept { return Reg::fromTypeAndId(indexType(), indexId()); }
+ ASMJIT_INLINE_NODEBUG Reg indexReg() const noexcept { return Reg::fromTypeAndId(indexType(), indexId()); }
using BaseMem::setIndex;
- inline void setIndex(const BaseReg& index, uint32_t shift) noexcept {
+ ASMJIT_INLINE_NODEBUG void setIndex(const BaseReg& index, uint32_t shift) noexcept {
setIndex(index);
setShift(shift);
}
//! \}
+ //! \name Memory Size
+ //! \{
+
+ //! Tests whether the memory operand specifies a size (i.e. the size is not zero).
+ ASMJIT_INLINE_NODEBUG constexpr bool hasSize() const noexcept { return _signature.hasField<Signature::kSizeMask>(); }
+ //! Tests whether the memory operand size matches size `s`.
+ ASMJIT_INLINE_NODEBUG constexpr bool hasSize(uint32_t s) const noexcept { return size() == s; }
+
+ //! Returns the size of the memory operand in bytes.
+ //!
+ //! \note Most instructions would deduce the size of the memory operand, so in most cases it's expected that the
+ //! returned value would be zero. However, some instruction require the size to select between multiple variations,
+ //! so in some cases size is required would be non-zero (for example `inc [mem], immediate` requires size to
+ //! distinguish between 8-bit, 16-bit, 32-bit, and 64-bit increments.
+ ASMJIT_INLINE_NODEBUG constexpr uint32_t size() const noexcept { return _signature.getField<Signature::kSizeMask>(); }
+
+ //! Sets the memory operand size (in bytes).
+ ASMJIT_INLINE_NODEBUG void setSize(uint32_t size) noexcept { _signature.setField<Signature::kSizeMask>(size); }
+
+ //! \}
+
//! \name Address Type
//! \{
//! Returns the address type of the memory operand.
//!
//! 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>(); }
+ ASMJIT_INLINE_NODEBUG 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)); }
+ ASMJIT_INLINE_NODEBUG 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)); }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG constexpr bool isAbs() const noexcept { return addrType() == AddrType::kAbs; }
//! Sets the address type to \ref AddrType::kAbs.
- inline void setAbs() noexcept { setAddrType(AddrType::kAbs); }
+ ASMJIT_INLINE_NODEBUG 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; }
+ ASMJIT_INLINE_NODEBUG constexpr bool isRel() const noexcept { return addrType() == AddrType::kRel; }
//! Sets the address type to \ref AddrType::kRel.
- inline void setRel() noexcept { setAddrType(AddrType::kRel); }
+ ASMJIT_INLINE_NODEBUG void setRel() noexcept { setAddrType(AddrType::kRel); }
//! \}
@@ -853,18 +904,18 @@ public:
//! \{
//! Tests whether the memory operand has a segment override.
- inline constexpr bool hasSegment() const noexcept { return _signature.hasField<kSignatureMemSegmentMask>(); }
+ ASMJIT_INLINE_NODEBUG constexpr bool hasSegment() const noexcept { return _signature.hasField<kSignatureMemSegmentMask>(); }
//! Returns the associated segment override as `SReg` operand.
- inline constexpr SReg segment() const noexcept { return SReg(segmentId()); }
+ ASMJIT_INLINE_NODEBUG constexpr SReg segment() const noexcept { return SReg(segmentId()); }
//! Returns segment override register id, see `SReg::Id`.
- inline constexpr uint32_t segmentId() const noexcept { return _signature.getField<kSignatureMemSegmentMask>(); }
+ ASMJIT_INLINE_NODEBUG 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()); }
+ ASMJIT_INLINE_NODEBUG void setSegment(const SReg& seg) noexcept { setSegment(seg.id()); }
//! Sets the segment override to `id`.
- inline void setSegment(uint32_t rId) noexcept { _signature.setField<kSignatureMemSegmentMask>(rId); }
+ ASMJIT_INLINE_NODEBUG void setSegment(uint32_t rId) noexcept { _signature.setField<kSignatureMemSegmentMask>(rId); }
//! Resets the segment override.
- inline void resetSegment() noexcept { _signature.setField<kSignatureMemSegmentMask>(0); }
+ ASMJIT_INLINE_NODEBUG void resetSegment() noexcept { _signature.setField<kSignatureMemSegmentMask>(0); }
//! \}
@@ -872,13 +923,13 @@ public:
//! \{
//! Tests whether the memory operand has shift (aka scale) value.
- inline constexpr bool hasShift() const noexcept { return _signature.hasField<kSignatureMemShiftValueMask>(); }
+ ASMJIT_INLINE_NODEBUG constexpr bool hasShift() const noexcept { return _signature.hasField<kSignatureMemShiftValueMask>(); }
//! Returns the memory operand's shift (aka scale) value.
- inline constexpr uint32_t shift() const noexcept { return _signature.getField<kSignatureMemShiftValueMask>(); }
+ ASMJIT_INLINE_NODEBUG 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 { _signature.setField<kSignatureMemShiftValueMask>(shift); }
+ ASMJIT_INLINE_NODEBUG 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 { _signature.setField<kSignatureMemShiftValueMask>(0); }
+ ASMJIT_INLINE_NODEBUG void resetShift() noexcept { _signature.setField<kSignatureMemShiftValueMask>(0); }
//! \}
@@ -886,156 +937,168 @@ public:
//! \{
//! Tests whether the memory operand has broadcast {1tox}.
- inline constexpr bool hasBroadcast() const noexcept { return _signature.hasField<kSignatureMemBroadcastMask>(); }
+ ASMJIT_INLINE_NODEBUG constexpr bool hasBroadcast() const noexcept { return _signature.hasField<kSignatureMemBroadcastMask>(); }
//! Returns the memory operand's broadcast.
- inline constexpr Broadcast getBroadcast() const noexcept { return (Broadcast)_signature.getField<kSignatureMemBroadcastMask>(); }
+ ASMJIT_INLINE_NODEBUG constexpr Broadcast getBroadcast() const noexcept { return (Broadcast)_signature.getField<kSignatureMemBroadcastMask>(); }
//! Sets the memory operand's broadcast.
- inline void setBroadcast(Broadcast b) noexcept { _signature.setField<kSignatureMemBroadcastMask>(uint32_t(b)); }
+ ASMJIT_INLINE_NODEBUG void setBroadcast(Broadcast b) noexcept { _signature.setField<kSignatureMemBroadcastMask>(uint32_t(b)); }
//! Resets the memory operand's broadcast to none.
- inline void resetBroadcast() noexcept { _signature.setField<kSignatureMemBroadcastMask>(0); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG 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); }
+ ASMJIT_INLINE_NODEBUG constexpr Mem _1to64() const noexcept { return cloneBroadcasted(Broadcast::k1To64); }
//! \}
};
//! Creates `[base.reg + offset]` memory operand.
-static inline constexpr Mem ptr(const Gp& base, int32_t offset = 0, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG 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 inline constexpr Mem ptr(const Gp& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG 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 inline constexpr Mem ptr(const Gp& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG 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 inline constexpr Mem ptr(const Label& base, int32_t offset = 0, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG 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 inline constexpr Mem ptr(const Label& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG 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 inline constexpr Mem ptr(const Label& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG 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 inline constexpr Mem ptr(const Rip& rip_, int32_t offset = 0, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG 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 inline constexpr Mem ptr(uint64_t base, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG constexpr Mem ptr(uint64_t base, uint32_t size = 0) noexcept {
return Mem(base, size);
}
//! Creates `[base + (index.reg << shift)]` absolute memory operand.
-static inline constexpr Mem ptr(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG 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 inline constexpr Mem ptr(uint64_t base, const Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG 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 inline constexpr Mem ptr_abs(uint64_t base, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG 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 inline constexpr Mem ptr_abs(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG 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 inline constexpr Mem ptr_abs(uint64_t base, const Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG 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 inline constexpr Mem ptr_rel(uint64_t base, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG 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 inline constexpr Mem ptr_rel(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG 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 inline constexpr Mem ptr_rel(uint64_t base, const Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
+static ASMJIT_INLINE_NODEBUG 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)); \
- }
+#define ASMJIT_MEM_PTR(FUNC, SIZE) \
+ static ASMJIT_INLINE_NODEBUG constexpr Mem FUNC( \
+ const Gp& base, int32_t offset = 0) noexcept \
+ { return Mem(base, offset, SIZE); } \
+ \
+ static ASMJIT_INLINE_NODEBUG 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 ASMJIT_INLINE_NODEBUG 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 ASMJIT_INLINE_NODEBUG constexpr Mem FUNC( \
+ const Label& base, int32_t offset = 0) noexcept \
+ { return Mem(base, offset, SIZE); } \
+ \
+ static ASMJIT_INLINE_NODEBUG 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 ASMJIT_INLINE_NODEBUG constexpr Mem FUNC( \
+ const Rip& rip_, int32_t offset = 0) noexcept \
+ { return Mem(rip_, offset, SIZE); } \
+ \
+ static ASMJIT_INLINE_NODEBUG constexpr Mem FUNC( \
+ uint64_t base) noexcept \
+ { return Mem(base, SIZE); } \
+ \
+ static ASMJIT_INLINE_NODEBUG constexpr Mem FUNC( \
+ uint64_t base, const Gp& index, uint32_t shift = 0) noexcept \
+ { return Mem(base, index, shift, SIZE); } \
+ \
+ static ASMJIT_INLINE_NODEBUG constexpr Mem FUNC( \
+ uint64_t base, const Vec& index, uint32_t shift = 0) noexcept \
+ { return Mem(base, index, shift, SIZE); } \
+ \
+ static ASMJIT_INLINE_NODEBUG constexpr Mem FUNC##_abs( \
+ uint64_t base) noexcept \
+ { return Mem(base, SIZE, \
+ OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs)); } \
+ \
+ static ASMJIT_INLINE_NODEBUG 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 ASMJIT_INLINE_NODEBUG 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 ASMJIT_INLINE_NODEBUG constexpr Mem FUNC##_rel( \
+ uint64_t base) noexcept \
+ { return Mem(base, SIZE, \
+ OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel)); } \
+ \
+ static ASMJIT_INLINE_NODEBUG 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 ASMJIT_INLINE_NODEBUG 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)
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86rapass.cpp b/3rdparty/asmjit/src/asmjit/x86/x86rapass.cpp
index 02870d95ffe..c106c6c7e1d 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86rapass.cpp
+++ b/3rdparty/asmjit/src/asmjit/x86/x86rapass.cpp
@@ -183,6 +183,9 @@ Error RACFGBuilder::onInst(InstNode* inst, InstControlFlow& cf, RAInstBuilder& i
RATiedFlags flags = raRegRwFlags(opRwInfo.opFlags());
RegMask allowedRegs = instructionAllowedRegs;
+ if (opRwInfo.isUnique())
+ flags |= RATiedFlags::kUnique;
+
// 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.
@@ -220,9 +223,11 @@ Error RACFGBuilder::onInst(InstNode* inst, InstControlFlow& cf, RAInstBuilder& i
}
}
- // Do not use RegMem flag if changing Reg to Mem requires additional CPU feature that may not be enabled.
+ // Do not use RegMem flag if changing Reg to Mem requires a CPU feature that is not available.
if (rwInfo.rmFeature() && Support::test(flags, RATiedFlags::kUseRM | RATiedFlags::kOutRM)) {
- flags &= ~(RATiedFlags::kUseRM | RATiedFlags::kOutRM);
+ if (!cc()->code()->cpuFeatures().has(rwInfo.rmFeature())) {
+ flags &= ~(RATiedFlags::kUseRM | RATiedFlags::kOutRM);
+ }
}
RegGroup group = workReg->group();
@@ -472,6 +477,20 @@ Error RACFGBuilder::onInst(InstNode* inst, InstControlFlow& cf, RAInstBuilder& i
}
}
}
+ else if (opCount == 4 && inst->op(3).isImm()) {
+ const Imm& imm = inst->op(3).as<Imm>();
+
+ switch (inst->id()) {
+ case Inst::kIdVpternlogd:
+ case Inst::kIdVpternlogq: {
+ uint32_t predicate = uint32_t(imm.value() & 0xFFu);
+ if (predicate == 0x00u || predicate == 0xFFu) {
+ ib[0]->makeWriteOnly();
+ }
+ break;
+ }
+ }
+ }
switch (sameRegHint) {
case InstSameRegHint::kNone:
@@ -818,7 +837,7 @@ Error RACFGBuilder::moveImmToStackArg(InvokeNode* invokeNode, const FuncValue& a
stackPtr.setSize(4);
imm[0] = imm_;
- uint32_t nMovs = 0;
+ uint32_t movCount = 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
@@ -834,7 +853,7 @@ Error RACFGBuilder::moveImmToStackArg(InvokeNode* invokeNode, const FuncValue& a
case TypeId::kFloat32:
MovU32:
imm[0].zeroExtend32Bits();
- nMovs = 1;
+ movCount = 1;
break;
case TypeId::kInt64:
@@ -844,20 +863,20 @@ MovU32:
case TypeId::kMmx64:
if (_is64Bit && imm[0].isInt32()) {
stackPtr.setSize(8);
- nMovs = 1;
+ movCount = 1;
break;
}
imm[1].setValue(imm[0].uint32Hi());
imm[0].zeroExtend32Bits();
- nMovs = 2;
+ movCount = 2;
break;
default:
return DebugUtils::errored(kErrorInvalidAssignment);
}
- for (uint32_t i = 0; i < nMovs; i++) {
+ for (uint32_t i = 0; i < movCount; i++) {
ASMJIT_PROPAGATE(cc()->mov(stackPtr, imm[i]));
stackPtr.addOffsetLo32(int32_t(stackPtr.size()));
}
@@ -1304,6 +1323,54 @@ ASMJIT_FAVOR_SPEED Error X86RAPass::_rewrite(BaseNode* first, BaseNode* stop) no
}
}
+ // If one operand was rewritten from Reg to Mem, we have to ensure that we are using the correct instruction.
+ if (raInst->isRegToMemPatched()) {
+ switch (inst->id()) {
+ case Inst::kIdKmovb: {
+ if (operands[0].isGp() && operands[1].isMem()) {
+ // Transform from [V]MOVD to MOV.
+ operands[1].as<Mem>().setSize(1);
+ inst->setId(Inst::kIdMovzx);
+ }
+ break;
+ }
+
+ case Inst::kIdVmovw: {
+ if (operands[0].isGp() && operands[1].isMem()) {
+ // Transform from [V]MOVD to MOV.
+ operands[1].as<Mem>().setSize(2);
+ inst->setId(Inst::kIdMovzx);
+ }
+ break;
+ }
+
+ case Inst::kIdMovd:
+ case Inst::kIdVmovd:
+ case Inst::kIdKmovd: {
+ if (operands[0].isGp() && operands[1].isMem()) {
+ // Transform from [V]MOVD to MOV.
+ operands[1].as<Mem>().setSize(4);
+ inst->setId(Inst::kIdMov);
+ }
+ break;
+ }
+
+ case Inst::kIdMovq:
+ case Inst::kIdVmovq:
+ case Inst::kIdKmovq: {
+ if (operands[0].isGp() && operands[1].isMem()) {
+ // Transform from [V]MOVQ to MOV.
+ operands[1].as<Mem>().setSize(8);
+ inst->setId(Inst::kIdMov);
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
// Transform VEX instruction to EVEX when necessary.
if (raInst->isTransformable()) {
if (maxRegId > 15) {
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86rapass_p.h b/3rdparty/asmjit/src/asmjit/x86/x86rapass_p.h
index b9603c21afc..67227a1a619 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86rapass_p.h
+++ b/3rdparty/asmjit/src/asmjit/x86/x86rapass_p.h
@@ -36,7 +36,7 @@ public:
//! \{
X86RAPass() noexcept;
- virtual ~X86RAPass() noexcept;
+ ~X86RAPass() noexcept override;
//! \}
@@ -44,20 +44,20 @@ public:
//! \{
//! Returns the compiler casted to `x86::Compiler`.
- inline Compiler* cc() const noexcept { return static_cast<Compiler*>(_cb); }
+ ASMJIT_INLINE_NODEBUG Compiler* cc() const noexcept { return static_cast<Compiler*>(_cb); }
//! Returns emit helper.
- inline EmitHelper* emitHelper() noexcept { return &_emitHelper; }
+ ASMJIT_INLINE_NODEBUG EmitHelper* emitHelper() noexcept { return &_emitHelper; }
- inline bool avxEnabled() const noexcept { return _emitHelper._avxEnabled; }
- inline bool avx512Enabled() const noexcept { return _emitHelper._avx512Enabled; }
+ ASMJIT_INLINE_NODEBUG bool avxEnabled() const noexcept { return _emitHelper._avxEnabled; }
+ ASMJIT_INLINE_NODEBUG bool avx512Enabled() const noexcept { return _emitHelper._avx512Enabled; }
//! \}
//! \name Utilities
//! \{
- inline uint32_t choose(uint32_t sseInstId, uint32_t avxInstId) noexcept {
+ ASMJIT_INLINE_NODEBUG InstId choose(InstId sseInstId, InstId avxInstId) noexcept {
return avxEnabled() ? avxInstId : sseInstId;
}