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

github.com/asmjit/asmjit.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkobalicek <kobalicek.petr@gmail.com>2022-02-08 18:25:47 +0300
committerkobalicek <kobalicek.petr@gmail.com>2022-02-09 19:08:40 +0300
commit23ddf56b00f47d8aa0c82ad225e4b3a92661da7e (patch)
tree0cac2b45f63164b13273b61273f858d3b3dd5ccd
parent45b01147814594cca69d6cb9d93ed9eb049243cf (diff)
[ABI] Initial AArch64 support
-rw-r--r--CMakeLists.txt52
-rw-r--r--src/asmjit/a64.h62
-rw-r--r--src/asmjit/arm.h62
-rw-r--r--src/asmjit/arm/a64archtraits_p.h81
-rw-r--r--src/asmjit/arm/a64assembler.cpp5115
-rw-r--r--src/asmjit/arm/a64assembler.h72
-rw-r--r--src/asmjit/arm/a64builder.cpp51
-rw-r--r--src/asmjit/arm/a64builder.h57
-rw-r--r--src/asmjit/arm/a64compiler.cpp60
-rw-r--r--src/asmjit/arm/a64compiler.h235
-rw-r--r--src/asmjit/arm/a64emithelper.cpp464
-rw-r--r--src/asmjit/arm/a64emithelper_p.h50
-rw-r--r--src/asmjit/arm/a64emitter.h1228
-rw-r--r--src/asmjit/arm/a64formatter.cpp298
-rw-r--r--src/asmjit/arm/a64formatter_p.h59
-rw-r--r--src/asmjit/arm/a64func.cpp189
-rw-r--r--src/asmjit/arm/a64func_p.h33
-rw-r--r--src/asmjit/arm/a64globals.h1894
-rw-r--r--src/asmjit/arm/a64instapi.cpp278
-rw-r--r--src/asmjit/arm/a64instapi_p.h41
-rw-r--r--src/asmjit/arm/a64instdb.cpp1957
-rw-r--r--src/asmjit/arm/a64instdb.h74
-rw-r--r--src/asmjit/arm/a64instdb_p.h876
-rw-r--r--src/asmjit/arm/a64operand.cpp85
-rw-r--r--src/asmjit/arm/a64operand.h312
-rw-r--r--src/asmjit/arm/a64rapass.cpp806
-rw-r--r--src/asmjit/arm/a64rapass_p.h105
-rw-r--r--src/asmjit/arm/a64utils.h179
-rw-r--r--src/asmjit/arm/armformatter.cpp143
-rw-r--r--src/asmjit/arm/armformatter_p.h44
-rw-r--r--src/asmjit/arm/armglobals.h21
-rw-r--r--src/asmjit/arm/armoperand.h596
-rw-r--r--src/asmjit/core.h26
-rw-r--r--src/asmjit/core/api-config.h24
-rw-r--r--src/asmjit/core/archcommons.h103
-rw-r--r--src/asmjit/core/archtraits.cpp8
-rw-r--r--src/asmjit/core/assembler.cpp6
-rw-r--r--src/asmjit/core/builder.cpp4
-rw-r--r--src/asmjit/core/builder.h3
-rw-r--r--src/asmjit/core/codeholder.cpp34
-rw-r--r--src/asmjit/core/codeholder.h17
-rw-r--r--src/asmjit/core/codewriter.cpp86
-rw-r--r--src/asmjit/core/cpuinfo.cpp2
-rw-r--r--src/asmjit/core/cpuinfo.h2
-rw-r--r--src/asmjit/core/emitter.cpp68
-rw-r--r--src/asmjit/core/emitter.h43
-rw-r--r--src/asmjit/core/emitterutils.cpp4
-rw-r--r--src/asmjit/core/environment.h28
-rw-r--r--src/asmjit/core/formatter.cpp26
-rw-r--r--src/asmjit/core/func.cpp16
-rw-r--r--src/asmjit/core/inst.cpp22
-rw-r--r--src/asmjit/core/inst.h74
-rw-r--r--src/asmjit/core/jitruntime.cpp2
-rw-r--r--src/asmjit/core/operand.h23
-rw-r--r--src/asmjit/core/support.h46
-rw-r--r--src/asmjit/core/virtmem.cpp1
-rw-r--r--src/asmjit/core/zonetree.h1
-rw-r--r--src/asmjit/x86/x86assembler.cpp24
-rw-r--r--src/asmjit/x86/x86builder.cpp30
-rw-r--r--src/asmjit/x86/x86builder.h9
-rw-r--r--src/asmjit/x86/x86compiler.cpp36
-rw-r--r--src/asmjit/x86/x86compiler.h9
-rw-r--r--src/asmjit/x86/x86emithelper.cpp31
-rw-r--r--src/asmjit/x86/x86emithelper_p.h2
-rw-r--r--src/asmjit/x86/x86formatter.cpp3
-rw-r--r--src/asmjit/x86/x86formatter_p.h8
-rw-r--r--src/asmjit/x86/x86instapi_p.h10
-rw-r--r--test/asmjit_test_assembler.cpp23
-rw-r--r--test/asmjit_test_assembler.h2
-rw-r--r--test/asmjit_test_assembler_a64.cpp4006
-rw-r--r--test/asmjit_test_compiler.cpp10
-rw-r--r--test/asmjit_test_compiler_a64.cpp690
-rw-r--r--test/asmjit_test_perf.cpp11
-rw-r--r--test/asmjit_test_perf_a64.cpp699
-rw-r--r--test/asmjit_test_x86_sections.cpp5
-rw-r--r--tools/tablegen-arm.js365
-rwxr-xr-xtools/tablegen-arm.sh3
-rw-r--r--tools/tablegen-x86.js1
-rwxr-xr-xtools/tablegen-x86.sh3
-rw-r--r--tools/tablegen.js38
-rwxr-xr-xtools/tablegen.sh1
81 files changed, 22011 insertions, 256 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 554722c..50c9bcc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -55,6 +55,14 @@ if (NOT DEFINED ASMJIT_NO_X86)
set(ASMJIT_NO_X86 FALSE)
endif()
+if (NOT DEFINED ASMJIT_NO_AARCH32)
+ set(ASMJIT_NO_AARCH32 FALSE)
+endif()
+
+if (NOT DEFINED ASMJIT_NO_AARCH64)
+ set(ASMJIT_NO_AARCH64 FALSE)
+endif()
+
if (NOT DEFINED ASMJIT_NO_FOREIGN)
set(ASMJIT_NO_FOREIGN FALSE)
endif()
@@ -78,7 +86,9 @@ set(ASMJIT_EMBED "${ASMJIT_EMBED}" CACHE BOOL "Embed 'asmjit
set(ASMJIT_STATIC "${ASMJIT_STATIC}" CACHE BOOL "Build 'asmjit' library as static")
set(ASMJIT_SANITIZE "${ASMJIT_SANITIZE}" CACHE STRING "Build with sanitizers: 'address', 'undefined', etc...")
set(ASMJIT_NO_X86 "${ASMJIT_NO_X86}" CACHE BOOL "Disable X86/X64 backend")
-set(ASMJIT_NO_FOREIGN "${ASMJIT_NO_FOREIGN}" CACHE BOOL "Disable all foreign architectures (builds only host backend)")
+set(ASMJIT_NO_AARCH32 "${ASMJIT_NO_AARCH32}" CACHE BOOL "Disable AArch32 backend (ARM and THUMB)")
+set(ASMJIT_NO_AARCH64 "${ASMJIT_NO_AARCH64}" CACHE BOOL "Disable AArch64 backend")
+set(ASMJIT_NO_FOREIGN "${ASMJIT_NO_FOREIGN}" CACHE BOOL "Disable all foreign architectures (enables only a native architecture)")
set(ASMJIT_NO_NATVIS "${ASMJIT_NO_NATVIS}" CACHE BOOL "Disable natvis support (embedding asmjit.natvis in PDB)")
set(ASMJIT_NO_CUSTOM_FLAGS "${ASMJIT_NO_CUSTOM_FLAGS}" CACHE BOOL "Disable extra compilation flags added by AsmJit to its targets")
@@ -189,6 +199,7 @@ if (NOT ASMJIT_NO_CUSTOM_FLAGS)
list(APPEND ASMJIT_PRIVATE_CFLAGS
-MP # [+] Multi-Process Compilation.
-GF # [+] Eliminate duplicate strings.
+ -Zc:__cplusplus # [+] Conforming __cplusplus definition.
-Zc:inline # [+] Remove unreferenced COMDAT.
-Zc:strictStrings # [+] Strict const qualification of string literals.
-Zc:threadSafeInit- # [-] Thread-safe statics.
@@ -262,6 +273,8 @@ endif()
foreach(build_option ASMJIT_STATIC
# AsmJit backends selection.
ASMJIT_NO_X86
+ ASMJIT_NO_AARCH32
+ ASMJIT_NO_AARCH64
ASMJIT_NO_FOREIGN
# AsmJit features selection.
ASMJIT_NO_DEPRECATED
@@ -381,6 +394,36 @@ set(ASMJIT_SRC_LIST
asmjit/core/zonevector.cpp
asmjit/core/zonevector.h
+ asmjit/arm.h
+ asmjit/arm/armformatter.cpp
+ asmjit/arm/armformatter_p.h
+ asmjit/arm/armglobals.h
+ asmjit/arm/armoperand.h
+ asmjit/arm/a64archtraits_p.h
+ asmjit/arm/a64assembler.cpp
+ asmjit/arm/a64assembler.h
+ asmjit/arm/a64builder.cpp
+ asmjit/arm/a64builder.h
+ asmjit/arm/a64compiler.cpp
+ asmjit/arm/a64compiler.h
+ asmjit/arm/a64emithelper.cpp
+ asmjit/arm/a64emithelper_p.h
+ asmjit/arm/a64emitter.h
+ asmjit/arm/a64formatter.cpp
+ asmjit/arm/a64formatter_p.h
+ asmjit/arm/a64func.cpp
+ asmjit/arm/a64func_p.h
+ asmjit/arm/a64globals.h
+ asmjit/arm/a64instapi.cpp
+ asmjit/arm/a64instapi_p.h
+ asmjit/arm/a64instdb.cpp
+ asmjit/arm/a64instdb.h
+ asmjit/arm/a64operand.cpp
+ asmjit/arm/a64operand.h
+ asmjit/arm/a64rapass.cpp
+ asmjit/arm/a64rapass_p.h
+ asmjit/arm/a64utils.h
+
asmjit/x86.h
asmjit/x86/x86archtraits_p.h
asmjit/x86/x86assembler.cpp
@@ -504,9 +547,10 @@ if (NOT ASMJIT_EMBED)
asmjit_add_target(asmjit_test_assembler TEST
SOURCES test/asmjit_test_assembler.cpp
+ test/asmjit_test_assembler.h
+ test/asmjit_test_assembler_a64.cpp
test/asmjit_test_assembler_x64.cpp
test/asmjit_test_assembler_x86.cpp
- test/asmjit_test_assembler.h
LIBRARIES asmjit::asmjit
CFLAGS ${ASMJIT_PRIVATE_CFLAGS}
CFLAGS_DBG ${ASMJIT_PRIVATE_CFLAGS_DBG}
@@ -514,6 +558,7 @@ if (NOT ASMJIT_EMBED)
asmjit_add_target(asmjit_test_perf EXECUTABLE
SOURCES test/asmjit_test_perf.cpp
+ test/asmjit_test_perf_a64.cpp
test/asmjit_test_perf_x86.cpp
SOURCES test/asmjit_test_perf.h
LIBRARIES asmjit::asmjit
@@ -550,8 +595,9 @@ if (NOT ASMJIT_EMBED)
endif()
asmjit_add_target(asmjit_test_compiler TEST
SOURCES test/asmjit_test_compiler.cpp
- test/asmjit_test_compiler_x86.cpp
test/asmjit_test_compiler.h
+ test/asmjit_test_compiler_a64.cpp
+ test/asmjit_test_compiler_x86.cpp
LIBRARIES asmjit::asmjit
CFLAGS ${ASMJIT_PRIVATE_CFLAGS} ${sse2_flags}
CFLAGS_DBG ${ASMJIT_PRIVATE_CFLAGS_DBG}
diff --git a/src/asmjit/a64.h b/src/asmjit/a64.h
new file mode 100644
index 0000000..ea4d304
--- /dev/null
+++ b/src/asmjit/a64.h
@@ -0,0 +1,62 @@
+// 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_A64_H_INCLUDED
+#define ASMJIT_A64_H_INCLUDED
+
+//! \addtogroup asmjit_a64
+//!
+//! ### Emitters
+//!
+//! - \ref a64::Assembler - AArch64 assembler (must read, provides examples).
+//! - \ref a64::Builder - AArch64 builder.
+//! - \ref a64::Compiler - AArch64 compiler.
+//! - \ref a64::Emitter - AArch64 emitter (abstract).
+//!
+//! ### 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.
+//!
+//! - 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.
+//!
+//! ### Memory Operands
+//!
+//! - \ref arm::Mem - AArch32/AArch64 memory operand that provides support for all ARM addressing features
+//! including base, index, pre/post increment, and ARM-specific shift addressing and index extending.
+//!
+//! ### Other
+//!
+//! - \ref arm::Shift - Shift operation and value.
+//! - \ref a64::Utils - Utilities that can help during code generation for AArch64.
+
+#include "./arm.h"
+#include "./arm/a64assembler.h"
+#include "./arm/a64builder.h"
+#include "./arm/a64compiler.h"
+#include "./arm/a64emitter.h"
+#include "./arm/a64globals.h"
+#include "./arm/a64instdb.h"
+#include "./arm/a64operand.h"
+#include "./arm/a64utils.h"
+
+#endif // ASMJIT_A64_H_INCLUDED
+
diff --git a/src/asmjit/arm.h b/src/asmjit/arm.h
new file mode 100644
index 0000000..57ffa81
--- /dev/null
+++ b/src/asmjit/arm.h
@@ -0,0 +1,62 @@
+// 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_ARM_H_INCLUDED
+#define ASMJIT_ARM_H_INCLUDED
+
+//! \addtogroup asmjit_arm
+//!
+//! ### Namespaces
+//!
+//! - \ref arm - arm namespace provides common functionality for both AArch32 and AArch64 backends.
+//! - \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
+//!
+//! - AArch64
+//! - \ref a64::Assembler - AArch64 assembler (must read, provides examples).
+//! - \ref a64::Builder - AArch64 builder.
+//! - \ref a64::Compiler - AArch64 compiler.
+//! - \ref a64::Emitter - AArch64 emitter (abstract).
+//!
+//! ### Supported Instructions
+//!
+//! - 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.
+//!
+//! ### Memory Operands
+//!
+//! - \ref arm::Mem - AArch32/AArch64 memory operand that provides support for all ARM addressing features
+//! including base, index, pre/post increment, and ARM-specific shift addressing and index extending.
+//!
+//! ### Other
+//!
+//! - \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.
+
+#include "./core.h"
+#include "./arm/armglobals.h"
+#include "./arm/armoperand.h"
+
+#endif // ASMJIT_ARM_H_INCLUDED
diff --git a/src/asmjit/arm/a64archtraits_p.h b/src/asmjit/arm/a64archtraits_p.h
new file mode 100644
index 0000000..87559c7
--- /dev/null
+++ b/src/asmjit/arm/a64archtraits_p.h
@@ -0,0 +1,81 @@
+// 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_ARM_A64ARCHTRAITS_P_H_INCLUDED
+#define ASMJIT_ARM_A64ARCHTRAITS_P_H_INCLUDED
+
+#include "../core/archtraits.h"
+#include "../core/misc_p.h"
+#include "../core/type.h"
+#include "../arm/a64operand.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+
+//! \cond INTERNAL
+//! \addtogroup asmjit_a64
+//! \{
+
+static const constexpr ArchTraits a64ArchTraits = {
+ // SP/FP/LR/PC.
+ Gp::kIdSp, Gp::kIdFp, Gp::kIdLr, 0xFF,
+
+ // Reserved.
+ { 0, 0, 0 },
+
+ // HW stack alignment (AArch64 requires stack aligned to 64 bytes).
+ 16,
+
+ // Min/max stack offset - byte addressing is the worst, VecQ addressing the best.
+ 4095, 65520,
+
+ // Instruction hints [Gp, Vec, ExtraVirt2, ExtraVirt3].
+ {{
+ InstHints::kPushPop,
+ InstHints::kPushPop,
+ InstHints::kNoHints,
+ InstHints::kNoHints
+ }},
+
+ // RegInfo.
+ #define V(index) OperandSignature{arm::RegTraits<RegType(index)>::kSignature}
+ {{ ASMJIT_LOOKUP_TABLE_32(V, 0) }},
+ #undef V
+
+ // RegTypeToTypeId.
+ #define V(index) TypeId(arm::RegTraits<RegType(index)>::kTypeId)
+ {{ ASMJIT_LOOKUP_TABLE_32(V, 0) }},
+ #undef V
+
+ // TypeIdToRegType.
+ #define V(index) (index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kInt8) ? RegType::kARM_GpW : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kUInt8) ? RegType::kARM_GpW : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kInt16) ? RegType::kARM_GpW : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kUInt16) ? RegType::kARM_GpW : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kInt32) ? RegType::kARM_GpW : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kUInt32) ? RegType::kARM_GpW : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kInt64) ? RegType::kARM_GpX : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kUInt64) ? RegType::kARM_GpX : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kIntPtr) ? RegType::kARM_GpX : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kUIntPtr) ? RegType::kARM_GpX : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kFloat32) ? RegType::kARM_VecS : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kFloat64) ? RegType::kARM_VecD : RegType::kNone)
+ {{ ASMJIT_LOOKUP_TABLE_32(V, 0) }},
+ #undef V
+
+ // Word names of 8-bit, 16-bit, 32-bit, and 64-bit quantities.
+ {
+ ArchTypeNameId::kByte,
+ ArchTypeNameId::kHWord,
+ ArchTypeNameId::kWord,
+ ArchTypeNameId::kXWord
+ }
+};
+
+//! \}
+//! \endcond
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // ASMJIT_ARM_A64ARCHTRAITS_P_H_INCLUDED
diff --git a/src/asmjit/arm/a64assembler.cpp b/src/asmjit/arm/a64assembler.cpp
new file mode 100644
index 0000000..9f8c9b1
--- /dev/null
+++ b/src/asmjit/arm/a64assembler.cpp
@@ -0,0 +1,5115 @@
+// 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"
+#if !defined(ASMJIT_NO_AARCH64)
+
+#include "../core/codewriter_p.h"
+#include "../core/cpuinfo.h"
+#include "../core/emitterutils_p.h"
+#include "../core/formatter.h"
+#include "../core/logger.h"
+#include "../core/misc_p.h"
+#include "../core/support.h"
+#include "../arm/armformatter_p.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 - Cond
+// =====================
+
+static inline uint32_t condCodeToOpcodeCond(uint32_t cond) noexcept {
+ return (uint32_t(cond) - 2u) & 0xFu;
+}
+
+// a64::Assembler - Bits
+// =====================
+
+template<typename T>
+static inline constexpr uint32_t B(const T& index) noexcept { return uint32_t(1u) << uint32_t(index); }
+
+static constexpr uint32_t kSP = Gp::kIdSp;
+static constexpr uint32_t kZR = Gp::kIdZr;
+static constexpr uint32_t kWX = InstDB::kWX;
+
+// a64::Assembler - ShiftOpToLdStOptMap
+// ====================================
+
+// Table that maps ShiftOp to OPT part in LD/ST (register) opcode.
+#define VALUE(index) index == uint32_t(ShiftOp::kUXTW) ? 2u : \
+ index == uint32_t(ShiftOp::kLSL) ? 3u : \
+ index == uint32_t(ShiftOp::kSXTW) ? 6u : \
+ index == uint32_t(ShiftOp::kSXTX) ? 7u : 0xFF
+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);
+}
+
+// asmjit::a64::Assembler - SizeOp
+// ===============================
+
+//! Struct that contains Size (2 bits), Q flag, and S (scalar) flag. These values
+//! are used to encode Q, Size, and Scalar fields in an opcode.
+struct SizeOp {
+ enum : uint8_t {
+ k128BitShift = 0,
+ kScalarShift = 1,
+ kSizeShift = 2,
+
+ kQ = uint8_t(1u << k128BitShift),
+ kS = uint8_t(1u << kScalarShift),
+
+ k00 = uint8_t(0 << kSizeShift),
+ k01 = uint8_t(1 << kSizeShift),
+ k10 = uint8_t(2 << kSizeShift),
+ k11 = uint8_t(3 << kSizeShift),
+
+ k00Q = k00 | kQ,
+ k01Q = k01 | kQ,
+ k10Q = k10 | kQ,
+ k11Q = k11 | kQ,
+
+ k00S = k00 | kS,
+ k01S = k01 | kS,
+ k10S = k10 | kS,
+ k11S = k11 | kS,
+
+ kInvalid = 0xFFu,
+
+ // Masks used by SizeOpMap.
+ kSzQ = (0x3u << kSizeShift) | kQ,
+ kSzS = (0x3u << kSizeShift) | kS,
+ kSzQS = (0x3u << kSizeShift) | kQ | kS
+ };
+
+ uint8_t value;
+
+ inline bool isValid() const noexcept { return value != kInvalid; }
+ inline void makeInvalid() noexcept { value = kInvalid; }
+
+ inline uint32_t q() const noexcept { return (value >> k128BitShift) & 0x1u; }
+ inline uint32_t qs() const noexcept { return ((value >> k128BitShift) | (value >> kScalarShift)) & 0x1u; }
+ inline uint32_t scalar() const noexcept { return (value >> kScalarShift) & 0x1u; }
+ inline uint32_t size() const noexcept { return (value >> kSizeShift) & 0x3u; }
+
+ inline void decrementSize() noexcept {
+ ASMJIT_ASSERT(size() > 0);
+ value = uint8_t(value - (1u << kSizeShift));
+ }
+};
+
+struct SizeOpTable {
+ enum TableId : uint8_t {
+ kTableBin = 0,
+ kTableAny,
+ kCount
+ };
+
+ // 40 elements for each combination.
+ SizeOp array[(uint32_t(RegType::kARM_VecV) - uint32_t(RegType::kARM_VecB) + 1) * 8];
+};
+
+#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 \
+}
+
+#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 \
+}
+
+static const SizeOpTable sizeOpTable[SizeOpTable::kCount] = {
+ {{ ASMJIT_LOOKUP_TABLE_40(VALUE_BIN, 0) }},
+ {{ ASMJIT_LOOKUP_TABLE_40(VALUE_ANY, 0) }}
+};
+
+#undef VALUE_ANY
+#undef VALUE_BIN
+
+struct SizeOpMap {
+ uint8_t tableId;
+ uint8_t sizeOpMask;
+ uint16_t acceptMask;
+};
+
+static const constexpr SizeOpMap sizeOpMap[InstDB::kVO_Count] = {
+ { // kVO_V_B:
+ SizeOpTable::kTableBin, SizeOp::kQ , uint16_t(B(SizeOp::k00) | B(SizeOp::k00Q))
+ },
+
+ { // kVO_V_BH:
+ SizeOpTable::kTableAny, SizeOp::kSzQS, uint16_t(B(SizeOp::k00) | B(SizeOp::k00Q) | B(SizeOp::k01) | B(SizeOp::k01Q))
+ },
+
+ { // kVO_V_BH_4S:
+ SizeOpTable::kTableAny, SizeOp::kSzQS, uint16_t(B(SizeOp::k00) | B(SizeOp::k00Q) | B(SizeOp::k01) | B(SizeOp::k01Q) | B(SizeOp::k10Q))
+ },
+
+ { // kVO_V_BHS:
+ SizeOpTable::kTableAny, SizeOp::kSzQS, uint16_t(B(SizeOp::k00) | B(SizeOp::k00Q) | B(SizeOp::k01) | B(SizeOp::k01Q) | B(SizeOp::k10) | B(SizeOp::k10Q))
+ },
+
+ { // kVO_V_BHS_D2:
+ SizeOpTable::kTableAny, SizeOp::kSzQS, uint16_t(B(SizeOp::k00) | B(SizeOp::k00Q) | B(SizeOp::k01) | B(SizeOp::k01Q) | B(SizeOp::k10) | B(SizeOp::k10Q) | B(SizeOp::k11Q))
+ },
+
+ { // kVO_V_HS:
+ SizeOpTable::kTableAny, SizeOp::kSzQS, uint16_t(B(SizeOp::k01) | B(SizeOp::k01Q) | B(SizeOp::k10) | B(SizeOp::k10Q))
+ },
+
+ { // kVO_V_S:
+ SizeOpTable::kTableAny, SizeOp::kQ , uint16_t(B(SizeOp::k10) | B(SizeOp::k10Q))
+ },
+
+ { // kVO_V_B8H4:
+ SizeOpTable::kTableAny, SizeOp::kSzQS, uint16_t(B(SizeOp::k00) | B(SizeOp::k01))
+ },
+
+ { // kVO_V_B8H4S2:
+ SizeOpTable::kTableAny, SizeOp::kSzQS, uint16_t(B(SizeOp::k00) | B(SizeOp::k01) | B(SizeOp::k10))
+ },
+
+ { // kVO_V_B8D1:
+ SizeOpTable::kTableAny, SizeOp::kSzQ , uint16_t(B(SizeOp::k00) | B(SizeOp::k11S))
+ },
+
+ { // kVO_V_H4S2:
+ SizeOpTable::kTableAny, SizeOp::kSzQS, uint16_t(B(SizeOp::k01) | B(SizeOp::k10))
+ },
+
+ { // kVO_V_B16:
+ SizeOpTable::kTableBin, SizeOp::kQ , uint16_t(B(SizeOp::k00Q))
+ },
+
+ { // kVO_V_B16H8:
+ SizeOpTable::kTableAny, SizeOp::kSzQS, uint16_t(B(SizeOp::k00Q) | B(SizeOp::k01Q))
+ },
+
+ { // kVO_V_B16H8S4:
+ SizeOpTable::kTableAny, SizeOp::kSzQS, uint16_t(B(SizeOp::k00Q) | B(SizeOp::k01Q) | B(SizeOp::k10Q))
+ },
+
+ { // kVO_V_B16D2:
+ SizeOpTable::kTableAny, SizeOp::kSzQS, uint16_t(B(SizeOp::k00Q) | B(SizeOp::k11Q))
+ },
+
+ { // kVO_V_H8S4:
+ SizeOpTable::kTableAny, SizeOp::kSzQS, uint16_t(B(SizeOp::k01Q) | B(SizeOp::k10Q))
+ },
+
+ { // kVO_V_S4:
+ SizeOpTable::kTableAny, 0 , uint16_t(B(SizeOp::k10Q))
+ },
+
+ { // kVO_V_D2:
+ SizeOpTable::kTableAny, 0 , uint16_t(B(SizeOp::k11Q))
+ },
+
+ { // kVO_SV_BHS:
+ SizeOpTable::kTableAny, SizeOp::kSzQS, uint16_t(B(SizeOp::k00) | B(SizeOp::k00Q) | B(SizeOp::k00S) | B(SizeOp::k01) | B(SizeOp::k01Q) | B(SizeOp::k01S) | B(SizeOp::k10) | B(SizeOp::k10Q) | B(SizeOp::k10S))
+ },
+
+ { // kVO_SV_B8H4S2:
+ SizeOpTable::kTableAny, SizeOp::kSzQS, uint16_t(B(SizeOp::k00) | B(SizeOp::k00S) | B(SizeOp::k01) | B(SizeOp::k01S) | B(SizeOp::k10) | B(SizeOp::k10S))
+ },
+
+ { // kVO_SV_HS:
+ SizeOpTable::kTableAny, SizeOp::kSzQS, uint16_t(B(SizeOp::k01) | B(SizeOp::k01Q) | B(SizeOp::k01S) | B(SizeOp::k10) | B(SizeOp::k10Q) | B(SizeOp::k10S))
+ },
+
+ { // kVO_V_Any:
+ SizeOpTable::kTableAny, SizeOp::kSzQS, uint16_t(B(SizeOp::k00) | B(SizeOp::k00Q) | B(SizeOp::k01) | B(SizeOp::k01Q) | B(SizeOp::k10) | B(SizeOp::k10Q) | B(SizeOp::k11S) | B(SizeOp::k11Q))
+ },
+
+ { // kVO_SV_Any:
+ SizeOpTable::kTableAny, SizeOp::kSzQS, uint16_t(B(SizeOp::k00) | B(SizeOp::k00Q) | B(SizeOp::k00S) |
+ B(SizeOp::k01) | B(SizeOp::k01Q) | B(SizeOp::k01S) |
+ B(SizeOp::k10) | B(SizeOp::k10Q) | B(SizeOp::k10S) |
+ B(SizeOp::k11) | B(SizeOp::k11Q) | B(SizeOp::k11S))
+ }
+};
+
+static const Operand_& significantSimdOp(const Operand_& o0, const Operand_& o1, uint32_t instFlags) noexcept {
+ return !(instFlags & InstDB::kInstFlagLong) ? o0 : o1;
+}
+
+static inline SizeOp armElementTypeToSizeOp(uint32_t vecOpType, RegType regType, uint32_t 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);
+
+ 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;
+ SizeOp op = table.array[index];
+ SizeOp modifiedOp { uint8_t(op.value & map.sizeOpMask) };
+
+ if (!Support::bitTest(map.acceptMask, op.value))
+ modifiedOp.makeInvalid();
+
+ return modifiedOp;
+}
+
+// a64::Assembler - Immediate Encoding Utilities (Integral)
+// ========================================================
+
+using Utils::LogicalImm;
+
+struct HalfWordImm {
+ uint32_t hw;
+ uint32_t inv;
+ uint32_t imm;
+};
+
+struct LMHImm {
+ uint32_t lm;
+ uint32_t h;
+ uint32_t maxRmId;
+};
+
+static inline uint32_t countZeroHalfWords64(uint64_t imm) noexcept {
+ return uint32_t((imm & 0x000000000000FFFFu) == 0) +
+ uint32_t((imm & 0x00000000FFFF0000u) == 0) +
+ uint32_t((imm & 0x0000FFFF00000000u) == 0) +
+ uint32_t((imm & 0xFFFF000000000000u) == 0) ;
+}
+
+static uint32_t encodeMovSequence32(uint32_t out[2], uint32_t imm, uint32_t rd, uint32_t x) noexcept {
+ ASMJIT_ASSERT(rd <= 31);
+
+ uint32_t kMovZ = 0b01010010100000000000000000000000 | (x << 31);
+ uint32_t kMovN = 0b00010010100000000000000000000000;
+ uint32_t kMovK = 0b01110010100000000000000000000000;
+
+ if ((imm & 0xFFFF0000u) == 0x00000000u) {
+ out[0] = kMovZ | (0 << 21) | ((imm & 0xFFFFu) << 5) | rd;
+ return 1;
+ }
+
+ if ((imm & 0xFFFF0000u) == 0xFFFF0000u) {
+ out[0] = kMovN | (0 << 21) | ((~imm & 0xFFFFu) << 5) | rd;
+ return 1;
+ }
+
+ if ((imm & 0x0000FFFFu) == 0x00000000u) {
+ out[0] = kMovZ | (1 << 21) | ((imm >> 16) << 5) | rd;
+ return 1;
+ }
+
+ if ((imm & 0x0000FFFFu) == 0x0000FFFFu) {
+ out[0] = kMovN | (1 << 21) | ((~imm >> 16) << 5) | rd;
+ return 1;
+ }
+
+ out[0] = kMovZ | (0 << 21) | ((imm & 0xFFFFu) << 5) | rd;
+ out[1] = kMovK | (1 << 21) | ((imm >> 16) << 5) | rd;
+ return 2;
+}
+
+static uint32_t encodeMovSequence64(uint32_t out[4], uint64_t imm, uint32_t rd, uint32_t x) noexcept {
+ ASMJIT_ASSERT(rd <= 31);
+
+ uint32_t kMovZ = 0b11010010100000000000000000000000;
+ uint32_t kMovN = 0b10010010100000000000000000000000;
+ uint32_t kMovK = 0b11110010100000000000000000000000;
+
+ if (imm <= 0xFFFFFFFFu)
+ return encodeMovSequence32(out, uint32_t(imm), rd, x);
+
+ uint32_t zhw = countZeroHalfWords64( imm);
+ uint32_t ohw = countZeroHalfWords64(~imm);
+
+ if (zhw >= ohw) {
+ uint32_t op = kMovZ;
+ uint32_t count = 0;
+
+ for (uint32_t hwIndex = 0; hwIndex < 4; hwIndex++, imm >>= 16) {
+ uint32_t hwImm = uint32_t(imm & 0xFFFFu);
+ if (hwImm == 0)
+ continue;
+
+ out[count++] = op | (hwIndex << 21) | (hwImm << 5) | rd;
+ op = kMovK;
+ }
+
+ // This should not happen - zero should be handled by encodeMovSequence32().
+ ASMJIT_ASSERT(count > 0);
+
+ return count;
+ }
+ else {
+ uint32_t op = kMovN;
+ uint32_t count = 0;
+ uint32_t negMask = 0xFFFFu;
+
+ for (uint32_t hwIndex = 0; hwIndex < 4; hwIndex++, imm >>= 16) {
+ uint32_t hwImm = uint32_t(imm & 0xFFFFu);
+ if (hwImm == 0xFFFFu)
+ continue;
+
+ out[count++] = op | (hwIndex << 21) | ((hwImm ^ negMask) << 5) | rd;
+ op = kMovK;
+ negMask = 0;
+ }
+
+ if (count == 0) {
+ out[count++] = kMovN | ((0xFFFF ^ negMask) << 5) | rd;
+ }
+
+ return count;
+ }
+}
+
+static inline bool encodeLMH(uint32_t sizeField, uint32_t elementIndex, LMHImm* out) noexcept {
+ if (sizeField != 1 && sizeField != 2)
+ return false;
+
+ uint32_t hShift = 3u - sizeField;
+ uint32_t lmShift = sizeField - 1u;
+ uint32_t maxElementIndex = 15u >> sizeField;
+
+ out->h = elementIndex >> hShift;
+ out->lm = (elementIndex << lmShift) & 0x3u;
+ out->maxRmId = (8u << sizeField) - 1;
+
+ 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
+// =======================
+
+//! Helper class to store and manipulate ARM opcode.
+struct Opcode {
+ uint32_t v;
+
+ enum Bits : uint32_t {
+ kN = (1u << 22),
+ kQ = (1u << 30),
+ kX = (1u << 31)
+ };
+
+ // --------------------------------------------------------------------------
+ // [Opcode Builder]
+ // --------------------------------------------------------------------------
+
+ inline uint32_t get() const noexcept { return v; }
+ inline void reset(uint32_t value) noexcept { v = value; }
+
+ inline bool hasQ() const noexcept { return (v & kQ) != 0; }
+ inline bool hasX() const noexcept { return (v & kX) != 0; }
+
+ template<typename T>
+ inline Opcode& addImm(T value, uint32_t bitIndex) noexcept { return operator|=(uint32_t(value) << bitIndex); }
+
+ template<typename T>
+ inline Opcode& xorImm(T value, uint32_t bitIndex) noexcept { return operator^=(uint32_t(value) << bitIndex); }
+
+ template<typename T, typename Condition>
+ inline Opcode& addIf(T value, const Condition& condition) noexcept { return operator|=(condition ? uint32_t(value) : uint32_t(0)); }
+
+ inline Opcode& addLogicalImm(const LogicalImm& logicalImm) noexcept {
+ addImm(logicalImm.n, 22);
+ addImm(logicalImm.r, 16);
+ addImm(logicalImm.s, 10);
+ return *this;
+ }
+
+ inline Opcode& addReg(uint32_t id, uint32_t bitIndex) noexcept { return operator|=((id & 31u) << bitIndex); }
+ inline Opcode& addReg(const Operand_& op, uint32_t bitIndex) noexcept { return addReg(op.id(), bitIndex); }
+
+ 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; }
+};
+
+// a64::Assembler - Signature Utilities
+// ====================================
+
+// TODO: [ARM] Deprecate matchSignature.
+static inline bool matchSignature(const Operand_& o0, const Operand_& o1, uint32_t instFlags) noexcept {
+ if (!(instFlags & (InstDB::kInstFlagLong | InstDB::kInstFlagNarrow)))
+ return o0.signature() == o1.signature();
+
+ // TODO: [ARM] Something smart to validate this.
+ return true;
+}
+
+static inline bool matchSignature(const Operand_& o0, const Operand_& o1, const Operand_& o2, uint32_t instFlags) noexcept {
+ return matchSignature(o0, o1, instFlags) && o1.signature() == o2.signature();
+}
+
+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();;
+}
+
+// Memory must be either:
+// 1. Absolute address, which will be converted to relative.
+// 2. Relative displacement (Label).
+// 3. Base register + either offset or index.
+static inline bool armCheckMemBaseIndexRel(const Mem& mem) noexcept {
+ // Allowed base types (Nothing, Label, and GpX).
+ constexpr uint32_t kBaseMask = B(0) |
+ B(RegType::kLabelTag) |
+ B(RegType::kARM_GpX);
+
+ // Allowed index types (Nothing, GpW, and GpX).
+ constexpr uint32_t kIndexMask = B(0) |
+ B(RegType::kARM_GpW) |
+ B(RegType::kARM_GpX) ;
+
+ RegType baseType = mem.baseType();
+ RegType indexType = mem.indexType();
+
+ if (!Support::bitTest(kBaseMask, baseType))
+ return false;
+
+ if (baseType > RegType::kLabelTag) {
+ // Index allows either GpW or GpX.
+ if (!Support::bitTest(kIndexMask, indexType))
+ return false;
+
+ if (indexType == RegType::kNone)
+ return true;
+ else
+ return !mem.hasOffset();
+ }
+ else {
+ // No index register allowed if this is a PC relative address (literal).
+ return indexType == RegType::kNone;
+ }
+}
+
+struct EncodeFpOpcodeBits {
+ uint32_t sizeMask;
+ uint32_t mask[3];
+};
+
+static inline bool pickFpOpcode(const Vec& reg, uint32_t sOp, uint32_t sHf, uint32_t vOp, uint32_t vHf, Opcode* opcode, uint32_t* szOut) noexcept {
+ static constexpr uint32_t kQBitIndex = 30;
+
+ static const EncodeFpOpcodeBits szBits[InstDB::kHF_Count] = {
+ { B(2) | B(1) , { 0u , 0u, B(22) } },
+ { B(2) | B(1) | B(0), { 0u , 0u, 0u } },
+ { B(2) | B(1) | B(0), { B(23) | B(22) , 0u, B(22) } },
+ { B(2) | B(1) | B(0), { B(22) | B(20) | B(19) , 0u, B(22) } },
+ { B(2) | B(1) | B(0), { B(22) | B(21) | B(15) | B(14), 0u, B(22) } },
+ { B(2) | B(1) | B(0), { B(23) , 0u, B(22) } }
+ };
+
+ if (!reg.hasElementType()) {
+ // Scalar operation [HSD].
+ uint32_t sz = diff(reg.type(), RegType::kARM_VecH);
+ if (sz > 2u || !Support::bitTest(szBits[sHf].sizeMask, sz))
+ return false;
+
+ opcode->reset(szBits[sHf].mask[sz] ^ sOp);
+ *szOut = sz;
+ return sOp != 0;
+ }
+ else {
+ // Vector operation [HSD].
+ uint32_t q = diff(reg.type(), RegType::kARM_VecD);
+ uint32_t sz = reg.elementType() - Vec::kElementTypeH;
+
+ if (q > 1u || sz > 2u || !Support::bitTest(szBits[vHf].sizeMask, sz))
+ return false;
+
+ opcode->reset(szBits[vHf].mask[sz] ^ (vOp | (q << kQBitIndex)));
+ *szOut = sz;
+ return vOp != 0;
+ }
+}
+
+static inline bool pickFpOpcode(const Vec& reg, uint32_t sOp, uint32_t sHf, uint32_t vOp, uint32_t vHf, Opcode* opcode) noexcept {
+ uint32_t sz;
+ return pickFpOpcode(reg, sOp, sHf, vOp, vHf, opcode, &sz);
+}
+
+// a64::Assembler - Operand Checks
+// ===============================
+
+// Checks whether all operands have the same signature.
+static inline bool checkSignature(const Operand_& o0, const Operand_& o1) noexcept {
+ return o0.signature() == o1.signature();
+}
+
+static inline bool checkSignature(const Operand_& o0, const Operand_& o1, const Operand_& o2) noexcept {
+ return o0.signature() == o1.signature() &&
+ o1.signature() == o2.signature();
+}
+
+static inline bool checkSignature(const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) noexcept {
+ return o0.signature() == o1.signature() &&
+ o1.signature() == o2.signature() &&
+ o2.signature() == o3.signature();
+}
+
+// Checks whether the register is GP register of the allowed types.
+//
+// Allowed is a 2-bit mask, where the first bits allows GpW and the second bit
+// allows GpX. These bits are usually stored within the instruction, but could
+// be also hardcoded in the assembler for instructions where GP types are not
+// selectable.
+static inline bool checkGpType(const Operand_& op, uint32_t allowed) noexcept {
+ RegType type = op.as<Reg>().type();
+ return Support::bitTest(allowed << uint32_t(RegType::kARM_GpW), type);
+}
+
+static inline bool checkGpType(const Operand_& op, uint32_t allowed, uint32_t* x) noexcept {
+ // NOTE: We set 'x' to one only when GpW is allowed, otherwise the X is part
+ // of the opcode and we cannot set it. This is why this works without requiring
+ // additional logic.
+ RegType type = op.as<Reg>().type();
+ *x = diff(type, RegType::kARM_GpW) & allowed;
+ return Support::bitTest(allowed << uint32_t(RegType::kARM_GpW), type);
+}
+
+static inline bool checkGpType(const Operand_& o0, const Operand_& o1, uint32_t allowed, uint32_t* x) noexcept {
+ return checkGpType(o0, allowed, x) && checkSignature(o0, o1);
+}
+
+static inline bool checkGpType(const Operand_& o0, const Operand_& o1, const Operand_& o2, uint32_t allowed, uint32_t* x) noexcept {
+ return checkGpType(o0, allowed, x) && checkSignature(o0, o1, o2);
+}
+
+static inline bool checkGpId(const Operand_& op, uint32_t hiId = kZR) noexcept {
+ uint32_t id = op.as<Reg>().id();
+ return id < 31u || id == hiId;
+}
+
+static inline bool checkGpId(const Operand_& o0, const Operand_& o1, uint32_t hiId = kZR) noexcept {
+ uint32_t id0 = o0.as<Reg>().id();
+ uint32_t id1 = o1.as<Reg>().id();
+
+ return (id0 < 31u || id0 == hiId) && (id1 < 31u || id1 == hiId);
+}
+
+static inline bool checkGpId(const Operand_& o0, const Operand_& o1, const Operand_& o2, uint32_t hiId = kZR) noexcept {
+ uint32_t id0 = o0.as<Reg>().id();
+ uint32_t id1 = o1.as<Reg>().id();
+ uint32_t id2 = o2.as<Reg>().id();
+
+ return (id0 < 31u || id0 == hiId) && (id1 < 31u || id1 == hiId) && (id2 < 31u || id2 == hiId);
+}
+
+static inline bool checkVecId(const Operand_& op) noexcept {
+ uint32_t id = op.as<Reg>().id();
+ return id <= 31u;
+}
+
+static inline bool checkVecId(const Operand_& o0, const Operand_& o1) noexcept {
+ uint32_t id0 = o0.as<Reg>().id();
+ uint32_t id1 = o1.as<Reg>().id();
+
+ return (id0 | id1) <= 31u;
+}
+
+/* Unused at the moment.
+static inline bool checkVecId(const Operand_& o0, const Operand_& o1, const Operand_& o2) noexcept {
+ uint32_t id0 = o0.as<Reg>().id();
+ uint32_t id1 = o1.as<Reg>().id();
+ uint32_t id2 = o2.as<Reg>().id();
+
+ return (id0 | id1 | id2) <= 31u;
+}
+
+static inline bool checkVecId(const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) noexcept {
+ uint32_t id0 = o0.as<Reg>().id();
+ uint32_t id1 = o1.as<Reg>().id();
+ uint32_t id2 = o2.as<Reg>().id();
+ uint32_t id3 = o3.as<Reg>().id();
+
+ return (id0 | id1 | id2 | id3) <= 31u;
+}
+*/
+
+static inline bool checkMemBase(const Mem& mem) noexcept {
+ return mem.baseType() == RegType::kARM_GpX && mem.baseId() <= 31;
+}
+
+static inline bool checkEven(const Operand_& o0, const Operand_& o1) noexcept {
+ return ((o0.id() | o1.id()) & 1) == 0;
+}
+
+static inline bool checkConsecutive(const Operand_& o0, const Operand_& o1) noexcept {
+ return ((o0.id() + 1u) & 0x1Fu) == o1.id();
+}
+
+static inline bool checkConsecutive(const Operand_& o0, const Operand_& o1, const Operand_& o2) noexcept {
+ return ((o0.id() + 1u) & 0x1Fu) == o1.id() &&
+ ((o0.id() + 2u) & 0x1Fu) == o2.id();
+}
+
+static inline bool checkConsecutive(const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) noexcept {
+ return ((o0.id() + 1u) & 0x1Fu) == o1.id() &&
+ ((o0.id() + 2u) & 0x1Fu) == o2.id() &&
+ ((o0.id() + 3u) & 0x1Fu) == o3.id();
+}
+
+// a64::Assembler - CheckReg
+// =========================
+
+#define V(index) (index == uint32_t(RegType::kARM_GpW) ? Gp::kIdZr : \
+ index == uint32_t(RegType::kARM_GpX) ? Gp::kIdZr : \
+ index == uint32_t(RegType::kARM_VecB) ? 31u : \
+ index == uint32_t(RegType::kARM_VecH) ? 31u : \
+ index == uint32_t(RegType::kARM_VecS) ? 31u : \
+ index == uint32_t(RegType::kARM_VecD) ? 31u : \
+ index == uint32_t(RegType::kARM_VecV) ? 31u : 0)
+static const Support::Array<uint8_t, 32> commonHiRegIdOfType = {{
+ ASMJIT_LOOKUP_TABLE_32(V, 0)
+}};
+#undef V
+
+static inline bool checkValidRegs(const Operand_& o0) noexcept {
+ return ((o0.id() < 31) | (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()])) ;
+}
+
+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()])) ;
+}
+
+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()])) ;
+}
+
+// a64::Assembler - Construction & Destruction
+// ===========================================
+
+Assembler::Assembler(CodeHolder* code) noexcept : BaseAssembler() {
+ _archMask = uint64_t(1) << uint32_t(Arch::kAArch64);
+ assignEmitterFuncs(this);
+
+ if (code)
+ code->attach(this);
+}
+
+Assembler::~Assembler() noexcept {}
+
+// a64::Assembler - Emit
+// =====================
+
+#define ENC_OPS1(OP0) \
+ (uint32_t(OperandType::k##OP0))
+
+#define ENC_OPS2(OP0, OP1) \
+ (uint32_t(OperandType::k##OP0) + \
+ (uint32_t(OperandType::k##OP1) << 3))
+
+#define ENC_OPS3(OP0, OP1, OP2) \
+ (uint32_t(OperandType::k##OP0) + \
+ (uint32_t(OperandType::k##OP1) << 3) + \
+ (uint32_t(OperandType::k##OP2) << 6))
+
+#define ENC_OPS4(OP0, OP1, OP2, OP3) \
+ (uint32_t(OperandType::k##OP0) + \
+ (uint32_t(OperandType::k##OP1) << 3) + \
+ (uint32_t(OperandType::k##OP2) << 6) + \
+ (uint32_t(OperandType::k##OP3) << 9))
+
+Error Assembler::_emit(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) {
+ // Logging/Validation/Error.
+ constexpr InstOptions kRequiresSpecialHandling = InstOptions::kReserved;
+
+ Error err;
+ CodeWriter writer(this);
+
+ // Combine all instruction options and also check whether the instruction
+ // is valid. All options that require special handling (including invalid
+ // instruction) are handled by the next branch.
+ InstOptions options = InstOptions(instId - 1 >= Inst::_kIdCount - 1) | InstOptions((size_t)(_bufferEnd - writer.cursor()) < 4) | instOptions() | forcedInstOptions();
+
+ CondCode instCC = BaseInst::extractARMCondCode(instId);
+ instId = instId & uint32_t(InstIdParts::kRealId);
+
+ if (instId >= Inst::_kIdCount)
+ instId = 0;
+
+ const InstDB::InstInfo* instInfo = &InstDB::_instInfoTable[instId];
+ uint32_t encodingIndex = instInfo->_encodingDataIndex;
+
+ Opcode opcode;
+ uint32_t isign4;
+ uint32_t instFlags;
+
+ const Operand_& o3 = opExt[EmitterUtils::kOp3];
+ const Operand_* rmRel = nullptr;
+
+ uint32_t multipleOpData[4];
+ uint32_t multipleOpCount;
+
+ // These are only used when instruction uses a relative displacement.
+ OffsetFormat offsetFormat; // Offset format.
+ uint64_t offsetValue; // Offset value (if known).
+
+ if (ASMJIT_UNLIKELY(Support::test(options, kRequiresSpecialHandling))) {
+ if (ASMJIT_UNLIKELY(!_code))
+ return reportError(DebugUtils::errored(kErrorNotInitialized));
+
+ // Unknown instruction.
+ if (ASMJIT_UNLIKELY(instId == 0))
+ goto InvalidInstruction;
+
+ // Condition code can only be used with 'B' instruction.
+ if (ASMJIT_UNLIKELY(instCC != CondCode::kAL && instId != Inst::kIdB))
+ goto InvalidInstruction;
+
+ // Grow request, happens rarely.
+ err = writer.ensureSpace(this, 4);
+ if (ASMJIT_UNLIKELY(err))
+ goto Failed;
+
+#ifndef ASMJIT_NO_VALIDATION
+ // Strict validation.
+ if (hasDiagnosticOption(DiagnosticOptions::kValidateAssembler)) {
+ Operand_ opArray[Globals::kMaxOpCount];
+ EmitterUtils::opArrayFromEmitArgs(opArray, o0, o1, o2, opExt);
+
+ err = _funcs.validate(arch(), BaseInst(instId, options, _extraReg), opArray, Globals::kMaxOpCount, ValidationFlags::kNone);
+ if (ASMJIT_UNLIKELY(err))
+ goto Failed;
+ }
+#endif
+ }
+
+ // Signature of the first 4 operands.
+ isign4 = (uint32_t(o0.opType()) ) +
+ (uint32_t(o1.opType()) << 3) +
+ (uint32_t(o2.opType()) << 6) +
+ (uint32_t(o3.opType()) << 9);
+ instFlags = instInfo->flags();
+
+ switch (instInfo->_encoding) {
+ // ------------------------------------------------------------------------
+ // [Base - Universal]
+ // ------------------------------------------------------------------------
+
+ case InstDB::kEncodingBaseOp: {
+ const InstDB::EncodingData::BaseOp& opData = InstDB::EncodingData::baseOp[encodingIndex];
+
+ if (isign4 == 0) {
+ opcode.reset(opData.opcode);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseOpImm: {
+ const InstDB::EncodingData::BaseOpImm& opData = InstDB::EncodingData::baseOpImm[encodingIndex];
+
+ if (isign4 == ENC_OPS1(Imm)) {
+ uint64_t imm = o0.as<Imm>().valueAs<uint64_t>();
+ uint32_t immMax = 1u << opData.immBits;
+
+ if (imm >= immMax)
+ goto InvalidImmediate;
+
+ opcode.reset(opData.opcode);
+ opcode.addImm(imm, opData.immOffset);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseR: {
+ const InstDB::EncodingData::BaseR& opData = InstDB::EncodingData::baseR[encodingIndex];
+
+ if (isign4 == ENC_OPS1(Reg)) {
+ if (!checkGpType(o0, opData.rType))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, opData.rHiId))
+ goto InvalidPhysId;
+
+ opcode.reset(opData.opcode);
+ opcode.addReg(o0, opData.rShift);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseRR: {
+ const InstDB::EncodingData::BaseRR& opData = InstDB::EncodingData::baseRR[encodingIndex];
+
+ if (isign4 == ENC_OPS2(Reg, Reg)) {
+ uint32_t x;
+ if (!checkGpType(o0, opData.aType, &x))
+ goto InvalidInstruction;
+
+ if (!checkGpType(o1, opData.bType))
+ goto InvalidInstruction;
+
+ if (opData.uniform && !checkSignature(o0, o1))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, opData.aHiId))
+ goto InvalidPhysId;
+
+ if (!checkGpId(o1, opData.bHiId))
+ goto InvalidPhysId;
+
+ opcode.reset(opData.opcode);
+ opcode.addImm(x, 31);
+ opcode.addReg(o1, opData.bShift);
+ opcode.addReg(o0, opData.aShift);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseRRR: {
+ const InstDB::EncodingData::BaseRRR& opData = InstDB::EncodingData::baseRRR[encodingIndex];
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Reg)) {
+ uint32_t x;
+ if (!checkGpType(o0, opData.aType, &x))
+ goto InvalidInstruction;
+
+ if (!checkGpType(o1, opData.bType))
+ goto InvalidInstruction;
+
+ if (!checkGpType(o2, opData.cType))
+ goto InvalidInstruction;
+
+ if (opData.uniform && !checkSignature(o0, o1, o2))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, opData.aHiId))
+ goto InvalidPhysId;
+
+ if (!checkGpId(o1, opData.bHiId))
+ goto InvalidPhysId;
+
+ if (!checkGpId(o2, opData.cHiId))
+ goto InvalidPhysId;
+
+ opcode.reset(opData.opcode());
+ opcode.addImm(x, 31);
+ opcode.addReg(o2, 16);
+ opcode.addReg(o1, 5);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseRRRR: {
+ const InstDB::EncodingData::BaseRRRR& opData = InstDB::EncodingData::baseRRRR[encodingIndex];
+
+ if (isign4 == ENC_OPS4(Reg, Reg, Reg, Reg)) {
+ uint32_t x;
+ if (!checkGpType(o0, opData.aType, &x))
+ goto InvalidInstruction;
+
+ if (!checkGpType(o1, opData.bType))
+ goto InvalidInstruction;
+
+ if (!checkGpType(o2, opData.cType))
+ goto InvalidInstruction;
+
+ if (!checkGpType(o3, opData.dType))
+ goto InvalidInstruction;
+
+ if (opData.uniform && !checkSignature(o0, o1, o2, o3))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, opData.aHiId))
+ goto InvalidPhysId;
+
+ if (!checkGpId(o1, opData.bHiId))
+ goto InvalidPhysId;
+
+ if (!checkGpId(o2, opData.cHiId))
+ goto InvalidPhysId;
+
+ if (!checkGpId(o3, opData.dHiId))
+ goto InvalidPhysId;
+
+ opcode.reset(opData.opcode());
+ opcode.addImm(x, 31);
+ opcode.addReg(o2, 16);
+ opcode.addReg(o3, 10);
+ opcode.addReg(o1, 5);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseRRII: {
+ const InstDB::EncodingData::BaseRRII& opData = InstDB::EncodingData::baseRRII[encodingIndex];
+
+ if (isign4 == ENC_OPS4(Reg, Reg, Imm, Imm)) {
+ if (!checkGpType(o0, opData.aType))
+ goto InvalidInstruction;
+
+ if (!checkGpType(o1, opData.bType))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, opData.aHiId))
+ goto InvalidPhysId;
+
+ if (!checkGpId(o1, opData.bHiId))
+ goto InvalidPhysId;
+
+ if (o2.as<Imm>().valueAs<uint64_t>() >= Support::bitMask(opData.aImmSize + opData.aImmDiscardLsb) ||
+ o3.as<Imm>().valueAs<uint64_t>() >= Support::bitMask(opData.bImmSize + opData.bImmDiscardLsb))
+ goto InvalidImmediate;
+
+ uint32_t aImm = o2.as<Imm>().valueAs<uint32_t>() >> opData.aImmDiscardLsb;
+ uint32_t bImm = o3.as<Imm>().valueAs<uint32_t>() >> opData.bImmDiscardLsb;
+
+ if ((aImm << opData.aImmDiscardLsb) != o2.as<Imm>().valueAs<uint32_t>() ||
+ (bImm << opData.bImmDiscardLsb) != o3.as<Imm>().valueAs<uint32_t>())
+ goto InvalidImmediate;
+
+ opcode.reset(opData.opcode());
+ opcode.addImm(aImm, opData.aImmOffset);
+ opcode.addImm(bImm, opData.bImmOffset);
+ opcode.addReg(o1, 5);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ // ------------------------------------------------------------------------
+ // [Base - Mov]
+ // ------------------------------------------------------------------------
+
+ case InstDB::kEncodingBaseMov: {
+ // MOV is a pseudo instruction that uses various instructions depending on its signature.
+ uint32_t x = diff(o0.as<Reg>().type(), RegType::kARM_GpW);
+ if (x > 1)
+ goto InvalidInstruction;
+
+ if (isign4 == ENC_OPS2(Reg, Reg)) {
+ if (!o0.as<Reg>().isGp())
+ goto InvalidInstruction;
+
+ if (!checkSignature(o0, o1))
+ goto InvalidInstruction;
+
+ bool hasSP = o0.as<Gp>().isSP() || o1.as<Gp>().isSP();
+ if (hasSP) {
+ // Cannot be combined with ZR.
+ if (!checkGpId(o0, o1, kSP))
+ goto InvalidPhysId;
+
+ // MOV Rd, Rm -> ADD Rd, Rn, #0.
+ opcode.reset(0b00010001000000000000000000000000);
+ opcode.addImm(x, 31);
+ opcode.addReg(o1, 5);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+ else {
+ if (!checkGpId(o0, o1, kZR))
+ goto InvalidPhysId;
+
+ // MOV Rd, Rm -> ORR Rd, <ZR>, Rm.
+ opcode.reset(0b00101010000000000000001111100000);
+ opcode.addImm(x, 31);
+ opcode.addReg(o1, 16);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+ }
+
+ if (isign4 == ENC_OPS2(Reg, Imm)) {
+ if (!o0.as<Reg>().isGp())
+ goto InvalidInstruction;
+
+ uint64_t immValue = o1.as<Imm>().valueAs<uint64_t>();
+ if (!x)
+ immValue &= 0xFFFFFFFFu;
+
+ // Prefer a single MOVN/MOVZ instruction over a logical instruction.
+ multipleOpCount = encodeMovSequence64(multipleOpData, immValue, o0.id() & 31, x);
+ if (multipleOpCount == 1 && !o0.as<Gp>().isSP()) {
+ opcode.reset(multipleOpData[0]);
+ goto EmitOp;
+ }
+
+ // Logical instructions use 13-bit immediate pattern encoded as N:ImmR:ImmS.
+ LogicalImm logicalImm;
+ if (!o0.as<Gp>().isZR()) {
+ if (Utils::encodeLogicalImm(immValue, x ? 64 : 32, &logicalImm)) {
+ if (!checkGpId(o0, kSP))
+ goto InvalidPhysId;
+
+ opcode.reset(0b00110010000000000000001111100000);
+ opcode.addImm(x, 31);
+ opcode.addLogicalImm(logicalImm);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+ }
+
+ if (!checkGpId(o0, kZR))
+ goto InvalidPhysId;
+
+ goto EmitOp_Multiple;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseMovKNZ: {
+ const InstDB::EncodingData::BaseMovKNZ& opData = InstDB::EncodingData::baseMovKNZ[encodingIndex];
+
+ uint32_t x = diff(o0.as<Reg>().type(), RegType::kARM_GpW);
+ if (x > 1)
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, kZR))
+ goto InvalidPhysId;
+
+ opcode.reset(opData.opcode);
+ opcode.addImm(x, 31);
+
+ if (isign4 == ENC_OPS2(Reg, Imm)) {
+ uint64_t imm16 = o1.as<Imm>().valueAs<uint64_t>();
+ if (imm16 > 0xFFFFu)
+ goto InvalidImmediate;
+
+ opcode.addImm(imm16, 5);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+
+ if (isign4 == ENC_OPS3(Reg, Imm, Imm)) {
+ uint64_t imm16 = o1.as<Imm>().valueAs<uint64_t>();
+ uint32_t shiftType = o2.as<Imm>().predicate();
+ uint64_t shiftValue = o2.as<Imm>().valueAs<uint64_t>();
+
+ if (imm16 > 0xFFFFu || shiftValue > 48 || shiftType != uint32_t(ShiftOp::kLSL))
+ goto InvalidImmediate;
+
+ // Convert shift value to 'hw' field.
+ uint32_t hw = uint32_t(shiftValue) >> 4;
+ if ((hw << 4) != uint32_t(shiftValue))
+ goto InvalidImmediate;
+
+ opcode.addImm(hw, 21);
+ opcode.addImm(imm16, 5);
+ opcode.addReg(o0, 0);
+
+ if (!x && hw > 1u)
+ goto InvalidImmediate;
+
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ // ------------------------------------------------------------------------
+ // [Base - Adr]
+ // ------------------------------------------------------------------------
+
+ case InstDB::kEncodingBaseAdr: {
+ const InstDB::EncodingData::BaseAdr& opData = InstDB::EncodingData::baseAdr[encodingIndex];
+
+ if (isign4 == ENC_OPS2(Reg, Label) || isign4 == ENC_OPS2(Reg, Imm)) {
+ if (!o0.as<Reg>().isGpX())
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, kZR))
+ goto InvalidPhysId;
+
+ opcode.reset(opData.opcode());
+ opcode.addReg(o0, 0);
+ offsetFormat.resetToImmValue(opData.offsetType, 4, 5, 21, 0);
+
+ if (instId == Inst::kIdAdrp)
+ offsetFormat._immDiscardLsb = 12;
+
+ rmRel = &o1;
+ goto EmitOp_Rel;
+ }
+
+ break;
+ }
+
+ // ------------------------------------------------------------------------
+ // [Base - Arithmetic and Logical]
+ // ------------------------------------------------------------------------
+
+ case InstDB::kEncodingBaseAddSub: {
+ const InstDB::EncodingData::BaseAddSub& opData = InstDB::EncodingData::baseAddSub[encodingIndex];
+
+ uint32_t x;
+ if (!checkGpType(o0, o1, kWX, &x))
+ goto InvalidInstruction;
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Imm) || isign4 == ENC_OPS4(Reg, Reg, Imm, Imm)) {
+ opcode.reset(uint32_t(opData.immediateOp) << 24);
+
+ // ADD | SUB (immediate) - ZR is not allowed.
+ // ADDS|SUBS (immediate) - ZR allowed in Rd, SP allowed in Rn.
+ uint32_t aHiId = opcode.get() & B(29) ? kZR : kSP;
+ uint32_t bHiId = kSP;
+
+ if (!checkGpId(o0, aHiId) || !checkGpId(o1, bHiId))
+ goto InvalidPhysId;
+
+ // ADD|SUB (immediate) use 12-bit immediate optionally shifted by 'LSL #12'.
+ uint64_t imm = o2.as<Imm>().valueAs<uint64_t>();
+ uint32_t shift = 0;
+
+ if (isign4 == ENC_OPS4(Reg, Reg, Imm, Imm)) {
+ if (o3.as<Imm>().predicate() != uint32_t(ShiftOp::kLSL))
+ goto InvalidImmediate;
+
+ if (o3.as<Imm>().value() != 0 && o3.as<Imm>().value() != 12)
+ goto InvalidImmediate;
+
+ shift = uint32_t(o3.as<Imm>().value() != 0);
+ }
+
+ // Accept immediate value of '0x00XXX000' by setting 'shift' to 12.
+ if (imm > 0xFFFu) {
+ if (shift || (imm & ~uint64_t(0xFFFu << 12)) != 0)
+ goto InvalidImmediate;
+ shift = 1;
+ imm >>= 12;
+ }
+
+ opcode.addImm(x, 31);
+ opcode.addImm(shift, 22);
+ opcode.addImm(imm, 10);
+ opcode.addReg(o1, 5);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+
+ 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);
+
+ if (isign4 == ENC_OPS4(Reg, Reg, Reg, Imm)) {
+ sType = o3.as<Imm>().predicate();
+ shift = o3.as<Imm>().valueAs<uint64_t>();
+ }
+
+ if (!checkGpId(o2, kZR))
+ goto InvalidPhysId;
+
+ // Shift operation - LSL, LSR, ASR.
+ if (sType <= uint32_t(ShiftOp::kASR)) {
+ bool hasSP = o0.as<Gp>().isSP() || o1.as<Gp>().isSP();
+ if (!hasSP) {
+ if (!checkGpId(o0, o1, kZR))
+ goto InvalidPhysId;
+
+ if (shift >= opSize)
+ goto InvalidImmediate;
+
+ opcode.reset(uint32_t(opData.shiftedOp) << 21);
+ opcode.addImm(x, 31);
+ opcode.addImm(sType, 22);
+ opcode.addReg(o2, 16);
+ opcode.addImm(shift, 10);
+ opcode.addReg(o1, 5);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+
+ // SP register can only be used with LSL or Extend.
+ if (sType != uint32_t(ShiftOp::kLSL))
+ goto InvalidImmediate;
+ sType = x ? uint32_t(ShiftOp::kUXTX) : uint32_t(ShiftOp::kUXTW);
+ }
+
+ // Extend operation - UXTB, UXTH, UXTW, UXTX, SXTB, SXTH, SXTW, SXTX.
+ opcode.reset(uint32_t(opData.extendedOp) << 21);
+ sType -= uint32_t(ShiftOp::kUXTB);
+
+ if (sType > 7 || shift > 4)
+ goto InvalidImmediate;
+
+ if (!(opcode.get() & B(29))) {
+ // ADD|SUB (extend) - ZR is not allowed.
+ if (!checkGpId(o0, o1, kSP))
+ goto InvalidPhysId;
+ }
+ else {
+ // ADDS|SUBS (extend) - ZR allowed in Rd, SP allowed in Rn.
+ if (!checkGpId(o0, kZR) || !checkGpId(o1, kSP))
+ goto InvalidPhysId;
+ }
+
+ opcode.addImm(x, 31);
+ opcode.addReg(o2, 16);
+ opcode.addImm(sType, 13);
+ opcode.addImm(shift, 10);
+ opcode.addReg(o1, 5);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseLogical: {
+ const InstDB::EncodingData::BaseLogical& opData = InstDB::EncodingData::baseLogical[encodingIndex];
+
+ uint32_t x;
+ if (!checkGpType(o0, o1, kWX, &x))
+ goto InvalidInstruction;
+
+ if (!checkSignature(o0, o1))
+ goto InvalidInstruction;
+
+ uint32_t opSize = x ? 64 : 32;
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Imm) && opData.immediateOp != 0) {
+ opcode.reset(uint32_t(opData.immediateOp) << 23);
+
+ // AND|ANDS|BIC|BICS|ORR|EOR (immediate) uses a LogicalImm format described by N:R:S values.
+ uint64_t immMask = Support::lsbMask<uint64_t>(opSize);
+ uint64_t immValue = o2.as<Imm>().valueAs<uint64_t>();
+
+ if (opData.negateImm)
+ immValue ^= immMask;
+
+ // Logical instructions use 13-bit immediate pattern encoded as N:ImmS:ImmR.
+ LogicalImm logicalImm;
+ if (!Utils::encodeLogicalImm(immValue & immMask, opSize, &logicalImm))
+ goto InvalidImmediate;
+
+ // AND|BIC|ORR|EOR (immediate) can have SP on destination, but ANDS|BICS (immediate) cannot.
+ uint32_t kOpANDS = 0x3 << 29;
+ bool isANDS = (opcode.get() & kOpANDS) == kOpANDS;
+
+ if (!checkGpId(o0, isANDS ? kZR : kSP) || !checkGpId(o1, kZR))
+ goto InvalidPhysId;
+
+ opcode.addImm(x, 31);
+ opcode.addLogicalImm(logicalImm);
+ opcode.addReg(o1, 5);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+
+ if (!checkSignature(o1, o2))
+ goto InvalidInstruction;
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Reg)) {
+ if (!checkGpId(o0, o1, o2, kZR))
+ goto InvalidPhysId;
+
+ opcode.reset(uint32_t(opData.shiftedOp) << 21);
+ opcode.addImm(x, 31);
+ opcode.addReg(o2, 16);
+ opcode.addReg(o1, 5);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+
+ if (isign4 == ENC_OPS4(Reg, Reg, Reg, Imm)) {
+ if (!checkGpId(o0, o1, o2, kZR))
+ goto InvalidPhysId;
+
+ uint32_t shiftType = o3.as<Imm>().predicate();
+ uint64_t opShift = o3.as<Imm>().valueAs<uint64_t>();
+
+ if (shiftType > 0x3 || opShift >= opSize)
+ goto InvalidImmediate;
+
+ opcode.reset(uint32_t(opData.shiftedOp) << 21);
+ opcode.addImm(x, 31);
+ opcode.addImm(shiftType, 22);
+ opcode.addReg(o2, 16);
+ opcode.addImm(opShift, 10);
+ opcode.addReg(o1, 5);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseCmpCmn: {
+ const InstDB::EncodingData::BaseCmpCmn& opData = InstDB::EncodingData::baseCmpCmn[encodingIndex];
+
+ uint32_t x;
+ if (!checkGpType(o0, kWX, &x))
+ goto InvalidInstruction;
+
+ if (isign4 == ENC_OPS2(Reg, Imm)) {
+ // CMN|CMP (immediate) - ZR is not allowed.
+ if (!checkGpId(o0, kSP))
+ goto InvalidPhysId;
+
+ // CMN|CMP (immediate) use 12-bit immediate optionally shifted by 'LSL #12'.
+ const Imm& imm12 = o1.as<Imm>();
+ uint32_t immShift = 0;
+ uint64_t immValue = imm12.valueAs<uint64_t>();
+
+ if (immValue > 0xFFFu) {
+ if ((immValue & ~uint64_t(0xFFFu << 12)) != 0)
+ goto InvalidImmediate;
+ immShift = 1;
+ immValue >>= 12;
+ }
+
+ opcode.reset(uint32_t(opData.immediateOp) << 24);
+ opcode.addImm(x, 31);
+ opcode.addImm(immShift, 22);
+ opcode.addImm(immValue, 10);
+ opcode.addReg(o0, 5);
+ opcode.addReg(Gp::kIdZr, 0);
+ goto EmitOp;
+ }
+
+ 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;
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Imm)) {
+ sType = o2.as<Imm>().predicate();
+ shift = o2.as<Imm>().valueAs<uint64_t>();
+ }
+
+ bool hasSP = o0.as<Gp>().isSP() || o1.as<Gp>().isSP();
+
+ // Shift operation - LSL, LSR, ASR.
+ if (sType <= uint32_t(ShiftOp::kASR)) {
+ if (!hasSP) {
+ if (shift >= opSize)
+ goto InvalidImmediate;
+
+ opcode.reset(uint32_t(opData.shiftedOp) << 21);
+ opcode.addImm(x, 31);
+ opcode.addImm(sType, 22);
+ opcode.addReg(o1, 16);
+ opcode.addImm(shift, 10);
+ opcode.addReg(o0, 5);
+ opcode.addReg(Gp::kIdZr, 0);
+ goto EmitOp;
+ }
+
+ // SP register can only be used with LSL or Extend.
+ if (sType != uint32_t(ShiftOp::kLSL))
+ goto InvalidImmediate;
+
+ sType = x ? uint32_t(ShiftOp::kUXTX) : uint32_t(ShiftOp::kUXTW);
+ }
+
+ // Extend operation - UXTB, UXTH, UXTW, UXTX, SXTB, SXTH, SXTW, SXTX.
+ sType -= uint32_t(ShiftOp::kUXTB);
+ if (sType > 7 || shift > 4)
+ goto InvalidImmediate;
+
+ opcode.reset(uint32_t(opData.extendedOp) << 21);
+ opcode.addImm(x, 31);
+ opcode.addReg(o1, 16);
+ opcode.addImm(sType, 13);
+ opcode.addImm(shift, 10);
+ opcode.addReg(o0, 5);
+ opcode.addReg(Gp::kIdZr, 0);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseMvnNeg: {
+ const InstDB::EncodingData::BaseMvnNeg& opData = InstDB::EncodingData::baseMvnNeg[encodingIndex];
+
+ uint32_t x;
+ if (!checkGpType(o0, o1, kWX, &x))
+ goto InvalidInstruction;
+
+ opcode.reset(opData.opcode);
+ opcode.addImm(x, 31);
+ opcode.addReg(o1, 16);
+ opcode.addReg(o0, 0);
+
+ if (isign4 == ENC_OPS2(Reg, Reg)) {
+ if (!checkGpId(o0, o1, kZR))
+ goto InvalidPhysId;
+
+ goto EmitOp;
+ }
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Imm)) {
+ if (!checkGpId(o0, o1, kZR))
+ goto InvalidPhysId;
+
+ uint32_t opSize = x ? 64 : 32;
+ uint32_t shiftType = o2.as<Imm>().predicate();
+ uint64_t opShift = o2.as<Imm>().valueAs<uint64_t>();
+
+ if (shiftType > uint32_t(ShiftOp::kROR) || opShift >= opSize)
+ goto InvalidImmediate;
+
+ opcode.addImm(shiftType, 22);
+ opcode.addImm(opShift, 10);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseTst: {
+ const InstDB::EncodingData::BaseTst& opData = InstDB::EncodingData::baseTst[encodingIndex];
+
+ uint32_t x;
+ if (!checkGpType(o0, kWX, &x))
+ goto InvalidInstruction;
+
+ uint32_t opSize = x ? 64 : 32;
+
+ if (isign4 == ENC_OPS2(Reg, Imm) && opData.immediateOp != 0) {
+ if (!checkGpId(o0, kZR))
+ goto InvalidPhysId;
+
+ // TST (immediate) uses a LogicalImm format described by N:R:S values.
+ uint64_t immMask = Support::lsbMask<uint64_t>(opSize);
+ uint64_t immValue = o1.as<Imm>().valueAs<uint64_t>();
+
+ // Logical instructions use 13-bit immediate pattern encoded as N:ImmS:ImmR.
+ LogicalImm logicalImm;
+ if (!Utils::encodeLogicalImm(immValue & immMask, opSize, &logicalImm))
+ goto InvalidImmediate;
+
+ opcode.reset(uint32_t(opData.immediateOp) << 22);
+ opcode.addLogicalImm(logicalImm);
+ opcode.addImm(x, 31);
+ opcode.addReg(o0, 5);
+ opcode.addReg(Gp::kIdZr, 0);
+ goto EmitOp;
+ }
+
+ opcode.reset(uint32_t(opData.shiftedOp) << 21);
+ opcode.addImm(x, 31);
+ opcode.addReg(o1, 16);
+ opcode.addReg(o0, 5);
+ opcode.addReg(Gp::kIdZr, 0);
+
+ if (isign4 == ENC_OPS2(Reg, Reg)) {
+ if (!checkGpId(o0, o1, kZR))
+ goto InvalidPhysId;
+
+ goto EmitOp;
+ }
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Imm)) {
+ if (!checkGpId(o0, o1, kZR))
+ goto InvalidPhysId;
+
+ uint32_t shiftType = o2.as<Imm>().predicate();
+ uint64_t opShift = o2.as<Imm>().valueAs<uint64_t>();
+
+ if (shiftType > 0x3 || opShift >= opSize)
+ goto InvalidImmediate;
+
+ opcode.addImm(shiftType, 22);
+ opcode.addImm(opShift, 10);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ // ------------------------------------------------------------------------
+ // [Base - Bit Manipulation]
+ // ------------------------------------------------------------------------
+
+ case InstDB::kEncodingBaseBfc: {
+ const InstDB::EncodingData::BaseBfc& opData = InstDB::EncodingData::baseBfc[encodingIndex];
+
+ if (isign4 == ENC_OPS3(Reg, Imm, Imm)) {
+ uint32_t x;
+ if (!checkGpType(o0, InstDB::kWX, &x))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0))
+ goto InvalidPhysId;
+
+ uint64_t lsb = o1.as<Imm>().valueAs<uint64_t>();
+ uint64_t width = o2.as<Imm>().valueAs<uint64_t>();
+ uint32_t opSize = x ? 64 : 32;
+
+ if (lsb >= opSize || width == 0 || width > opSize)
+ goto InvalidImmediate;
+
+ uint32_t lsb32 = Support::neg(uint32_t(lsb)) & (opSize - 1);
+ uint32_t width32 = uint32_t(width) - 1;
+
+ opcode.reset(opData.opcode);
+ opcode.addImm(x, 31);
+ opcode.addImm(x, 22);
+ opcode.addImm(lsb32, 16);
+ opcode.addImm(width32, 10);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseBfi: {
+ const InstDB::EncodingData::BaseBfi& opData = InstDB::EncodingData::baseBfi[encodingIndex];
+
+ if (isign4 == ENC_OPS4(Reg, Reg, Imm, Imm)) {
+ uint32_t x;
+ if (!checkGpType(o0, InstDB::kWX, &x))
+ goto InvalidInstruction;
+
+ if (!checkSignature(o0, o1))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, o1))
+ goto InvalidPhysId;
+
+ uint64_t lsb = o2.as<Imm>().valueAs<uint64_t>();
+ uint64_t width = o3.as<Imm>().valueAs<uint64_t>();
+ uint32_t opSize = x ? 64 : 32;
+
+ if (lsb >= opSize || width == 0 || width > opSize)
+ goto InvalidImmediate;
+
+ uint32_t lImm = Support::neg(uint32_t(lsb)) & (opSize - 1);
+ uint32_t wImm = uint32_t(width) - 1;
+
+ opcode.reset(opData.opcode);
+ opcode.addImm(x, 31);
+ opcode.addImm(x, 22);
+ opcode.addImm(lImm, 16);
+ opcode.addImm(wImm, 10);
+ opcode.addReg(o1, 5);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseBfm: {
+ const InstDB::EncodingData::BaseBfm& opData = InstDB::EncodingData::baseBfm[encodingIndex];
+
+ if (isign4 == ENC_OPS4(Reg, Reg, Imm, Imm)) {
+ uint32_t x;
+ if (!checkGpType(o0, InstDB::kWX, &x))
+ goto InvalidInstruction;
+
+ if (!checkSignature(o0, o1))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, o1))
+ goto InvalidPhysId;
+
+ uint64_t immR = o2.as<Imm>().valueAs<uint64_t>();
+ uint64_t immS = o3.as<Imm>().valueAs<uint64_t>();
+ uint32_t opSize = x ? 64 : 32;
+
+ if ((immR | immS) >= opSize)
+ goto InvalidImmediate;
+
+ opcode.reset(opData.opcode);
+ opcode.addImm(x, 31);
+ opcode.addImm(x, 22);
+ opcode.addImm(immR, 16);
+ opcode.addImm(immS, 10);
+ opcode.addReg(o1, 5);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseBfx: {
+ const InstDB::EncodingData::BaseBfx& opData = InstDB::EncodingData::baseBfx[encodingIndex];
+
+ if (isign4 == ENC_OPS4(Reg, Reg, Imm, Imm)) {
+ uint32_t x;
+ if (!checkGpType(o0, InstDB::kWX, &x))
+ goto InvalidInstruction;
+
+ if (!checkSignature(o0, o1))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, o1))
+ goto InvalidPhysId;
+
+ uint64_t lsb = o2.as<Imm>().valueAs<uint64_t>();
+ uint64_t width = o3.as<Imm>().valueAs<uint64_t>();
+ uint32_t opSize = x ? 64 : 32;
+
+ if (lsb >= opSize || width == 0 || width > opSize)
+ goto InvalidImmediate;
+
+ uint32_t lsb32 = uint32_t(lsb);
+ uint32_t width32 = lsb32 + uint32_t(width) - 1u;
+
+ if (width32 >= opSize)
+ goto InvalidImmediate;
+
+ opcode.reset(opData.opcode);
+ opcode.addImm(x, 31);
+ opcode.addImm(x, 22);
+ opcode.addImm(lsb32, 16);
+ opcode.addImm(width32, 10);
+ opcode.addReg(o1, 5);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseExtend: {
+ const InstDB::EncodingData::BaseExtend& opData = InstDB::EncodingData::baseExtend[encodingIndex];
+
+ if (isign4 == ENC_OPS2(Reg, Reg)) {
+ uint32_t x;
+ if (!checkGpType(o0, opData.rType, &x))
+ goto InvalidInstruction;
+
+ if (!o1.as<Reg>().isGpW())
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, o1))
+ goto InvalidPhysId;
+
+ opcode.reset(opData.opcode());
+ opcode.addImm(x, 31);
+ opcode.addImm(x, 22);
+ opcode.addReg(o1, 5);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseExtract: {
+ const InstDB::EncodingData::BaseExtract& opData = InstDB::EncodingData::baseExtract[encodingIndex];
+
+ if (isign4 == ENC_OPS4(Reg, Reg, Reg, Imm)) {
+ uint32_t x;
+ if (!checkGpType(o0, kWX, &x))
+ goto InvalidInstruction;
+
+ if (!checkSignature(o0, o1, o2))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, o1, o2))
+ goto InvalidPhysId;
+
+ uint64_t lsb = o3.as<Imm>().valueAs<uint64_t>();
+ uint32_t opSize = x ? 64 : 32;
+
+ if (lsb >= opSize)
+ goto InvalidImmediate;
+
+ opcode.reset(opData.opcode);
+ opcode.addImm(x, 31);
+ opcode.addImm(x, 22);
+ opcode.addReg(o2, 16);
+ opcode.addImm(lsb, 10);
+ opcode.addReg(o1, 5);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseRev: {
+ if (isign4 == ENC_OPS2(Reg, Reg)) {
+ uint32_t x;
+ if (!checkGpType(o0, InstDB::kWX, &x))
+ goto InvalidInstruction;
+
+ if (!checkSignature(o0, o1))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, o1))
+ goto InvalidPhysId;
+
+ opcode.reset(0b01011010110000000000100000000000);
+ opcode.addImm(x, 31);
+ opcode.addImm(x, 10);
+ opcode.addReg(o1, 5);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseShift: {
+ const InstDB::EncodingData::BaseShift& opData = InstDB::EncodingData::baseShift[encodingIndex];
+
+ uint32_t x;
+ if (!checkGpType(o0, kWX, &x))
+ goto InvalidInstruction;
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Reg)) {
+ if (!checkSignature(o0, o1, o2))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, o1, o2, kZR))
+ goto InvalidPhysId;
+
+ opcode.reset(opData.registerOp());
+ opcode.addImm(x, 31);
+ opcode.addReg(o2, 16);
+ opcode.addReg(o1, 5);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Imm) && opData.immediateOp()) {
+ if (!checkSignature(o0, o1))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, o1, kZR))
+ goto InvalidPhysId;
+
+ uint64_t immR = o2.as<Imm>().valueAs<uint64_t>();
+ uint32_t opSize = x ? 64 : 32;
+
+ if (immR >= opSize)
+ goto InvalidImmediate;
+
+ opcode.reset(opData.immediateOp());
+ opcode.addImm(x, 31);
+ opcode.addImm(x, 22);
+ opcode.addReg(o1, 5);
+ opcode.addReg(o0, 0);
+
+ if (opcode.get() & B(10)) {
+ // ASR and LSR (immediate) has the same logic.
+ opcode.addImm(x, 15);
+ opcode.addImm(immR, 16);
+ goto EmitOp;
+ }
+
+ if (opData.ror == 0) {
+ // LSL (immediate) is an alias to UBFM
+ uint32_t ubfmImmR = Support::neg(uint32_t(immR)) & (opSize - 1);
+ uint32_t ubfmImmS = opSize - 1 - uint32_t(immR);
+
+ opcode.addImm(ubfmImmR, 16);
+ opcode.addImm(ubfmImmS, 10);
+ goto EmitOp;
+ }
+ else {
+ // ROR (immediate) is an alias to EXTR.
+ opcode.addImm(immR, 10);
+ opcode.addReg(o1, 16);
+ goto EmitOp;
+ }
+ }
+
+ break;
+ }
+
+ // ------------------------------------------------------------------------
+ // [Base - Conditionals]
+ // ------------------------------------------------------------------------
+
+ case InstDB::kEncodingBaseCCmp: {
+ const InstDB::EncodingData::BaseCCmp& opData = InstDB::EncodingData::baseCCmp[encodingIndex];
+
+ if (isign4 == ENC_OPS4(Reg, Reg, Imm, Imm) || isign4 == ENC_OPS4(Reg, Imm, Imm, Imm)) {
+ uint32_t x;
+ if (!checkGpType(o0, InstDB::kWX, &x))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, kZR))
+ goto InvalidPhysId;
+
+ uint64_t nzcv = o2.as<Imm>().valueAs<uint64_t>();
+ uint64_t cond = o3.as<Imm>().valueAs<uint64_t>();
+
+ if ((nzcv | cond) > 0xFu)
+ goto InvalidImmediate;
+
+ opcode.reset(opData.opcode);
+ opcode.addImm(x, 31);
+ opcode.addImm(condCodeToOpcodeCond(uint32_t(cond)), 12);
+ opcode.addImm(nzcv, 0);
+
+ if (isign4 == ENC_OPS4(Reg, Reg, Imm, Imm)) {
+ // CCMN|CCMP (register) form.
+ if (!checkSignature(o0, o1))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o1, kZR))
+ goto InvalidPhysId;
+
+ opcode.addReg(o1, 16);
+ opcode.addReg(o0, 5);
+ goto EmitOp;
+ }
+ else {
+ // CCMN|CCMP (immediate) form.
+ uint64_t imm5 = o1.as<Imm>().valueAs<uint64_t>();
+ if (imm5 > 0x1F)
+ goto InvalidImmediate;
+
+ opcode.addImm(1, 11);
+ opcode.addImm(imm5, 16);
+ opcode.addReg(o0, 5);
+ goto EmitOp;
+ }
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseCInc: {
+ const InstDB::EncodingData::BaseCInc& opData = InstDB::EncodingData::baseCInc[encodingIndex];
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Imm)) {
+ uint32_t x;
+ if (!checkGpType(o0, o1, InstDB::kWX, &x))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, o1, kZR))
+ goto InvalidPhysId;
+
+ uint64_t cond = o2.as<Imm>().valueAs<uint64_t>();
+ if (cond - 2u > 0xEu)
+ goto InvalidImmediate;
+
+ opcode.reset(opData.opcode);
+ opcode.addImm(x, 31);
+ opcode.addReg(o1, 16);
+ opcode.addImm(condCodeToOpcodeCond(uint32_t(cond)) ^ 1u, 12);
+ opcode.addReg(o1, 5);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseCSel: {
+ const InstDB::EncodingData::BaseCSel& opData = InstDB::EncodingData::baseCSel[encodingIndex];
+
+ if (isign4 == ENC_OPS4(Reg, Reg, Reg, Imm)) {
+ uint32_t x;
+ if (!checkGpType(o0, o1, o2, InstDB::kWX, &x))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, o1, o2, kZR))
+ goto InvalidPhysId;
+
+ uint64_t cond = o3.as<Imm>().valueAs<uint64_t>();
+ if (cond > 0xFu)
+ goto InvalidImmediate;
+
+ opcode.reset(opData.opcode);
+ opcode.addImm(x, 31);
+ opcode.addReg(o2, 16);
+ opcode.addImm(condCodeToOpcodeCond(uint32_t(cond)), 12);
+ opcode.addReg(o1, 5);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseCSet: {
+ const InstDB::EncodingData::BaseCSet& opData = InstDB::EncodingData::baseCSet[encodingIndex];
+
+ if (isign4 == ENC_OPS2(Reg, Imm)) {
+ uint32_t x;
+ if (!checkGpType(o0, InstDB::kWX, &x))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, kZR))
+ goto InvalidPhysId;
+
+ uint64_t cond = o1.as<Imm>().valueAs<uint64_t>();
+ if (cond - 2u >= 0xEu)
+ goto InvalidImmediate;
+
+ opcode.reset(opData.opcode);
+ opcode.addImm(x, 31);
+ opcode.addImm(condCodeToOpcodeCond(uint32_t(cond)) ^ 1u, 12);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ // ------------------------------------------------------------------------
+ // [Base - Special]
+ // ------------------------------------------------------------------------
+
+ case InstDB::kEncodingBaseAtDcIcTlbi: {
+ const InstDB::EncodingData::BaseAtDcIcTlbi& opData = InstDB::EncodingData::baseAtDcIcTlbi[encodingIndex];
+
+ if (isign4 == ENC_OPS1(Imm) || isign4 == ENC_OPS2(Imm, Reg)) {
+ if (opData.mandatoryReg && isign4 != ENC_OPS2(Imm, Reg))
+ goto InvalidInstruction;
+
+ if (o0.as<Imm>().valueAs<uint64_t>() > 0x7FFFu)
+ goto InvalidImmediate;
+
+ uint32_t imm = o0.as<Imm>().valueAs<uint32_t>();
+ if ((imm & opData.immVerifyMask) != opData.immVerifyData)
+ goto InvalidImmediate;
+
+ uint32_t rt = 31;
+ if (o1.isReg()) {
+ if (!o1.as<Reg>().isGpX())
+ goto InvalidInstruction;
+
+ if (!checkGpId(o1, kZR))
+ goto InvalidPhysId;
+
+ rt = o1.id() & 31;
+ }
+
+ opcode.reset(0b11010101000010000000000000000000);
+ opcode.addImm(imm, 5);
+ opcode.addReg(rt, 0);
+ goto EmitOp;
+ }
+ break;
+ }
+
+ case InstDB::kEncodingBaseMrs: {
+ if (isign4 == ENC_OPS2(Reg, Imm)) {
+ if (!o0.as<Reg>().isGpX())
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, kZR))
+ goto InvalidPhysId;
+
+ if (o1.as<Imm>().valueAs<uint64_t>() > 0xFFFFu)
+ goto InvalidImmediate;
+
+ uint32_t imm = o1.as<Imm>().valueAs<uint32_t>();
+ if (!(imm & B(15)))
+ goto InvalidImmediate;
+
+ opcode.reset(0b11010101001100000000000000000000);
+ opcode.addImm(imm, 5);
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseMsr: {
+ if (isign4 == ENC_OPS2(Imm, Reg)) {
+ if (!o1.as<Reg>().isGpX())
+ goto InvalidInstruction;
+
+ if (o0.as<Imm>().valueAs<uint64_t>() > 0xFFFFu)
+ goto InvalidImmediate;
+
+ uint32_t imm = o0.as<Imm>().valueAs<uint32_t>();
+ if (!(imm & B(15)))
+ goto InvalidImmediate;
+
+ if (!checkGpId(o1, kZR))
+ goto InvalidPhysId;
+
+ opcode.reset(0b11010101000100000000000000000000);
+ opcode.addImm(imm, 5);
+ opcode.addReg(o1, 0);
+ goto EmitOp;
+ }
+
+ if (isign4 == ENC_OPS2(Imm, Imm)) {
+ if (o0.as<Imm>().valueAs<uint64_t>() > 0x1Fu)
+ goto InvalidImmediate;
+
+ if (o1.as<Imm>().valueAs<uint64_t>() > 0xFu)
+ goto InvalidImmediate;
+
+ uint32_t op = o0.as<Imm>().valueAs<uint32_t>();
+ uint32_t cRm = o1.as<Imm>().valueAs<uint32_t>();
+
+ uint32_t op1 = uint32_t(op) >> 3;
+ uint32_t op2 = uint32_t(op) & 0x7u;
+
+ opcode.reset(0b11010101000000000100000000011111);
+ opcode.addImm(op1, 16);
+ opcode.addImm(cRm, 8);
+ opcode.addImm(op2, 5);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseSys: {
+ if (isign4 == ENC_OPS4(Imm, Imm, Imm, Imm)) {
+ if (o0.as<Imm>().valueAs<uint64_t>() > 0x7u ||
+ o1.as<Imm>().valueAs<uint64_t>() > 0xFu ||
+ o2.as<Imm>().valueAs<uint64_t>() > 0xFu ||
+ o3.as<Imm>().valueAs<uint64_t>() > 0x7u)
+ goto InvalidImmediate;
+
+ uint32_t op1 = o0.as<Imm>().valueAs<uint32_t>();
+ uint32_t cRn = o1.as<Imm>().valueAs<uint32_t>();
+ uint32_t cRm = o2.as<Imm>().valueAs<uint32_t>();
+ uint32_t op2 = o3.as<Imm>().valueAs<uint32_t>();
+ uint32_t rt = 31;
+
+ const Operand_& o4 = opExt[EmitterUtils::kOp4];
+ if (o4.isReg()) {
+ if (!o4.as<Reg>().isGpX())
+ goto InvalidInstruction;
+
+ if (!checkGpId(o4, kZR))
+ goto InvalidPhysId;
+
+ rt = o4.id() & 31;
+ }
+ else if (!o4.isNone()) {
+ goto InvalidInstruction;
+ }
+
+ opcode.reset(0b11010101000010000000000000000000);
+ opcode.addImm(op1, 16);
+ opcode.addImm(cRn, 12);
+ opcode.addImm(cRm, 8);
+ opcode.addImm(op2, 5);
+ opcode.addImm(rt, 0);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ // ------------------------------------------------------------------------
+ // [Base - Branch]
+ // ------------------------------------------------------------------------
+
+ case InstDB::kEncodingBaseBranchReg: {
+ const InstDB::EncodingData::BaseBranchReg& opData = InstDB::EncodingData::baseBranchReg[encodingIndex];
+
+ if (isign4 == ENC_OPS1(Reg)) {
+ if (!o0.as<Reg>().isGpX())
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, kZR))
+ goto InvalidPhysId;
+
+ opcode.reset(opData.opcode);
+ opcode.addReg(o0, 5);
+ goto EmitOp;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseBranchRel: {
+ const InstDB::EncodingData::BaseBranchRel& opData = InstDB::EncodingData::baseBranchRel[encodingIndex];
+
+ if (isign4 == ENC_OPS1(Label) || isign4 == ENC_OPS1(Imm)) {
+ opcode.reset(opData.opcode);
+ rmRel = &o0;
+
+ if (instCC != CondCode::kAL) {
+ opcode |= B(30);
+ opcode.addImm(condCodeToOpcodeCond(uint32_t(instCC)), 0);
+ offsetFormat.resetToImmValue(OffsetType::kSignedOffset, 4, 5, 19, 2);
+ goto EmitOp_Rel;
+ }
+
+ offsetFormat.resetToImmValue(OffsetType::kSignedOffset, 4, 0, 26, 2);
+ goto EmitOp_Rel;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseBranchCmp: {
+ const InstDB::EncodingData::BaseBranchCmp& opData = InstDB::EncodingData::baseBranchCmp[encodingIndex];
+
+ if (isign4 == ENC_OPS2(Reg, Label) || isign4 == ENC_OPS2(Reg, Imm)) {
+ uint32_t x;
+ if (!checkGpType(o0, kWX, &x))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, kZR))
+ goto InvalidPhysId;
+
+ opcode.reset(opData.opcode);
+ opcode.addImm(x, 31);
+ opcode.addReg(o0, 0);
+ offsetFormat.resetToImmValue(OffsetType::kSignedOffset, 4, 5, 19, 2);
+
+ rmRel = &o1;
+ goto EmitOp_Rel;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseBranchTst: {
+ const InstDB::EncodingData::BaseBranchTst& opData = InstDB::EncodingData::baseBranchTst[encodingIndex];
+
+ if (isign4 == ENC_OPS3(Reg, Imm, Label) || isign4 == ENC_OPS3(Reg, Imm, Imm)) {
+ uint32_t x;
+ if (!checkGpType(o0, kWX, &x))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, kZR))
+ goto InvalidPhysId;
+
+ uint64_t imm = o1.as<Imm>().valueAs<uint64_t>();
+
+ opcode.reset(opData.opcode);
+ if (imm >= 32) {
+ if (!x)
+ goto InvalidImmediate;
+ opcode.addImm(x, 31);
+ imm &= 0x1F;
+ }
+
+ opcode.addReg(o0, 0);
+ opcode.addImm(imm, 19);
+ offsetFormat.resetToImmValue(OffsetType::kSignedOffset, 4, 5, 14, 2);
+
+ rmRel = &o2;
+ goto EmitOp_Rel;
+ }
+
+ break;
+ }
+
+ // ------------------------------------------------------------------------
+ // [Base - Load / Store]
+ // ------------------------------------------------------------------------
+
+ case InstDB::kEncodingBaseLdSt: {
+ const InstDB::EncodingData::BaseLdSt& opData = InstDB::EncodingData::baseLdSt[encodingIndex];
+
+ if (isign4 == ENC_OPS2(Reg, Mem)) {
+ const Mem& m = o1.as<Mem>();
+ rmRel = &m;
+
+ uint32_t x;
+ if (!checkGpType(o0, opData.rType, &x))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, kZR))
+ goto InvalidPhysId;
+
+ // Instructions that work with either word or dword have the unsigned
+ // offset shift set to 2 (word), so we set it to 3 (dword) if this is
+ // X version of the instruction.
+ uint32_t xShiftMask = uint32_t(opData.uOffsetShift == 2);
+ uint32_t immShift = uint32_t(opData.uOffsetShift) + (x & xShiftMask);
+
+ if (!armCheckMemBaseIndexRel(m))
+ goto InvalidAddress;
+
+ int64_t offset = m.offset();
+ if (m.hasBaseReg()) {
+ // [Base {Offset | Index}]
+ if (m.hasIndex()) {
+ uint32_t opt = armShiftOpToLdStOptMap[m.predicate()];
+ 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.xorImm(x, opData.xOffset);
+ opcode.addImm(opt, 13);
+ opcode.addImm(s, 12);
+ opcode |= B(11);
+ opcode.addReg(o0, 0);
+ goto EmitOp_MemBaseIndex_Rn5_Rm16;
+ }
+
+ // Makes it easier to work with the offset especially on 32-bit arch.
+ if (!Support::isInt32(offset))
+ goto InvalidDisplacement;
+ int32_t offset32 = int32_t(offset);
+
+ if (m.isPreOrPost()) {
+ if (!Support::isInt9(offset32))
+ goto InvalidDisplacement;
+
+ opcode.reset(uint32_t(opData.prePostOp) << 21);
+ opcode.xorImm(x, opData.xOffset);
+ opcode.addImm(offset32 & 0x1FF, 12);
+ opcode.addImm(m.isPreIndex(), 11);
+ opcode |= B(10);
+ opcode.addReg(o0, 0);
+ goto EmitOp_MemBase_Rn5;
+ }
+ else {
+ uint32_t imm12 = uint32_t(offset32) >> immShift;
+
+ // Alternative form of LDUR/STUR and related instructions as described by AArch64 reference manual:
+ //
+ // If this instruction is not encodable with scaled unsigned offset, try unscaled signed offset.
+ if (!Support::isUInt12(imm12) || (imm12 << immShift) != uint32_t(offset32)) {
+ instId = opData.uAltInstId;
+ instInfo = &InstDB::_instInfoTable[instId];
+ encodingIndex = instInfo->_encodingDataIndex;
+ goto Case_BaseLdurStur;
+ }
+
+ opcode.reset(uint32_t(opData.uOffsetOp) << 22);
+ opcode.xorImm(x, opData.xOffset);
+ opcode.addImm(imm12, 10);
+ opcode.addReg(o0, 0);
+ goto EmitOp_MemBase_Rn5;
+ }
+ }
+ else {
+ if (!opData.literalOp)
+ goto InvalidAddress;
+
+ opcode.reset(uint32_t(opData.literalOp) << 24);
+ opcode.xorImm(x, opData.xOffset);
+ opcode.addReg(o0, 0);
+ offsetFormat.resetToImmValue(OffsetType::kSignedOffset, 4, 5, 19, 2);
+ goto EmitOp_Rel;
+ }
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseLdpStp: {
+ const InstDB::EncodingData::BaseLdpStp& opData = InstDB::EncodingData::baseLdpStp[encodingIndex];
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Mem)) {
+ const Mem& m = o2.as<Mem>();
+ rmRel = &m;
+
+ uint32_t x;
+ if (!checkGpType(o0, o1, opData.rType, &x))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, o1, kZR))
+ goto InvalidPhysId;
+
+ if (m.baseType() != RegType::kARM_GpX || m.hasIndex())
+ goto InvalidAddress;
+
+ if (m.isOffset64Bit())
+ goto InvalidDisplacement;
+
+ uint32_t offsetShift = opData.offsetShift + x;
+ int32_t offset32 = m.offsetLo32() >> offsetShift;
+
+ // Make sure we didn't lose bits by applying the mandatory offset shift.
+ if (uint32_t(offset32) << offsetShift != uint32_t(m.offsetLo32()))
+ goto InvalidDisplacement;
+
+ // Offset is encoded as 7-bit immediate.
+ if (!Support::isInt7(offset32))
+ goto InvalidDisplacement;
+
+ if (m.isPreOrPost() && offset32 != 0) {
+ if (!opData.prePostOp)
+ goto InvalidAddress;
+
+ opcode.reset(uint32_t(opData.prePostOp) << 22);
+ opcode.addImm(m.isPreIndex(), 24);
+ }
+ else {
+ opcode.reset(uint32_t(opData.offsetOp) << 22);
+ }
+
+ opcode.addImm(x, opData.xOffset);
+ opcode.addImm(offset32 & 0x7F, 15);
+ opcode.addReg(o1, 10);
+ opcode.addReg(o0, 0);
+ goto EmitOp_MemBase_Rn5;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseStx: {
+ const InstDB::EncodingData::BaseStx& opData = InstDB::EncodingData::baseStx[encodingIndex];
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Mem)) {
+ const Mem& m = o2.as<Mem>();
+ uint32_t x;
+
+ if (!o0.as<Reg>().isGpW() || !checkGpType(o1, opData.rType, &x))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, o1, kZR))
+ goto InvalidPhysId;
+
+ opcode.reset(opData.opcode());
+ opcode.addImm(x, opData.xOffset);
+ opcode.addReg(o0, 16);
+ opcode.addReg(o1, 0);
+
+ rmRel = &m;
+ goto EmitOp_MemBaseNoImm_Rn5;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseLdxp: {
+ const InstDB::EncodingData::BaseLdxp& opData = InstDB::EncodingData::baseLdxp[encodingIndex];
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Mem)) {
+ const Mem& m = o2.as<Mem>();
+ uint32_t x;
+
+ if (!checkGpType(o0, opData.rType, &x) || !checkSignature(o0, o1))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, o1, kZR))
+ goto InvalidPhysId;
+
+ opcode.reset(opData.opcode());
+ opcode.addImm(x, opData.xOffset);
+ opcode.addReg(o1, 10);
+ opcode.addReg(o0, 0);
+
+ rmRel = &m;
+ goto EmitOp_MemBaseNoImm_Rn5;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseStxp: {
+ const InstDB::EncodingData::BaseStxp& opData = InstDB::EncodingData::baseStxp[encodingIndex];
+
+ if (isign4 == ENC_OPS4(Reg, Reg, Reg, Mem)) {
+ const Mem& m = o3.as<Mem>();
+ uint32_t x;
+
+ if (!o0.as<Reg>().isGpW() || !checkGpType(o1, opData.rType, &x) || !checkSignature(o1, o2))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, o1, o2, kZR))
+ goto InvalidPhysId;
+
+ opcode.reset(opData.opcode());
+ opcode.addImm(x, opData.xOffset);
+ opcode.addReg(o0, 16);
+ opcode.addReg(o2, 10);
+ opcode.addReg(o1, 0);
+
+ rmRel = &m;
+ goto EmitOp_MemBaseNoImm_Rn5;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseRM_NoImm: {
+ const InstDB::EncodingData::BaseRM_NoImm& opData = InstDB::EncodingData::baseRM_NoImm[encodingIndex];
+
+ if (isign4 == ENC_OPS2(Reg, Mem)) {
+ const Mem& m = o1.as<Mem>();
+ rmRel = &m;
+
+ uint32_t x;
+ if (!checkGpType(o0, opData.rType, &x))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, opData.rHiId))
+ goto InvalidPhysId;
+
+ opcode.reset(opData.opcode());
+ opcode.addImm(x, opData.xOffset);
+ opcode.addReg(o0, 0);
+ goto EmitOp_MemBaseNoImm_Rn5;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseRM_SImm9: {
+Case_BaseLdurStur:
+ const InstDB::EncodingData::BaseRM_SImm9& opData = InstDB::EncodingData::baseRM_SImm9[encodingIndex];
+
+ if (isign4 == ENC_OPS2(Reg, Mem)) {
+ const Mem& m = o1.as<Mem>();
+ rmRel = &m;
+
+ uint32_t x;
+ if (!checkGpType(o0, opData.rType, &x))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, opData.rHiId))
+ goto InvalidPhysId;
+
+ if (m.hasBaseReg() && !m.hasIndex()) {
+ if (m.isOffset64Bit())
+ goto InvalidDisplacement;
+
+ int32_t offset32 = m.offsetLo32() >> opData.immShift;
+ if (Support::shl(offset32, opData.immShift) != m.offsetLo32())
+ goto InvalidDisplacement;
+
+ if (!Support::isInt9(offset32))
+ goto InvalidDisplacement;
+
+ if (m.isFixedOffset()) {
+ opcode.reset(opData.offsetOp());
+ }
+ else {
+ if (!opData.prePostOp())
+ goto InvalidInstruction;
+
+ opcode.reset(opData.prePostOp());
+ opcode.xorImm(m.isPreIndex(), 11);
+ }
+
+ opcode.xorImm(x, opData.xOffset);
+ opcode.addImm(offset32 & 0x1FF, 12);
+ opcode.addReg(o0, 0);
+ goto EmitOp_MemBase_Rn5;
+ }
+
+ goto InvalidAddress;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseRM_SImm10: {
+ const InstDB::EncodingData::BaseRM_SImm10& opData = InstDB::EncodingData::baseRM_SImm10[encodingIndex];
+
+ if (isign4 == ENC_OPS2(Reg, Mem)) {
+ const Mem& m = o1.as<Mem>();
+ rmRel = &m;
+
+ uint32_t x;
+ if (!checkGpType(o0, opData.rType, &x))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, opData.rHiId))
+ goto InvalidPhysId;
+
+ if (m.hasBaseReg() && !m.hasIndex()) {
+ if (m.isOffset64Bit())
+ goto InvalidDisplacement;
+
+ int32_t offset32 = m.offsetLo32() >> opData.immShift;
+ if (Support::shl(offset32, opData.immShift) != m.offsetLo32())
+ goto InvalidDisplacement;
+
+ if (!Support::isInt10(offset32))
+ goto InvalidDisplacement;
+
+ if (m.isPostIndex())
+ goto InvalidAddress;
+
+ // Offset has 10 bits, sign is stored in the 10th bit.
+ offset32 &= 0x3FF;
+
+ opcode.reset(opData.opcode());
+ opcode.xorImm(m.isPreIndex(), 11);
+ opcode.xorImm(x, opData.xOffset);
+ opcode.addImm(offset32 >> 9, 22);
+ opcode.addImm(offset32, 12);
+ opcode.addReg(o0, 0);
+ goto EmitOp_MemBase_Rn5;
+ }
+
+ goto InvalidAddress;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseAtomicOp: {
+ const InstDB::EncodingData::BaseAtomicOp& opData = InstDB::EncodingData::baseAtomicOp[encodingIndex];
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Mem)) {
+ const Mem& m = o2.as<Mem>();
+ uint32_t x;
+
+ if (!checkGpType(o0, opData.rType, &x) || !checkSignature(o0, o1))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, o1, kZR))
+ goto InvalidInstruction;
+
+ opcode.reset(opData.opcode());
+ opcode.addImm(x, opData.xOffset);
+ opcode.addReg(o0, 16);
+ opcode.addReg(o1, 0);
+
+ rmRel = &m;
+ goto EmitOp_MemBaseNoImm_Rn5;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseAtomicSt: {
+ const InstDB::EncodingData::BaseAtomicSt& opData = InstDB::EncodingData::baseAtomicSt[encodingIndex];
+
+ if (isign4 == ENC_OPS2(Reg, Mem)) {
+ const Mem& m = o1.as<Mem>();
+ uint32_t x;
+
+ if (!checkGpType(o0, opData.rType, &x))
+ goto InvalidInstruction;
+
+ if (!checkGpId(o0, kZR))
+ goto InvalidPhysId;
+
+ opcode.reset(opData.opcode());
+ opcode.addImm(x, opData.xOffset);
+ opcode.addReg(o0, 16);
+ opcode.addReg(Gp::kIdZr, 0);
+
+ rmRel = &m;
+ goto EmitOp_MemBaseNoImm_Rn5;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingBaseAtomicCasp: {
+ const InstDB::EncodingData::BaseAtomicCasp& opData = InstDB::EncodingData::baseAtomicCasp[encodingIndex];
+ const Operand_& o4 = opExt[EmitterUtils::kOp4];
+
+ if (isign4 == ENC_OPS4(Reg, Reg, Reg, Reg) && o4.isMem()) {
+ const Mem& m = o4.as<Mem>();
+ uint32_t x;
+
+ if (!checkGpType(o0, opData.rType, &x))
+ goto InvalidInstruction;
+
+ if (!checkSignature(o0, o1, o2, o3))
+ goto InvalidInstruction;
+
+ if (!checkEven(o0, o2) || !checkGpId(o0, o2, kZR))
+ goto InvalidPhysId;
+
+ if (!checkConsecutive(o0, o1) || !checkConsecutive(o2, o3))
+ goto InvalidPhysId;
+
+ opcode.reset(opData.opcode());
+ opcode.addImm(x, opData.xOffset);
+ opcode.addReg(o0, 16);
+ opcode.addReg(o2, 0);
+
+ rmRel = &m;
+ goto EmitOp_MemBaseNoImm_Rn5;
+ }
+
+ break;
+ }
+
+ // ------------------------------------------------------------------------
+ // [FSimd - Instructions]
+ // ------------------------------------------------------------------------
+
+ case InstDB::kEncodingFSimdSV: {
+ const InstDB::EncodingData::FSimdSV& opData = InstDB::EncodingData::fSimdSV[encodingIndex];
+
+ if (isign4 == ENC_OPS2(Reg, Reg)) {
+ uint32_t q = diff(o1.as<Reg>().type(), RegType::kARM_VecD);
+ if (q > 1)
+ goto InvalidInstruction;
+
+ if (o0.as<Vec>().hasElementType())
+ goto InvalidInstruction;
+
+ // This operation is only defined for:
+ // 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;
+
+ // Size greater than 1 means 64-bit elements, not supported.
+ if ((sz | elementSz) > 1 || sz != elementSz)
+ goto InvalidInstruction;
+
+ // Size 1 (32-bit float) requires at least 4 elements.
+ if (sz && !q)
+ goto InvalidInstruction;
+
+ // Bit flipping according to sz.
+ static const uint32_t szBits[] = { B(29), 0 };
+
+ opcode.reset(opData.opcode << 10);
+ opcode ^= szBits[sz];
+ opcode.addImm(q, 30);
+ goto EmitOp_Rd0_Rn5;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingFSimdVV: {
+ const InstDB::EncodingData::FSimdVV& opData = InstDB::EncodingData::fSimdVV[encodingIndex];
+
+ if (isign4 == ENC_OPS2(Reg, Reg)) {
+ if (!matchSignature(o0, o1, instFlags))
+ goto InvalidInstruction;
+
+ if (!pickFpOpcode(o0.as<Vec>(), opData.scalarOp(), opData.scalarHf(), opData.vectorOp(), opData.vectorHf(), &opcode))
+ goto InvalidInstruction;
+
+ goto EmitOp_Rd0_Rn5;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingFSimdVVV: {
+ const InstDB::EncodingData::FSimdVVV& opData = InstDB::EncodingData::fSimdVVV[encodingIndex];
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Reg)) {
+ if (!matchSignature(o0, o1, o2, instFlags))
+ goto InvalidInstruction;
+
+ if (!pickFpOpcode(o0.as<Vec>(), opData.scalarOp(), opData.scalarHf(), opData.vectorOp(), opData.vectorHf(), &opcode))
+ goto InvalidInstruction;
+
+ goto EmitOp_Rd0_Rn5_Rm16;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingFSimdVVVe: {
+ const InstDB::EncodingData::FSimdVVVe& opData = InstDB::EncodingData::fSimdVVVe[encodingIndex];
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Reg)) {
+ if (!o2.as<Vec>().hasElementIndex()) {
+ if (!matchSignature(o0, o1, o2, instFlags))
+ goto InvalidInstruction;
+
+ if (!pickFpOpcode(o0.as<Vec>(), opData.scalarOp(), opData.scalarHf(), opData.vectorOp(), opData.vectorHf(), &opcode))
+ goto InvalidInstruction;
+
+ goto EmitOp_Rd0_Rn5_Rm16;
+ }
+ else {
+ if (!matchSignature(o0, o1, instFlags))
+ goto InvalidInstruction;
+
+ uint32_t q = o1.as<Reg>().isVecQ();
+ uint32_t sz;
+
+ if (!pickFpOpcode(o0.as<Vec>(), opData.elementScalarOp(), InstDB::kHF_D, opData.elementVectorOp(), InstDB::kHF_D, &opcode, &sz))
+ goto InvalidInstruction;
+
+ if (sz == 0 && o2.as<Reg>().id() > 15)
+ goto InvalidPhysId;
+
+ uint32_t elementIndex = o2.as<Vec>().elementIndex();
+ if (elementIndex > (7u >> sz))
+ goto InvalidElementIndex;
+
+ uint32_t hlm = elementIndex << sz;
+ opcode.addImm(q, 30);
+ opcode.addImm(hlm & 3u, 20);
+ opcode.addImm(hlm >> 2, 11);
+ goto EmitOp_Rd0_Rn5_Rm16;
+ }
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingFSimdVVVV: {
+ const InstDB::EncodingData::FSimdVVVV& opData = InstDB::EncodingData::fSimdVVVV[encodingIndex];
+
+ if (isign4 == ENC_OPS4(Reg, Reg, Reg, Reg)) {
+ if (!matchSignature(o0, o1, o2, o3, instFlags))
+ goto InvalidInstruction;
+
+ if (!pickFpOpcode(o0.as<Vec>(), opData.scalarOp(), opData.scalarHf(), opData.vectorOp(), opData.vectorHf(), &opcode))
+ goto InvalidInstruction;
+
+ goto EmitOp_Rd0_Rn5_Rm16_Ra10;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdFcadd: {
+ const InstDB::EncodingData::SimdFcadd& opData = InstDB::EncodingData::simdFcadd[encodingIndex];
+
+ if (isign4 == ENC_OPS4(Reg, Reg, Reg, Imm)) {
+ if (!checkSignature(o0, o1, o2) || o0.as<Vec>().hasElementIndex())
+ goto InvalidInstruction;
+
+ uint32_t q = diff(o0.as<Reg>().type(), RegType::kARM_VecD);
+ if (q > 1)
+ goto InvalidInstruction;
+
+ uint32_t sz = o0.as<Vec>().elementType() - Vec::kElementTypeB;
+ if (sz == 0 || sz > 3)
+ goto InvalidInstruction;
+
+ // 0 <- 90deg.
+ // 1 <- 270deg.
+ uint32_t rot = 0;
+ if (o3.as<Imm>().value() == 270)
+ rot = 1;
+ else if (o3.as<Imm>().value() != 90)
+ goto InvalidImmediate;
+
+ opcode.reset(opData.opcode());
+ opcode.addImm(q, 30);
+ opcode.addImm(sz, 22);
+ opcode.addImm(rot, 12);
+ goto EmitOp_Rd0_Rn5_Rm16;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdFccmpFccmpe: {
+ const InstDB::EncodingData::SimdFccmpFccmpe& opData = InstDB::EncodingData::simdFccmpFccmpe[encodingIndex];
+
+ if (isign4 == ENC_OPS4(Reg, Reg, Imm, Imm)) {
+ uint32_t sz = diff(o0.as<Reg>().type(), RegType::kARM_VecH);
+ if (sz > 2)
+ goto InvalidInstruction;
+
+ if (!checkSignature(o0, o1) || o0.as<Vec>().hasElementType())
+ goto InvalidInstruction;
+
+ uint64_t nzcv = o2.as<Imm>().valueAs<uint64_t>();
+ uint64_t cond = o3.as<Imm>().valueAs<uint64_t>();
+
+ if ((nzcv | cond) > 0xFu)
+ goto InvalidImmediate;
+
+ uint32_t type = (sz - 1) & 0x3u;
+
+ opcode.reset(opData.opcode());
+ opcode.addImm(type, 22);
+ opcode.addImm(condCodeToOpcodeCond(uint32_t(cond)), 12);
+ opcode.addImm(nzcv, 0);
+
+ goto EmitOp_Rn5_Rm16;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdFcm: {
+ const InstDB::EncodingData::SimdFcm& opData = InstDB::EncodingData::simdFcm[encodingIndex];
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Reg) && opData.hasRegisterOp()) {
+ if (!matchSignature(o0, o1, o2, instFlags))
+ goto InvalidInstruction;
+
+ if (!pickFpOpcode(o0.as<Vec>(), opData.registerScalarOp(), opData.registerScalarHf(), opData.registerVectorOp(), opData.registerVectorHf(), &opcode))
+ goto InvalidInstruction;
+
+ goto EmitOp_Rd0_Rn5_Rm16;
+ }
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Imm) && opData.hasZeroOp()) {
+ if (!checkSignature(o0, o1))
+ goto InvalidInstruction;
+
+ if (o2.as<Imm>().value() != 0 || o2.as<Imm>().predicate() != 0)
+ goto InvalidImmediate;
+
+ if (!pickFpOpcode(o0.as<Vec>(), opData.zeroScalarOp(), InstDB::kHF_B, opData.zeroVectorOp(), InstDB::kHF_B, &opcode))
+ goto InvalidInstruction;
+
+ goto EmitOp_Rd0_Rn5;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdFcmla: {
+ const InstDB::EncodingData::SimdFcmla& opData = InstDB::EncodingData::simdFcmla[encodingIndex];
+
+ if (isign4 == ENC_OPS4(Reg, Reg, Reg, Imm)) {
+ if (!checkSignature(o0, o1))
+ goto InvalidInstruction;
+
+ uint32_t q = diff(o0.as<Reg>().type(), RegType::kARM_VecD);
+ if (q > 1)
+ goto InvalidInstruction;
+
+ uint32_t sz = o0.as<Vec>().elementType() - Vec::kElementTypeB;
+ if (sz == 0 || sz > 3)
+ goto InvalidInstruction;
+
+ uint32_t rot = 0;
+ switch (o3.as<Imm>().value()) {
+ case 0 : rot = 0; break;
+ case 90 : rot = 1; break;
+ case 180: rot = 2; break;
+ case 270: rot = 3; break;
+ default:
+ goto InvalidImmediate;
+ }
+
+ if (!o2.as<Vec>().hasElementIndex()) {
+ if (!checkSignature(o1, o2))
+ goto InvalidInstruction;
+
+ opcode.reset(opData.regularOp());
+ opcode.addImm(q, 30);
+ opcode.addImm(sz, 22);
+ opcode.addImm(rot, 11);
+ goto EmitOp_Rd0_Rn5_Rm16;
+ }
+ else {
+ if (o0.as<Vec>().elementType() != o2.as<Vec>().elementType())
+ goto InvalidInstruction;
+
+ // Only allowed vectors are: 4H, 8H, and 4S.
+ if (!(sz == 1 || (q == 1 && sz == 2)))
+ goto InvalidInstruction;
+
+ // Element index ranges:
+ // 4H - ElementIndex[0..1] (index 2..3 is UNDEFINED).
+ // 8H - ElementIndex[0..3].
+ // 4S - ElementIndex[0..1].
+ uint32_t elementIndex = o2.as<Vec>().elementIndex();
+ uint32_t hlFieldShift = sz == 1 ? 0u : 1u;
+ uint32_t maxElementIndex = q == 1 && sz == 1 ? 3u : 1u;
+
+ if (elementIndex > maxElementIndex)
+ goto InvalidElementIndex;
+
+ uint32_t hl = elementIndex << hlFieldShift;
+
+ opcode.reset(opData.elementOp());
+ opcode.addImm(q, 30);
+ opcode.addImm(sz, 22);
+ opcode.addImm(hl & 1u, 21); // L field.
+ opcode.addImm(hl >> 1, 11); // H field.
+ opcode.addImm(rot, 13);
+ goto EmitOp_Rd0_Rn5_Rm16;
+ }
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdFcmpFcmpe: {
+ const InstDB::EncodingData::SimdFcmpFcmpe& opData = InstDB::EncodingData::simdFcmpFcmpe[encodingIndex];
+
+ uint32_t sz = diff(o0.as<Reg>().type(), RegType::kARM_VecH);
+ uint32_t type = (sz - 1) & 0x3u;
+
+ if (sz > 2)
+ goto InvalidInstruction;
+
+ if (o0.as<Vec>().hasElementType())
+ goto InvalidInstruction;
+
+ opcode.reset(opData.opcode());
+ opcode.addImm(type, 22);
+
+ if (isign4 == ENC_OPS2(Reg, Reg)) {
+ if (!checkSignature(o0, o1))
+ goto InvalidInstruction;
+
+ goto EmitOp_Rn5_Rm16;
+ }
+
+ if (isign4 == ENC_OPS2(Reg, Imm)) {
+ if (o1.as<Imm>().value() != 0 || o1.as<Imm>().predicate() != 0)
+ goto InvalidInstruction;
+
+ opcode |= B(3);
+ goto EmitOp_Rn5;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdFcsel: {
+ if (isign4 == ENC_OPS4(Reg, Reg, Reg, Imm)) {
+ if (!checkSignature(o0, o1, o2))
+ goto InvalidInstruction;
+
+ uint32_t sz = diff(o0.as<Reg>().type(), RegType::kARM_VecH);
+ uint32_t type = (sz - 1) & 0x3u;
+
+ if (sz > 2 || o0.as<Vec>().hasElementType())
+ goto InvalidInstruction;
+
+ uint64_t cond = o3.as<Imm>().valueAs<uint64_t>();
+ if (cond > 0xFu)
+ goto InvalidImmediate;
+
+ opcode.reset(0b00011110001000000000110000000000);
+ opcode.addImm(type, 22);
+ opcode.addImm(condCodeToOpcodeCond(uint32_t(cond)), 12);
+ goto EmitOp_Rd0_Rn5_Rm16;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdFcvt: {
+ if (isign4 == ENC_OPS2(Reg, Reg)) {
+ uint32_t dstSz = diff(o0.as<Reg>().type(), RegType::kARM_VecH);
+ uint32_t srcSz = diff(o1.as<Reg>().type(), RegType::kARM_VecH);
+
+ if ((dstSz | srcSz) > 3)
+ goto InvalidInstruction;
+
+ if (o0.as<Vec>().hasElementType() || o1.as<Vec>().hasElementType())
+ goto InvalidInstruction;
+
+ // Table that provides 'type' and 'opc' according to the dst/src combination.
+ static const uint8_t table[] = {
+ 0xFFu, // H <- H (Invalid).
+ 0x03u, // H <- S (type=00 opc=11).
+ 0x13u, // H <- D (type=01 opc=11).
+ 0xFFu, // H <- Q (Invalid).
+ 0x30u, // S <- H (type=11 opc=00).
+ 0xFFu, // S <- S (Invalid).
+ 0x10u, // S <- D (type=01 opc=00).
+ 0xFFu, // S <- Q (Invalid).
+ 0x31u, // D <- H (type=11 opc=01).
+ 0x01u, // D <- S (type=00 opc=01).
+ 0xFFu, // D <- D (Invalid).
+ 0xFFu, // D <- Q (Invalid).
+ 0xFFu, // Q <- H (Invalid).
+ 0xFFu, // Q <- S (Invalid).
+ 0xFFu, // Q <- D (Invalid).
+ 0xFFu // Q <- Q (Invalid).
+ };
+
+ uint32_t typeOpc = table[(dstSz << 2) | srcSz];
+ opcode.reset(0b0001111000100010010000 << 10);
+ opcode.addImm(typeOpc >> 4, 22);
+ opcode.addImm(typeOpc & 15, 15);
+ goto EmitOp_Rd0_Rn5;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdFcvtLN: {
+ const InstDB::EncodingData::SimdFcvtLN& opData = InstDB::EncodingData::simdFcvtLN[encodingIndex];
+
+ if (isign4 == ENC_OPS2(Reg, Reg)) {
+ // Scalar form - only FCVTXN.
+ if (o0.as<Vec>().isVecS() && o1.as<Vec>().isVecD()) {
+ if (!opData.hasScalar())
+ goto InvalidInstruction;
+
+ if (o0.as<Vec>().hasElementType() || o1.as<Vec>().hasElementType())
+ goto InvalidInstruction;
+
+ opcode.reset(opData.scalarOp());
+ opcode |= B(22); // sz bit must be 1, the only supported combination of FCVTXN.
+ goto EmitOp_Rd0_Rn5;
+ }
+
+ opcode.reset(opData.vectorOp());
+
+ const Vec& rL = (instFlags & InstDB::kInstFlagLong) ? o0.as<Vec>() : o1.as<Vec>();
+ const Vec& rN = (instFlags & InstDB::kInstFlagLong) ? o1.as<Vec>() : o0.as<Vec>();
+
+ uint32_t q = diff(rN.type(), RegType::kARM_VecD);
+ if (uint32_t(opcode.hasQ()) != q)
+ goto InvalidInstruction;
+
+ if (rL.isVecS4() && rN.elementType() == Vec::kElementTypeH && !opData.isCvtxn()) {
+ goto EmitOp_Rd0_Rn5;
+ }
+
+ if (rL.isVecD2() && rN.elementType() == Vec::kElementTypeS) {
+ opcode |= B(22);
+ goto EmitOp_Rd0_Rn5;
+ }
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdFcvtSV: {
+ const InstDB::EncodingData::SimdFcvtSV& opData = InstDB::EncodingData::simdFcvtSV[encodingIndex];
+
+ // So we can support both IntToFloat and FloatToInt conversions.
+ const Operand_& oGp = opData.isFloatToInt() ? o0 : o1;
+ const Operand_& oVec = opData.isFloatToInt() ? o1 : o0;
+
+ if (isign4 == ENC_OPS2(Reg, Reg)) {
+ if (oGp.as<Reg>().isGp() && oVec.as<Reg>().isVec()) {
+ uint32_t x = oGp.as<Reg>().isGpX();
+ uint32_t type = diff(oVec.as<Reg>().type(), RegType::kARM_VecH);
+
+ if (type > 2u)
+ goto InvalidInstruction;
+
+ type = (type - 1u) & 0x3;
+ opcode.reset(opData.generalOp());
+ opcode.addImm(type, 22);
+ opcode.addImm(x, 31);
+ goto EmitOp_Rd0_Rn5;
+ }
+
+ if (o0.as<Reg>().isVec() && o1.as<Reg>().isVec()) {
+ if (!checkSignature(o0, o1))
+ goto InvalidInstruction;
+
+ if (!pickFpOpcode(o0.as<Vec>(), opData.scalarIntOp(), InstDB::kHF_B, opData.vectorIntOp(), InstDB::kHF_B, &opcode))
+ goto InvalidInstruction;
+
+ goto EmitOp_Rd0_Rn5;
+ }
+ }
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Imm) && opData.isFixedPoint()) {
+ if (o2.as<Imm>().valueAs<uint64_t>() >= 64)
+ goto InvalidInstruction;
+
+ uint32_t scale = o2.as<Imm>().valueAs<uint32_t>();
+ if (scale == 0)
+ goto InvalidInstruction;
+
+ if (oGp.as<Reg>().isGp() && oVec.as<Reg>().isVec()) {
+ uint32_t x = oGp.as<Reg>().isGpX();
+ uint32_t type = diff(oVec.as<Reg>().type(), RegType::kARM_VecH);
+
+ uint32_t scaleLimit = 32u << x;
+ if (scale > scaleLimit)
+ goto InvalidInstruction;
+
+ type = (type - 1u) & 0x3;
+ opcode.reset(opData.generalOp() ^ B(21));
+ opcode.addImm(type, 22);
+ opcode.addImm(x, 31);
+ opcode.addImm(64u - scale, 10);
+ goto EmitOp_Rd0_Rn5;
+ }
+
+ if (o0.as<Reg>().isVec() && o1.as<Reg>().isVec()) {
+ if (!checkSignature(o0, o1))
+ goto InvalidInstruction;
+
+ uint32_t sz;
+ if (!pickFpOpcode(o0.as<Vec>(), opData.scalarFpOp(), InstDB::kHF_0, opData.vectorFpOp(), InstDB::kHF_0, &opcode, &sz))
+ goto InvalidInstruction;
+
+ uint32_t scaleLimit = 16u << sz;
+ if (scale > scaleLimit)
+ goto InvalidInstruction;
+
+ uint32_t imm = Support::neg(scale) & Support::lsbMask<uint32_t>(sz + 4 + 1);
+ opcode.addImm(imm, 16);
+ goto EmitOp_Rd0_Rn5;
+ }
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdFmlal: {
+ const InstDB::EncodingData::SimdFmlal& opData = InstDB::EncodingData::simdFmlal[encodingIndex];
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Reg)) {
+ uint32_t q = diff(o0.as<Reg>().type(), RegType::kARM_VecD);
+ uint32_t qIsOptional = opData.optionalQ();
+
+ if (qIsOptional) {
+ // This instruction works with either 64-bit or 128-bit registers,
+ // encoded by Q bit.
+ if (q > 1)
+ goto InvalidInstruction;
+ }
+ else {
+ // This instruction requires 128-bit vector registers.
+ if (q != 1)
+ goto InvalidInstruction;
+
+ // The instruction is ehtier B (bottom) or T (top), which is part of
+ // the opcode, which uses Q bit, so we have to clear it explicitly.
+ q = 0;
+ }
+
+ 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)
+ goto InvalidInstruction;
+
+ if (!o2.as<Vec>().hasElementIndex()) {
+ if (!checkSignature(o1, o2))
+ goto InvalidInstruction;
+
+ opcode.reset(opData.vectorOp());
+ opcode.addImm(q, 30);
+ goto EmitOp_Rd0_Rn5_Rm16;
+ }
+ else {
+ if (o2.as<Vec>().elementType() != opData.tElement)
+ goto InvalidInstruction;
+
+ if (o2.as<Reg>().id() > 15)
+ goto InvalidPhysId;
+
+ uint32_t elementIndex = o2.as<Vec>().elementIndex();
+ if (elementIndex > 7u)
+ goto InvalidElementIndex;
+
+ opcode.reset(opData.elementOp());
+ opcode.addImm(q, 30);
+ opcode.addImm(elementIndex & 3u, 20);
+ opcode.addImm(elementIndex >> 2, 11);
+ goto EmitOp_Rd0_Rn5_Rm16;
+ }
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdFmov: {
+ if (isign4 == ENC_OPS2(Reg, Reg)) {
+ // FMOV Gp <-> Vec opcode:
+ opcode.reset(0b00011110001001100000000000000000);
+
+ if (o0.as<Reg>().isGp() && o1.as<Reg>().isVec()) {
+ // FMOV Wd, Hn (sf=0 type=11 rmode=00 op=110)
+ // FMOV Xd, Hn (sf=1 type=11 rmode=00 op=110)
+ // FMOV Wd, Sn (sf=0 type=00 rmode=00 op=110)
+ // FMOV Xd, Dn (sf=1 type=11 rmode=00 op=110)
+ // FMOV Xd, Vn.d[1] (sf=1 type=10 rmode=01 op=110)
+ uint32_t x = o0.as<Reg>().isGpX();
+ uint32_t sz = diff(o1.as<Reg>().type(), RegType::kARM_VecH);
+
+ uint32_t type = (sz - 1) & 0x3u;
+ uint32_t rModeOp = 0b00110;
+
+ if (o1.as<Vec>().hasElementIndex()) {
+ // Special case.
+ if (!x || !o1.as<Vec>().isVecD2() || o1.as<Vec>().elementIndex() != 1)
+ goto InvalidInstruction;
+ type = 0b10;
+ rModeOp = 0b01110;
+ }
+ else {
+ // Must be scalar.
+ if (sz > 2)
+ goto InvalidInstruction;
+
+ if (o1.as<Vec>().hasElementType())
+ goto InvalidInstruction;
+
+ if (o1.as<Vec>().isVecS() && x)
+ goto InvalidInstruction;
+
+ if (o1.as<Vec>().isVecD() && !x)
+ goto InvalidInstruction;
+ }
+
+ opcode.addImm(x, 31);
+ opcode.addImm(type, 22);
+ opcode.addImm(rModeOp, 16);
+ goto EmitOp_Rd0_Rn5;
+ }
+
+ if (o0.as<Reg>().isVec() && o1.as<Reg>().isGp()) {
+ // FMOV Hd, Wn (sf=0 type=11 rmode=00 op=111)
+ // FMOV Hd, Xn (sf=1 type=11 rmode=00 op=111)
+ // FMOV Sd, Wn (sf=0 type=00 rmode=00 op=111)
+ // FMOV Dd, Xn (sf=1 type=11 rmode=00 op=111)
+ // FMOV Vd.d[1], Xn (sf=1 type=10 rmode=01 op=111)
+ uint32_t x = o1.as<Reg>().isGpX();
+ uint32_t sz = diff(o0.as<Reg>().type(), RegType::kARM_VecH);
+
+ uint32_t type = (sz - 1) & 0x3u;
+ uint32_t rModeOp = 0b00111;
+
+ if (o0.as<Vec>().hasElementIndex()) {
+ // Special case.
+ if (!x || !o0.as<Vec>().isVecD2() || o0.as<Vec>().elementIndex() != 1)
+ goto InvalidInstruction;
+ type = 0b10;
+ rModeOp = 0b01111;
+ }
+ else {
+ // Must be scalar.
+ if (sz > 2)
+ goto InvalidInstruction;
+
+ if (o0.as<Vec>().hasElementType())
+ goto InvalidInstruction;
+
+ if (o0.as<Vec>().isVecS() && x)
+ goto InvalidInstruction;
+
+ if (o0.as<Vec>().isVecD() && !x)
+ goto InvalidInstruction;
+ }
+
+ opcode.addImm(x, 31);
+ opcode.addImm(type, 22);
+ opcode.addImm(rModeOp, 16);
+ goto EmitOp_Rd0_Rn5;
+ }
+
+ if (checkSignature(o0, o1)) {
+ uint32_t sz = diff(o0.as<Reg>().type(), RegType::kARM_VecH);
+ if (sz > 2)
+ goto InvalidInstruction;
+
+ if (o0.as<Vec>().hasElementType())
+ goto InvalidInstruction;
+
+ uint32_t type = (sz - 1) & 0x3;
+ opcode.reset(0b00011110001000000100000000000000);
+ opcode.addImm(type, 22);
+ goto EmitOp_Rd0_Rn5;
+ }
+ }
+
+ if (isign4 == ENC_OPS2(Reg, Imm)) {
+ if (o0.as<Reg>().isVec()) {
+ double fpValue;
+ if (o1.as<Imm>().isDouble())
+ fpValue = o1.as<Imm>().valueAs<double>();
+ else if (o1.as<Imm>().isInt32())
+ fpValue = o1.as<Imm>().valueAs<int32_t>();
+ else
+ goto InvalidImmediate;
+
+ if (!Utils::isFP64Imm8(fpValue))
+ goto InvalidImmediate;
+
+ uint32_t imm8 = Utils::encodeFP64ToImm8(fpValue);
+ if (!o0.as<Vec>().hasElementType()) {
+ // FMOV (scalar, immediate).
+ uint32_t sz = diff(o0.as<Reg>().type(), RegType::kARM_VecH);
+ uint32_t type = (sz - 1u) & 0x3u;
+
+ if (sz > 2)
+ goto InvalidInstruction;
+
+ opcode.reset(0b00011110001000000001000000000000);
+ opcode.addImm(type, 22);
+ opcode.addImm(imm8, 13);
+ goto EmitOp_Rd0;
+ }
+ else {
+ uint32_t q = diff(o0.as<Vec>().type(), RegType::kARM_VecD);
+ uint32_t sz = o0.as<Vec>().elementType() - Vec::kElementTypeH;
+
+ if (q > 1 || sz > 2)
+ goto InvalidInstruction;
+
+ static const uint32_t szBits[3] = { B(11), B(0), B(29) };
+ opcode.reset(0b00001111000000001111010000000000);
+ opcode ^= szBits[sz];
+ opcode.addImm(q, 30);
+ opcode.addImm(imm8 >> 5, 16);
+ opcode.addImm(imm8 & 31, 5);
+ goto EmitOp_Rd0;
+ }
+ }
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingFSimdPair: {
+ const InstDB::EncodingData::FSimdPair& opData = InstDB::EncodingData::fSimdPair[encodingIndex];
+
+ if (isign4 == ENC_OPS2(Reg, Reg)) {
+ // This operation is only defined for:
+ // hD, vS.2h (16-bit)
+ // sD, vS.2s (32-bit)
+ // dD, vS.2d (64-bit)
+ uint32_t sz = diff(o0.as<Reg>().type(), RegType::kARM_VecH);
+ if (sz > 2)
+ goto InvalidInstruction;
+
+ static const uint32_t szSignatures[3] = {
+ VecS::kSignature | (Vec::kSignatureElementH),
+ VecD::kSignature | (Vec::kSignatureElementS),
+ VecV::kSignature | (Vec::kSignatureElementD)
+ };
+
+ if (o1.signature() != szSignatures[sz])
+ goto InvalidInstruction;
+
+ static const uint32_t szBits[] = { B(29), 0, B(22) };
+ opcode.reset(opData.scalarOp());
+ opcode ^= szBits[sz];
+ goto EmitOp_Rd0_Rn5;
+ }
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Reg)) {
+ if (!checkSignature(o0, o1, o2))
+ goto InvalidInstruction;
+
+ uint32_t q = diff(o0.as<Reg>().type(), RegType::kARM_VecD);
+ if (q > 1)
+ goto InvalidInstruction;
+
+ uint32_t sz = o0.as<Vec>().elementType() - Vec::kElementTypeH;
+ if (sz > 2)
+ goto InvalidInstruction;
+
+ static const uint32_t szBits[3] = { B(22) | B(21) | B(15) | B(14), 0, B(22) };
+ opcode.reset(opData.vectorOp());
+ opcode ^= szBits[sz];
+ opcode.addImm(q, 30);
+ goto EmitOp_Rd0_Rn5_Rm16;
+ }
+
+ break;
+ }
+
+ // ------------------------------------------------------------------------
+ // [ISimd - Instructions]
+ // ------------------------------------------------------------------------
+
+ case InstDB::kEncodingISimdSV: {
+ const InstDB::EncodingData::ISimdSV& opData = InstDB::EncodingData::iSimdSV[encodingIndex];
+
+ 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)
+ goto InvalidInstruction;
+
+ SizeOp sizeOp = armElementTypeToSizeOp(opData.vecOpType, o1.as<Reg>().type(), o1.as<Vec>().elementType());
+ if (!sizeOp.isValid())
+ goto InvalidInstruction;
+
+ opcode.reset(opData.opcode());
+ opcode.addImm(sizeOp.q(), 30);
+ opcode.addImm(sizeOp.size(), 22);
+ goto EmitOp_Rd0_Rn5;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingISimdVV: {
+ const InstDB::EncodingData::ISimdVV& opData = InstDB::EncodingData::iSimdVV[encodingIndex];
+
+ if (isign4 == ENC_OPS2(Reg, Reg)) {
+ const Operand_& sop = significantSimdOp(o0, o1, instFlags);
+ if (!matchSignature(o0, o1, instFlags))
+ goto InvalidInstruction;
+
+ SizeOp sizeOp = armElementTypeToSizeOp(opData.vecOpType, sop.as<Reg>().type(), sop.as<Vec>().elementType());
+ if (!sizeOp.isValid())
+ goto InvalidInstruction;
+
+ opcode.reset(opData.opcode());
+ opcode.addImm(sizeOp.qs(), 30);
+ opcode.addImm(sizeOp.scalar(), 28);
+ opcode.addImm(sizeOp.size(), 22);
+ goto EmitOp_Rd0_Rn5;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingISimdVVx: {
+ const InstDB::EncodingData::ISimdVVx& opData = InstDB::EncodingData::iSimdVVx[encodingIndex];
+
+ if (isign4 == ENC_OPS2(Reg, Reg)) {
+ if (o0.signature() != opData.op0Signature ||
+ o1.signature() != opData.op1Signature)
+ goto InvalidInstruction;
+
+ opcode.reset(opData.opcode());
+ goto EmitOp_Rd0_Rn5;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingISimdVVV: {
+ const InstDB::EncodingData::ISimdVVV& opData = InstDB::EncodingData::iSimdVVV[encodingIndex];
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Reg)) {
+ const Operand_& sop = significantSimdOp(o0, o1, instFlags);
+ if (!matchSignature(o0, o1, o2, instFlags))
+ goto InvalidInstruction;
+
+ SizeOp sizeOp = armElementTypeToSizeOp(opData.vecOpType, sop.as<Reg>().type(), sop.as<Vec>().elementType());
+ if (!sizeOp.isValid())
+ goto InvalidInstruction;
+
+ opcode.reset(opData.opcode());
+ opcode.addImm(sizeOp.qs(), 30);
+ opcode.addImm(sizeOp.scalar(), 28);
+ opcode.addImm(sizeOp.size(), 22);
+ goto EmitOp_Rd0_Rn5_Rm16;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingISimdVVVx: {
+ const InstDB::EncodingData::ISimdVVVx& opData = InstDB::EncodingData::iSimdVVVx[encodingIndex];
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Reg)) {
+ if (o0.signature() != opData.op0Signature ||
+ o1.signature() != opData.op1Signature ||
+ o2.signature() != opData.op2Signature)
+ goto InvalidInstruction;
+
+ opcode.reset(opData.opcode());
+ goto EmitOp_Rd0_Rn5_Rm16;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingISimdWWV: {
+ // Special case for wide add/sub [s|b][add|sub][w]{2}.
+ const InstDB::EncodingData::ISimdWWV& opData = InstDB::EncodingData::iSimdWWV[encodingIndex];
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Reg)) {
+ SizeOp sizeOp = armElementTypeToSizeOp(opData.vecOpType, o2.as<Reg>().type(), o2.as<Vec>().elementType());
+ if (!sizeOp.isValid())
+ goto InvalidInstruction;
+
+ if (!checkSignature(o0, o1) || !o0.as<Reg>().isVecV() || o0.as<Vec>().elementType() != o2.as<Vec>().elementType() + 1)
+ goto InvalidInstruction;
+
+ opcode.reset(opData.opcode());
+ opcode.addImm(sizeOp.qs(), 30);
+ opcode.addImm(sizeOp.scalar(), 28);
+ opcode.addImm(sizeOp.size(), 22);
+ goto EmitOp_Rd0_Rn5_Rm16;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingISimdVVVe: {
+ const InstDB::EncodingData::ISimdVVVe& opData = InstDB::EncodingData::iSimdVVVe[encodingIndex];
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Reg)) {
+ const Operand_& sop = significantSimdOp(o0, o1, instFlags);
+ if (!matchSignature(o0, o1, instFlags))
+ goto InvalidInstruction;
+
+ if (!o2.as<Vec>().hasElementIndex()) {
+ SizeOp sizeOp = armElementTypeToSizeOp(opData.regularVecType, sop.as<Reg>().type(), sop.as<Vec>().elementType());
+ if (!sizeOp.isValid())
+ goto InvalidInstruction;
+
+ if (!checkSignature(o1, o2))
+ goto InvalidInstruction;
+
+ opcode.reset(uint32_t(opData.regularOp) << 10);
+ opcode.addImm(sizeOp.qs(), 30);
+ opcode.addImm(sizeOp.scalar(), 28);
+ opcode.addImm(sizeOp.size(), 22);
+ goto EmitOp_Rd0_Rn5_Rm16;
+ }
+ else {
+ SizeOp sizeOp = armElementTypeToSizeOp(opData.elementVecType, sop.as<Reg>().type(), sop.as<Vec>().elementType());
+ if (!sizeOp.isValid())
+ goto InvalidInstruction;
+
+ uint32_t elementIndex = o2.as<Vec>().elementIndex();
+ LMHImm lmh;
+
+ if (!encodeLMH(sizeOp.size(), elementIndex, &lmh))
+ goto InvalidElementIndex;
+
+ if (o2.as<Reg>().id() > lmh.maxRmId)
+ goto InvalidPhysId;
+
+ opcode.reset(uint32_t(opData.elementOp) << 10);
+ opcode.addImm(sizeOp.q(), 30);
+ opcode.addImm(sizeOp.size(), 22);
+ opcode.addImm(lmh.lm, 20);
+ opcode.addImm(lmh.h, 11);
+ goto EmitOp_Rd0_Rn5_Rm16;
+ }
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingISimdVVVI: {
+ const InstDB::EncodingData::ISimdVVVI& opData = InstDB::EncodingData::iSimdVVVI[encodingIndex];
+
+ if (isign4 == ENC_OPS4(Reg, Reg, Reg, Imm)) {
+ const Operand_& sop = significantSimdOp(o0, o1, instFlags);
+ if (!matchSignature(o0, o1, o2, instFlags))
+ goto InvalidInstruction;
+
+ SizeOp sizeOp = armElementTypeToSizeOp(opData.vecOpType, sop.as<Reg>().type(), sop.as<Vec>().elementType());
+ if (!sizeOp.isValid())
+ goto InvalidInstruction;
+
+ uint64_t immValue = o3.as<Imm>().valueAs<uint64_t>();
+ uint32_t immSize = opData.immSize;
+
+ if (opData.imm64HasOneBitLess && !sizeOp.q())
+ immSize--;
+
+ uint32_t immMax = 1u << immSize;
+ if (immValue >= immMax)
+ goto InvalidImmediate;
+
+ opcode.reset(opData.opcode());
+ opcode.addImm(sizeOp.qs(), 30);
+ opcode.addImm(sizeOp.scalar(), 28);
+ opcode.addImm(sizeOp.size(), 22);
+ opcode.addImm(immValue, opData.immShift);
+ goto EmitOp_Rd0_Rn5_Rm16;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingISimdVVVV: {
+ const InstDB::EncodingData::ISimdVVVV& opData = InstDB::EncodingData::iSimdVVVV[encodingIndex];
+
+ if (isign4 == ENC_OPS4(Reg, Reg, Reg, Reg)) {
+ const Operand_& sop = significantSimdOp(o0, o1, instFlags);
+ if (!matchSignature(o0, o1, o2, o3, instFlags))
+ goto InvalidInstruction;
+
+ SizeOp sizeOp = armElementTypeToSizeOp(opData.vecOpType, sop.as<Reg>().type(), sop.as<Vec>().elementType());
+ if (!sizeOp.isValid())
+ goto InvalidInstruction;
+
+ opcode.reset(uint32_t(opData.opcode) << 10);
+ opcode.addImm(sizeOp.qs(), 30);
+ opcode.addImm(sizeOp.scalar(), 28);
+ opcode.addImm(sizeOp.size(), 22);
+ goto EmitOp_Rd0_Rn5_Rm16_Ra10;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingISimdVVVVx: {
+ const InstDB::EncodingData::ISimdVVVVx& opData = InstDB::EncodingData::iSimdVVVVx[encodingIndex];
+
+ if (isign4 == ENC_OPS4(Reg, Reg, Reg, Reg)) {
+ if (o0.signature() != opData.op0Signature ||
+ o1.signature() != opData.op1Signature ||
+ o2.signature() != opData.op2Signature ||
+ o3.signature() != opData.op3Signature)
+ goto InvalidInstruction;
+
+ opcode.reset(uint32_t(opData.opcode) << 10);
+ goto EmitOp_Rd0_Rn5_Rm16_Ra10;
+ }
+
+ break;
+ }
+
+
+ case InstDB::kEncodingISimdPair: {
+ const InstDB::EncodingData::ISimdPair& opData = InstDB::EncodingData::iSimdPair[encodingIndex];
+
+ if (isign4 == ENC_OPS2(Reg, Reg) && opData.opcode2) {
+ if (o0.as<Vec>().isVecD1() && o1.as<Vec>().isVecD2()) {
+ opcode.reset(uint32_t(opData.opcode2) << 10);
+ opcode.addImm(0x3, 22); // size.
+ goto EmitOp_Rd0_Rn5;
+ }
+ }
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Reg)) {
+ if (!matchSignature(o0, o1, o2, instFlags))
+ goto InvalidInstruction;
+
+ SizeOp sizeOp = armElementTypeToSizeOp(opData.opType3, o0.as<Reg>().type(), o0.as<Vec>().elementType());
+ if (!sizeOp.isValid())
+ goto InvalidInstruction;
+
+ opcode.reset(uint32_t(opData.opcode3) << 10);
+ opcode.addImm(sizeOp.qs(), 30);
+ opcode.addImm(sizeOp.scalar(), 28);
+ opcode.addImm(sizeOp.size(), 22);
+ goto EmitOp_Rd0_Rn5_Rm16;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdBicOrr: {
+ const InstDB::EncodingData::SimdBicOrr& opData = InstDB::EncodingData::simdBicOrr[encodingIndex];
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Reg)) {
+ if (!matchSignature(o0, o1, o2, instFlags))
+ goto InvalidInstruction;
+
+ SizeOp sizeOp = armElementTypeToSizeOp(InstDB::kVO_V_B, o0.as<Reg>().type(), o0.as<Vec>().elementType());
+ if (!sizeOp.isValid())
+ goto InvalidInstruction;
+
+ opcode.reset(uint32_t(opData.registerOp) << 10);
+ opcode.addImm(sizeOp.q(), 30);
+ goto EmitOp_Rd0_Rn5_Rm16;
+ }
+
+ if (isign4 == ENC_OPS2(Reg, Imm) || isign4 == ENC_OPS3(Reg, Imm, Imm)) {
+ SizeOp sizeOp = armElementTypeToSizeOp(InstDB::kVO_V_HS, o0.as<Reg>().type(), o0.as<Vec>().elementType());
+ if (!sizeOp.isValid())
+ goto InvalidInstruction;
+
+ if (o1.as<Imm>().valueAs<uint64_t>() > 0xFFFFFFFFu)
+ goto InvalidImmediate;
+
+ uint32_t imm = o1.as<Imm>().valueAs<uint32_t>();
+ uint32_t shift = 0;
+ uint32_t maxShift = (8u << sizeOp.size()) - 8u;
+
+ if (o2.isImm()) {
+ if (o2.as<Imm>().predicate() != uint32_t(ShiftOp::kLSL))
+ goto InvalidImmediate;
+
+ if (imm > 0xFFu || o2.as<Imm>().valueAs<uint64_t>() > maxShift)
+ goto InvalidImmediate;
+
+ shift = o2.as<Imm>().valueAs<uint32_t>();
+ if ((shift & 0x7u) != 0u)
+ goto InvalidImmediate;
+ }
+ else if (imm) {
+ shift = Support::ctz(imm) & 0x7u;
+ imm >>= shift;
+
+ if (imm > 0xFFu || shift > maxShift)
+ goto InvalidImmediate;
+ }
+
+ uint32_t cmode = 0x1u | ((shift / 8u) << 1);
+ if (sizeOp.size() == 1)
+ cmode |= B(3);
+
+ // The immediate value is split into ABC and DEFGH parts.
+ uint32_t abc = (imm >> 5) & 0x7u;
+ uint32_t defgh = imm & 0x1Fu;
+
+ opcode.reset(uint32_t(opData.immediateOp) << 10);
+ opcode.addImm(sizeOp.q(), 30);
+ opcode.addImm(abc, 16);
+ opcode.addImm(cmode, 12);
+ opcode.addImm(defgh, 5);
+ goto EmitOp_Rd0;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdCmp: {
+ const InstDB::EncodingData::SimdCmp& opData = InstDB::EncodingData::simdCmp[encodingIndex];
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Reg) && opData.regOp) {
+ if (!matchSignature(o0, o1, o2, instFlags))
+ goto InvalidInstruction;
+
+ SizeOp sizeOp = armElementTypeToSizeOp(opData.vecOpType, o0.as<Reg>().type(), o0.as<Vec>().elementType());
+ if (!sizeOp.isValid())
+ goto InvalidInstruction;
+
+ opcode.reset(uint32_t(opData.regOp) << 10);
+ opcode.addImm(sizeOp.qs(), 30);
+ opcode.addImm(sizeOp.scalar(), 28);
+ opcode.addImm(sizeOp.size(), 22);
+ goto EmitOp_Rd0_Rn5_Rm16;
+ }
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Imm) && opData.zeroOp) {
+ if (!matchSignature(o0, o1, instFlags))
+ goto InvalidInstruction;
+
+ if (o2.as<Imm>().value() != 0)
+ goto InvalidImmediate;
+
+ SizeOp sizeOp = armElementTypeToSizeOp(opData.vecOpType, o0.as<Reg>().type(), o0.as<Vec>().elementType());
+ if (!sizeOp.isValid())
+ goto InvalidInstruction;
+
+ opcode.reset(uint32_t(opData.zeroOp) << 10);
+ opcode.addImm(sizeOp.qs(), 30);
+ opcode.addImm(sizeOp.scalar(), 28);
+ opcode.addImm(sizeOp.size(), 22);
+ goto EmitOp_Rd0_Rn5;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdDot: {
+ const InstDB::EncodingData::SimdDot& opData = InstDB::EncodingData::simdDot[encodingIndex];
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Reg)) {
+ uint32_t q = diff(o0.as<Reg>().type(), RegType::kARM_VecD);
+ uint32_t size = 2;
+
+ if (q > 1u)
+ goto InvalidInstruction;
+
+ if (!o2.as<Vec>().hasElementIndex()) {
+ if (!opData.vectorOp)
+ goto InvalidInstruction;
+
+ 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)
+ goto InvalidInstruction;
+
+ opcode.reset(uint32_t(opData.vectorOp) << 10);
+ opcode.addImm(q, 30);
+ goto EmitOp_Rd0_Rn5_Rm16;
+ }
+ else {
+ if (!opData.elementOp)
+ goto InvalidInstruction;
+
+ 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)
+ goto InvalidInstruction;
+
+ uint32_t elementIndex = o2.as<Vec>().elementIndex();
+ LMHImm lmh;
+
+ if (!encodeLMH(size, elementIndex, &lmh))
+ goto InvalidElementIndex;
+
+ if (o2.as<Reg>().id() > lmh.maxRmId)
+ goto InvalidPhysId;
+
+ opcode.reset(uint32_t(opData.elementOp) << 10);
+ opcode.addImm(q, 30);
+ opcode.addImm(lmh.lm, 20);
+ opcode.addImm(lmh.h, 11);
+ goto EmitOp_Rd0_Rn5_Rm16;
+ }
+ }
+
+ break;
+ }
+
+ 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 q = diff(o0.as<Reg>().type(), RegType::kARM_VecD);
+
+ if (o1.as<Reg>().isGp()) {
+ // DUP - Vec (scalar|vector) <- GP register.
+ //
+ // 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();
+ if (q > 1 || !Support::bitTest(kValidEncodings, (q << 3) | elementType))
+ goto InvalidInstruction;
+
+ uint32_t lsbIndex = elementType - 1u;
+ uint32_t imm5 = 1u << lsbIndex;
+
+ opcode.reset(0b0000111000000000000011 << 10);
+ opcode.addImm(q, 30);
+ opcode.addImm(imm5, 16);
+ goto EmitOp_Rd0_Rn5;
+ }
+
+ if (!o1.as<Reg>().isVec() || !o1.as<Vec>().hasElementIndex())
+ goto InvalidInstruction;
+
+ uint32_t dstIndex = o1.as<Vec>().elementIndex();
+ if (!o0.as<Vec>().hasElementType()) {
+ // 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)
+ goto InvalidInstruction;
+
+ uint32_t imm5 = ((dstIndex << 1) | 1u) << lsbIndex;
+ if (imm5 > 31)
+ goto InvalidElementIndex;
+
+ opcode.reset(0b0101111000000000000001 << 10);
+ opcode.addImm(imm5, 16);
+ goto EmitOp_Rd0_Rn5;
+ }
+ else {
+ // DUP - Vec (all) <- Vec[N].
+ uint32_t elementType = o0.as<Vec>().elementType();
+ if (q > 1 || !Support::bitTest(kValidEncodings, (q << 3) | elementType))
+ goto InvalidInstruction;
+
+ uint32_t lsbIndex = elementType - 1u;
+ uint32_t imm5 = ((dstIndex << 1) | 1u) << lsbIndex;
+
+ if (imm5 > 31)
+ goto InvalidElementIndex;
+
+ opcode.reset(0b0000111000000000000001 << 10);
+ opcode.addImm(q, 30);
+ opcode.addImm(imm5, 16);
+ goto EmitOp_Rd0_Rn5;
+ }
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdIns: SimdIns: {
+ if (isign4 == ENC_OPS2(Reg, Reg) && o0.as<Reg>().isVecV()) {
+ if (!o0.as<Vec>().hasElementIndex())
+ goto InvalidInstruction;
+
+ uint32_t elementType = o0.as<Vec>().elementType();
+ uint32_t dstIndex = o0.as<Vec>().elementIndex();
+ uint32_t lsbIndex = elementType - 1u;
+
+ uint32_t imm5 = ((dstIndex << 1) | 1u) << lsbIndex;
+ if (imm5 > 31)
+ goto InvalidElementIndex;
+
+ if (o1.as<Reg>().isGp()) {
+ // INS - Vec[N] <- GP register.
+ opcode.reset(0b0100111000000000000111 << 10);
+ opcode.addImm(imm5, 16);
+ goto EmitOp_Rd0_Rn5;
+ }
+ else if (o1.as<Reg>().isVecV() && o1.as<Vec>().hasElementIndex()) {
+ // INS - Vec[N] <- Vec[M].
+ if (o0.as<Vec>().elementType() != o1.as<Vec>().elementType())
+ goto InvalidInstruction;
+
+ uint32_t srcIndex = o1.as<Vec>().elementIndex();
+ if (o0.as<Reg>().type() != o1.as<Reg>().type())
+ goto InvalidInstruction;
+
+ uint32_t imm4 = srcIndex << lsbIndex;
+ if (imm4 > 15)
+ goto InvalidElementIndex;
+
+ opcode.reset(0b0110111000000000000001 << 10);
+ opcode.addImm(imm5, 16);
+ opcode.addImm(imm4, 11);
+ goto EmitOp_Rd0_Rn5;
+ }
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdMov: {
+ if (isign4 == ENC_OPS2(Reg, Reg)) {
+ if (o0.as<Reg>().isVec() && o1.as<Reg>().isVec()) {
+ // INS v.x[index], v.x[index].
+ if (o0.as<Vec>().hasElementIndex() && o1.as<Vec>().hasElementIndex())
+ goto SimdIns;
+
+ // DUP {b|h|s|d}, v.{b|h|s|d}[index].
+ if (o1.as<Vec>().hasElementIndex())
+ goto SimdDup;
+
+ if (!checkSignature(o0, o1))
+ goto InvalidInstruction;
+
+ // ORR Vd, Vn, Vm
+ uint32_t q = diff(o0.as<Reg>().type(), RegType::kARM_VecD);
+ if (q > 1)
+ goto InvalidInstruction;
+
+ opcode.reset(0b0000111010100000000111 << 10);
+ opcode.addImm(q, 30);
+ opcode.addReg(o1, 16); // Vn == Vm.
+ goto EmitOp_Rd0_Rn5;
+ }
+
+ if (o0.as<Reg>().isVec() && o1.as<Reg>().isGp()) {
+ // INS v.x[index], Rn.
+ if (o0.as<Vec>().hasElementIndex())
+ goto SimdIns;
+
+ goto InvalidInstruction;
+ }
+
+ if (o0.as<Reg>().isGp() && o1.as<Reg>().isVec()) {
+ // UMOV Rd, V.{s|d}[index].
+ encodingIndex = 1;
+ goto SimdUmov;
+ }
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdMoviMvni: {
+ const InstDB::EncodingData::SimdMoviMvni& opData = InstDB::EncodingData::simdMoviMvni[encodingIndex];
+
+ if (isign4 == ENC_OPS2(Reg, Imm) || isign4 == ENC_OPS3(Reg, Imm, Imm)) {
+ SizeOp sizeOp = armElementTypeToSizeOp(InstDB::kVO_V_Any, o0.as<Reg>().type(), o0.as<Vec>().elementType());
+ if (!sizeOp.isValid())
+ goto InvalidInstruction;
+
+ uint64_t imm64 = o1.as<Imm>().valueAs<uint64_t>();
+ uint32_t imm8 = 0;
+ uint32_t cmode = 0;
+ uint32_t inverted = opData.inverted;
+ uint32_t op = 0;
+ uint32_t shift = 0;
+ uint32_t shiftOp = uint32_t(ShiftOp::kLSL);
+
+ if (sizeOp.size() == 3u) {
+ // The second immediate should not be present, however, we accept
+ // an immediate value of zero as some user code may still pass it.
+ if (o2.isImm() && o0.as<Imm>().value() != 0)
+ goto InvalidImmediate;
+
+ if (Utils::isByteMaskImm8(imm64)) {
+ imm8 = encodeImm64ByteMaskToImm8(imm64);
+ }
+ else {
+ // Change from D to S and from 64-bit imm to 32-bit imm if this
+ // is not a byte-mask pattern.
+ if ((imm64 >> 32) == (imm64 & 0xFFFFFFFFu)) {
+ imm64 &= 0xFFFFFFFFu;
+ sizeOp.decrementSize();
+ }
+ else {
+ goto InvalidImmediate;
+ }
+ }
+ }
+
+ if (sizeOp.size() < 3u) {
+ if (imm64 > 0xFFFFFFFFu)
+ goto InvalidImmediate;
+ imm8 = uint32_t(imm64);
+
+ if (sizeOp.size() == 2) {
+ if ((imm8 >> 16) == (imm8 & 0xFFFFu)) {
+ imm8 >>= 16;
+ sizeOp.decrementSize();
+ }
+ }
+
+ if (sizeOp.size() == 1) {
+ if (imm8 > 0xFFFFu)
+ goto InvalidImmediate;
+
+ if ((imm8 >> 8) == (imm8 & 0xFFu)) {
+ imm8 >>= 8;
+ sizeOp.decrementSize();
+ }
+ }
+
+ uint32_t maxShift = (8u << sizeOp.size()) - 8u;
+ if (o2.isImm()) {
+ if (imm8 > 0xFFu || o2.as<Imm>().valueAs<uint64_t>() > maxShift)
+ goto InvalidImmediate;
+
+ shift = o2.as<Imm>().valueAs<uint32_t>();
+ shiftOp = o2.as<Imm>().predicate();
+ }
+ else if (imm8) {
+ shift = Support::ctz(imm8) & ~0x7u;
+ imm8 >>= shift;
+
+ if (imm8 > 0xFFu || shift > maxShift)
+ goto InvalidImmediate;
+ }
+
+ if ((shift & 0x7u) != 0u)
+ goto InvalidImmediate;
+ }
+
+ shift /= 8u;
+
+ switch (sizeOp.size()) {
+ case 0:
+ if (shiftOp != uint32_t(ShiftOp::kLSL))
+ goto InvalidImmediate;
+
+ if (inverted) {
+ imm8 = ~imm8 & 0xFFu;
+ inverted = 0;
+ }
+
+ cmode = B(3) | B(2) | B(1);
+ break;
+
+ case 1:
+ if (shiftOp != uint32_t(ShiftOp::kLSL))
+ goto InvalidImmediate;
+
+ cmode = B(3) | (shift << 1);
+ op = inverted;
+ break;
+
+ case 2:
+ if (shiftOp == uint32_t(ShiftOp::kLSL)) {
+ cmode = shift << 1;
+ }
+ else if (shiftOp == uint32_t(ShiftOp::kMSL)) {
+ if (shift == 0 || shift > 2)
+ goto InvalidImmediate;
+ cmode = B(3) | B(2) | (shift - 1u);
+ }
+ else {
+ goto InvalidImmediate;
+ }
+
+ op = inverted;
+ break;
+
+ case 3:
+ if (inverted) {
+ imm8 = ~imm8 & 0xFFu;
+ inverted = 0;
+ }
+
+ op = 1;
+ cmode = B(3) | B(2) | B(1);
+ break;
+ }
+
+ // The immediate value is split into ABC and DEFGH parts.
+ uint32_t abc = (imm8 >> 5) & 0x7u;
+ uint32_t defgh = imm8 & 0x1Fu;
+
+ opcode.reset(uint32_t(opData.opcode) << 10);
+ opcode.addImm(sizeOp.q(), 30);
+ opcode.addImm(op, 29);
+ opcode.addImm(abc, 16);
+ opcode.addImm(cmode, 12);
+ opcode.addImm(defgh, 5);
+ goto EmitOp_Rd0;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdShift: {
+ const InstDB::EncodingData::SimdShift& opData = InstDB::EncodingData::simdShift[encodingIndex];
+
+ const Operand_& sop = significantSimdOp(o0, o1, instFlags);
+ SizeOp sizeOp = armElementTypeToSizeOp(opData.vecOpType, sop.as<Reg>().type(), sop.as<Vec>().elementType());
+
+ if (!sizeOp.isValid())
+ goto InvalidInstruction;
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Imm) && opData.immediateOp) {
+ if (!matchSignature(o0, o1, instFlags))
+ goto InvalidInstruction;
+
+ if (o2.as<Imm>().valueAs<uint64_t>() > 63)
+ goto InvalidImmediate;
+
+ uint32_t lsbShift = sizeOp.size() + 3u;
+ uint32_t lsbMask = (1u << lsbShift) - 1u;
+ uint32_t imm = o2.as<Imm>().valueAs<uint32_t>();
+
+ // Some instructions use IMM and some X - IMM, so negate if required.
+ if (opData.invertedImm) {
+ if (imm == 0 || imm > (1u << lsbShift))
+ goto InvalidImmediate;
+ imm = Support::neg(imm) & lsbMask;
+ }
+
+ if (imm > lsbMask)
+ goto InvalidImmediate;
+ imm |= (1u << lsbShift);
+
+ opcode.reset(uint32_t(opData.immediateOp) << 10);
+ opcode.addImm(sizeOp.qs(), 30);
+ opcode.addImm(sizeOp.scalar(), 28);
+ opcode.addImm(imm, 16);
+ goto EmitOp_Rd0_Rn5;
+ }
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Reg) && opData.registerOp) {
+ if (!matchSignature(o0, o1, o2, instFlags))
+ goto InvalidInstruction;
+
+ opcode.reset(uint32_t(opData.registerOp) << 10);
+ opcode.addImm(sizeOp.qs(), 30);
+ opcode.addImm(sizeOp.scalar(), 28);
+ opcode.addImm(sizeOp.size(), 22);
+ goto EmitOp_Rd0_Rn5_Rm16;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdShiftES: {
+ const InstDB::EncodingData::SimdShiftES& opData = InstDB::EncodingData::simdShiftES[encodingIndex];
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Imm)) {
+ SizeOp sizeOp = armElementTypeToSizeOp(opData.vecOpType, o1.as<Reg>().type(), o1.as<Vec>().elementType());
+ if (!sizeOp.isValid())
+ goto InvalidInstruction;
+
+ if (!matchSignature(o0, o1, instFlags))
+ goto InvalidInstruction;
+
+ // The immediate value must match the element size.
+ uint64_t shift = o2.as<Imm>().valueAs<uint64_t>();
+ uint32_t shiftOp = o2.as<Imm>().predicate();
+
+ if (shift != (8u << sizeOp.size()) || shiftOp != uint32_t(ShiftOp::kLSL))
+ goto InvalidImmediate;
+
+ opcode.reset(uint32_t(opData.opcode) << 10);
+ opcode.addImm(sizeOp.q(), 30);
+ opcode.addImm(sizeOp.size(), 22);
+ goto EmitOp_Rd0_Rn5;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdSm3tt: {
+ const InstDB::EncodingData::SimdSm3tt& opData = InstDB::EncodingData::simdSm3tt[encodingIndex];
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Reg)) {
+ if (o0.as<Vec>().isVecS4() && o1.as<Vec>().isVecS4() && o2.as<Vec>().isVecS4() && o2.as<Vec>().hasElementIndex()) {
+ uint32_t imm2 = o2.as<Vec>().elementIndex();
+ if (imm2 > 3)
+ goto InvalidElementIndex;
+
+ opcode.reset(uint32_t(opData.opcode) << 10);
+ opcode.addImm(imm2, 12);
+ goto EmitOp_Rd0_Rn5_Rm16;
+ }
+ }
+
+ break;
+ }
+
+
+ case InstDB::kEncodingSimdSmovUmov: SimdUmov: {
+ const InstDB::EncodingData::SimdSmovUmov& opData = InstDB::EncodingData::simdSmovUmov[encodingIndex];
+
+ if (isign4 == ENC_OPS2(Reg, Reg) && o0.as<Reg>().isGp() && o1.as<Reg>().isVec()) {
+ SizeOp sizeOp = armElementTypeToSizeOp(opData.vecOpType, o1.as<Reg>().type(), o1.as<Vec>().elementType());
+ if (!sizeOp.isValid())
+ goto InvalidInstruction;
+
+ if (!o1.as<Vec>().hasElementIndex())
+ goto InvalidInstruction;
+
+ uint32_t x = o0.as<Gp>().isGpX();
+ uint32_t gpMustBeX = uint32_t(sizeOp.size() >= 3u - opData.isSigned);
+
+ if (opData.isSigned) {
+ if (gpMustBeX && !x)
+ goto InvalidInstruction;
+ }
+ else {
+ if (x != gpMustBeX)
+ goto InvalidInstruction;
+ }
+
+ uint32_t elementIndex = o1.as<Vec>().elementIndex();
+ uint32_t maxElementIndex = 15u >> sizeOp.size();
+
+ if (elementIndex > maxElementIndex)
+ goto InvalidElementIndex;
+
+ uint32_t imm5 = (1u | (elementIndex << 1)) << sizeOp.size();
+
+ opcode.reset(uint32_t(opData.opcode) << 10);
+ opcode.addImm(x, 30);
+ opcode.addImm(imm5, 16);
+ goto EmitOp_Rd0_Rn5;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdSxtlUxtl: {
+ const InstDB::EncodingData::SimdSxtlUxtl& opData = InstDB::EncodingData::simdSxtlUxtl[encodingIndex];
+
+ if (isign4 == ENC_OPS2(Reg, Reg)) {
+ SizeOp sizeOp = armElementTypeToSizeOp(opData.vecOpType, o1.as<Reg>().type(), o1.as<Vec>().elementType());
+ if (!sizeOp.isValid())
+ goto InvalidInstruction;
+
+ if (!matchSignature(o0, o1, instFlags))
+ goto InvalidInstruction;
+
+ opcode.reset(uint32_t(opData.opcode) << 10);
+ opcode.addImm(sizeOp.q(), 30);
+ opcode.addImm(1u, sizeOp.size() + 19);
+ goto EmitOp_Rd0_Rn5;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdTblTbx: {
+ const InstDB::EncodingData::SimdTblTbx& opData = InstDB::EncodingData::simdTblTbx[encodingIndex];
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Reg) || isign4 == ENC_OPS4(Reg, Reg, Reg, Reg)) {
+ // TBL/TBX <Vd>.<Ta>, { <Vn>.16B }, <Vm>.<Ta>
+ // TBL/TBX <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B }, <Vm>.<Ta>
+ // TBL/TBX <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B, <Vn+2>.16B }, <Vm>.<Ta>
+ // TBL/TBX <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B, <Vn+2>.16B, <Vn+3>.16B }, <Vm>.<Ta>
+ opcode.reset(uint32_t(opData.opcode) << 10);
+
+ const Operand_& o4 = opExt[EmitterUtils::kOp4];
+ const Operand_& o5 = opExt[EmitterUtils::kOp5];
+
+ uint32_t q = diff(o0.as<Reg>().type(), RegType::kARM_VecD);
+ if (q > 1 || o0.as<Vec>().hasElementIndex())
+ goto InvalidInstruction;
+
+ if (!o1.as<Vec>().isVecB16() || o1.as<Vec>().hasElementIndex())
+ goto InvalidInstruction;
+
+ uint32_t len = uint32_t(!o3.isNone()) + uint32_t(!o4.isNone()) + uint32_t(!o5.isNone());
+ opcode.addImm(q, 30);
+ opcode.addImm(len, 13);
+
+ switch (len) {
+ case 0:
+ if (!checkSignature(o0, o2))
+ goto InvalidInstruction;
+
+ if (o2.id() > 31)
+ goto InvalidPhysId;
+
+ opcode.addReg(o2, 16);
+ goto EmitOp_Rd0_Rn5;
+
+ case 1:
+ if (!checkSignature(o0, o3))
+ goto InvalidInstruction;
+
+ if (o3.id() > 31)
+ goto InvalidPhysId;
+
+ opcode.addReg(o3, 16);
+ goto EmitOp_Rd0_Rn5;
+
+ case 2:
+ if (!checkSignature(o0, o4))
+ goto InvalidInstruction;
+
+ if (o4.id() > 31)
+ goto InvalidPhysId;
+
+ opcode.addReg(o4, 16);
+ goto EmitOp_Rd0_Rn5;
+
+ case 3:
+ if (!checkSignature(o0, o5))
+ goto InvalidInstruction;
+
+ if (o5.id() > 31)
+ goto InvalidPhysId;
+
+ opcode.addReg(o5, 16);
+ goto EmitOp_Rd0_Rn5;
+
+ default:
+ // Should never happen.
+ goto InvalidInstruction;
+ }
+ }
+
+ break;
+ }
+
+ // ------------------------------------------------------------------------
+ // [Simd - Load / Store]
+ // ------------------------------------------------------------------------
+
+ case InstDB::kEncodingSimdLdSt: {
+ const InstDB::EncodingData::SimdLdSt& opData = InstDB::EncodingData::simdLdSt[encodingIndex];
+
+ if (isign4 == ENC_OPS2(Reg, Mem)) {
+ const Mem& m = o1.as<Mem>();
+ rmRel = &m;
+
+ // Width | SZ | XY | XSZ
+ // -------+----------+-----------+-----
+ // 8-bit | size==00 | opc == 01 | 000
+ // 16-bit | size==01 | opc == 01 | 001
+ // 32-bit | size==10 | opc == 01 | 010
+ // 64-bit | size==11 | opc == 01 | 011
+ // 128-bit| size==00 | opc == 11 | 100
+ uint32_t xsz = diff(o0.as<Reg>().type(), RegType::kARM_VecB);
+ if (xsz > 4u || o0.as<Vec>().hasElementIndex())
+ goto InvalidRegType;
+
+ if (!checkVecId(o0))
+ goto InvalidPhysId;
+
+ if (!armCheckMemBaseIndexRel(m))
+ goto InvalidAddress;
+
+ int64_t offset = m.offset();
+ if (m.hasBaseReg()) {
+ // [Base {Offset | Index}]
+ if (m.hasIndex()) {
+ uint32_t opt = armShiftOpToLdStOptMap[m.predicate()];
+ if (opt == 0xFFu)
+ goto InvalidAddress;
+
+ uint32_t shift = m.shift();
+ uint32_t s = (shift != 0);
+
+ if (s && shift != xsz)
+ goto InvalidAddressScale;
+
+ opcode.reset(uint32_t(opData.registerOp) << 21);
+ opcode.addImm(xsz & 3u, 30);
+ opcode.addImm(xsz >> 2, 23);
+ opcode.addImm(opt, 13);
+ opcode.addImm(s, 12);
+ opcode |= B(11);
+ opcode.addReg(o0, 0);
+ goto EmitOp_MemBaseIndex_Rn5_Rm16;
+ }
+
+ // Makes it easier to work with the offset especially on 32-bit arch.
+ if (!Support::isInt32(offset))
+ goto InvalidDisplacement;
+ int32_t offset32 = int32_t(offset);
+
+ if (m.isPreOrPost()) {
+ if (!Support::isInt9(offset32))
+ goto InvalidDisplacement;
+
+ opcode.reset(uint32_t(opData.prePostOp) << 21);
+ opcode.addImm(xsz & 3u, 30);
+ opcode.addImm(xsz >> 2, 23);
+ opcode.addImm(offset32 & 0x1FF, 12);
+ opcode.addImm(m.isPreIndex(), 11);
+ opcode |= B(10);
+ opcode.addReg(o0, 0);
+ goto EmitOp_MemBase_Rn5;
+ }
+ else {
+ uint32_t imm12 = uint32_t(offset32) >> xsz;
+
+ // If this instruction is not encodable with scaled unsigned offset, try unscaled signed offset.
+ if (!Support::isUInt12(imm12) || (imm12 << xsz) != uint32_t(offset32)) {
+ instId = opData.uAltInstId;
+ instInfo = &InstDB::_instInfoTable[instId];
+ encodingIndex = instInfo->_encodingDataIndex;
+ goto Case_SimdLdurStur;
+ }
+
+ opcode.reset(uint32_t(opData.uOffsetOp) << 22);
+ opcode.addImm(xsz & 3u, 30);
+ opcode.addImm(xsz >> 2, 23);
+ opcode.addImm(imm12, 10);
+ opcode.addReg(o0, 0);
+ goto EmitOp_MemBase_Rn5;
+ }
+ }
+ else {
+ if (!opData.literalOp)
+ goto InvalidAddress;
+
+ if (xsz < 2u)
+ goto InvalidRegType;
+
+ uint32_t opc = xsz - 2u;
+ opcode.reset(uint32_t(opData.literalOp) << 24);
+ opcode.addImm(opc, 30);
+ opcode.addReg(o0, 0);
+ offsetFormat.resetToImmValue(OffsetType::kSignedOffset, 4, 5, 19, 2);
+ goto EmitOp_Rel;
+ }
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdLdpStp: {
+ const InstDB::EncodingData::SimdLdpStp& opData = InstDB::EncodingData::simdLdpStp[encodingIndex];
+
+ if (isign4 == ENC_OPS3(Reg, Reg, Mem)) {
+ const Mem& m = o2.as<Mem>();
+ rmRel = &m;
+
+ uint32_t opc = diff(o0.as<Reg>().type(), RegType::kARM_VecS);
+ if (opc > 2u || o0.as<Vec>().hasElementTypeOrIndex())
+ goto InvalidInstruction;
+
+ if (!checkSignature(o0, o1))
+ goto InvalidInstruction;
+
+ if (!checkVecId(o0, o1))
+ goto InvalidPhysId;
+
+ if (m.baseType() != RegType::kARM_GpX || m.hasIndex())
+ goto InvalidAddress;
+
+ if (m.isOffset64Bit())
+ goto InvalidDisplacement;
+
+ uint32_t offsetShift = 2u + opc;
+ int32_t offset32 = m.offsetLo32() >> offsetShift;
+
+ // Make sure we didn't lose bits by applying the mandatory offset shift.
+ if (Support::shl(offset32, offsetShift) != m.offsetLo32())
+ goto InvalidDisplacement;
+
+ // Offset is encoded as a 7-bit immediate.
+ if (!Support::isInt7(offset32))
+ goto InvalidDisplacement;
+
+ if (m.isPreOrPost() && offset32 != 0) {
+ if (!opData.prePostOp)
+ goto InvalidAddress;
+
+ opcode.reset(uint32_t(opData.prePostOp) << 22);
+ opcode.addImm(m.isPreIndex(), 24);
+ }
+ else {
+ opcode.reset(uint32_t(opData.offsetOp) << 22);
+ }
+
+ opcode.addImm(opc, 30);
+ opcode.addImm(offset32 & 0x7F, 15);
+ opcode.addReg(o1, 10);
+ opcode.addReg(o0, 0);
+ goto EmitOp_MemBase_Rn5;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdLdurStur: {
+Case_SimdLdurStur:
+ const InstDB::EncodingData::SimdLdurStur& opData = InstDB::EncodingData::simdLdurStur[encodingIndex];
+
+ if (isign4 == ENC_OPS2(Reg, Mem)) {
+ const Mem& m = o1.as<Mem>();
+ rmRel = &m;
+
+ uint32_t sz = diff(o0.as<Reg>().type(), RegType::kARM_VecB);
+ if (sz > 4 || o0.as<Vec>().hasElementTypeOrIndex())
+ goto InvalidInstruction;
+
+ if (!checkVecId(o0))
+ goto InvalidPhysId;
+
+ if (!armCheckMemBaseIndexRel(m))
+ goto InvalidAddress;
+
+ if (m.hasBaseReg() && !m.hasIndex() && !m.isPreOrPost()) {
+ if (m.isOffset64Bit())
+ goto InvalidDisplacement;
+
+ int32_t offset32 = m.offsetLo32();
+ if (!Support::isInt9(offset32))
+ goto InvalidDisplacement;
+
+ opcode.reset(uint32_t(opData.opcode) << 10);
+ opcode.addImm(sz & 3u, 30);
+ opcode.addImm(sz >> 2, 23);
+ opcode.addImm(offset32 & 0x1FF, 12);
+ opcode.addReg(o0, 0);
+ goto EmitOp_MemBase_Rn5;
+ }
+
+ goto InvalidAddress;
+ }
+
+ break;
+ }
+
+ case InstDB::kEncodingSimdLdNStN: {
+ const InstDB::EncodingData::SimdLdNStN& opData = InstDB::EncodingData::simdLdNStN[encodingIndex];
+ const Operand_& o4 = opExt[EmitterUtils::kOp4];
+
+ uint32_t n = 1;
+
+ if (isign4 == ENC_OPS2(Reg, Mem)) {
+ if (opData.n != 1)
+ goto InvalidInstruction;
+
+ rmRel = &o1;
+ }
+ else if (isign4 == ENC_OPS3(Reg, Reg, Mem)) {
+ if (opData.n != 1 && opData.n != 2)
+ goto InvalidInstruction;
+
+ if (!checkSignature(o0, o1) || !checkConsecutive(o0, o1))
+ goto InvalidInstruction;
+
+ n = 2;
+ rmRel = &o2;
+ }
+ else if (isign4 == ENC_OPS4(Reg, Reg, Reg, Mem) && o4.isNone()) {
+ if (opData.n != 1 && opData.n != 3)
+ goto InvalidInstruction;
+
+ if (!checkSignature(o0, o1, o2) || !checkConsecutive(o0, o1, o2))
+ goto InvalidInstruction;
+
+ n = 3;
+ rmRel = &o3;
+ }
+ else if (isign4 == ENC_OPS4(Reg, Reg, Reg, Reg) && o4.isMem()) {
+ if (opData.n != 1 && opData.n != 4)
+ goto InvalidInstruction;
+
+ if (!checkSignature(o0, o1, o2, o3) || !checkConsecutive(o0, o1, o2, o3))
+ goto InvalidInstruction;
+
+ n = 4;
+ rmRel = &o4;
+ }
+ else {
+ goto InvalidInstruction;
+ }
+
+ // We will use `v` and `m` from now as those are relevant for encoding.
+ const Vec& v = o0.as<Vec>();
+ const Mem& m = rmRel->as<Mem>();
+
+ uint32_t q = 0;
+ uint32_t rm = 0;
+ uint32_t rn = m.baseId();
+ uint32_t sz = v.elementType() - Vec::kElementTypeB;
+ uint32_t opcSsize = sz;
+ uint32_t offsetPossibility = 0;
+
+ if (sz > 3)
+ goto InvalidInstruction;
+
+ if (m.baseType() != RegType::kARM_GpX)
+ goto InvalidAddress;
+
+ // Rn cannot be ZR, but can be SP.
+ if (rn > 30 && rn != Gp::kIdSp)
+ goto InvalidAddress;
+
+ rn &= 31;
+
+ if (opData.replicate) {
+ if (n != opData.n)
+ goto InvalidInstruction;
+
+ // Replicates to the whole register, element index cannot be used.
+ if (v.hasElementIndex())
+ goto InvalidInstruction;
+
+ q = diff(v.type(), RegType::kARM_VecD);
+ if (q > 1)
+ goto InvalidInstruction;
+
+ opcode.reset(uint32_t(opData.singleOp) << 10);
+ offsetPossibility = (1u << sz) * n;
+ }
+ else if (v.hasElementIndex()) {
+ if (n != opData.n)
+ goto InvalidInstruction;
+
+ // LDx/STx (single structure).
+ static const uint8_t opcSsizeBySzS[] = { 0x0u << 3, 0x2u << 3, 0x4u << 3, (0x4u << 3) | 1u };
+
+ opcode.reset(uint32_t(opData.singleOp) << 10);
+ opcSsize = opcSsizeBySzS[sz];
+ offsetPossibility = (1u << sz) * opData.n;
+
+ uint32_t elementIndex = v.elementIndex();
+ uint32_t maxElementIndex = 15 >> sz;
+
+ if (elementIndex > maxElementIndex)
+ goto InvalidElementIndex;
+
+ elementIndex <<= sz;
+ q = elementIndex >> 3;
+ opcSsize |= elementIndex & 0x7u;
+ }
+ else {
+ // LDx/STx (multiple structures).
+ static const uint8_t opcSsizeByN[] = { 0u, 0x7u << 2, 0xAu << 2, 0x6u << 2, 0x2u << 2 };
+
+ q = diff(v.type(), RegType::kARM_VecD);
+ if (q > 1)
+ goto InvalidInstruction;
+
+ if (opData.n == 1)
+ opcSsize |= opcSsizeByN[n];
+
+ opcode.reset(uint32_t(opData.multipleOp) << 10);
+ offsetPossibility = (8u << q) * n;
+ }
+
+ if (m.hasIndex()) {
+ if (m.hasOffset() || !m.isPostIndex())
+ goto InvalidAddress;
+
+ rm = m.indexId();
+ if (rm > 30)
+ goto InvalidAddress;
+
+ // Bit 23 - PostIndex.
+ opcode |= B(23);
+ }
+ else {
+ if (m.hasOffset()) {
+ if (m.offset() != int32_t(offsetPossibility) || !m.isPostIndex())
+ goto InvalidAddress;
+ rm = 31;
+
+ // Bit 23 - PostIndex.
+ opcode |= B(23);
+ }
+ }
+
+ opcode.addImm(q, 30);
+ opcode.addImm(rm, 16);
+ opcode.addImm(opcSsize, 10);
+ opcode.addImm(rn, 5);
+ goto EmitOp_Rd0;
+ }
+
+ default:
+ break;
+ }
+
+ goto InvalidInstruction;
+
+ // --------------------------------------------------------------------------
+ // [EmitGp - Single]
+ // --------------------------------------------------------------------------
+
+EmitOp_Rd0:
+ if (!checkValidRegs(o0))
+ goto InvalidPhysId;
+
+ opcode.addReg(o0, 0);
+ goto EmitOp;
+
+EmitOp_Rn5:
+ if (!checkValidRegs(o0))
+ goto InvalidPhysId;
+
+ opcode.addReg(o0, 5);
+ goto EmitOp;
+
+EmitOp_Rn5_Rm16:
+ if (!checkValidRegs(o0, o1))
+ goto InvalidPhysId;
+
+ opcode.addReg(o0, 5);
+ opcode.addReg(o1, 16);
+ goto EmitOp;
+
+EmitOp_Rd0_Rn5:
+ if (!checkValidRegs(o0, o1))
+ goto InvalidPhysId;
+
+ opcode.addReg(o0, 0);
+ opcode.addReg(o1, 5);
+ goto EmitOp;
+
+EmitOp_Rd0_Rn5_Rm16_Ra10:
+ if (!checkValidRegs(o0, o1, o2, o3))
+ goto InvalidPhysId;
+
+ opcode.addReg(o0, 0);
+ opcode.addReg(o1, 5);
+ opcode.addReg(o2, 16);
+ opcode.addReg(o3, 10);
+ goto EmitOp;
+
+EmitOp_Rd0_Rn5_Rm16:
+ if (!checkValidRegs(o0, o1, o3))
+ goto InvalidPhysId;
+
+ opcode.addReg(o0, 0);
+ opcode.addReg(o1, 5);
+ opcode.addReg(o2, 16);
+ goto EmitOp;
+
+ // --------------------------------------------------------------------------
+ // [EmitGp - Multiple]
+ // --------------------------------------------------------------------------
+
+EmitOp_Multiple:
+ {
+ ASMJIT_ASSERT(multipleOpCount > 0);
+ err = writer.ensureSpace(this, multipleOpCount * 4u);
+ if (ASMJIT_UNLIKELY(err))
+ goto Failed;
+
+ for (uint32_t i = 0; i < multipleOpCount; i++)
+ writer.emit32uLE(multipleOpData[i]);
+
+ goto EmitDone;
+ }
+
+ // --------------------------------------------------------------------------
+ // [EmitGp - Memory]
+ // --------------------------------------------------------------------------
+
+EmitOp_MemBase_Rn5:
+ if (!checkMemBase(rmRel->as<Mem>()))
+ goto InvalidAddress;
+
+ opcode.addReg(rmRel->as<Mem>().baseId(), 5);
+ goto EmitOp;
+
+EmitOp_MemBaseNoImm_Rn5:
+ if (!checkMemBase(rmRel->as<Mem>()) || rmRel->as<Mem>().hasIndex())
+ goto InvalidAddress;
+
+ if (rmRel->as<Mem>().hasOffset())
+ goto InvalidDisplacement;
+
+ opcode.addReg(rmRel->as<Mem>().baseId(), 5);
+ goto EmitOp;
+
+EmitOp_MemBaseIndex_Rn5_Rm16:
+ if (!rmRel->as<Mem>().hasBaseReg())
+ goto InvalidAddress;
+
+ if (rmRel->as<Mem>().indexId() > 30 && rmRel->as<Mem>().indexId() != Gp::kIdZr)
+ goto InvalidPhysId;
+
+ opcode.addReg(rmRel->as<Mem>().indexId(), 16);
+ opcode.addReg(rmRel->as<Mem>().baseId(), 5);
+ goto EmitOp;
+
+ // --------------------------------------------------------------------------
+ // [EmitOp - PC Relative]
+ // --------------------------------------------------------------------------
+
+EmitOp_Rel:
+ {
+ if (rmRel->isLabel() || rmRel->isMem()) {
+ uint32_t labelId;
+ int64_t labelOffset = 0;
+
+ if (rmRel->isLabel()) {
+ labelId = rmRel->as<Label>().id();
+ }
+ else {
+ labelId = rmRel->as<Mem>().baseId();
+ labelOffset = rmRel->as<Mem>().offset();
+ }
+
+ LabelEntry* label = _code->labelEntry(labelId);
+ if (ASMJIT_UNLIKELY(!label))
+ goto InvalidLabel;
+
+ if (offsetFormat.type() == OffsetType::kAArch64_ADRP) {
+ // TODO: [ARM] Always create relocation entry.
+ }
+
+ if (label->isBoundTo(_section)) {
+ // Label bound to the current section.
+ offsetValue = label->offset() - uint64_t(offset()) + uint64_t(labelOffset);
+ goto EmitOp_DispImm;
+ }
+ else {
+ // Record non-bound label.
+ size_t codeOffset = writer.offsetFrom(_bufferData);
+ LabelLink* link = _code->newLabelLink(label, _section->id(), codeOffset, intptr_t(labelOffset), offsetFormat);
+
+ if (ASMJIT_UNLIKELY(!link))
+ goto OutOfMemory;
+
+ goto EmitOp;
+ }
+ }
+ }
+
+ if (rmRel->isImm()) {
+ uint64_t baseAddress = _code->baseAddress();
+ uint64_t targetOffset = rmRel->as<Imm>().valueAs<uint64_t>();
+
+ size_t codeOffset = writer.offsetFrom(_bufferData);
+
+ if (baseAddress == Globals::kNoBaseAddress || _section->id() != 0) {
+ // Create a new RelocEntry as we cannot calculate the offset right now.
+ RelocEntry* re;
+ err = _code->newRelocEntry(&re, RelocType::kAbsToRel);
+ if (err)
+ goto Failed;
+
+ re->_sourceSectionId = _section->id();
+ re->_sourceOffset = codeOffset;
+ re->_format = offsetFormat;
+ re->_payload = rmRel->as<Imm>().valueAs<uint64_t>() + 4u;
+ goto EmitOp;
+ }
+ else {
+ uint64_t pc = baseAddress + codeOffset;
+
+ if (offsetFormat.type() == OffsetType::kAArch64_ADRP)
+ pc &= ~uint64_t(4096 - 1);
+
+ offsetValue = targetOffset - pc;
+ goto EmitOp_DispImm;
+ }
+ }
+
+ goto InvalidInstruction;
+
+EmitOp_DispImm:
+ {
+ if ((offsetValue & Support::lsbMask<uint32_t>(offsetFormat.immDiscardLsb())) != 0)
+ goto InvalidDisplacement;
+
+ int64_t dispImm64 = int64_t(offsetValue) >> offsetFormat.immDiscardLsb();
+ if (!Support::isEncodableOffset64(dispImm64, offsetFormat.immBitCount()))
+ goto InvalidDisplacement;
+
+ uint32_t dispImm32 = uint32_t(dispImm64 & Support::lsbMask<uint32_t>(offsetFormat.immBitCount()));
+ switch (offsetFormat.type()) {
+ case OffsetType::kSignedOffset: {
+ opcode.addImm(dispImm32, offsetFormat.immBitShift());
+ goto EmitOp;
+ }
+
+ case OffsetType::kAArch64_ADR:
+ case OffsetType::kAArch64_ADRP: {
+ uint32_t immLo = dispImm32 & 0x3u;
+ uint32_t immHi = dispImm32 >> 2;
+ opcode.addImm(immLo, 29);
+ opcode.addImm(immHi, 5);
+ goto EmitOp;
+ }
+
+ default:
+ goto InvalidDisplacement;
+ }
+ }
+
+ // --------------------------------------------------------------------------
+ // [EmitOp - Opcode]
+ // --------------------------------------------------------------------------
+
+EmitOp:
+ writer.emit32uLE(opcode.get());
+ goto EmitDone;
+
+ // --------------------------------------------------------------------------
+ // [Done]
+ // --------------------------------------------------------------------------
+
+EmitDone:
+ if (Support::test(options, InstOptions::kReserved)) {
+#ifndef ASMJIT_NO_LOGGING
+ if (_logger)
+ EmitterUtils::logInstructionEmitted(this, instId, options, o0, o1, o2, opExt, 0, 0, writer.cursor());
+#endif
+ }
+
+ resetExtraReg();
+ resetInstOptions();
+ resetInlineComment();
+
+ writer.done(this);
+ return kErrorOk;
+
+ // --------------------------------------------------------------------------
+ // [Error Handler]
+ // --------------------------------------------------------------------------
+
+#define ERROR_HANDLER(ERR) ERR: err = DebugUtils::errored(kError##ERR); goto Failed;
+ ERROR_HANDLER(OutOfMemory)
+ ERROR_HANDLER(InvalidAddress)
+ ERROR_HANDLER(InvalidAddressScale)
+ ERROR_HANDLER(InvalidDisplacement)
+ ERROR_HANDLER(InvalidElementIndex)
+ ERROR_HANDLER(InvalidLabel)
+ ERROR_HANDLER(InvalidImmediate)
+ ERROR_HANDLER(InvalidInstruction)
+ ERROR_HANDLER(InvalidPhysId)
+ ERROR_HANDLER(InvalidRegType)
+#undef ERROR_HANDLER
+
+Failed:
+#ifndef ASMJIT_NO_LOGGING
+ return EmitterUtils::logInstructionFailed(this, err, instId, options, o0, o1, o2, opExt);
+#else
+ resetExtraReg();
+ resetInstOptions();
+ resetInlineComment();
+ return reportError(err);
+#endif
+}
+
+#undef ENC_OPS1
+#undef ENC_OPS2
+#undef ENC_OPS3
+#undef ENC_OPS4
+
+// a64::Assembler - Align
+// ======================
+
+Error Assembler::align(AlignMode alignMode, uint32_t alignment) {
+ constexpr uint32_t kNopA64 = 0xD503201Fu; // [11010101|00000011|00100000|00011111].
+
+ if (ASMJIT_UNLIKELY(!_code))
+ return reportError(DebugUtils::errored(kErrorNotInitialized));
+
+ if (ASMJIT_UNLIKELY(uint32_t(alignMode) > uint32_t(AlignMode::kMaxValue)))
+ return reportError(DebugUtils::errored(kErrorInvalidArgument));
+
+ if (alignment <= 1)
+ return kErrorOk;
+
+ if (ASMJIT_UNLIKELY(alignment > Globals::kMaxAlignment || !Support::isPowerOf2(alignment)))
+ return reportError(DebugUtils::errored(kErrorInvalidArgument));
+
+ uint32_t i = uint32_t(Support::alignUpDiff<size_t>(offset(), alignment));
+ if (i == 0)
+ return kErrorOk;
+
+ CodeWriter writer(this);
+ ASMJIT_PROPAGATE(writer.ensureSpace(this, i));
+
+ switch (alignMode) {
+ case AlignMode::kCode: {
+ uint32_t pattern = kNopA64;
+
+ if (ASMJIT_UNLIKELY(offset() & 0x3u))
+ return DebugUtils::errored(kErrorInvalidState);
+
+ while (i >= 4) {
+ writer.emit32uLE(pattern);
+ i -= 4;
+ }
+
+ ASMJIT_ASSERT(i == 0);
+ break;
+ }
+
+ case AlignMode::kData:
+ case AlignMode::kZero:
+ writer.emitZeros(i);
+ break;
+ }
+
+ writer.done(this);
+
+#ifndef ASMJIT_NO_LOGGING
+ if (_logger) {
+ StringTmp<128> sb;
+ sb.appendChars(' ', _logger->indentation(FormatIndentationGroup::kCode));
+ sb.appendFormat("align %u\n", alignment);
+ _logger->log(sb);
+ }
+#endif
+
+ return kErrorOk;
+}
+
+// a64::Assembler - Events
+// =======================
+
+Error Assembler::onAttach(CodeHolder* code) noexcept {
+ ASMJIT_PROPAGATE(Base::onAttach(code));
+ return kErrorOk;
+}
+
+Error Assembler::onDetach(CodeHolder* code) noexcept {
+ return Base::onDetach(code);
+}
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // !ASMJIT_NO_AARCH64
diff --git a/src/asmjit/arm/a64assembler.h b/src/asmjit/arm/a64assembler.h
new file mode 100644
index 0000000..f1ac72b
--- /dev/null
+++ b/src/asmjit/arm/a64assembler.h
@@ -0,0 +1,72 @@
+// 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_ARM_A64ASSEMBLER_H_INCLUDED
+#define ASMJIT_ARM_A64ASSEMBLER_H_INCLUDED
+
+#include "../core/assembler.h"
+#include "../arm/a64emitter.h"
+#include "../arm/a64operand.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+
+//! \addtogroup asmjit_a64
+//! \{
+
+//! AArch64 assembler implementation.
+class ASMJIT_VIRTAPI Assembler
+ : public BaseAssembler,
+ public EmitterExplicitT<Assembler> {
+
+public:
+ typedef BaseAssembler Base;
+
+ //! \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; }
+
+ //! \}
+
+ //! \name Emit
+ //! \{
+
+ ASMJIT_API Error _emit(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) override;
+
+ //! \}
+
+ //! \name Align
+ //! \{
+
+ ASMJIT_API Error align(AlignMode alignMode, uint32_t alignment) override;
+
+ //! \}
+
+ //! \name Events
+ //! \{
+
+ ASMJIT_API Error onAttach(CodeHolder* code) noexcept override;
+ ASMJIT_API Error onDetach(CodeHolder* code) noexcept override;
+
+ //! \}
+};
+
+//! \}
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // ASMJIT_ARM_A64ASSEMBLER_H_INCLUDED
diff --git a/src/asmjit/arm/a64builder.cpp b/src/asmjit/arm/a64builder.cpp
new file mode 100644
index 0000000..3a52b2a
--- /dev/null
+++ b/src/asmjit/arm/a64builder.cpp
@@ -0,0 +1,51 @@
+// 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"
+#if !defined(ASMJIT_NO_AARCH64) && !defined(ASMJIT_NO_BUILDER)
+
+#include "../arm/a64assembler.h"
+#include "../arm/a64builder.h"
+#include "../arm/a64emithelper_p.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+
+// a64::Builder - Construction & Destruction
+// =========================================
+
+Builder::Builder(CodeHolder* code) noexcept : BaseBuilder() {
+ _archMask = uint64_t(1) << uint32_t(Arch::kAArch64);
+ assignEmitterFuncs(this);
+
+ if (code)
+ code->attach(this);
+}
+Builder::~Builder() noexcept {}
+
+// a64::Builder - Events
+// =====================
+
+Error Builder::onAttach(CodeHolder* code) noexcept {
+ return Base::onAttach(code);
+}
+
+Error Builder::onDetach(CodeHolder* code) noexcept {
+ return Base::onDetach(code);
+}
+
+// a64::Builder - Finalize
+// =======================
+
+Error Builder::finalize() {
+ ASMJIT_PROPAGATE(runPasses());
+ Assembler a(_code);
+ a.addEncodingOptions(encodingOptions());
+ a.addDiagnosticOptions(diagnosticOptions());
+ return serializeTo(&a);
+}
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // !ASMJIT_NO_AARCH64 && !ASMJIT_NO_BUILDER
diff --git a/src/asmjit/arm/a64builder.h b/src/asmjit/arm/a64builder.h
new file mode 100644
index 0000000..adc99aa
--- /dev/null
+++ b/src/asmjit/arm/a64builder.h
@@ -0,0 +1,57 @@
+// 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_ARM_A64BUILDER_H_INCLUDED
+#define ASMJIT_ARM_A64BUILDER_H_INCLUDED
+
+#include "../core/api-config.h"
+#ifndef ASMJIT_NO_BUILDER
+
+#include "../core/builder.h"
+#include "../arm/a64emitter.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+
+//! \addtogroup asmjit_a64
+//! \{
+
+//! AArch64 builder implementation.
+class ASMJIT_VIRTAPI Builder
+ : public BaseBuilder,
+ public EmitterExplicitT<Builder> {
+public:
+ ASMJIT_NONCOPYABLE(Builder)
+ typedef BaseBuilder Base;
+
+ //! \name Construction & Destruction
+ //! \{
+
+ ASMJIT_API explicit Builder(CodeHolder* code = nullptr) noexcept;
+ ASMJIT_API virtual ~Builder() noexcept;
+
+ //! \}
+
+ //! \name Events
+ //! \{
+
+ ASMJIT_API Error onAttach(CodeHolder* code) noexcept override;
+ ASMJIT_API Error onDetach(CodeHolder* code) noexcept override;
+
+ //! \}
+
+ //! \name Finalize
+ //! \{
+
+ ASMJIT_API Error finalize() override;
+
+ //! \}
+};
+
+//! \}
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // !ASMJIT_NO_BUILDER
+#endif // ASMJIT_ARM_A64BUILDER_H_INCLUDED
diff --git a/src/asmjit/arm/a64compiler.cpp b/src/asmjit/arm/a64compiler.cpp
new file mode 100644
index 0000000..d6c4ed2
--- /dev/null
+++ b/src/asmjit/arm/a64compiler.cpp
@@ -0,0 +1,60 @@
+// 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"
+#if !defined(ASMJIT_NO_AARCH64) && !defined(ASMJIT_NO_COMPILER)
+
+#include "../arm/a64assembler.h"
+#include "../arm/a64compiler.h"
+#include "../arm/a64emithelper_p.h"
+#include "../arm/a64rapass_p.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+
+// a64::Compiler - Construction & Destruction
+// ==========================================
+
+Compiler::Compiler(CodeHolder* code) noexcept : BaseCompiler() {
+ _archMask = uint64_t(1) << uint32_t(Arch::kAArch64);
+ assignEmitterFuncs(this);
+
+ if (code)
+ code->attach(this);
+}
+Compiler::~Compiler() noexcept {}
+
+// a64::Compiler - Events
+// ======================
+
+Error Compiler::onAttach(CodeHolder* code) noexcept {
+ ASMJIT_PROPAGATE(Base::onAttach(code));
+ Error err = addPassT<ARMRAPass>();
+
+ if (ASMJIT_UNLIKELY(err)) {
+ onDetach(code);
+ return err;
+ }
+
+ return kErrorOk;
+}
+
+Error Compiler::onDetach(CodeHolder* code) noexcept {
+ return Base::onDetach(code);
+}
+
+// a64::Compiler - Finalize
+// ========================
+
+Error Compiler::finalize() {
+ ASMJIT_PROPAGATE(runPasses());
+ Assembler a(_code);
+ a.addEncodingOptions(encodingOptions());
+ a.addDiagnosticOptions(diagnosticOptions());
+ return serializeTo(&a);
+}
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // !ASMJIT_NO_AARCH64 && !ASMJIT_NO_COMPILER
diff --git a/src/asmjit/arm/a64compiler.h b/src/asmjit/arm/a64compiler.h
new file mode 100644
index 0000000..ebed549
--- /dev/null
+++ b/src/asmjit/arm/a64compiler.h
@@ -0,0 +1,235 @@
+// 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_ARM_ARMCOMPILER_H_INCLUDED
+#define ASMJIT_ARM_ARMCOMPILER_H_INCLUDED
+
+#include "../core/api-config.h"
+#ifndef ASMJIT_NO_COMPILER
+
+#include "../core/compiler.h"
+#include "../core/type.h"
+#include "../arm/a64emitter.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+
+//! \addtogroup asmjit_a64
+//! \{
+
+//! AArch64 compiler implementation.
+class ASMJIT_VIRTAPI Compiler
+ : public BaseCompiler,
+ public EmitterExplicitT<Compiler> {
+public:
+ ASMJIT_NONCOPYABLE(Compiler)
+ typedef BaseCompiler Base;
+
+ //! \name Construction & Destruction
+ //! \{
+
+ ASMJIT_API explicit Compiler(CodeHolder* code = nullptr) noexcept;
+ ASMJIT_API virtual ~Compiler() noexcept;
+
+ //! \}
+
+ //! \name Virtual Registers
+ //! \{
+
+ //! \cond INTERNAL
+ template<typename RegT, typename Type>
+ inline 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) {
+#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)...);
+ return reg;
+#else
+ DebugUtils::unused(std::forward<Args>(args)...);
+ RegT reg(Globals::NoInit);
+ _newReg(&reg, type, nullptr);
+ return reg;
+#endif
+ }
+ //! \endcond
+
+ template<typename RegT, typename... Args>
+ inline 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)...); }
+
+ template<typename... Args>
+ inline 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)...); }
+
+ template<typename... Args>
+ inline 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)...); }
+
+ template<typename... Args>
+ inline 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)...); }
+
+ template<typename... Args>
+ inline 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)...); }
+
+ template<typename... Args>
+ inline 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)...); }
+ template<typename... Args>
+ inline 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)...); }
+
+ template<typename... Args>
+ inline 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)...); }
+
+ //! \}
+
+ //! \name Stack
+ //! \{
+
+ //! 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) {
+ Mem m(Globals::NoInit);
+ _newStack(&m, size, alignment, name);
+ return m;
+ }
+
+ //! \}
+
+ //! \name Constants
+ //! \{
+
+ //! Put data to a constant-pool and get a memory reference to it.
+ inline Mem newConst(ConstPoolScope scope, const void* data, size_t size) {
+ Mem m(Globals::NoInit);
+ _newConst(&m, scope, data, size);
+ return m;
+ }
+
+ //! Put a BYTE `val` to a constant-pool (8 bits).
+ inline 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); }
+ //! Put a WORD `val` to a constant-pool (32 bits).
+ inline 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); }
+
+ //! Put a WORD `val` to a constant-pool.
+ inline Mem newInt16Const(ConstPoolScope scope, int16_t val) noexcept { return newConst(scope, &val, 2); }
+ //! Put a WORD `val` to a constant-pool.
+ inline Mem newUInt16Const(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); }
+ //! Put a DWORD `val` to a constant-pool.
+ inline Mem newUInt32Const(ConstPoolScope scope, uint32_t val) noexcept { return newConst(scope, &val, 4); }
+ //! Put a QWORD `val` to a constant-pool.
+ inline Mem newInt64Const(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); }
+
+ //! Put a SP-FP `val` to a constant-pool.
+ inline Mem newFloatConst(ConstPoolScope scope, float val) noexcept { return newConst(scope, &val, 4); }
+ //! Put a DP-FP `val` to a constant-pool.
+ inline Mem newDoubleConst(ConstPoolScope scope, double val) noexcept { return newConst(scope, &val, 8); }
+
+ //! \}
+
+ //! \name Instruction Options
+ //! \{
+
+ //! Force the compiler to not follow the conditional or unconditional jump.
+ inline Compiler& unfollow() noexcept { _instOptions |= InstOptions::kUnfollow; return *this; }
+
+ //! \}
+
+ //! \name Function Call & Ret Intrinsics
+ //! \{
+
+ //! Invoke a function call without `target` type enforcement.
+ inline Error invoke_(InvokeNode** out, const Operand_& target, const FuncSignature& signature) {
+ return addInvokeNode(out, Inst::kIdBlr, target, signature);
+ }
+
+ //! Invoke a function call of the given `target` and `signature` and store the added node to `out`.
+ //!
+ //! Creates a new \ref InvokeNode, initializes all the necessary members to match the given function `signature`,
+ //! adds the node to the compiler, and stores its pointer to `out`. The operation is atomic, if anything fails
+ //! nullptr is stored in `out` and error code is returned.
+ inline Error invoke(InvokeNode** out, const Gp& target, const FuncSignature& signature) { return invoke_(out, target, signature); }
+ //! \overload
+ inline 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); }
+ //! \overload
+ inline 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); }
+
+ //! Return.
+ inline Error ret() { return addRet(Operand(), Operand()); }
+ //! \overload
+ inline Error ret(const BaseReg& o0) { return addRet(o0, Operand()); }
+ //! \overload
+ inline Error ret(const BaseReg& o0, const BaseReg& o1) { return addRet(o0, o1); }
+
+ //! \}
+
+ //! \name Jump Tables Support
+ //! \{
+
+ 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); }
+
+ //! \}
+
+ //! \name Events
+ //! \{
+
+ ASMJIT_API Error onAttach(CodeHolder* code) noexcept override;
+ ASMJIT_API Error onDetach(CodeHolder* code) noexcept override;
+
+ //! \}
+
+ //! \name Finalize
+ //! \{
+
+ ASMJIT_API Error finalize() override;
+
+ //! \}
+};
+
+//! \}
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // !ASMJIT_NO_COMPILER
+#endif // ASMJIT_ARM_ARMCOMPILER_H_INCLUDED
diff --git a/src/asmjit/arm/a64emithelper.cpp b/src/asmjit/arm/a64emithelper.cpp
new file mode 100644
index 0000000..2d8a578
--- /dev/null
+++ b/src/asmjit/arm/a64emithelper.cpp
@@ -0,0 +1,464 @@
+// 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"
+#if !defined(ASMJIT_NO_AARCH64)
+
+#include "../core/formatter.h"
+#include "../core/funcargscontext_p.h"
+#include "../core/string.h"
+#include "../core/support.h"
+#include "../core/type.h"
+#include "../arm/a64emithelper_p.h"
+#include "../arm/a64formatter_p.h"
+#include "../arm/a64instapi_p.h"
+#include "../arm/a64operand.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+
+// a64::EmitHelper - Emit Operations
+// =================================
+
+ASMJIT_FAVOR_SIZE Error EmitHelper::emitRegMove(
+ const Operand_& dst_,
+ const Operand_& src_, TypeId typeId, const char* comment) {
+
+ Emitter* emitter = _emitter->as<Emitter>();
+
+ // Invalid or abstract TypeIds are not allowed.
+ ASMJIT_ASSERT(TypeUtils::isValid(typeId) && !TypeUtils::isAbstract(typeId));
+
+ emitter->setInlineComment(comment);
+
+ if (dst_.isReg() && src_.isMem()) {
+ Reg dst(dst_.as<Reg>());
+ Mem src(src_.as<Mem>());
+
+ switch (typeId) {
+ case TypeId::kInt8:
+ case TypeId::kUInt8:
+ return emitter->ldrb(dst.as<Gp>(), src);
+
+ case TypeId::kInt16:
+ case TypeId::kUInt16:
+ return emitter->ldrh(dst.as<Gp>(), src);
+
+ case TypeId::kInt32:
+ case TypeId::kUInt32:
+ return emitter->ldr(dst.as<Gp>().w(), src);
+
+ case TypeId::kInt64:
+ case TypeId::kUInt64:
+ return emitter->ldr(dst.as<Gp>().x(), src);
+
+ default: {
+ if (TypeUtils::isFloat32(typeId) || TypeUtils::isVec32(typeId))
+ return emitter->ldr(dst.as<Vec>().s(), src);
+
+ if (TypeUtils::isFloat64(typeId) || TypeUtils::isVec64(typeId))
+ return emitter->ldr(dst.as<Vec>().d(), src);
+
+ if (TypeUtils::isVec128(typeId))
+ return emitter->ldr(dst.as<Vec>().q(), src);
+
+ break;
+ }
+ }
+ }
+
+ if (dst_.isMem() && src_.isReg()) {
+ Mem dst(dst_.as<Mem>());
+ Reg src(src_.as<Reg>());
+
+ switch (typeId) {
+ case TypeId::kInt8:
+ case TypeId::kUInt8:
+ return emitter->strb(src.as<Gp>(), dst);
+
+ case TypeId::kInt16:
+ case TypeId::kUInt16:
+ return emitter->strh(src.as<Gp>(), dst);
+
+ case TypeId::kInt32:
+ case TypeId::kUInt32:
+ return emitter->str(src.as<Gp>().w(), dst);
+
+ case TypeId::kInt64:
+ case TypeId::kUInt64:
+ return emitter->str(src.as<Gp>().x(), dst);
+
+ default: {
+ if (TypeUtils::isFloat32(typeId) || TypeUtils::isVec32(typeId))
+ return emitter->str(src.as<Vec>().s(), dst);
+
+ if (TypeUtils::isFloat64(typeId) || TypeUtils::isVec64(typeId))
+ return emitter->str(src.as<Vec>().d(), dst);
+
+ if (TypeUtils::isVec128(typeId))
+ return emitter->str(src.as<Vec>().q(), dst);
+
+ break;
+ }
+ }
+ }
+
+ if (dst_.isReg() && src_.isReg()) {
+ Reg dst(dst_.as<Reg>());
+ Reg src(src_.as<Reg>());
+
+ switch (typeId) {
+ case TypeId::kInt8:
+ case TypeId::kUInt8:
+ case TypeId::kInt16:
+ case TypeId::kUInt16:
+ case TypeId::kInt32:
+ case TypeId::kUInt32:
+ case TypeId::kInt64:
+ case TypeId::kUInt64:
+ return emitter->mov(src.as<Gp>().x(), dst.as<Gp>().x());
+
+ default: {
+ if (TypeUtils::isFloat32(typeId) || TypeUtils::isVec32(typeId))
+ return emitter->fmov(dst.as<Vec>().s(), src.as<Vec>().s());
+
+ if (TypeUtils::isFloat64(typeId) || TypeUtils::isVec64(typeId))
+ return emitter->mov(dst.as<Vec>().b8(), src.as<Vec>().b8());
+
+ if (TypeUtils::isVec128(typeId))
+ return emitter->mov(dst.as<Vec>().b16(), src.as<Vec>().b16());
+
+ break;
+ }
+ }
+ }
+
+ emitter->setInlineComment(nullptr);
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
+Error EmitHelper::emitRegSwap(
+ const BaseReg& a,
+ const BaseReg& b, const char* comment) {
+
+ DebugUtils::unused(a, b, comment);
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
+// TODO: [ARM] EmitArgMove is unfinished.
+Error EmitHelper::emitArgMove(
+ const BaseReg& dst_, TypeId dstTypeId,
+ const Operand_& src_, TypeId srcTypeId, const char* comment) {
+
+ // Deduce optional `dstTypeId`, which may be `TypeId::kVoid` in some cases.
+ if (dstTypeId == TypeId::kVoid) {
+ const ArchTraits& archTraits = ArchTraits::byArch(_emitter->arch());
+ dstTypeId = archTraits.regTypeToTypeId(dst_.type());
+ }
+
+ // Invalid or abstract TypeIds are not allowed.
+ ASMJIT_ASSERT(TypeUtils::isValid(dstTypeId) && !TypeUtils::isAbstract(dstTypeId));
+ ASMJIT_ASSERT(TypeUtils::isValid(srcTypeId) && !TypeUtils::isAbstract(srcTypeId));
+
+ Reg dst(dst_.as<Reg>());
+ Operand src(src_);
+
+ uint32_t dstSize = TypeUtils::sizeOf(dstTypeId);
+ uint32_t srcSize = TypeUtils::sizeOf(srcTypeId);
+
+ if (TypeUtils::isInt(dstTypeId)) {
+ if (TypeUtils::isInt(srcTypeId)) {
+ uint32_t x = dstSize == 8;
+
+ dst.setSignature(OperandSignature{x ? uint32_t(GpX::kSignature) : uint32_t(GpW::kSignature)});
+ _emitter->setInlineComment(comment);
+
+ if (src.isReg()) {
+ src.setSignature(dst.signature());
+ return _emitter->emit(Inst::kIdMov, dst, src);
+ }
+ else if (src.isMem()) {
+ InstId instId = Inst::kIdNone;
+ switch (srcTypeId) {
+ case TypeId::kInt8: instId = Inst::kIdLdrsb; break;
+ case TypeId::kUInt8: instId = Inst::kIdLdrb; break;
+ 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::kInt64: instId = Inst::kIdLdr; break;
+ case TypeId::kUInt64: instId = Inst::kIdLdr; break;
+ default:
+ return DebugUtils::errored(kErrorInvalidState);
+ }
+ return _emitter->emit(instId, dst, src);
+ }
+ }
+ }
+
+ if (TypeUtils::isFloat(dstTypeId) || TypeUtils::isVec(dstTypeId)) {
+ if (TypeUtils::isFloat(srcTypeId) || TypeUtils::isVec(srcTypeId)) {
+ switch (srcSize) {
+ case 2: dst.as<Vec>().setSignature(OperandSignature{VecH::kSignature}); break;
+ case 4: dst.as<Vec>().setSignature(OperandSignature{VecS::kSignature}); break;
+ case 8: dst.as<Vec>().setSignature(OperandSignature{VecD::kSignature}); break;
+ case 16: dst.as<Vec>().setSignature(OperandSignature{VecV::kSignature}); break;
+ default:
+ return DebugUtils::errored(kErrorInvalidState);
+ }
+
+ _emitter->setInlineComment(comment);
+
+ if (src.isReg()) {
+ InstId instId = srcSize <= 4 ? Inst::kIdFmov_v : Inst::kIdMov_v;
+ src.setSignature(dst.signature());
+ return _emitter->emit(instId, dst, src);
+ }
+ else if (src.isMem()) {
+ return _emitter->emit(Inst::kIdLdr_v, dst, src);
+ }
+ }
+ }
+
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
+// a64::EmitHelper - Emit Prolog & Epilog
+// ======================================
+
+struct LoadStoreInstructions {
+ InstId singleInstId;
+ InstId pairInstId;
+};
+
+struct PrologEpilogInfo {
+ struct RegPair {
+ uint8_t ids[2];
+ uint16_t offset;
+ };
+
+ struct GroupData {
+ RegPair pairs[16];
+ uint32_t pairCount;
+ };
+
+ Support::Array<GroupData, 2> groups;
+ uint32_t sizeTotal;
+
+ Error init(const FuncFrame& frame) noexcept {
+ uint32_t offset = 0;
+
+ for (RegGroup group : Support::EnumValues<RegGroup, RegGroup::kGp, RegGroup::kVec>{}) {
+ GroupData& data = groups[group];
+
+ uint32_t n = 0;
+ uint32_t pairCount = 0;
+ RegPair* pairs = data.pairs;
+
+ uint32_t slotSize = frame.saveRestoreRegSize(group);
+ uint32_t savedRegs = frame.savedRegs(group);
+
+ if (group == RegGroup::kGp && frame.hasPreservedFP()) {
+ // Must be at the beginning of the push/pop sequence.
+ ASMJIT_ASSERT(pairCount == 0);
+
+ pairs[0].offset = uint16_t(offset);
+ pairs[0].ids[0] = Gp::kIdFp;
+ pairs[0].ids[1] = Gp::kIdLr;
+ offset += slotSize * 2;
+ pairCount++;
+
+ savedRegs &= ~Support::bitMask(Gp::kIdFp, Gp::kIdLr);
+ }
+
+ Support::BitWordIterator<uint32_t> it(savedRegs);
+ while (it.hasNext()) {
+ pairs[pairCount].ids[n] = uint8_t(it.next());
+
+ if (++n == 2) {
+ pairs[pairCount].offset = uint16_t(offset);
+ offset += slotSize * 2;
+
+ n = 0;
+ pairCount++;
+ }
+ }
+
+ if (n == 1) {
+ pairs[pairCount].ids[1] = uint8_t(BaseReg::kIdBad);
+ pairs[pairCount].offset = uint16_t(offset);
+ offset += slotSize * 2;
+ pairCount++;
+ }
+
+ data.pairCount = pairCount;
+ }
+
+ sizeTotal = offset;
+ return kErrorOk;
+ }
+};
+
+ASMJIT_FAVOR_SIZE Error EmitHelper::emitProlog(const FuncFrame& frame) {
+ Emitter* emitter = _emitter->as<Emitter>();
+
+ PrologEpilogInfo pei;
+ ASMJIT_PROPAGATE(pei.init(frame));
+
+ static const Support::Array<Reg, 2> groupRegs = {{ x0, d0 }};
+ static const Support::Array<LoadStoreInstructions, 2> groupInsts = {{
+ { Inst::kIdStr , Inst::kIdStp },
+ { Inst::kIdStr_v, Inst::kIdStp_v }
+ }};
+
+ uint32_t adjustInitialOffset = pei.sizeTotal;
+
+ for (RegGroup group : Support::EnumValues<RegGroup, RegGroup::kGp, RegGroup::kVec>{}) {
+ const PrologEpilogInfo::GroupData& data = pei.groups[group];
+ uint32_t pairCount = data.pairCount;
+
+ Reg regs[2] = { groupRegs[group], groupRegs[group] };
+ Mem mem = ptr(sp);
+
+ const LoadStoreInstructions& insts = groupInsts[group];
+ for (uint32_t i = 0; i < pairCount; i++) {
+ const PrologEpilogInfo::RegPair& pair = data.pairs[i];
+
+ regs[0].setId(pair.ids[0]);
+ regs[1].setId(pair.ids[1]);
+ mem.setOffsetLo32(pair.offset);
+
+ if (pair.offset == 0 && adjustInitialOffset) {
+ mem.setOffset(-int(adjustInitialOffset));
+ mem.makePreIndex();
+ }
+
+ if (pair.ids[1] == BaseReg::kIdBad)
+ ASMJIT_PROPAGATE(emitter->emit(insts.singleInstId, regs[0], mem));
+ else
+ ASMJIT_PROPAGATE(emitter->emit(insts.pairInstId, regs[0], regs[1], mem));
+
+ mem.resetToFixedOffset();
+
+ if (i == 0 && frame.hasPreservedFP()) {
+ ASMJIT_PROPAGATE(emitter->mov(x29, sp));
+ }
+ }
+ }
+
+ if (frame.hasStackAdjustment()) {
+ uint32_t adj = frame.stackAdjustment();
+ if (adj <= 0xFFFu) {
+ ASMJIT_PROPAGATE(emitter->sub(sp, sp, adj));
+ }
+ else if (adj <= 0xFFFFFFu) {
+ // TODO: [ARM] Prolog - we must touch the pages otherwise it's undefined.
+ ASMJIT_PROPAGATE(emitter->sub(sp, sp, adj & 0x000FFFu));
+ ASMJIT_PROPAGATE(emitter->sub(sp, sp, adj & 0xFFF000u));
+ }
+ else {
+ return DebugUtils::errored(kErrorInvalidState);
+ }
+ }
+
+ return kErrorOk;
+}
+
+// TODO: [ARM] Emit epilog.
+ASMJIT_FAVOR_SIZE Error EmitHelper::emitEpilog(const FuncFrame& frame) {
+ Emitter* emitter = _emitter->as<Emitter>();
+
+ PrologEpilogInfo pei;
+ ASMJIT_PROPAGATE(pei.init(frame));
+
+ static const Support::Array<Reg, 2> groupRegs = {{ x0, d0 }};
+ static const Support::Array<LoadStoreInstructions, 2> groupInsts = {{
+ { Inst::kIdLdr , Inst::kIdLdp },
+ { Inst::kIdLdr_v, Inst::kIdLdp_v }
+ }};
+
+ uint32_t adjustInitialOffset = pei.sizeTotal;
+
+ if (frame.hasStackAdjustment()) {
+ uint32_t adj = frame.stackAdjustment();
+ if (adj <= 0xFFFu) {
+ ASMJIT_PROPAGATE(emitter->add(sp, sp, adj));
+ }
+ else if (adj <= 0xFFFFFFu) {
+ ASMJIT_PROPAGATE(emitter->add(sp, sp, adj & 0x000FFFu));
+ ASMJIT_PROPAGATE(emitter->add(sp, sp, adj & 0xFFF000u));
+ }
+ else {
+ return DebugUtils::errored(kErrorInvalidState);
+ }
+ }
+
+ for (int g = 1; g >= 0; g--) {
+ RegGroup group = RegGroup(g);
+ const PrologEpilogInfo::GroupData& data = pei.groups[group];
+ uint32_t pairCount = data.pairCount;
+
+ Reg regs[2] = { groupRegs[group], groupRegs[group] };
+ Mem mem = ptr(sp);
+
+ const LoadStoreInstructions& insts = groupInsts[group];
+
+ for (int i = int(pairCount) - 1; i >= 0; i--) {
+ const PrologEpilogInfo::RegPair& pair = data.pairs[i];
+
+ regs[0].setId(pair.ids[0]);
+ regs[1].setId(pair.ids[1]);
+ mem.setOffsetLo32(pair.offset);
+
+ if (pair.offset == 0 && adjustInitialOffset) {
+ mem.setOffset(int(adjustInitialOffset));
+ mem.makePostIndex();
+ }
+
+ if (pair.ids[1] == BaseReg::kIdBad)
+ ASMJIT_PROPAGATE(emitter->emit(insts.singleInstId, regs[0], mem));
+ else
+ ASMJIT_PROPAGATE(emitter->emit(insts.pairInstId, regs[0], regs[1], mem));
+
+ mem.resetToFixedOffset();
+ }
+ }
+
+ ASMJIT_PROPAGATE(emitter->ret(x30));
+
+ return kErrorOk;
+}
+
+static Error ASMJIT_CDECL Emitter_emitProlog(BaseEmitter* emitter, const FuncFrame& frame) {
+ EmitHelper emitHelper(emitter);
+ return emitHelper.emitProlog(frame);
+}
+
+static Error ASMJIT_CDECL Emitter_emitEpilog(BaseEmitter* emitter, const FuncFrame& frame) {
+ EmitHelper emitHelper(emitter);
+ return emitHelper.emitEpilog(frame);
+}
+
+static Error ASMJIT_CDECL Emitter_emitArgsAssignment(BaseEmitter* emitter, const FuncFrame& frame, const FuncArgsAssignment& args) {
+ EmitHelper emitHelper(emitter);
+ return emitHelper.emitArgsAssignment(frame, args);
+}
+
+void assignEmitterFuncs(BaseEmitter* emitter) {
+ emitter->_funcs.emitProlog = Emitter_emitProlog;
+ emitter->_funcs.emitEpilog = Emitter_emitEpilog;
+ emitter->_funcs.emitArgsAssignment = Emitter_emitArgsAssignment;
+
+#ifndef ASMJIT_NO_LOGGING
+ emitter->_funcs.formatInstruction = FormatterInternal::formatInstruction;
+#endif
+
+#ifndef ASMJIT_NO_VALIDATION
+ emitter->_funcs.validate = InstInternal::validate;
+#endif
+}
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // !ASMJIT_NO_AARCH64
diff --git a/src/asmjit/arm/a64emithelper_p.h b/src/asmjit/arm/a64emithelper_p.h
new file mode 100644
index 0000000..b1ba1a9
--- /dev/null
+++ b/src/asmjit/arm/a64emithelper_p.h
@@ -0,0 +1,50 @@
+// 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_ARM_ARMEMITHELPER_P_H_INCLUDED
+#define ASMJIT_ARM_ARMEMITHELPER_P_H_INCLUDED
+
+#include "../core/api-config.h"
+
+#include "../core/emithelper_p.h"
+#include "../core/func.h"
+#include "../arm/a64emitter.h"
+#include "../arm/a64operand.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+
+//! \cond INTERNAL
+//! \addtogroup asmjit_a64
+//! \{
+
+class EmitHelper : public BaseEmitHelper {
+public:
+ inline explicit EmitHelper(BaseEmitter* emitter = nullptr) noexcept
+ : BaseEmitHelper(emitter) {}
+
+ Error emitRegMove(
+ const Operand_& dst_,
+ const Operand_& src_, TypeId typeId, const char* comment = nullptr) override;
+
+ Error emitRegSwap(
+ const BaseReg& a,
+ const BaseReg& b, const char* comment = nullptr) override;
+
+ Error emitArgMove(
+ const BaseReg& dst_, TypeId dstTypeId,
+ const Operand_& src_, TypeId srcTypeId, const char* comment = nullptr) override;
+
+ Error emitProlog(const FuncFrame& frame);
+ Error emitEpilog(const FuncFrame& frame);
+};
+
+void assignEmitterFuncs(BaseEmitter* emitter);
+
+//! \}
+//! \endcond
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // ASMJIT_ARM_ARMEMITHELPER_P_H_INCLUDED
diff --git a/src/asmjit/arm/a64emitter.h b/src/asmjit/arm/a64emitter.h
new file mode 100644
index 0000000..54354ea
--- /dev/null
+++ b/src/asmjit/arm/a64emitter.h
@@ -0,0 +1,1228 @@
+// 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_ARM_A64EMITTER_H_INCLUDED
+#define ASMJIT_ARM_A64EMITTER_H_INCLUDED
+
+#include "../core/emitter.h"
+#include "../core/support.h"
+#include "../arm/a64instdb.h"
+#include "../arm/a64operand.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+
+#define ASMJIT_INST_0x(NAME, ID) \
+ inline Error NAME() { return _emitter()->_emitI(Inst::kId##ID); }
+
+#define ASMJIT_INST_1x(NAME, ID, T0) \
+ inline Error NAME(const T0& o0) { return _emitter()->_emitI(Inst::kId##ID, o0); }
+
+#define ASMJIT_INST_2x(NAME, ID, T0, T1) \
+ inline Error NAME(const T0& o0, const T1& o1) { return _emitter()->_emitI(Inst::kId##ID, o0, o1); }
+
+#define ASMJIT_INST_3x(NAME, ID, T0, T1, T2) \
+ inline Error NAME(const T0& o0, const T1& o1, const T2& o2) { return _emitter()->_emitI(Inst::kId##ID, o0, o1, o2); }
+
+#define ASMJIT_INST_4x(NAME, ID, T0, T1, T2, T3) \
+ inline Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3) { return _emitter()->_emitI(Inst::kId##ID, o0, o1, o2, o3); }
+
+#define ASMJIT_INST_5x(NAME, ID, T0, T1, T2, T3, T4) \
+ inline Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3, const T4& o4) { return _emitter()->_emitI(Inst::kId##ID, o0, o1, o2, o3, o4); }
+
+#define ASMJIT_INST_6x(NAME, ID, T0, T1, T2, T3, T4, T5) \
+ inline Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3, const T4& o4, const T5& o5) { return _emitter()->_emitI(Inst::kId##ID, o0, o1, o2, o3, o4, o5); }
+
+#define ASMJIT_INST_1cc(NAME, ID, T0) \
+ inline Error NAME(const T0& o0) { return _emitter()->_emitI(Inst::kId##ID, o0); } \
+ \
+ inline Error NAME(CondCode cc, const T0& o0) { return _emitter()->_emitI(BaseInst::composeARMInstId(Inst::kId##ID, cc), o0); } \
+ \
+ inline Error NAME##_eq(const T0& o0) { return _emitter()->_emitI(BaseInst::composeARMInstId(Inst::kId##ID, CondCode::kEQ), o0); } \
+ inline Error NAME##_ne(const T0& o0) { return _emitter()->_emitI(BaseInst::composeARMInstId(Inst::kId##ID, CondCode::kNE), o0); } \
+ inline Error NAME##_cs(const T0& o0) { return _emitter()->_emitI(BaseInst::composeARMInstId(Inst::kId##ID, CondCode::kCS), o0); } \
+ inline Error NAME##_hs(const T0& o0) { return _emitter()->_emitI(BaseInst::composeARMInstId(Inst::kId##ID, CondCode::kHS), o0); } \
+ inline Error NAME##_cc(const T0& o0) { return _emitter()->_emitI(BaseInst::composeARMInstId(Inst::kId##ID, CondCode::kCC), o0); } \
+ inline Error NAME##_lo(const T0& o0) { return _emitter()->_emitI(BaseInst::composeARMInstId(Inst::kId##ID, CondCode::kLO), o0); } \
+ inline Error NAME##_mi(const T0& o0) { return _emitter()->_emitI(BaseInst::composeARMInstId(Inst::kId##ID, CondCode::kMI), o0); } \
+ inline Error NAME##_pl(const T0& o0) { return _emitter()->_emitI(BaseInst::composeARMInstId(Inst::kId##ID, CondCode::kPL), o0); } \
+ inline Error NAME##_vs(const T0& o0) { return _emitter()->_emitI(BaseInst::composeARMInstId(Inst::kId##ID, CondCode::kVS), o0); } \
+ inline Error NAME##_vc(const T0& o0) { return _emitter()->_emitI(BaseInst::composeARMInstId(Inst::kId##ID, CondCode::kVC), o0); } \
+ inline Error NAME##_hi(const T0& o0) { return _emitter()->_emitI(BaseInst::composeARMInstId(Inst::kId##ID, CondCode::kHI), o0); } \
+ inline Error NAME##_ls(const T0& o0) { return _emitter()->_emitI(BaseInst::composeARMInstId(Inst::kId##ID, CondCode::kLS), o0); } \
+ inline Error NAME##_ge(const T0& o0) { return _emitter()->_emitI(BaseInst::composeARMInstId(Inst::kId##ID, CondCode::kGE), o0); } \
+ inline Error NAME##_lt(const T0& o0) { return _emitter()->_emitI(BaseInst::composeARMInstId(Inst::kId##ID, CondCode::kLT), o0); } \
+ inline Error NAME##_gt(const T0& o0) { return _emitter()->_emitI(BaseInst::composeARMInstId(Inst::kId##ID, CondCode::kGT), o0); } \
+ inline Error NAME##_le(const T0& o0) { return _emitter()->_emitI(BaseInst::composeARMInstId(Inst::kId##ID, CondCode::kLE), o0); } \
+ inline Error NAME##_al(const T0& o0) { return _emitter()->_emitI(BaseInst::composeARMInstId(Inst::kId##ID, CondCode::kAL), o0); }
+
+//! \addtogroup asmjit_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
+//! registers to be used).
+template<typename This>
+struct EmitterExplicitT {
+ //! \cond
+
+ // 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); }
+
+ //! \endcond
+
+ // --------------------------------------------------------------------------
+ // [Options]
+ // --------------------------------------------------------------------------
+
+protected:
+ inline This& _addInstOptions(InstOptions options) noexcept {
+ static_cast<This*>(this)->addInstOptions(options);
+ return *static_cast<This*>(this);
+ }
+
+public:
+ //! \name General Purpose Instructions
+ //! \{
+
+ ASMJIT_INST_3x(adc, Adc, Gp, Gp, Gp)
+ ASMJIT_INST_3x(adcs, Adcs, Gp, Gp, Gp)
+
+ ASMJIT_INST_3x(add, Add, Gp, Gp, Gp)
+ ASMJIT_INST_4x(add, Add, Gp, Gp, Gp, Imm)
+ ASMJIT_INST_3x(add, Add, Gp, Gp, Imm)
+ ASMJIT_INST_4x(add, Add, Gp, Gp, Imm, Imm)
+ ASMJIT_INST_3x(adds, Adds, Gp, Gp, Gp)
+ ASMJIT_INST_3x(adds, Adds, Gp, Gp, Imm)
+ ASMJIT_INST_4x(adds, Adds, Gp, Gp, Gp, Imm)
+ ASMJIT_INST_4x(adds, Adds, Gp, Gp, Imm, Imm)
+
+ ASMJIT_INST_2x(adr, Adr, Gp, Imm)
+ ASMJIT_INST_2x(adr, Adr, Gp, Label)
+ ASMJIT_INST_2x(adrp, Adrp, Gp, Imm)
+ ASMJIT_INST_2x(adrp, Adrp, Gp, Label)
+
+ ASMJIT_INST_3x(and_, And, Gp, Gp, Imm)
+ ASMJIT_INST_3x(and_, And, Gp, Gp, Gp)
+ ASMJIT_INST_4x(and_, And, Gp, Gp, Gp, Imm)
+ ASMJIT_INST_3x(ands, Ands, Gp, Gp, Imm)
+ ASMJIT_INST_3x(ands, Ands, Gp, Gp, Gp)
+ ASMJIT_INST_4x(ands, Ands, Gp, Gp, Gp, Imm)
+
+ ASMJIT_INST_3x(asr, Asr, Gp, Gp, Imm)
+ ASMJIT_INST_3x(asr, Asr, Gp, Gp, Gp)
+ ASMJIT_INST_3x(asrv, Asrv, Gp, Gp, Gp)
+
+ ASMJIT_INST_2x(at, At, Imm, Gp)
+
+ ASMJIT_INST_3x(bfc, Bfc, Gp, Imm, Imm)
+ ASMJIT_INST_4x(bfi, Bfi, Gp, Gp, Imm, Imm)
+ ASMJIT_INST_4x(bfm, Bfm, Gp, Gp, Imm, Imm)
+ ASMJIT_INST_4x(bfxil, Bfxil, Gp, Gp, Imm, Imm)
+
+ ASMJIT_INST_3x(bic, Bic, Gp, Gp, Imm);
+ ASMJIT_INST_3x(bic, Bic, Gp, Gp, Gp);
+ ASMJIT_INST_4x(bic, Bic, Gp, Gp, Gp, Imm);
+ ASMJIT_INST_3x(bics, Bics, Gp, Gp, Imm);
+ ASMJIT_INST_3x(bics, Bics, Gp, Gp, Gp);
+ ASMJIT_INST_4x(bics, Bics, Gp, Gp, Gp, Imm);
+
+ ASMJIT_INST_1x(brk, Brk, Imm)
+
+ ASMJIT_INST_4x(ccmn, Ccmn, Gp, Gp, Imm, Imm);
+ ASMJIT_INST_4x(ccmn, Ccmn, Gp, Imm, Imm, Imm);
+ ASMJIT_INST_4x(ccmp, Ccmp, Gp, Gp, Imm, Imm);
+ ASMJIT_INST_4x(ccmp, Ccmp, Gp, Imm, Imm, Imm);
+
+ ASMJIT_INST_3x(cinc, Cinc, Gp, Gp, Imm);
+ ASMJIT_INST_3x(cinv, Cinv, Gp, Gp, Imm);
+
+ ASMJIT_INST_1x(clrex, Clrex, Imm)
+
+ ASMJIT_INST_2x(cls, Cls, Gp, Gp)
+ ASMJIT_INST_2x(clz, Clz, Gp, Gp)
+
+ ASMJIT_INST_2x(cmn, Cmn, Gp, Gp)
+ ASMJIT_INST_3x(cmn, Cmn, Gp, Gp, Imm)
+ ASMJIT_INST_2x(cmn, Cmn, Gp, Imm)
+ ASMJIT_INST_3x(cmn, Cmn, Gp, Imm, Imm)
+ ASMJIT_INST_2x(cmp, Cmp, Gp, Gp)
+ ASMJIT_INST_3x(cmp, Cmp, Gp, Gp, Imm)
+ ASMJIT_INST_2x(cmp, Cmp, Gp, Imm)
+ ASMJIT_INST_3x(cmp, Cmp, Gp, Imm, Imm)
+
+ ASMJIT_INST_3x(cneg, Cneg, Gp, Gp, Imm);
+
+ ASMJIT_INST_4x(csel, Csel, Gp, Gp, Gp, Imm);
+ ASMJIT_INST_2x(cset, Cset, Gp, Imm);
+ ASMJIT_INST_2x(csetm, Csetm, Gp, Imm);
+
+ ASMJIT_INST_4x(csinc, Csinc, Gp, Gp, Gp, Imm);
+ ASMJIT_INST_4x(csinv, Csinv, Gp, Gp, Gp, Imm);
+ ASMJIT_INST_4x(csneg, Csneg, Gp, Gp, Gp, Imm);
+
+ ASMJIT_INST_2x(dc, Dc, Imm, Gp)
+ ASMJIT_INST_1x(dmb, Dmb, Imm)
+ ASMJIT_INST_1x(dsb, Dsb, Imm)
+ ASMJIT_INST_0x(drps, Drps)
+
+ ASMJIT_INST_3x(eon, Eon, Gp, Gp, Gp)
+ ASMJIT_INST_4x(eon, Eon, Gp, Gp, Gp, Imm)
+
+ ASMJIT_INST_3x(eor, Eor, Gp, Gp, Imm)
+ ASMJIT_INST_3x(eor, Eor, Gp, Gp, Gp)
+ ASMJIT_INST_4x(eor, Eor, Gp, Gp, Gp, Imm)
+
+ ASMJIT_INST_0x(eret, Eret)
+ ASMJIT_INST_0x(esb, Esb)
+
+ ASMJIT_INST_4x(extr, Extr, Gp, Gp, Gp, Imm)
+
+ ASMJIT_INST_1x(hlt, Hlt, Imm)
+ ASMJIT_INST_1x(hvc, Hvc, Imm)
+ ASMJIT_INST_2x(ic, Ic, Imm, Gp)
+ ASMJIT_INST_1x(isb, Isb, Imm)
+
+ ASMJIT_INST_3x(lsl, Lsl, Gp, Gp, Imm)
+ ASMJIT_INST_3x(lsl, Lsl, Gp, Gp, Gp)
+ ASMJIT_INST_3x(lslv, Lslv, Gp, Gp, Gp)
+
+ ASMJIT_INST_3x(lsr, Lsr, Gp, Gp, Imm)
+ ASMJIT_INST_3x(lsr, Lsr, Gp, Gp, Gp)
+ ASMJIT_INST_3x(lsrv, Lsrv, Gp, Gp, Gp)
+
+ ASMJIT_INST_4x(madd, Madd, Gp, Gp, Gp, Gp)
+ ASMJIT_INST_3x(mneg, Mneg, Gp, Gp, Gp)
+
+ ASMJIT_INST_2x(mov, Mov, Gp, Gp)
+ ASMJIT_INST_2x(mov, Mov, Gp, Imm)
+ ASMJIT_INST_2x(movk, Movk, Gp, Imm)
+ ASMJIT_INST_3x(movk, Movk, Gp, Imm, Imm)
+ ASMJIT_INST_2x(movn, Movn, Gp, Imm)
+ ASMJIT_INST_3x(movn, Movn, Gp, Imm, Imm)
+ ASMJIT_INST_2x(movz, Movz, Gp, Imm)
+ ASMJIT_INST_3x(movz, Movz, Gp, Imm, Imm)
+
+ ASMJIT_INST_2x(mrs, Mrs, Gp, Imm)
+ ASMJIT_INST_2x(msr, Msr, Imm, Gp)
+ ASMJIT_INST_2x(msr, Msr, Imm, Imm)
+
+ ASMJIT_INST_4x(msub, Msub, Gp, Gp, Gp, Gp)
+ ASMJIT_INST_3x(mul, Mul, Gp, Gp, Gp)
+
+ ASMJIT_INST_2x(mvn, Mvn, Gp, Gp)
+ ASMJIT_INST_3x(mvn, Mvn, Gp, Gp, Imm)
+
+ ASMJIT_INST_2x(neg, Neg, Gp, Gp)
+ ASMJIT_INST_3x(neg, Neg, Gp, Gp, Imm)
+ ASMJIT_INST_2x(negs, Negs, Gp, Gp)
+ ASMJIT_INST_3x(negs, Negs, Gp, Gp, Imm)
+
+ ASMJIT_INST_2x(ngc, Ngc, Gp, Gp)
+ ASMJIT_INST_2x(ngcs, Ngcs, Gp, Gp)
+
+ ASMJIT_INST_3x(orn, Orn, Gp, Gp, Gp)
+ ASMJIT_INST_4x(orn, Orn, Gp, Gp, Gp, Imm)
+
+ ASMJIT_INST_3x(orr, Orr, Gp, Gp, Imm)
+ ASMJIT_INST_3x(orr, Orr, Gp, Gp, Gp)
+ ASMJIT_INST_4x(orr, Orr, Gp, Gp, Gp, Imm)
+
+ ASMJIT_INST_2x(rbit, Rbit, Gp, Gp)
+ ASMJIT_INST_1x(ret, Ret, Gp)
+
+ ASMJIT_INST_2x(rev, Rev, Gp, Gp)
+ ASMJIT_INST_2x(rev16, Rev16, Gp, Gp)
+ ASMJIT_INST_2x(rev32, Rev32, Gp, Gp)
+ ASMJIT_INST_2x(rev64, Rev64, Gp, Gp)
+
+ ASMJIT_INST_3x(ror, Ror, Gp, Gp, Imm)
+ ASMJIT_INST_3x(ror, Ror, Gp, Gp, Gp)
+ ASMJIT_INST_3x(rorv, Rorv, Gp, Gp, Gp)
+
+ ASMJIT_INST_3x(sbc, Sbc, Gp, Gp, Gp)
+ ASMJIT_INST_3x(sbcs, Sbcs, Gp, Gp, Gp)
+
+ ASMJIT_INST_4x(sbfiz, Sbfiz, Gp, Gp, Imm, Imm)
+ ASMJIT_INST_4x(sbfm, Sbfm, Gp, Gp, Imm, Imm)
+ ASMJIT_INST_4x(sbfx, Sbfx, Gp, Gp, Imm, Imm)
+
+ ASMJIT_INST_3x(sdiv, Sdiv, Gp, Gp, Gp)
+
+ ASMJIT_INST_4x(smaddl, Smaddl, Gp, Gp, Gp, Gp)
+ ASMJIT_INST_1x(smc, Smc, Imm)
+ ASMJIT_INST_3x(smnegl, Smnegl, Gp, Gp, Gp)
+ ASMJIT_INST_4x(smsubl, Smsubl, Gp, Gp, Gp, Gp)
+ ASMJIT_INST_3x(smulh, Smulh, Gp, Gp, Gp)
+ ASMJIT_INST_3x(smull, Smull, Gp, Gp, Gp)
+
+ ASMJIT_INST_3x(sub, Sub, Gp, Gp, Gp)
+ ASMJIT_INST_4x(sub, Sub, Gp, Gp, Gp, Imm)
+ ASMJIT_INST_3x(sub, Sub, Gp, Gp, Imm)
+ ASMJIT_INST_4x(sub, Sub, Gp, Gp, Imm, Imm)
+ ASMJIT_INST_3x(subs, Subs, Gp, Gp, Gp)
+ ASMJIT_INST_4x(subs, Subs, Gp, Gp, Gp, Imm)
+ ASMJIT_INST_3x(subs, Subs, Gp, Gp, Imm)
+ ASMJIT_INST_4x(subs, Subs, Gp, Gp, Imm, Imm)
+
+ ASMJIT_INST_1x(svc, Svc, Imm)
+
+ ASMJIT_INST_2x(sxtb, Sxtb, Gp, Gp)
+ ASMJIT_INST_2x(sxth, Sxth, Gp, Gp)
+ ASMJIT_INST_2x(sxtw, Sxtw, Gp, Gp)
+
+ ASMJIT_INST_4x(sys, Sys, Imm, Imm, Imm, Imm)
+ ASMJIT_INST_5x(sys, Sys, Imm, Imm, Imm, Imm, Gp)
+
+ ASMJIT_INST_2x(tlbi, Tlbi, Imm, Gp)
+ ASMJIT_INST_2x(tst, Tst, Gp, Imm)
+ ASMJIT_INST_2x(tst, Tst, Gp, Gp)
+ ASMJIT_INST_3x(tst, Tst, Gp, Gp, Imm)
+
+ ASMJIT_INST_3x(udiv, Udiv, Gp, Gp, Gp)
+
+ ASMJIT_INST_4x(ubfiz, Ubfiz, Gp, Gp, Imm, Imm)
+ ASMJIT_INST_4x(ubfm, Ubfm, Gp, Gp, Imm, Imm)
+ ASMJIT_INST_4x(ubfx, Ubfx, Gp, Gp, Imm, Imm)
+
+ ASMJIT_INST_4x(umaddl, Umaddl, Gp, Gp, Gp, Gp)
+ ASMJIT_INST_3x(umnegl, Umnegl, Gp, Gp, Gp)
+ ASMJIT_INST_4x(umsubl, Umsubl, Gp, Gp, Gp, Gp)
+ ASMJIT_INST_3x(umull, Umull, Gp, Gp, Gp)
+ ASMJIT_INST_3x(umulh, Umulh, Gp, Gp, Gp)
+
+ ASMJIT_INST_2x(uxtb, Uxtb, Gp, Gp)
+ ASMJIT_INST_2x(uxth, Uxth, Gp, Gp)
+
+ ASMJIT_INST_0x(csdb, Csdb)
+ ASMJIT_INST_1x(dcps1, Dcps1, Imm)
+ ASMJIT_INST_1x(dcps2, Dcps2, Imm)
+ ASMJIT_INST_1x(dcps3, Dcps3, Imm)
+ ASMJIT_INST_0x(dgh, Dgh)
+ ASMJIT_INST_0x(pssbb, Pssbb)
+ ASMJIT_INST_0x(ssbb, Ssbb)
+ ASMJIT_INST_1x(udf, Udf, Imm)
+ ASMJIT_INST_1x(setf8, Setf8, Gp)
+ ASMJIT_INST_1x(setf16, Setf16, Gp)
+
+ //! \}
+
+ //! \name ARMv8.4 Instructions
+ //! \{
+
+ ASMJIT_INST_0x(cfinv, Cfinv)
+
+ //! \}
+
+ //! \name ARMv8.5 Instructions
+ //! \{
+
+ ASMJIT_INST_0x(axflag, Axflag)
+ ASMJIT_INST_0x(xaflag, Xaflag)
+
+ //! \}
+
+ //! \name Branch Instructions
+ //! \{
+
+ ASMJIT_INST_1cc(b, B, Imm)
+ ASMJIT_INST_1cc(b, B, Label)
+ ASMJIT_INST_1x(bl, Bl, Imm)
+ ASMJIT_INST_1x(bl, Bl, Label)
+ ASMJIT_INST_1x(blr, Blr, Gp)
+ ASMJIT_INST_1x(br, Br, Gp)
+ ASMJIT_INST_2x(cbz, Cbz, Gp, Imm)
+ ASMJIT_INST_2x(cbz, Cbz, Gp, Label)
+ ASMJIT_INST_2x(cbnz, Cbnz, Gp, Imm)
+ ASMJIT_INST_2x(cbnz, Cbnz, Gp, Label)
+ ASMJIT_INST_3x(tbnz, Tbnz, Gp, Imm, Imm)
+ ASMJIT_INST_3x(tbnz, Tbnz, Gp, Imm, Label)
+ ASMJIT_INST_3x(tbz, Tbz, Gp, Imm, Imm)
+ ASMJIT_INST_3x(tbz, Tbz, Gp, Imm, Label)
+
+ //! \}
+
+ //! \name Load & Store Instructions
+ //! \{
+
+ ASMJIT_INST_3x(cas, Cas, Gp, Gp, Mem)
+ ASMJIT_INST_3x(casa, Casa, Gp, Gp, Mem)
+ ASMJIT_INST_3x(casab, Casab, Gp, Gp, Mem)
+ ASMJIT_INST_3x(casah, Casah, Gp, Gp, Mem)
+ ASMJIT_INST_3x(casal, Casal, Gp, Gp, Mem)
+ ASMJIT_INST_3x(casalb, Casalb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(casalh, Casalh, Gp, Gp, Mem)
+ ASMJIT_INST_3x(casb, Casb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(cash, Cash, Gp, Gp, Mem)
+ ASMJIT_INST_3x(casl, Casl, Gp, Gp, Mem)
+ ASMJIT_INST_3x(caslb, Caslb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(caslh, Caslh, Gp, Gp, Mem)
+
+ ASMJIT_INST_5x(casp, Casp, Gp, Gp, Gp, Gp, Mem)
+ ASMJIT_INST_5x(caspa, Caspa, Gp, Gp, Gp, Gp, Mem)
+ ASMJIT_INST_5x(caspal, Caspal, Gp, Gp, Gp, Gp, Mem)
+ ASMJIT_INST_5x(caspl, Caspl, Gp, Gp, Gp, Gp, Mem)
+
+ ASMJIT_INST_3x(ldadd, Ldadd, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldadda, Ldadda, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldaddab, Ldaddab, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldaddah, Ldaddah, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldaddal, Ldaddal, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldaddalb, Ldaddalb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldaddalh, Ldaddalh, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldaddb, Ldaddb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldaddh, Ldaddh, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldaddl, Ldaddl, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldaddlb, Ldaddlb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldaddlh, Ldaddlh, Gp, Gp, Mem)
+
+ ASMJIT_INST_2x(ldar, Ldar, Gp, Mem)
+ ASMJIT_INST_2x(ldarb, Ldarb, Gp, Mem)
+ ASMJIT_INST_2x(ldarh, Ldarh, Gp, Mem)
+
+ ASMJIT_INST_2x(ldaxr, Ldaxr, Gp, Mem)
+ ASMJIT_INST_2x(ldaxrb, Ldaxrb, Gp, Mem)
+ ASMJIT_INST_2x(ldaxrh, Ldaxrh, Gp, Mem)
+
+ ASMJIT_INST_3x(ldclr, Ldclr, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldclra, Ldclra, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldclrab, Ldclrab, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldclrah, Ldclrah, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldclral, Ldclral, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldclralb, Ldclralb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldclralh, Ldclralh, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldclrb, Ldclrb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldclrh, Ldclrh, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldclrl, Ldclrl, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldclrlb, Ldclrlb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldclrlh, Ldclrlh, Gp, Gp, Mem)
+
+ ASMJIT_INST_3x(ldeor, Ldeor, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldeora, Ldeora, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldeorab, Ldeorab, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldeorah, Ldeorah, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldeoral, Ldeoral, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldeoralb, Ldeoralb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldeoralh, Ldeoralh, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldeorb, Ldeorb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldeorh, Ldeorh, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldeorl, Ldeorl, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldeorlb, Ldeorlb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldeorlh, Ldeorlh, Gp, Gp, Mem)
+
+ ASMJIT_INST_2x(ldlar, Ldlar, Gp, Mem)
+ ASMJIT_INST_2x(ldlarb, Ldlarb, Gp, Mem)
+ ASMJIT_INST_2x(ldlarh, Ldlarh, Gp, Mem)
+
+ ASMJIT_INST_3x(ldnp, Ldnp, Gp, Gp, Mem)
+
+ ASMJIT_INST_3x(ldp, Ldp, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldpsw, Ldpsw, Gp, Gp, Mem)
+
+ ASMJIT_INST_2x(ldr, Ldr, Gp, Mem)
+ ASMJIT_INST_2x(ldrb, Ldrb, Gp, Mem)
+ ASMJIT_INST_2x(ldrh, Ldrh, Gp, Mem)
+ ASMJIT_INST_2x(ldrsb, Ldrsb, Gp, Mem)
+ ASMJIT_INST_2x(ldrsh, Ldrsh, Gp, Mem)
+ ASMJIT_INST_2x(ldrsw, Ldrsw, Gp, Mem)
+
+ ASMJIT_INST_3x(ldset, Ldset, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldseta, Ldseta, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsetab, Ldsetab, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsetah, Ldsetah, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsetal, Ldsetal, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsetalb, Ldsetalb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsetalh, Ldsetalh, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsetb, Ldsetb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldseth, Ldseth, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsetl, Ldsetl, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsetlb, Ldsetlb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsetlh, Ldsetlh, Gp, Gp, Mem)
+
+ ASMJIT_INST_3x(ldsmax, Ldsmax, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsmaxa, Ldsmaxa, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsmaxab, Ldsmaxab, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsmaxah, Ldsmaxah, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsmaxal, Ldsmaxal, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsmaxalb, Ldsmaxalb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsmaxalh, Ldsmaxalh, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsmaxb, Ldsmaxb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsmaxh, Ldsmaxh, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsmaxl, Ldsmaxl, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsmaxlb, Ldsmaxlb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsmaxlh, Ldsmaxlh, Gp, Gp, Mem)
+
+ ASMJIT_INST_3x(ldsmin, Ldsmin, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsmina, Ldsmina, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsminab, Ldsminab, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsminah, Ldsminah, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsminal, Ldsminal, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsminalb, Ldsminalb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsminalh, Ldsminalh, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsminb, Ldsminb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsminh, Ldsminh, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsminl, Ldsminl, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsminlb, Ldsminlb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldsminlh, Ldsminlh, Gp, Gp, Mem)
+
+ ASMJIT_INST_2x(ldtr, Ldtr, Gp, Mem)
+ ASMJIT_INST_2x(ldtrb, Ldtrb, Gp, Mem)
+ ASMJIT_INST_2x(ldtrh, Ldtrh, Gp, Mem)
+ ASMJIT_INST_2x(ldtrsb, Ldtrsb, Gp, Mem)
+ ASMJIT_INST_2x(ldtrsh, Ldtrsh, Gp, Mem)
+ ASMJIT_INST_2x(ldtrsw, Ldtrsw, Gp, Mem)
+
+ ASMJIT_INST_3x(ldumax, Ldumax, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldumaxa, Ldumaxa, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldumaxab, Ldumaxab, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldumaxah, Ldumaxah, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldumaxal, Ldumaxal, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldumaxalb, Ldumaxalb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldumaxalh, Ldumaxalh, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldumaxb, Ldumaxb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldumaxh, Ldumaxh, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldumaxl, Ldumaxl, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldumaxlb, Ldumaxlb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldumaxlh, Ldumaxlh, Gp, Gp, Mem)
+
+ ASMJIT_INST_3x(ldumin, Ldumin, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldumina, Ldumina, Gp, Gp, Mem)
+ ASMJIT_INST_3x(lduminab, Lduminab, Gp, Gp, Mem)
+ ASMJIT_INST_3x(lduminah, Lduminah, Gp, Gp, Mem)
+ ASMJIT_INST_3x(lduminal, Lduminal, Gp, Gp, Mem)
+ ASMJIT_INST_3x(lduminalb, Lduminalb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(lduminalh, Lduminalh, Gp, Gp, Mem)
+ ASMJIT_INST_3x(lduminb, Lduminb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(lduminh, Lduminh, Gp, Gp, Mem)
+ ASMJIT_INST_3x(lduminl, Lduminl, Gp, Gp, Mem)
+ ASMJIT_INST_3x(lduminlb, Lduminlb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(lduminlh, Lduminlh, Gp, Gp, Mem)
+
+ ASMJIT_INST_2x(ldur, Ldur, Gp, Mem)
+ ASMJIT_INST_2x(ldurb, Ldurb, Gp, Mem)
+ ASMJIT_INST_2x(ldurh, Ldurh, Gp, Mem)
+ ASMJIT_INST_2x(ldursb, Ldursb, Gp, Mem)
+ ASMJIT_INST_2x(ldursh, Ldursh, Gp, Mem)
+ ASMJIT_INST_2x(ldursw, Ldursw, Gp, Mem)
+
+ ASMJIT_INST_3x(ldxp, Ldxp, Gp, Gp, Mem)
+ ASMJIT_INST_3x(ldaxp, Ldaxp, Gp, Gp, Mem)
+
+ ASMJIT_INST_2x(ldxr, Ldxr, Gp, Mem)
+ ASMJIT_INST_2x(ldxrb, Ldxrb, Gp, Mem)
+ ASMJIT_INST_2x(ldxrh, Ldxrh, Gp, Mem)
+
+ ASMJIT_INST_2x(stadd, Stadd, Gp, Mem)
+ ASMJIT_INST_2x(staddb, Staddb, Gp, Mem)
+ ASMJIT_INST_2x(staddh, Staddh, Gp, Mem)
+ ASMJIT_INST_2x(staddl, Staddl, Gp, Mem)
+ ASMJIT_INST_2x(staddlb, Staddlb, Gp, Mem)
+ ASMJIT_INST_2x(staddlh, Staddlh, Gp, Mem)
+
+ ASMJIT_INST_2x(stclr, Stclr, Gp, Mem)
+ ASMJIT_INST_2x(stclrb, Stclrb, Gp, Mem)
+ ASMJIT_INST_2x(stclrh, Stclrh, Gp, Mem)
+ ASMJIT_INST_2x(stclrl, Stclrl, Gp, Mem)
+ ASMJIT_INST_2x(stclrlb, Stclrlb, Gp, Mem)
+ ASMJIT_INST_2x(stclrlh, Stclrlh, Gp, Mem)
+
+ ASMJIT_INST_2x(steor, Steor, Gp, Mem)
+ ASMJIT_INST_2x(steorb, Steorb, Gp, Mem)
+ ASMJIT_INST_2x(steorh, Steorh, Gp, Mem)
+ ASMJIT_INST_2x(steorl, Steorl, Gp, Mem)
+ ASMJIT_INST_2x(steorlb, Steorlb, Gp, Mem)
+ ASMJIT_INST_2x(steorlh, Steorlh, Gp, Mem)
+
+ ASMJIT_INST_2x(stllr, Stllr, Gp, Mem)
+ ASMJIT_INST_2x(stllrb, Stllrb, Gp, Mem)
+ ASMJIT_INST_2x(stllrh, Stllrh, Gp, Mem)
+
+ ASMJIT_INST_2x(stlr, Stllr, Gp, Mem)
+ ASMJIT_INST_2x(stlrb, Stllrb, Gp, Mem)
+ ASMJIT_INST_2x(stlrh, Stllrh, Gp, Mem)
+
+ ASMJIT_INST_3x(stlxr, Stlxr, Gp, Gp, Mem)
+ ASMJIT_INST_3x(stlxrb, Stlxrb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(stlxrh, Stlxrh, Gp, Gp, Mem)
+
+ ASMJIT_INST_3x(stnp, Stnp, Gp, Gp, Mem)
+ ASMJIT_INST_3x(stp, Stp, Gp, Gp, Mem)
+
+ ASMJIT_INST_2x(str, Str, Gp, Mem)
+ ASMJIT_INST_2x(strb, Strb, Gp, Mem)
+ ASMJIT_INST_2x(strh, Strh, Gp, Mem)
+
+ ASMJIT_INST_2x(stset, Stset, Gp, Mem)
+ ASMJIT_INST_2x(stsetb, Stsetb, Gp, Mem)
+ ASMJIT_INST_2x(stseth, Stseth, Gp, Mem)
+ ASMJIT_INST_2x(stsetl, Stsetl, Gp, Mem)
+ ASMJIT_INST_2x(stsetlb, Stsetlb, Gp, Mem)
+ ASMJIT_INST_2x(stsetlh, Stsetlh, Gp, Mem)
+
+ ASMJIT_INST_2x(stsmax, Stsmax, Gp, Mem)
+ ASMJIT_INST_2x(stsmaxb, Stsmaxb, Gp, Mem)
+ ASMJIT_INST_2x(stsmaxh, Stsmaxh, Gp, Mem)
+ ASMJIT_INST_2x(stsmaxl, Stsmaxl, Gp, Mem)
+ ASMJIT_INST_2x(stsmaxlb, Stsmaxlb, Gp, Mem)
+ ASMJIT_INST_2x(stsmaxlh, Stsmaxlh, Gp, Mem)
+
+ ASMJIT_INST_2x(stsmin, Stsmin, Gp, Mem)
+ ASMJIT_INST_2x(stsminb, Stsminb, Gp, Mem)
+ ASMJIT_INST_2x(stsminh, Stsminh, Gp, Mem)
+ ASMJIT_INST_2x(stsminl, Stsminl, Gp, Mem)
+ ASMJIT_INST_2x(stsminlb, Stsminlb, Gp, Mem)
+ ASMJIT_INST_2x(stsminlh, Stsminlh, Gp, Mem)
+
+ ASMJIT_INST_2x(sttr, Sttr, Gp, Mem)
+ ASMJIT_INST_2x(sttrb, Sttrb, Gp, Mem)
+ ASMJIT_INST_2x(sttrh, Sttrh, Gp, Mem)
+
+ ASMJIT_INST_2x(stumax, Stumax, Gp, Mem)
+ ASMJIT_INST_2x(stumaxb, Stumaxb, Gp, Mem)
+ ASMJIT_INST_2x(stumaxh, Stumaxh, Gp, Mem)
+ ASMJIT_INST_2x(stumaxl, Stumaxl, Gp, Mem)
+ ASMJIT_INST_2x(stumaxlb, Stumaxlb, Gp, Mem)
+ ASMJIT_INST_2x(stumaxlh, Stumaxlh, Gp, Mem)
+
+ ASMJIT_INST_2x(stumin, Stumin, Gp, Mem)
+ ASMJIT_INST_2x(stuminb, Stuminb, Gp, Mem)
+ ASMJIT_INST_2x(stuminh, Stuminh, Gp, Mem)
+ ASMJIT_INST_2x(stuminl, Stuminl, Gp, Mem)
+ ASMJIT_INST_2x(stuminlb, Stuminlb, Gp, Mem)
+ ASMJIT_INST_2x(stuminlh, Stuminlh, Gp, Mem)
+
+ ASMJIT_INST_2x(stur, Stur, Gp, Mem)
+ ASMJIT_INST_2x(sturb, Sturb, Gp, Mem)
+ ASMJIT_INST_2x(sturh, Sturh, Gp, Mem)
+
+ ASMJIT_INST_4x(stxp, Stxp, Gp, Gp, Gp, Mem)
+ ASMJIT_INST_4x(stlxp, Stlxp, Gp, Gp, Gp, Mem)
+
+ ASMJIT_INST_3x(stxr, Stxr, Gp, Gp, Mem)
+ ASMJIT_INST_3x(stxrb, Stxrb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(stxrh, Stxrh, Gp, Gp, Mem)
+
+ ASMJIT_INST_3x(swp, Swp, Gp, Gp, Mem)
+ ASMJIT_INST_3x(swpa, Swpa, Gp, Gp, Mem)
+ ASMJIT_INST_3x(swpab, Swpab, Gp, Gp, Mem)
+ ASMJIT_INST_3x(swpah, Swpah, Gp, Gp, Mem)
+ ASMJIT_INST_3x(swpal, Swpal, Gp, Gp, Mem)
+ ASMJIT_INST_3x(swpalb, Swpalb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(swpalh, Swpalh, Gp, Gp, Mem)
+ ASMJIT_INST_3x(swpb, Swpb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(swph, Swph, Gp, Gp, Mem)
+ ASMJIT_INST_3x(swpl, Swpl, Gp, Gp, Mem)
+ ASMJIT_INST_3x(swplb, Swplb, Gp, Gp, Mem)
+ ASMJIT_INST_3x(swplh, Swplh, Gp, Gp, Mem)
+ //! \}
+
+ //! \name CRC Instructions (ARMv8.1-A, optional in ARMv8.0-A)
+ //! \{
+
+ ASMJIT_INST_3x(crc32b, Crc32b, Gp, Gp, Gp);
+ ASMJIT_INST_3x(crc32h, Crc32h, Gp, Gp, Gp);
+ ASMJIT_INST_3x(crc32w, Crc32w, Gp, Gp, Gp);
+ ASMJIT_INST_3x(crc32x, Crc32x, Gp, Gp, Gp);
+
+ ASMJIT_INST_3x(crc32cb, Crc32cb, Gp, Gp, Gp);
+ ASMJIT_INST_3x(crc32ch, Crc32ch, Gp, Gp, Gp);
+ ASMJIT_INST_3x(crc32cw, Crc32cw, Gp, Gp, Gp);
+ ASMJIT_INST_3x(crc32cx, Crc32cx, Gp, Gp, Gp);
+
+ //! \}
+
+ //! \name MTE Instructions
+ //! \{
+
+ ASMJIT_INST_2x(autda, Autda, Gp, Gp);
+ ASMJIT_INST_2x(autdb, Autdb, Gp, Gp);
+ ASMJIT_INST_1x(autdza, Autdza, Gp);
+ ASMJIT_INST_1x(autdzb, Autdzb, Gp);
+ ASMJIT_INST_2x(autia, Autia, Gp, Gp);
+ ASMJIT_INST_0x(autia1716, Autia1716);
+ ASMJIT_INST_0x(autiasp, Autiasp);
+ ASMJIT_INST_0x(autiaz, Autiaz);
+ ASMJIT_INST_2x(autib, Autib, Gp, Gp);
+ ASMJIT_INST_0x(autib1716, Autib1716);
+ ASMJIT_INST_0x(autibsp, Autibsp);
+ ASMJIT_INST_0x(autibz, Autibz);
+ ASMJIT_INST_1x(autiza, Autiza, Gp);
+ ASMJIT_INST_1x(autizb, Autizb, Gp);
+
+ ASMJIT_INST_3x(gmi, Gmi, Gp, Gp, Gp);
+
+ ASMJIT_INST_2x(cmpp, Cmpp, Gp, Gp);
+ ASMJIT_INST_4x(addg, Addg, Gp, Gp, Imm, Imm);
+
+ ASMJIT_INST_2x(ldg, Ldg, Gp, Mem)
+ ASMJIT_INST_2x(ldgm, Ldgm, Gp, Mem)
+ ASMJIT_INST_2x(ldraa, Ldraa, Gp, Mem)
+ ASMJIT_INST_2x(ldrab, Ldrab, Gp, Mem)
+
+ ASMJIT_INST_2x(pacda, Pacda, Gp, Gp);
+ ASMJIT_INST_2x(pacdb, Pacdb, Gp, Gp);
+ ASMJIT_INST_1x(pacdza, Pacdza, Gp);
+ ASMJIT_INST_1x(pacdzb, Pacdzb, Gp);
+ ASMJIT_INST_3x(pacga, Pacga, Gp, Gp, Gp);
+
+ ASMJIT_INST_3x(subp, Subp, Gp, Gp, Gp);
+ ASMJIT_INST_3x(subps, Subps, Gp, Gp, Gp);
+ ASMJIT_INST_4x(subg, Subg, Gp, Gp, Imm, Imm);
+
+ ASMJIT_INST_2x(st2g, St2g, Gp, Mem)
+ ASMJIT_INST_2x(stg, Stg, Gp, Mem)
+ ASMJIT_INST_3x(stgp, Stgp, Gp, Gp, Mem)
+ ASMJIT_INST_2x(stgm, Stgm, Gp, Mem)
+ ASMJIT_INST_2x(stzg, Stzg, Gp, Mem)
+ ASMJIT_INST_2x(stz2g, Stz2g, Gp, Mem)
+ ASMJIT_INST_2x(stzgm, Stzgm, Gp, Mem)
+
+ ASMJIT_INST_1x(xpacd, Xpacd, Gp);
+ ASMJIT_INST_1x(xpaci, Xpaci, Gp);
+ ASMJIT_INST_0x(xpaclri, Xpaclri);
+
+ //! \}
+
+ //! \name Hint Instructions
+ //! \{
+
+ ASMJIT_INST_1x(hint, Hint, Imm)
+ ASMJIT_INST_0x(nop, Nop)
+ ASMJIT_INST_0x(sev, Sev)
+ ASMJIT_INST_0x(sevl, Sevl)
+ ASMJIT_INST_0x(wfe, Wfe)
+ ASMJIT_INST_0x(wfi, Wfi)
+ ASMJIT_INST_0x(yield, Yield)
+
+ //! \}
+
+ //! \name SIMD & FP Instructions
+ //! \{
+
+ ASMJIT_INST_2x(abs, Abs_v, Vec, Vec);
+ ASMJIT_INST_3x(add, Add_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(addhn, Addhn_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(addhn2, Addhn2_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(addp, Addp_v, Vec, Vec);
+ ASMJIT_INST_3x(addp, Addp_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(addv, Addv_v, Vec, Vec);
+ ASMJIT_INST_3x(and_, And_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(bic, Bic_v, Vec, Imm);
+ ASMJIT_INST_3x(bic, Bic_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(bic, Bic_v, Vec, Imm, Imm);
+ ASMJIT_INST_3x(bif, Bif_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(bit, Bit_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(bsl, Bsl_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(cls, Cls_v, Vec, Vec);
+ ASMJIT_INST_2x(clz, Clz_v, Vec, Vec);
+ ASMJIT_INST_3x(cmeq, Cmeq_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(cmeq, Cmeq_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(cmge, Cmge_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(cmge, Cmge_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(cmgt, Cmgt_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(cmgt, Cmgt_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(cmhi, Cmhi_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(cmhs, Cmhs_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(cmle, Cmle_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(cmlt, Cmlt_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(cmtst, Cmtst_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(cnt, Cnt_v, Vec, Vec);
+ ASMJIT_INST_2x(dup, Dup_v, Vec, Gp);
+ ASMJIT_INST_2x(dup, Dup_v, Vec, Vec);
+ ASMJIT_INST_3x(eor, Eor_v, Vec, Vec, Vec);
+ ASMJIT_INST_4x(ext, Ext_v, Vec, Vec, Vec, Imm);
+ ASMJIT_INST_3x(fabd, Fabd_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(fabs, Fabs_v, Vec, Vec);
+ ASMJIT_INST_3x(facge, Facge_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(facgt, Facgt_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(fadd, Fadd_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(faddp, Faddp_v, Vec, Vec);
+ ASMJIT_INST_3x(faddp, Faddp_v, Vec, Vec, Vec);
+ ASMJIT_INST_4x(fccmp, Fccmp_v, Vec, Vec, Imm, Imm);
+ ASMJIT_INST_4x(fccmpe, Fccmpe_v, Vec, Vec, Imm, Imm);
+ ASMJIT_INST_3x(fcmeq, Fcmeq_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(fcmeq, Fcmeq_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(fcmge, Fcmge_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(fcmge, Fcmge_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(fcmgt, Fcmgt_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(fcmgt, Fcmgt_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(fcmle, Fcmle_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(fcmlt, Fcmlt_v, Vec, Vec, Imm);
+ ASMJIT_INST_2x(fcmp, Fcmp_v, Vec, Vec);
+ ASMJIT_INST_2x(fcmp, Fcmp_v, Vec, Imm);
+ ASMJIT_INST_2x(fcmpe, Fcmpe_v, Vec, Vec);
+ ASMJIT_INST_2x(fcmpe, Fcmpe_v, Vec, Imm);
+ ASMJIT_INST_4x(fcsel, Fcsel_v, Vec, Vec, Vec, Imm);
+ ASMJIT_INST_2x(fcvt, Fcvt_v, Vec, Vec);
+ ASMJIT_INST_2x(fcvtas, Fcvtas_v, Gp, Vec);
+ ASMJIT_INST_2x(fcvtas, Fcvtas_v, Vec, Vec);
+ ASMJIT_INST_2x(fcvtau, Fcvtau_v, Gp, Vec);
+ ASMJIT_INST_2x(fcvtau, Fcvtau_v, Vec, Vec);
+ ASMJIT_INST_2x(fcvtl, Fcvtl_v, Vec, Vec);
+ ASMJIT_INST_2x(fcvtl2, Fcvtl2_v, Vec, Vec);
+ ASMJIT_INST_2x(fcvtms, Fcvtms_v, Gp, Vec);
+ ASMJIT_INST_2x(fcvtms, Fcvtms_v, Vec, Vec);
+ ASMJIT_INST_2x(fcvtmu, Fcvtmu_v, Gp, Vec);
+ ASMJIT_INST_2x(fcvtmu, Fcvtmu_v, Vec, Vec);
+ ASMJIT_INST_2x(fcvtn, Fcvtn_v, Vec, Vec);
+ ASMJIT_INST_2x(fcvtn2, Fcvtn2_v, Vec, Vec);
+ ASMJIT_INST_2x(fcvtns, Fcvtns_v, Gp, Vec);
+ ASMJIT_INST_2x(fcvtns, Fcvtns_v, Vec, Vec);
+ ASMJIT_INST_2x(fcvtnu, Fcvtnu_v, Gp, Vec);
+ ASMJIT_INST_2x(fcvtnu, Fcvtnu_v, Vec, Vec);
+ ASMJIT_INST_2x(fcvtps, Fcvtps_v, Gp, Vec);
+ ASMJIT_INST_2x(fcvtps, Fcvtps_v, Vec, Vec);
+ ASMJIT_INST_2x(fcvtpu, Fcvtpu_v, Gp, Vec);
+ ASMJIT_INST_2x(fcvtpu, Fcvtpu_v, Vec, Vec);
+ ASMJIT_INST_2x(fcvtxn, Fcvtxn_v, Vec, Vec);
+ ASMJIT_INST_2x(fcvtxn2, Fcvtxn2_v, Vec, Vec);
+ ASMJIT_INST_2x(fcvtzs, Fcvtzs_v, Gp, Vec);
+ ASMJIT_INST_3x(fcvtzs, Fcvtzs_v, Gp, Vec, Imm);
+ ASMJIT_INST_2x(fcvtzs, Fcvtzs_v, Vec, Vec);
+ ASMJIT_INST_3x(fcvtzs, Fcvtzs_v, Vec, Vec, Imm);
+ ASMJIT_INST_2x(fcvtzu, Fcvtzu_v, Gp, Vec);
+ ASMJIT_INST_3x(fcvtzu, Fcvtzu_v, Gp, Vec, Imm);
+ ASMJIT_INST_2x(fcvtzu, Fcvtzu_v, Vec, Vec);
+ ASMJIT_INST_3x(fcvtzu, Fcvtzu_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(fdiv, Fdiv_v, Vec, Vec, Vec);
+ ASMJIT_INST_4x(fmadd, Fmadd_v, Vec, Vec, Vec, Vec);
+ ASMJIT_INST_3x(fmax, Fmax_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(fmaxnm, Fmaxnm_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(fmaxnmp, Fmaxnmp_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(fmaxnmp, Fmaxnmp_v, Vec, Vec);
+ ASMJIT_INST_2x(fmaxnmv, Fmaxnmv_v, Vec, Vec);
+ ASMJIT_INST_3x(fmaxp, Fmaxp_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(fmaxp, Fmaxp_v, Vec, Vec);
+ ASMJIT_INST_2x(fmaxv, Fmaxv_v, Vec, Vec);
+ ASMJIT_INST_3x(fmin, Fmin_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(fminnm, Fminnm_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(fminnmv, Fminnmv_v, Vec, Vec);
+ ASMJIT_INST_3x(fminnmp, Fminnmp_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(fminnmp, Fminnmp_v, Vec, Vec);
+ ASMJIT_INST_2x(fminp, Fminp_v, Vec, Vec);
+ ASMJIT_INST_3x(fminp, Fminp_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(fminv, Fminv_v, Vec, Vec);
+ ASMJIT_INST_3x(fmla, Fmla_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(fmls, Fmls_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(fmov, Fmov_v, Gp, Vec);
+ ASMJIT_INST_2x(fmov, Fmov_v, Vec, Gp);
+ ASMJIT_INST_2x(fmov, Fmov_v, Vec, Vec);
+ ASMJIT_INST_2x(fmov, Fmov_v, Vec, Imm);
+ ASMJIT_INST_4x(fmsub, Fmsub_v, Vec, Vec, Vec, Vec);
+ ASMJIT_INST_3x(fmul, Fmul_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(fmulx, Fmulx_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(fneg, Fneg_v, Vec, Vec);
+ ASMJIT_INST_4x(fnmadd, Fnmadd_v, Vec, Vec, Vec, Vec);
+ ASMJIT_INST_4x(fnmsub, Fnmsub_v, Vec, Vec, Vec, Vec);
+ ASMJIT_INST_3x(fnmul, Fnmul_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(frecpe, Frecpe_v, Vec, Vec);
+ ASMJIT_INST_3x(frecps, Frecps_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(frecpx, Frecpx_v, Vec, Vec);
+ ASMJIT_INST_2x(frint32x, Frint32x_v, Vec, Vec);
+ ASMJIT_INST_2x(frint32z, Frint32z_v, Vec, Vec);
+ ASMJIT_INST_2x(frint64x, Frint64x_v, Vec, Vec);
+ ASMJIT_INST_2x(frint64z, Frint64z_v, Vec, Vec);
+ ASMJIT_INST_2x(frinta, Frinta_v, Vec, Vec);
+ ASMJIT_INST_2x(frinti, Frinti_v, Vec, Vec);
+ ASMJIT_INST_2x(frintm, Frintm_v, Vec, Vec);
+ ASMJIT_INST_2x(frintn, Frintn_v, Vec, Vec);
+ ASMJIT_INST_2x(frintp, Frintp_v, Vec, Vec);
+ ASMJIT_INST_2x(frintx, Frintx_v, Vec, Vec);
+ ASMJIT_INST_2x(frintz, Frintz_v, Vec, Vec);
+ ASMJIT_INST_2x(frsqrte, Frsqrte_v, Vec, Vec);
+ ASMJIT_INST_3x(frsqrts, Frsqrts_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(fsqrt, Fsqrt_v, Vec, Vec);
+ ASMJIT_INST_3x(fsub, Fsub_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(ins, Ins_v, Vec, Gp);
+ ASMJIT_INST_2x(ins, Ins_v, Vec, Vec);
+ ASMJIT_INST_2x(ld1, Ld1_v, Vec, Mem);
+ ASMJIT_INST_3x(ld1, Ld1_v, Vec, Vec, Mem);
+ ASMJIT_INST_4x(ld1, Ld1_v, Vec, Vec, Vec, Mem);
+ ASMJIT_INST_5x(ld1, Ld1_v, Vec, Vec, Vec, Vec, Mem);
+ ASMJIT_INST_2x(ld1r, Ld1r_v, Vec, Mem);
+ ASMJIT_INST_3x(ld2, Ld2_v, Vec, Vec, Mem);
+ ASMJIT_INST_3x(ld2r, Ld2r_v, Vec, Vec, Mem);
+ ASMJIT_INST_4x(ld3, Ld3_v, Vec, Vec, Vec, Mem);
+ ASMJIT_INST_4x(ld3r, Ld3r_v, Vec, Vec, Vec, Mem);
+ ASMJIT_INST_5x(ld4, Ld4_v, Vec, Vec, Vec, Vec, Mem);
+ ASMJIT_INST_5x(ld4r, Ld4r_v, Vec, Vec, Vec, Vec, Mem);
+ ASMJIT_INST_3x(ldnp, Ldnp_v, Vec, Vec, Mem);
+ ASMJIT_INST_3x(ldp, Ldp_v, Vec, Vec, Mem);
+ ASMJIT_INST_2x(ldr, Ldr_v, Vec, Mem);
+ ASMJIT_INST_2x(ldur, Ldur_v, Vec, Mem);
+ ASMJIT_INST_3x(mla, Mla_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(mls, Mls_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(mov, Mov_v, Vec, Vec);
+ ASMJIT_INST_2x(mov, Mov_v, Gp, Vec);
+ ASMJIT_INST_2x(mov, Mov_v, Vec, Gp);
+ ASMJIT_INST_2x(movi, Movi_v, Vec, Imm);
+ ASMJIT_INST_3x(movi, Movi_v, Vec, Imm, Imm);
+ ASMJIT_INST_3x(mul, Mul_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(mvn, Mvn_v, Vec, Vec);
+ ASMJIT_INST_2x(mvni, Mvni_v, Vec, Imm);
+ ASMJIT_INST_3x(mvni, Mvni_v, Vec, Imm, Imm);
+ ASMJIT_INST_2x(neg, Neg_v, Vec, Vec);
+ ASMJIT_INST_2x(not_, Not_v, Vec, Vec);
+ ASMJIT_INST_3x(orn, Orn_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(orr, Orr_v, Vec, Imm);
+ ASMJIT_INST_3x(orr, Orr_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(orr, Orr_v, Vec, Imm, Imm);
+ ASMJIT_INST_3x(pmul, Pmul_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(pmull, Pmull_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(pmull2, Pmull2_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(raddhn, Raddhn_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(raddhn2, Raddhn2_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(rbit, Rbit_v, Vec, Vec);
+ ASMJIT_INST_2x(rev16, Rev16_v, Vec, Vec);
+ ASMJIT_INST_2x(rev32, Rev32_v, Vec, Vec);
+ ASMJIT_INST_2x(rev64, Rev64_v, Vec, Vec);
+ ASMJIT_INST_3x(rshrn, Rshrn_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(rshrn2, Rshrn2_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(rsubhn, Rsubhn_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(rsubhn2, Rsubhn2_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(saba, Saba_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sabal, Sabal_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sabal2, Sabal2_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sabd, Sabd_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sabdl, Sabdl_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sabdl2, Sabdl2_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(sadalp, Sadalp_v, Vec, Vec);
+ ASMJIT_INST_3x(saddl, Saddl_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(saddl2, Saddl2_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(saddlp, Saddlp_v, Vec, Vec);
+ ASMJIT_INST_2x(saddlv, Saddlv_v, Vec, Vec);
+ ASMJIT_INST_3x(saddw, Saddw_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(saddw2, Saddw2_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(scvtf, Scvtf_v, Vec, Gp);
+ ASMJIT_INST_3x(scvtf, Scvtf_v, Vec, Gp, Imm);
+ ASMJIT_INST_2x(scvtf, Scvtf_v, Vec, Vec);
+ ASMJIT_INST_3x(scvtf, Scvtf_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(shadd, Shadd_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(shl, Shl_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(shll, Shll_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(shll2, Shll2_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(shrn, Shrn_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(shrn2, Shrn2_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(shsub, Shsub_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sli, Sli_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(smax, Smax_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(smaxp, Smaxp_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(smaxv, Smaxv_v, Vec, Vec);
+ ASMJIT_INST_3x(smin, Smin_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sminp, Sminp_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(sminv, Sminv_v, Vec, Vec);
+ ASMJIT_INST_3x(smlal, Smlal_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(smlal2, Smlal2_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(smlsl, Smlsl_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(smlsl2, Smlsl2_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(smov, Smov_v, Gp, Vec);
+ ASMJIT_INST_3x(smull, Smull_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(smull2, Smull2_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(sqabs, Sqabs_v, Vec, Vec);
+ ASMJIT_INST_3x(sqadd, Sqadd_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sqdmlal, Sqdmlal_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sqdmlal2, Sqdmlal2_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sqdmlsl, Sqdmlsl_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sqdmlsl2, Sqdmlsl2_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sqdmulh, Sqdmulh_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sqdmull, Sqdmull_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sqdmull2, Sqdmull2_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(sqneg, Sqneg_v, Vec, Vec);
+ ASMJIT_INST_3x(sqrdmulh, Sqrdmulh_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sqrshl, Sqrshl_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sqrshrn, Sqrshrn_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(sqrshrn2, Sqrshrn2_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(sqrshrun, Sqrshrun_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(sqrshrun2, Sqrshrun2_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(sqshl, Sqshl_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sqshl, Sqshl_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(sqshlu, Sqshlu_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(sqshrn, Sqshrn_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(sqshrn2, Sqshrn2_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(sqshrun, Sqshrun_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(sqshrun2, Sqshrun2_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(sqsub, Sqsub_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(sqxtn, Sqxtn_v, Vec, Vec);
+ ASMJIT_INST_2x(sqxtn2, Sqxtn2_v, Vec, Vec);
+ ASMJIT_INST_2x(sqxtun, Sqxtun_v, Vec, Vec);
+ ASMJIT_INST_2x(sqxtun2, Sqxtun2_v, Vec, Vec);
+ ASMJIT_INST_3x(srhadd, Srhadd_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sri, Sri_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(srshl, Srshl_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(srshr, Srshr_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(srsra, Srsra_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(sshl, Sshl_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sshll, Sshll_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(sshll2, Sshll2_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(sshr, Sshr_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(ssra, Ssra_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(ssubl, Ssubl_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(ssubl2, Ssubl2_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(ssubw, Ssubw_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(ssubw2, Ssubw2_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(st1, St1_v, Vec, Mem);
+ ASMJIT_INST_3x(st1, St1_v, Vec, Vec, Mem);
+ ASMJIT_INST_4x(st1, St1_v, Vec, Vec, Vec, Mem);
+ ASMJIT_INST_5x(st1, St1_v, Vec, Vec, Vec, Vec, Mem);
+ ASMJIT_INST_3x(st2, St2_v, Vec, Vec, Mem);
+ ASMJIT_INST_4x(st3, St3_v, Vec, Vec, Vec, Mem);
+ ASMJIT_INST_5x(st4, St4_v, Vec, Vec, Vec, Vec, Mem);
+ ASMJIT_INST_3x(stnp, Stnp_v, Vec, Vec, Mem);
+ ASMJIT_INST_3x(stp, Stp_v, Vec, Vec, Mem);
+ ASMJIT_INST_2x(str, Str_v, Vec, Mem);
+ ASMJIT_INST_2x(stur, Stur_v, Vec, Mem);
+ ASMJIT_INST_3x(sub, Sub_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(subhn, Subhn_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(subhn2, Subhn2_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(suqadd, Suqadd_v, Vec, Vec);
+ ASMJIT_INST_2x(sxtl, Sxtl_v, Vec, Vec);
+ ASMJIT_INST_2x(sxtl2, Sxtl2_v, Vec, Vec);
+ ASMJIT_INST_3x(tbl, Tbl_v, Vec, Vec, Vec);
+ ASMJIT_INST_4x(tbl, Tbl_v, Vec, Vec, Vec, Vec);
+ ASMJIT_INST_5x(tbl, Tbl_v, Vec, Vec, Vec, Vec, Vec);
+ ASMJIT_INST_6x(tbl, Tbl_v, Vec, Vec, Vec, Vec, Vec, Vec);
+ ASMJIT_INST_3x(tbx, Tbx_v, Vec, Vec, Vec);
+ ASMJIT_INST_4x(tbx, Tbx_v, Vec, Vec, Vec, Vec);
+ ASMJIT_INST_5x(tbx, Tbx_v, Vec, Vec, Vec, Vec, Vec);
+ ASMJIT_INST_6x(tbx, Tbx_v, Vec, Vec, Vec, Vec, Vec, Vec);
+ ASMJIT_INST_3x(trn1, Trn1_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(trn2, Trn2_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(uaba, Uaba_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(uabal, Uabal_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(uabal2, Uabal2_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(uabd, Uabd_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(uabdl, Uabdl_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(uabdl2, Uabdl2_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(uadalp, Uadalp_v, Vec, Vec);
+ ASMJIT_INST_3x(uaddl, Uaddl_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(uaddl2, Uaddl2_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(uaddlp, Uaddlp_v, Vec, Vec);
+ ASMJIT_INST_2x(uaddlv, Uaddlv_v, Vec, Vec);
+ ASMJIT_INST_3x(uaddw, Uaddw_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(uaddw2, Uaddw2_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(ucvtf, Ucvtf_v, Vec, Gp);
+ ASMJIT_INST_3x(ucvtf, Ucvtf_v, Vec, Gp, Imm);
+ ASMJIT_INST_2x(ucvtf, Ucvtf_v, Vec, Vec);
+ ASMJIT_INST_3x(ucvtf, Ucvtf_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(uhadd, Uhadd_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(uhsub, Uhsub_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(umax, Umax_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(umaxp, Umaxp_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(umaxv, Umaxv_v, Vec, Vec);
+ ASMJIT_INST_3x(umin, Umin_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(uminp, Uminp_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(uminv, Uminv_v, Vec, Vec);
+ ASMJIT_INST_3x(umlal, Umlal_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(umlal2, Umlal2_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(umlsl, Umlsl_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(umlsl2, Umlsl2_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(umov, Umov_v, Gp, Vec);
+ ASMJIT_INST_3x(umull, Umull_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(umull2, Umull2_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(uqadd, Uqadd_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(uqrshl, Uqrshl_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(uqrshl, Uqrshl_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(uqrshrn, Uqrshrn_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(uqrshrn2, Uqrshrn2_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(uqshl, Uqshl_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(uqshl, Uqshl_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(uqshrn, Uqshrn_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(uqshrn2, Uqshrn2_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(uqsub, Uqsub_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(uqxtn, Uqxtn_v, Vec, Vec);
+ ASMJIT_INST_2x(uqxtn2, Uqxtn2_v, Vec, Vec);
+ ASMJIT_INST_2x(urecpe, Urecpe_v, Vec, Vec);
+ ASMJIT_INST_3x(urhadd, Urhadd_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(urshl, Urshl_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(urshr, Urshr_v, Vec, Vec, Imm);
+ ASMJIT_INST_2x(ursqrte, Ursqrte_v, Vec, Vec);
+ ASMJIT_INST_3x(ursra, Ursra_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(ushl, Ushl_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(ushll, Ushll_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(ushll2, Ushll2_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(ushr, Ushr_v, Vec, Vec, Imm);
+ ASMJIT_INST_2x(usqadd, Usqadd_v, Vec, Vec);
+ ASMJIT_INST_3x(usra, Usra_v, Vec, Vec, Imm);
+ ASMJIT_INST_3x(usubl, Usubl_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(usubl2, Usubl2_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(usubw, Usubw_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(usubw2, Usubw2_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(uxtl, Uxtl_v, Vec, Vec);
+ ASMJIT_INST_2x(uxtl2, Uxtl2_v, Vec, Vec);
+ ASMJIT_INST_3x(uzp1, Uzp1_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(uzp2, Uzp2_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(xtn, Xtn_v, Vec, Vec);
+ ASMJIT_INST_2x(xtn2, Xtn2_v, Vec, Vec);
+ ASMJIT_INST_3x(zip1, Zip1_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(zip2, Zip2_v, Vec, Vec, Vec);
+
+ //! \}
+
+ //! \name AES Instructions
+ //! \{
+
+ ASMJIT_INST_2x(aesd, Aesd_v, Vec, Vec);
+ ASMJIT_INST_2x(aese, Aese_v, Vec, Vec);
+ ASMJIT_INST_2x(aesimc, Aesimc_v, Vec, Vec);
+ ASMJIT_INST_2x(aesmc, Aesmc_v, Vec, Vec);
+
+ //! \}
+
+ //! \name SHA1 Instructions
+ //! \{
+
+ ASMJIT_INST_3x(sha1c, Sha1c_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(sha1h, Sha1h_v, Vec, Vec);
+ ASMJIT_INST_3x(sha1m, Sha1m_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sha1p, Sha1p_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sha1su0, Sha1su0_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(sha1su1, Sha1su1_v, Vec, Vec);
+
+ //! \}
+
+ //! \name SHA2 Instructions
+ //! \{
+
+ ASMJIT_INST_3x(sha256h, Sha256h_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sha256h2, Sha256h2_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(sha256su0, Sha256su0_v, Vec, Vec);
+ ASMJIT_INST_3x(sha256su1, Sha256su1_v, Vec, Vec, Vec);
+
+ //! \}
+
+ //! \name RDMA Instructions (ARMv8.1-A)
+ //! \{
+
+ ASMJIT_INST_3x(sqrdmlah, Sqrdmlah_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sqrdmlsh, Sqrdmlsh_v, Vec, Vec, Vec);
+
+ //! \}
+
+ //! \name FCMA Instruction (ARMv8.3-A)
+ //! \{
+
+ ASMJIT_INST_4x(fcadd, Fcadd_v, Vec, Vec, Vec, Imm);
+ ASMJIT_INST_4x(fcmla, Fcmla_v, Vec, Vec, Vec, Imm);
+
+ //! \}
+
+ //! \name FJCVTZS Instruction (ARMv8.3-A)
+ //! \{
+
+ ASMJIT_INST_2x(fjcvtzs, Fjcvtzs_v, Gp, Vec);
+
+ //! \}
+
+ //! \name FP16FML Instructions (ARMv8.4-A, optional in ARMv8.2-A)
+ //! \{
+
+ ASMJIT_INST_3x(fmlal, Fmlal_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(fmlal2, Fmlal2_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(fmlsl, Fmlsl_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(fmlsl2, Fmlsl2_v, Vec, Vec, Vec);
+
+
+ //! \}
+
+ //! \name SHA3 Instructions (ARMv8.4-A, optional in ARMv8.2-A)
+ //! \{
+
+ ASMJIT_INST_4x(bcax, Bcax_v, Vec, Vec, Vec, Vec);
+ ASMJIT_INST_4x(eor3, Eor3_v, Vec, Vec, Vec, Vec);
+ ASMJIT_INST_3x(rax1, Rax1_v, Vec, Vec, Vec);
+ ASMJIT_INST_4x(xar, Xar_v, Vec, Vec, Vec, Imm);
+
+ //! \}
+
+ //! \name SHA512 Instructions (ARMv8.4-A)
+ //! \{
+
+ ASMJIT_INST_3x(sha512h, Sha512h_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sha512h2, Sha512h2_v, Vec, Vec, Vec);
+ ASMJIT_INST_2x(sha512su0, Sha512su0_v, Vec, Vec);
+ ASMJIT_INST_3x(sha512su1, Sha512su1_v, Vec, Vec, Vec);
+
+ //! \}
+
+ //! \name SM3 Instructions (ARMv8.4-A)
+ //! \{
+
+ ASMJIT_INST_3x(sm3partw1, Sm3partw1_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sm3partw2, Sm3partw2_v, Vec, Vec, Vec);
+ ASMJIT_INST_4x(sm3ss1, Sm3ss1_v, Vec, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sm3tt1a, Sm3tt1a_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sm3tt1b, Sm3tt1b_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sm3tt2a, Sm3tt2a_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sm3tt2b, Sm3tt2b_v, Vec, Vec, Vec);
+
+ //! \}
+
+ //! \name SM4 Instructions (ARMv8.4-A)
+ //! \{
+
+ ASMJIT_INST_2x(sm4e, Sm4e_v, Vec, Vec);
+ ASMJIT_INST_3x(sm4ekey, Sm4ekey_v, Vec, Vec, Vec);
+
+ //! \}
+
+ //! \name DOTPROD Instructions (ARMv8.4-A, optional in ARMv8.2-A)
+ //! \{
+
+ ASMJIT_INST_3x(sdot, Sdot_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(udot, Udot_v, Vec, Vec, Vec);
+
+ //! \}
+
+ //! \name BF16 Instructions (ARMv8.6-A)
+ //! \{
+
+ ASMJIT_INST_2x(bfcvt, Bfcvt_v, Vec, Vec);
+ ASMJIT_INST_2x(bfcvtn, Bfcvtn_v, Vec, Vec);
+ ASMJIT_INST_2x(bfcvtn2, Bfcvtn2_v, Vec, Vec);
+ ASMJIT_INST_3x(bfmlalb, Bfmlalb_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(bfmlalt, Bfmlalt_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(bfmmla, Bfmmla_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(bfdot, Bfdot_v, Vec, Vec, Vec);
+
+ //! \}
+
+ //! \name I8MM Instructions (ARMv8.6-A)
+ //! \{
+
+ ASMJIT_INST_3x(smmla, Smmla_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(sudot, Sudot_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(ummla, Ummla_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(usdot, Usdot_v, Vec, Vec, Vec);
+ ASMJIT_INST_3x(usmmla, Usmmla_v, Vec, Vec, Vec);
+
+ //! \}
+};
+
+//! Emitter (ARM).
+//!
+//! \note This class cannot be instantiated, you can only cast to it and use it as emitter that emits to either
+//! `a64::Assembler`, `a64::Builder`, or `a64::Compiler` (use with caution with `a64::Compiler` as it requires
+//! virtual registers).
+class Emitter : public BaseEmitter, public EmitterExplicitT<Emitter> {
+ ASMJIT_NONCONSTRUCTIBLE(Emitter)
+};
+
+//! \}
+
+#undef ASMJIT_INST_0x
+#undef ASMJIT_INST_1x
+#undef ASMJIT_INST_2x
+#undef ASMJIT_INST_3x
+#undef ASMJIT_INST_4x
+#undef ASMJIT_INST_5x
+#undef ASMJIT_INST_6x
+#undef ASMJIT_INST_1cc
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // ASMJIT_ARM_A64EMITTER_H_INCLUDED
diff --git a/src/asmjit/arm/a64formatter.cpp b/src/asmjit/arm/a64formatter.cpp
new file mode 100644
index 0000000..bccb68b
--- /dev/null
+++ b/src/asmjit/arm/a64formatter.cpp
@@ -0,0 +1,298 @@
+// 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"
+#ifndef ASMJIT_NO_LOGGING
+
+#include "../core/misc_p.h"
+#include "../core/support.h"
+#include "../arm/a64formatter_p.h"
+#include "../arm/a64instapi_p.h"
+#include "../arm/a64instdb_p.h"
+#include "../arm/a64operand.h"
+
+#ifndef ASMJIT_NO_COMPILER
+ #include "../core/compiler.h"
+#endif
+
+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
+// ===========================================
+
+ASMJIT_FAVOR_SIZE Error FormatterInternal::formatInstruction(
+ String& sb,
+ FormatFlags flags,
+ const BaseEmitter* emitter,
+ 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));
+ else
+ ASMJIT_PROPAGATE(sb.appendFormat("[InstId=#%u]", unsigned(instId)));
+
+ CondCode cc = inst.armCondCode();
+ if (cc != CondCode::kAL) {
+ ASMJIT_PROPAGATE(sb.append('.'));
+ ASMJIT_PROPAGATE(formatCondCode(sb, cc));
+ }
+
+ for (uint32_t i = 0; i < opCount; i++) {
+ const Operand_& op = operands[i];
+ if (op.isNone())
+ break;
+
+ ASMJIT_PROPAGATE(sb.append(i == 0 ? " " : ", "));
+ ASMJIT_PROPAGATE(formatOperand(sb, flags, emitter, arch, op));
+ }
+
+ return kErrorOk;
+}
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // !ASMJIT_NO_LOGGING
diff --git a/src/asmjit/arm/a64formatter_p.h b/src/asmjit/arm/a64formatter_p.h
new file mode 100644
index 0000000..bd7a144
--- /dev/null
+++ b/src/asmjit/arm/a64formatter_p.h
@@ -0,0 +1,59 @@
+// 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_ARM_A64FORMATTER_P_H_INCLUDED
+#define ASMJIT_ARM_A64FORMATTER_P_H_INCLUDED
+
+#include "../core/api-config.h"
+#ifndef ASMJIT_NO_LOGGING
+
+#include "../core/formatter.h"
+#include "../core/string.h"
+#include "../arm/armformatter_p.h"
+#include "../arm/a64globals.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+
+//! \cond INTERNAL
+//! \addtogroup asmjit_a64
+//! \{
+
+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,
+ const BaseEmitter* emitter,
+ Arch arch,
+ const BaseInst& inst, const Operand_* operands, size_t opCount) noexcept;
+
+} // {FormatterInternal}
+
+//! \}
+//! \endcond
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // !ASMJIT_NO_LOGGING
+#endif // ASMJIT_ARM_A64FORMATTER_P_H_INCLUDED
diff --git a/src/asmjit/arm/a64func.cpp b/src/asmjit/arm/a64func.cpp
new file mode 100644
index 0000000..55e3f2e
--- /dev/null
+++ b/src/asmjit/arm/a64func.cpp
@@ -0,0 +1,189 @@
+// 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"
+#if !defined(ASMJIT_NO_AARCH64)
+
+#include "../arm/a64func_p.h"
+#include "../arm/a64operand.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+
+namespace FuncInternal {
+
+static inline bool shouldThreatAsCDecl(CallConvId ccId) noexcept {
+ return ccId == CallConvId::kCDecl ||
+ ccId == CallConvId::kStdCall ||
+ ccId == CallConvId::kFastCall ||
+ ccId == CallConvId::kVectorCall ||
+ ccId == CallConvId::kThisCall ||
+ ccId == CallConvId::kRegParm1 ||
+ ccId == CallConvId::kRegParm2 ||
+ ccId == CallConvId::kRegParm3;
+}
+
+static RegType regTypeFromFpOrVecTypeId(TypeId typeId) noexcept {
+ if (typeId == TypeId::kFloat32)
+ return RegType::kARM_VecS;
+ else if (typeId == TypeId::kFloat64)
+ return RegType::kARM_VecD;
+ else if (TypeUtils::isVec32(typeId))
+ return RegType::kARM_VecS;
+ else if (TypeUtils::isVec64(typeId))
+ return RegType::kARM_VecD;
+ else if (TypeUtils::isVec128(typeId))
+ return RegType::kARM_VecV;
+ else
+ return RegType::kNone;
+}
+
+ASMJIT_FAVOR_SIZE Error initCallConv(CallConv& cc, CallConvId ccId, const Environment& environment) noexcept {
+ cc.setArch(environment.arch());
+
+ 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::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)) {
+ // 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));
+ cc.setPreservedRegs(RegGroup::kVec, Support::bitMask(8, 9, 10, 11, 12, 13, 14, 15));
+ }
+ else {
+ cc.setId(ccId);
+ cc.setSaveRestoreRegSize(RegGroup::kVec, 16);
+ cc.setPreservedRegs(RegGroup::kGp, Support::bitMask(4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30));
+ cc.setPreservedRegs(RegGroup::kVec, Support::bitMask(4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31));
+ }
+
+ return kErrorOk;
+}
+
+ASMJIT_FAVOR_SIZE Error initFuncDetail(FuncDetail& func, const FuncSignature& signature, uint32_t registerSize) noexcept {
+ DebugUtils::unused(signature);
+
+ const CallConv& cc = func.callConv();
+ uint32_t stackOffset = 0;
+
+ uint32_t i;
+ uint32_t argCount = func.argCount();
+
+ if (func.hasRet()) {
+ for (uint32_t valueIndex = 0; valueIndex < Globals::kMaxValuePack; valueIndex++) {
+ TypeId typeId = func._rets[valueIndex].typeId();
+
+ // Terminate at the first void type (end of the pack).
+ if (typeId == TypeId::kVoid)
+ break;
+
+ switch (typeId) {
+ case TypeId::kInt8:
+ case TypeId::kInt16:
+ case TypeId::kInt32: {
+ func._rets[valueIndex].initReg(RegType::kARM_GpW, valueIndex, TypeId::kInt32);
+ break;
+ }
+
+ case TypeId::kUInt8:
+ case TypeId::kUInt16:
+ case TypeId::kUInt32: {
+ func._rets[valueIndex].initReg(RegType::kARM_GpW, valueIndex, TypeId::kUInt32);
+ break;
+ }
+
+ case TypeId::kInt64:
+ case TypeId::kUInt64: {
+ func._rets[valueIndex].initReg(RegType::kARM_GpX, valueIndex, typeId);
+ break;
+ }
+
+ default: {
+ RegType regType = regTypeFromFpOrVecTypeId(typeId);
+ if (regType == RegType::kNone)
+ return DebugUtils::errored(kErrorInvalidRegType);
+
+ func._rets[valueIndex].initReg(regType, valueIndex, typeId);
+ break;
+ }
+ }
+ }
+ }
+
+ switch (cc.strategy()) {
+ case CallConvStrategy::kDefault: {
+ uint32_t gpzPos = 0;
+ uint32_t vecPos = 0;
+
+ for (i = 0; i < argCount; i++) {
+ FuncValue& arg = func._args[i][0];
+ TypeId typeId = arg.typeId();
+
+ if (TypeUtils::isInt(typeId)) {
+ uint32_t regId = BaseReg::kIdBad;
+
+ if (gpzPos < CallConv::kMaxRegArgsPerGroup)
+ regId = cc._passedOrder[RegGroup::kGp].id[gpzPos];
+
+ if (regId != BaseReg::kIdBad) {
+ RegType regType = typeId <= TypeId::kUInt32 ? RegType::kARM_GpW : RegType::kARM_GpX;
+ arg.assignRegData(regType, regId);
+ func.addUsedRegs(RegGroup::kGp, Support::bitMask(regId));
+ gpzPos++;
+ }
+ else {
+ uint32_t size = Support::max<uint32_t>(TypeUtils::sizeOf(typeId), registerSize);
+ arg.assignStackOffset(int32_t(stackOffset));
+ stackOffset += size;
+ }
+ continue;
+ }
+
+ if (TypeUtils::isFloat(typeId) || TypeUtils::isVec(typeId)) {
+ uint32_t regId = BaseReg::kIdBad;
+
+ if (vecPos < CallConv::kMaxRegArgsPerGroup)
+ regId = cc._passedOrder[RegGroup::kVec].id[vecPos];
+
+ if (regId != BaseReg::kIdBad) {
+ RegType regType = regTypeFromFpOrVecTypeId(typeId);
+ if (regType == RegType::kNone)
+ return DebugUtils::errored(kErrorInvalidRegType);
+
+ arg.initTypeId(typeId);
+ arg.assignRegData(regType, regId);
+ func.addUsedRegs(RegGroup::kVec, Support::bitMask(regId));
+ vecPos++;
+ }
+ else {
+ uint32_t size = TypeUtils::sizeOf(typeId);
+ arg.assignStackOffset(int32_t(stackOffset));
+ stackOffset += size;
+ }
+ continue;
+ }
+ }
+ break;
+ }
+
+ default:
+ return DebugUtils::errored(kErrorInvalidState);
+ }
+
+ func._argStackSize = stackOffset;
+ return kErrorOk;
+}
+
+} // {FuncInternal}
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // !ASMJIT_NO_AARCH64
diff --git a/src/asmjit/arm/a64func_p.h b/src/asmjit/arm/a64func_p.h
new file mode 100644
index 0000000..9f531fc
--- /dev/null
+++ b/src/asmjit/arm/a64func_p.h
@@ -0,0 +1,33 @@
+// 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_ARM_A64FUNC_P_H_INCLUDED
+#define ASMJIT_ARM_A64FUNC_P_H_INCLUDED
+
+#include "../core/func.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+
+//! \cond INTERNAL
+//! \addtogroup asmjit_a64
+//! \{
+
+//! AArch64-specific function API (calling conventions and other utilities).
+namespace FuncInternal {
+
+//! Initialize `CallConv` structure (AArch64 specific).
+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;
+
+} // {FuncInternal}
+
+//! \}
+//! \endcond
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // ASMJIT_ARM_A64FUNC_P_H_INCLUDED
diff --git a/src/asmjit/arm/a64globals.h b/src/asmjit/arm/a64globals.h
new file mode 100644
index 0000000..2b6b6f0
--- /dev/null
+++ b/src/asmjit/arm/a64globals.h
@@ -0,0 +1,1894 @@
+// 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_ARM_A64GLOBALS_H_INCLUDED
+#define ASMJIT_ARM_A64GLOBALS_H_INCLUDED
+
+#include "../arm/armglobals.h"
+
+//! \namespace asmjit::a64
+//! \ingroup asmjit_a64
+//!
+//! AArch64 backend.
+
+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 {
+ //! Instruction id.
+ enum Id : uint32_t {
+ // ${InstId:Begin}
+ kIdNone = 0, //!< Instruction ''.
+ kIdAdc, //!< Instruction 'adc'.
+ kIdAdcs, //!< Instruction 'adcs'.
+ kIdAdd, //!< Instruction 'add'.
+ kIdAddg, //!< Instruction 'addg'.
+ kIdAdds, //!< Instruction 'adds'.
+ kIdAdr, //!< Instruction 'adr'.
+ kIdAdrp, //!< Instruction 'adrp'.
+ kIdAnd, //!< Instruction 'and'.
+ kIdAnds, //!< Instruction 'ands'.
+ kIdAsr, //!< Instruction 'asr'.
+ kIdAsrv, //!< Instruction 'asrv'.
+ kIdAt, //!< Instruction 'at'.
+ kIdAutda, //!< Instruction 'autda'.
+ kIdAutdza, //!< Instruction 'autdza'.
+ kIdAutdb, //!< Instruction 'autdb'.
+ kIdAutdzb, //!< Instruction 'autdzb'.
+ kIdAutia, //!< Instruction 'autia'.
+ kIdAutia1716, //!< Instruction 'autia1716'.
+ kIdAutiasp, //!< Instruction 'autiasp'.
+ kIdAutiaz, //!< Instruction 'autiaz'.
+ kIdAutib, //!< Instruction 'autib'.
+ kIdAutib1716, //!< Instruction 'autib1716'.
+ kIdAutibsp, //!< Instruction 'autibsp'.
+ kIdAutibz, //!< Instruction 'autibz'.
+ kIdAutiza, //!< Instruction 'autiza'.
+ kIdAutizb, //!< Instruction 'autizb'.
+ kIdAxflag, //!< Instruction 'axflag'.
+ kIdB, //!< Instruction 'b'.
+ kIdBfc, //!< Instruction 'bfc'.
+ kIdBfi, //!< Instruction 'bfi'.
+ kIdBfm, //!< Instruction 'bfm'.
+ kIdBfxil, //!< Instruction 'bfxil'.
+ kIdBic, //!< Instruction 'bic'.
+ kIdBics, //!< Instruction 'bics'.
+ kIdBl, //!< Instruction 'bl'.
+ kIdBlr, //!< Instruction 'blr'.
+ kIdBr, //!< Instruction 'br'.
+ kIdBrk, //!< Instruction 'brk'.
+ kIdCas, //!< Instruction 'cas'.
+ kIdCasa, //!< Instruction 'casa'.
+ kIdCasab, //!< Instruction 'casab'.
+ kIdCasah, //!< Instruction 'casah'.
+ kIdCasal, //!< Instruction 'casal'.
+ kIdCasalb, //!< Instruction 'casalb'.
+ kIdCasalh, //!< Instruction 'casalh'.
+ kIdCasb, //!< Instruction 'casb'.
+ kIdCash, //!< Instruction 'cash'.
+ kIdCasl, //!< Instruction 'casl'.
+ kIdCaslb, //!< Instruction 'caslb'.
+ kIdCaslh, //!< Instruction 'caslh'.
+ kIdCasp, //!< Instruction 'casp'.
+ kIdCaspa, //!< Instruction 'caspa'.
+ kIdCaspal, //!< Instruction 'caspal'.
+ kIdCaspl, //!< Instruction 'caspl'.
+ kIdCbnz, //!< Instruction 'cbnz'.
+ kIdCbz, //!< Instruction 'cbz'.
+ kIdCcmn, //!< Instruction 'ccmn'.
+ kIdCcmp, //!< Instruction 'ccmp'.
+ kIdCfinv, //!< Instruction 'cfinv'.
+ kIdCinc, //!< Instruction 'cinc'.
+ kIdCinv, //!< Instruction 'cinv'.
+ kIdClrex, //!< Instruction 'clrex'.
+ kIdCls, //!< Instruction 'cls'.
+ kIdClz, //!< Instruction 'clz'.
+ kIdCmn, //!< Instruction 'cmn'.
+ kIdCmp, //!< Instruction 'cmp'.
+ kIdCmpp, //!< Instruction 'cmpp'.
+ kIdCneg, //!< Instruction 'cneg'.
+ kIdCrc32b, //!< Instruction 'crc32b'.
+ kIdCrc32cb, //!< Instruction 'crc32cb'.
+ kIdCrc32ch, //!< Instruction 'crc32ch'.
+ kIdCrc32cw, //!< Instruction 'crc32cw'.
+ kIdCrc32cx, //!< Instruction 'crc32cx'.
+ kIdCrc32h, //!< Instruction 'crc32h'.
+ kIdCrc32w, //!< Instruction 'crc32w'.
+ kIdCrc32x, //!< Instruction 'crc32x'.
+ kIdCsdb, //!< Instruction 'csdb'.
+ kIdCsel, //!< Instruction 'csel'.
+ kIdCset, //!< Instruction 'cset'.
+ kIdCsetm, //!< Instruction 'csetm'.
+ kIdCsinc, //!< Instruction 'csinc'.
+ kIdCsinv, //!< Instruction 'csinv'.
+ kIdCsneg, //!< Instruction 'csneg'.
+ kIdDc, //!< Instruction 'dc'.
+ kIdDcps1, //!< Instruction 'dcps1'.
+ kIdDcps2, //!< Instruction 'dcps2'.
+ kIdDcps3, //!< Instruction 'dcps3'.
+ kIdDgh, //!< Instruction 'dgh'.
+ kIdDmb, //!< Instruction 'dmb'.
+ kIdDrps, //!< Instruction 'drps'.
+ kIdDsb, //!< Instruction 'dsb'.
+ kIdEon, //!< Instruction 'eon'.
+ kIdEor, //!< Instruction 'eor'.
+ kIdEsb, //!< Instruction 'esb'.
+ kIdExtr, //!< Instruction 'extr'.
+ kIdEret, //!< Instruction 'eret'.
+ kIdGmi, //!< Instruction 'gmi'.
+ kIdHint, //!< Instruction 'hint'.
+ kIdHlt, //!< Instruction 'hlt'.
+ kIdHvc, //!< Instruction 'hvc'.
+ kIdIc, //!< Instruction 'ic'.
+ kIdIsb, //!< Instruction 'isb'.
+ kIdLdadd, //!< Instruction 'ldadd'.
+ kIdLdadda, //!< Instruction 'ldadda'.
+ kIdLdaddab, //!< Instruction 'ldaddab'.
+ kIdLdaddah, //!< Instruction 'ldaddah'.
+ kIdLdaddal, //!< Instruction 'ldaddal'.
+ kIdLdaddalb, //!< Instruction 'ldaddalb'.
+ kIdLdaddalh, //!< Instruction 'ldaddalh'.
+ kIdLdaddb, //!< Instruction 'ldaddb'.
+ kIdLdaddh, //!< Instruction 'ldaddh'.
+ kIdLdaddl, //!< Instruction 'ldaddl'.
+ kIdLdaddlb, //!< Instruction 'ldaddlb'.
+ kIdLdaddlh, //!< Instruction 'ldaddlh'.
+ kIdLdar, //!< Instruction 'ldar'.
+ kIdLdarb, //!< Instruction 'ldarb'.
+ kIdLdarh, //!< Instruction 'ldarh'.
+ kIdLdaxp, //!< Instruction 'ldaxp'.
+ kIdLdaxr, //!< Instruction 'ldaxr'.
+ kIdLdaxrb, //!< Instruction 'ldaxrb'.
+ kIdLdaxrh, //!< Instruction 'ldaxrh'.
+ kIdLdclr, //!< Instruction 'ldclr'.
+ kIdLdclra, //!< Instruction 'ldclra'.
+ kIdLdclrab, //!< Instruction 'ldclrab'.
+ kIdLdclrah, //!< Instruction 'ldclrah'.
+ kIdLdclral, //!< Instruction 'ldclral'.
+ kIdLdclralb, //!< Instruction 'ldclralb'.
+ kIdLdclralh, //!< Instruction 'ldclralh'.
+ kIdLdclrb, //!< Instruction 'ldclrb'.
+ kIdLdclrh, //!< Instruction 'ldclrh'.
+ kIdLdclrl, //!< Instruction 'ldclrl'.
+ kIdLdclrlb, //!< Instruction 'ldclrlb'.
+ kIdLdclrlh, //!< Instruction 'ldclrlh'.
+ kIdLdeor, //!< Instruction 'ldeor'.
+ kIdLdeora, //!< Instruction 'ldeora'.
+ kIdLdeorab, //!< Instruction 'ldeorab'.
+ kIdLdeorah, //!< Instruction 'ldeorah'.
+ kIdLdeoral, //!< Instruction 'ldeoral'.
+ kIdLdeoralb, //!< Instruction 'ldeoralb'.
+ kIdLdeoralh, //!< Instruction 'ldeoralh'.
+ kIdLdeorb, //!< Instruction 'ldeorb'.
+ kIdLdeorh, //!< Instruction 'ldeorh'.
+ kIdLdeorl, //!< Instruction 'ldeorl'.
+ kIdLdeorlb, //!< Instruction 'ldeorlb'.
+ kIdLdeorlh, //!< Instruction 'ldeorlh'.
+ kIdLdg, //!< Instruction 'ldg'.
+ kIdLdgm, //!< Instruction 'ldgm'.
+ kIdLdlar, //!< Instruction 'ldlar'.
+ kIdLdlarb, //!< Instruction 'ldlarb'.
+ kIdLdlarh, //!< Instruction 'ldlarh'.
+ kIdLdnp, //!< Instruction 'ldnp'.
+ kIdLdp, //!< Instruction 'ldp'.
+ kIdLdpsw, //!< Instruction 'ldpsw'.
+ kIdLdr, //!< Instruction 'ldr'.
+ kIdLdraa, //!< Instruction 'ldraa'.
+ kIdLdrab, //!< Instruction 'ldrab'.
+ kIdLdrb, //!< Instruction 'ldrb'.
+ kIdLdrh, //!< Instruction 'ldrh'.
+ kIdLdrsb, //!< Instruction 'ldrsb'.
+ kIdLdrsh, //!< Instruction 'ldrsh'.
+ kIdLdrsw, //!< Instruction 'ldrsw'.
+ kIdLdset, //!< Instruction 'ldset'.
+ kIdLdseta, //!< Instruction 'ldseta'.
+ kIdLdsetab, //!< Instruction 'ldsetab'.
+ kIdLdsetah, //!< Instruction 'ldsetah'.
+ kIdLdsetal, //!< Instruction 'ldsetal'.
+ kIdLdsetalb, //!< Instruction 'ldsetalb'.
+ kIdLdsetalh, //!< Instruction 'ldsetalh'.
+ kIdLdsetb, //!< Instruction 'ldsetb'.
+ kIdLdseth, //!< Instruction 'ldseth'.
+ kIdLdsetl, //!< Instruction 'ldsetl'.
+ kIdLdsetlb, //!< Instruction 'ldsetlb'.
+ kIdLdsetlh, //!< Instruction 'ldsetlh'.
+ kIdLdsmax, //!< Instruction 'ldsmax'.
+ kIdLdsmaxa, //!< Instruction 'ldsmaxa'.
+ kIdLdsmaxab, //!< Instruction 'ldsmaxab'.
+ kIdLdsmaxah, //!< Instruction 'ldsmaxah'.
+ kIdLdsmaxal, //!< Instruction 'ldsmaxal'.
+ kIdLdsmaxalb, //!< Instruction 'ldsmaxalb'.
+ kIdLdsmaxalh, //!< Instruction 'ldsmaxalh'.
+ kIdLdsmaxb, //!< Instruction 'ldsmaxb'.
+ kIdLdsmaxh, //!< Instruction 'ldsmaxh'.
+ kIdLdsmaxl, //!< Instruction 'ldsmaxl'.
+ kIdLdsmaxlb, //!< Instruction 'ldsmaxlb'.
+ kIdLdsmaxlh, //!< Instruction 'ldsmaxlh'.
+ kIdLdsmin, //!< Instruction 'ldsmin'.
+ kIdLdsmina, //!< Instruction 'ldsmina'.
+ kIdLdsminab, //!< Instruction 'ldsminab'.
+ kIdLdsminah, //!< Instruction 'ldsminah'.
+ kIdLdsminal, //!< Instruction 'ldsminal'.
+ kIdLdsminalb, //!< Instruction 'ldsminalb'.
+ kIdLdsminalh, //!< Instruction 'ldsminalh'.
+ kIdLdsminb, //!< Instruction 'ldsminb'.
+ kIdLdsminh, //!< Instruction 'ldsminh'.
+ kIdLdsminl, //!< Instruction 'ldsminl'.
+ kIdLdsminlb, //!< Instruction 'ldsminlb'.
+ kIdLdsminlh, //!< Instruction 'ldsminlh'.
+ kIdLdtr, //!< Instruction 'ldtr'.
+ kIdLdtrb, //!< Instruction 'ldtrb'.
+ kIdLdtrh, //!< Instruction 'ldtrh'.
+ kIdLdtrsb, //!< Instruction 'ldtrsb'.
+ kIdLdtrsh, //!< Instruction 'ldtrsh'.
+ kIdLdtrsw, //!< Instruction 'ldtrsw'.
+ kIdLdumax, //!< Instruction 'ldumax'.
+ kIdLdumaxa, //!< Instruction 'ldumaxa'.
+ kIdLdumaxab, //!< Instruction 'ldumaxab'.
+ kIdLdumaxah, //!< Instruction 'ldumaxah'.
+ kIdLdumaxal, //!< Instruction 'ldumaxal'.
+ kIdLdumaxalb, //!< Instruction 'ldumaxalb'.
+ kIdLdumaxalh, //!< Instruction 'ldumaxalh'.
+ kIdLdumaxb, //!< Instruction 'ldumaxb'.
+ kIdLdumaxh, //!< Instruction 'ldumaxh'.
+ kIdLdumaxl, //!< Instruction 'ldumaxl'.
+ kIdLdumaxlb, //!< Instruction 'ldumaxlb'.
+ kIdLdumaxlh, //!< Instruction 'ldumaxlh'.
+ kIdLdumin, //!< Instruction 'ldumin'.
+ kIdLdumina, //!< Instruction 'ldumina'.
+ kIdLduminab, //!< Instruction 'lduminab'.
+ kIdLduminah, //!< Instruction 'lduminah'.
+ kIdLduminal, //!< Instruction 'lduminal'.
+ kIdLduminalb, //!< Instruction 'lduminalb'.
+ kIdLduminalh, //!< Instruction 'lduminalh'.
+ kIdLduminb, //!< Instruction 'lduminb'.
+ kIdLduminh, //!< Instruction 'lduminh'.
+ kIdLduminl, //!< Instruction 'lduminl'.
+ kIdLduminlb, //!< Instruction 'lduminlb'.
+ kIdLduminlh, //!< Instruction 'lduminlh'.
+ kIdLdur, //!< Instruction 'ldur'.
+ kIdLdurb, //!< Instruction 'ldurb'.
+ kIdLdurh, //!< Instruction 'ldurh'.
+ kIdLdursb, //!< Instruction 'ldursb'.
+ kIdLdursh, //!< Instruction 'ldursh'.
+ kIdLdursw, //!< Instruction 'ldursw'.
+ kIdLdxp, //!< Instruction 'ldxp'.
+ kIdLdxr, //!< Instruction 'ldxr'.
+ kIdLdxrb, //!< Instruction 'ldxrb'.
+ kIdLdxrh, //!< Instruction 'ldxrh'.
+ kIdLsl, //!< Instruction 'lsl'.
+ kIdLslv, //!< Instruction 'lslv'.
+ kIdLsr, //!< Instruction 'lsr'.
+ kIdLsrv, //!< Instruction 'lsrv'.
+ kIdMadd, //!< Instruction 'madd'.
+ kIdMneg, //!< Instruction 'mneg'.
+ kIdMov, //!< Instruction 'mov'.
+ kIdMovk, //!< Instruction 'movk'.
+ kIdMovn, //!< Instruction 'movn'.
+ kIdMovz, //!< Instruction 'movz'.
+ kIdMrs, //!< Instruction 'mrs'.
+ kIdMsr, //!< Instruction 'msr'.
+ kIdMsub, //!< Instruction 'msub'.
+ kIdMul, //!< Instruction 'mul'.
+ kIdMvn, //!< Instruction 'mvn'.
+ kIdNeg, //!< Instruction 'neg'.
+ kIdNegs, //!< Instruction 'negs'.
+ kIdNgc, //!< Instruction 'ngc'.
+ kIdNgcs, //!< Instruction 'ngcs'.
+ kIdNop, //!< Instruction 'nop'.
+ kIdOrn, //!< Instruction 'orn'.
+ kIdOrr, //!< Instruction 'orr'.
+ kIdPacda, //!< Instruction 'pacda'.
+ kIdPacdb, //!< Instruction 'pacdb'.
+ kIdPacdza, //!< Instruction 'pacdza'.
+ kIdPacdzb, //!< Instruction 'pacdzb'.
+ kIdPacga, //!< Instruction 'pacga'.
+ kIdPssbb, //!< Instruction 'pssbb'.
+ kIdRbit, //!< Instruction 'rbit'.
+ kIdRet, //!< Instruction 'ret'.
+ kIdRev, //!< Instruction 'rev'.
+ kIdRev16, //!< Instruction 'rev16'.
+ kIdRev32, //!< Instruction 'rev32'.
+ kIdRev64, //!< Instruction 'rev64'.
+ kIdRor, //!< Instruction 'ror'.
+ kIdRorv, //!< Instruction 'rorv'.
+ kIdSbc, //!< Instruction 'sbc'.
+ kIdSbcs, //!< Instruction 'sbcs'.
+ kIdSbfiz, //!< Instruction 'sbfiz'.
+ kIdSbfm, //!< Instruction 'sbfm'.
+ kIdSbfx, //!< Instruction 'sbfx'.
+ kIdSdiv, //!< Instruction 'sdiv'.
+ kIdSetf8, //!< Instruction 'setf8'.
+ kIdSetf16, //!< Instruction 'setf16'.
+ kIdSev, //!< Instruction 'sev'.
+ kIdSevl, //!< Instruction 'sevl'.
+ kIdSmaddl, //!< Instruction 'smaddl'.
+ kIdSmc, //!< Instruction 'smc'.
+ kIdSmnegl, //!< Instruction 'smnegl'.
+ kIdSmsubl, //!< Instruction 'smsubl'.
+ kIdSmulh, //!< Instruction 'smulh'.
+ kIdSmull, //!< Instruction 'smull'.
+ kIdSsbb, //!< Instruction 'ssbb'.
+ kIdSt2g, //!< Instruction 'st2g'.
+ kIdStadd, //!< Instruction 'stadd'.
+ kIdStaddl, //!< Instruction 'staddl'.
+ kIdStaddb, //!< Instruction 'staddb'.
+ kIdStaddlb, //!< Instruction 'staddlb'.
+ kIdStaddh, //!< Instruction 'staddh'.
+ kIdStaddlh, //!< Instruction 'staddlh'.
+ kIdStclr, //!< Instruction 'stclr'.
+ kIdStclrl, //!< Instruction 'stclrl'.
+ kIdStclrb, //!< Instruction 'stclrb'.
+ kIdStclrlb, //!< Instruction 'stclrlb'.
+ kIdStclrh, //!< Instruction 'stclrh'.
+ kIdStclrlh, //!< Instruction 'stclrlh'.
+ kIdSteor, //!< Instruction 'steor'.
+ kIdSteorl, //!< Instruction 'steorl'.
+ kIdSteorb, //!< Instruction 'steorb'.
+ kIdSteorlb, //!< Instruction 'steorlb'.
+ kIdSteorh, //!< Instruction 'steorh'.
+ kIdSteorlh, //!< Instruction 'steorlh'.
+ kIdStg, //!< Instruction 'stg'.
+ kIdStgm, //!< Instruction 'stgm'.
+ kIdStgp, //!< Instruction 'stgp'.
+ kIdStllr, //!< Instruction 'stllr'.
+ kIdStllrb, //!< Instruction 'stllrb'.
+ kIdStllrh, //!< Instruction 'stllrh'.
+ kIdStlr, //!< Instruction 'stlr'.
+ kIdStlrb, //!< Instruction 'stlrb'.
+ kIdStlrh, //!< Instruction 'stlrh'.
+ kIdStlxp, //!< Instruction 'stlxp'.
+ kIdStlxr, //!< Instruction 'stlxr'.
+ kIdStlxrb, //!< Instruction 'stlxrb'.
+ kIdStlxrh, //!< Instruction 'stlxrh'.
+ kIdStnp, //!< Instruction 'stnp'.
+ kIdStp, //!< Instruction 'stp'.
+ kIdStr, //!< Instruction 'str'.
+ kIdStrb, //!< Instruction 'strb'.
+ kIdStrh, //!< Instruction 'strh'.
+ kIdStset, //!< Instruction 'stset'.
+ kIdStsetl, //!< Instruction 'stsetl'.
+ kIdStsetb, //!< Instruction 'stsetb'.
+ kIdStsetlb, //!< Instruction 'stsetlb'.
+ kIdStseth, //!< Instruction 'stseth'.
+ kIdStsetlh, //!< Instruction 'stsetlh'.
+ kIdStsmax, //!< Instruction 'stsmax'.
+ kIdStsmaxl, //!< Instruction 'stsmaxl'.
+ kIdStsmaxb, //!< Instruction 'stsmaxb'.
+ kIdStsmaxlb, //!< Instruction 'stsmaxlb'.
+ kIdStsmaxh, //!< Instruction 'stsmaxh'.
+ kIdStsmaxlh, //!< Instruction 'stsmaxlh'.
+ kIdStsmin, //!< Instruction 'stsmin'.
+ kIdStsminl, //!< Instruction 'stsminl'.
+ kIdStsminb, //!< Instruction 'stsminb'.
+ kIdStsminlb, //!< Instruction 'stsminlb'.
+ kIdStsminh, //!< Instruction 'stsminh'.
+ kIdStsminlh, //!< Instruction 'stsminlh'.
+ kIdSttr, //!< Instruction 'sttr'.
+ kIdSttrb, //!< Instruction 'sttrb'.
+ kIdSttrh, //!< Instruction 'sttrh'.
+ kIdStumax, //!< Instruction 'stumax'.
+ kIdStumaxl, //!< Instruction 'stumaxl'.
+ kIdStumaxb, //!< Instruction 'stumaxb'.
+ kIdStumaxlb, //!< Instruction 'stumaxlb'.
+ kIdStumaxh, //!< Instruction 'stumaxh'.
+ kIdStumaxlh, //!< Instruction 'stumaxlh'.
+ kIdStumin, //!< Instruction 'stumin'.
+ kIdStuminl, //!< Instruction 'stuminl'.
+ kIdStuminb, //!< Instruction 'stuminb'.
+ kIdStuminlb, //!< Instruction 'stuminlb'.
+ kIdStuminh, //!< Instruction 'stuminh'.
+ kIdStuminlh, //!< Instruction 'stuminlh'.
+ kIdStur, //!< Instruction 'stur'.
+ kIdSturb, //!< Instruction 'sturb'.
+ kIdSturh, //!< Instruction 'sturh'.
+ kIdStxp, //!< Instruction 'stxp'.
+ kIdStxr, //!< Instruction 'stxr'.
+ kIdStxrb, //!< Instruction 'stxrb'.
+ kIdStxrh, //!< Instruction 'stxrh'.
+ kIdStz2g, //!< Instruction 'stz2g'.
+ kIdStzg, //!< Instruction 'stzg'.
+ kIdStzgm, //!< Instruction 'stzgm'.
+ kIdSub, //!< Instruction 'sub'.
+ kIdSubg, //!< Instruction 'subg'.
+ kIdSubp, //!< Instruction 'subp'.
+ kIdSubps, //!< Instruction 'subps'.
+ kIdSubs, //!< Instruction 'subs'.
+ kIdSvc, //!< Instruction 'svc'.
+ kIdSwp, //!< Instruction 'swp'.
+ kIdSwpa, //!< Instruction 'swpa'.
+ kIdSwpab, //!< Instruction 'swpab'.
+ kIdSwpah, //!< Instruction 'swpah'.
+ kIdSwpal, //!< Instruction 'swpal'.
+ kIdSwpalb, //!< Instruction 'swpalb'.
+ kIdSwpalh, //!< Instruction 'swpalh'.
+ kIdSwpb, //!< Instruction 'swpb'.
+ kIdSwph, //!< Instruction 'swph'.
+ kIdSwpl, //!< Instruction 'swpl'.
+ kIdSwplb, //!< Instruction 'swplb'.
+ kIdSwplh, //!< Instruction 'swplh'.
+ kIdSxtb, //!< Instruction 'sxtb'.
+ kIdSxth, //!< Instruction 'sxth'.
+ kIdSxtw, //!< Instruction 'sxtw'.
+ kIdSys, //!< Instruction 'sys'.
+ kIdTlbi, //!< Instruction 'tlbi'.
+ kIdTst, //!< Instruction 'tst'.
+ kIdTbnz, //!< Instruction 'tbnz'.
+ kIdTbz, //!< Instruction 'tbz'.
+ kIdUbfiz, //!< Instruction 'ubfiz'.
+ kIdUbfm, //!< Instruction 'ubfm'.
+ kIdUbfx, //!< Instruction 'ubfx'.
+ kIdUdf, //!< Instruction 'udf'.
+ kIdUdiv, //!< Instruction 'udiv'.
+ kIdUmaddl, //!< Instruction 'umaddl'.
+ kIdUmnegl, //!< Instruction 'umnegl'.
+ kIdUmull, //!< Instruction 'umull'.
+ kIdUmulh, //!< Instruction 'umulh'.
+ kIdUmsubl, //!< Instruction 'umsubl'.
+ kIdUxtb, //!< Instruction 'uxtb'.
+ kIdUxth, //!< Instruction 'uxth'.
+ kIdWfe, //!< Instruction 'wfe'.
+ kIdWfi, //!< Instruction 'wfi'.
+ kIdXaflag, //!< Instruction 'xaflag'.
+ kIdXpacd, //!< Instruction 'xpacd'.
+ kIdXpaci, //!< Instruction 'xpaci'.
+ kIdXpaclri, //!< Instruction 'xpaclri'.
+ kIdYield, //!< Instruction 'yield'.
+ kIdAbs_v, //!< Instruction 'abs' {ASIMD}.
+ kIdAdd_v, //!< Instruction 'add' {ASIMD}.
+ kIdAddhn_v, //!< Instruction 'addhn' {ASIMD}.
+ kIdAddhn2_v, //!< Instruction 'addhn2' {ASIMD}.
+ kIdAddp_v, //!< Instruction 'addp' {ASIMD}.
+ kIdAddv_v, //!< Instruction 'addv' {ASIMD}.
+ kIdAesd_v, //!< Instruction 'aesd' {ASIMD}.
+ kIdAese_v, //!< Instruction 'aese' {ASIMD}.
+ kIdAesimc_v, //!< Instruction 'aesimc' {ASIMD}.
+ kIdAesmc_v, //!< Instruction 'aesmc' {ASIMD}.
+ kIdAnd_v, //!< Instruction 'and' {ASIMD}.
+ kIdBcax_v, //!< Instruction 'bcax' {ASIMD}.
+ kIdBfcvt_v, //!< Instruction 'bfcvt' {ASIMD}.
+ kIdBfcvtn_v, //!< Instruction 'bfcvtn' {ASIMD}.
+ kIdBfcvtn2_v, //!< Instruction 'bfcvtn2' {ASIMD}.
+ kIdBfdot_v, //!< Instruction 'bfdot' {ASIMD}.
+ kIdBfmlalb_v, //!< Instruction 'bfmlalb' {ASIMD}.
+ kIdBfmlalt_v, //!< Instruction 'bfmlalt' {ASIMD}.
+ kIdBfmmla_v, //!< Instruction 'bfmmla' {ASIMD}.
+ kIdBic_v, //!< Instruction 'bic' {ASIMD}.
+ kIdBif_v, //!< Instruction 'bif' {ASIMD}.
+ kIdBit_v, //!< Instruction 'bit' {ASIMD}.
+ kIdBsl_v, //!< Instruction 'bsl' {ASIMD}.
+ kIdCls_v, //!< Instruction 'cls' {ASIMD}.
+ kIdClz_v, //!< Instruction 'clz' {ASIMD}.
+ kIdCmeq_v, //!< Instruction 'cmeq' {ASIMD}.
+ kIdCmge_v, //!< Instruction 'cmge' {ASIMD}.
+ kIdCmgt_v, //!< Instruction 'cmgt' {ASIMD}.
+ kIdCmhi_v, //!< Instruction 'cmhi' {ASIMD}.
+ kIdCmhs_v, //!< Instruction 'cmhs' {ASIMD}.
+ kIdCmle_v, //!< Instruction 'cmle' {ASIMD}.
+ kIdCmlt_v, //!< Instruction 'cmlt' {ASIMD}.
+ kIdCmtst_v, //!< Instruction 'cmtst' {ASIMD}.
+ kIdCnt_v, //!< Instruction 'cnt' {ASIMD}.
+ kIdDup_v, //!< Instruction 'dup' {ASIMD}.
+ kIdEor_v, //!< Instruction 'eor' {ASIMD}.
+ kIdEor3_v, //!< Instruction 'eor3' {ASIMD}.
+ kIdExt_v, //!< Instruction 'ext' {ASIMD}.
+ kIdFabd_v, //!< Instruction 'fabd' {ASIMD}.
+ kIdFabs_v, //!< Instruction 'fabs' {ASIMD}.
+ kIdFacge_v, //!< Instruction 'facge' {ASIMD}.
+ kIdFacgt_v, //!< Instruction 'facgt' {ASIMD}.
+ kIdFadd_v, //!< Instruction 'fadd' {ASIMD}.
+ kIdFaddp_v, //!< Instruction 'faddp' {ASIMD}.
+ kIdFcadd_v, //!< Instruction 'fcadd' {ASIMD}.
+ kIdFccmp_v, //!< Instruction 'fccmp' {ASIMD}.
+ kIdFccmpe_v, //!< Instruction 'fccmpe' {ASIMD}.
+ kIdFcmeq_v, //!< Instruction 'fcmeq' {ASIMD}.
+ kIdFcmge_v, //!< Instruction 'fcmge' {ASIMD}.
+ kIdFcmgt_v, //!< Instruction 'fcmgt' {ASIMD}.
+ kIdFcmla_v, //!< Instruction 'fcmla' {ASIMD}.
+ kIdFcmle_v, //!< Instruction 'fcmle' {ASIMD}.
+ kIdFcmlt_v, //!< Instruction 'fcmlt' {ASIMD}.
+ kIdFcmp_v, //!< Instruction 'fcmp' {ASIMD}.
+ kIdFcmpe_v, //!< Instruction 'fcmpe' {ASIMD}.
+ kIdFcsel_v, //!< Instruction 'fcsel' {ASIMD}.
+ kIdFcvt_v, //!< Instruction 'fcvt' {ASIMD}.
+ kIdFcvtas_v, //!< Instruction 'fcvtas' {ASIMD}.
+ kIdFcvtau_v, //!< Instruction 'fcvtau' {ASIMD}.
+ kIdFcvtl_v, //!< Instruction 'fcvtl' {ASIMD}.
+ kIdFcvtl2_v, //!< Instruction 'fcvtl2' {ASIMD}.
+ kIdFcvtms_v, //!< Instruction 'fcvtms' {ASIMD}.
+ kIdFcvtmu_v, //!< Instruction 'fcvtmu' {ASIMD}.
+ kIdFcvtn_v, //!< Instruction 'fcvtn' {ASIMD}.
+ kIdFcvtn2_v, //!< Instruction 'fcvtn2' {ASIMD}.
+ kIdFcvtns_v, //!< Instruction 'fcvtns' {ASIMD}.
+ kIdFcvtnu_v, //!< Instruction 'fcvtnu' {ASIMD}.
+ kIdFcvtps_v, //!< Instruction 'fcvtps' {ASIMD}.
+ kIdFcvtpu_v, //!< Instruction 'fcvtpu' {ASIMD}.
+ kIdFcvtxn_v, //!< Instruction 'fcvtxn' {ASIMD}.
+ kIdFcvtxn2_v, //!< Instruction 'fcvtxn2' {ASIMD}.
+ kIdFcvtzs_v, //!< Instruction 'fcvtzs' {ASIMD}.
+ kIdFcvtzu_v, //!< Instruction 'fcvtzu' {ASIMD}.
+ kIdFdiv_v, //!< Instruction 'fdiv' {ASIMD}.
+ kIdFjcvtzs_v, //!< Instruction 'fjcvtzs' {ASIMD}.
+ kIdFmadd_v, //!< Instruction 'fmadd' {ASIMD}.
+ kIdFmax_v, //!< Instruction 'fmax' {ASIMD}.
+ kIdFmaxnm_v, //!< Instruction 'fmaxnm' {ASIMD}.
+ kIdFmaxnmp_v, //!< Instruction 'fmaxnmp' {ASIMD}.
+ kIdFmaxnmv_v, //!< Instruction 'fmaxnmv' {ASIMD}.
+ kIdFmaxp_v, //!< Instruction 'fmaxp' {ASIMD}.
+ kIdFmaxv_v, //!< Instruction 'fmaxv' {ASIMD}.
+ kIdFmin_v, //!< Instruction 'fmin' {ASIMD}.
+ kIdFminnm_v, //!< Instruction 'fminnm' {ASIMD}.
+ kIdFminnmp_v, //!< Instruction 'fminnmp' {ASIMD}.
+ kIdFminnmv_v, //!< Instruction 'fminnmv' {ASIMD}.
+ kIdFminp_v, //!< Instruction 'fminp' {ASIMD}.
+ kIdFminv_v, //!< Instruction 'fminv' {ASIMD}.
+ kIdFmla_v, //!< Instruction 'fmla' {ASIMD}.
+ kIdFmlal_v, //!< Instruction 'fmlal' {ASIMD}.
+ kIdFmlal2_v, //!< Instruction 'fmlal2' {ASIMD}.
+ kIdFmls_v, //!< Instruction 'fmls' {ASIMD}.
+ kIdFmlsl_v, //!< Instruction 'fmlsl' {ASIMD}.
+ kIdFmlsl2_v, //!< Instruction 'fmlsl2' {ASIMD}.
+ kIdFmov_v, //!< Instruction 'fmov' {ASIMD}.
+ kIdFmsub_v, //!< Instruction 'fmsub' {ASIMD}.
+ kIdFmul_v, //!< Instruction 'fmul' {ASIMD}.
+ kIdFmulx_v, //!< Instruction 'fmulx' {ASIMD}.
+ kIdFneg_v, //!< Instruction 'fneg' {ASIMD}.
+ kIdFnmadd_v, //!< Instruction 'fnmadd' {ASIMD}.
+ kIdFnmsub_v, //!< Instruction 'fnmsub' {ASIMD}.
+ kIdFnmul_v, //!< Instruction 'fnmul' {ASIMD}.
+ kIdFrecpe_v, //!< Instruction 'frecpe' {ASIMD}.
+ kIdFrecps_v, //!< Instruction 'frecps' {ASIMD}.
+ kIdFrecpx_v, //!< Instruction 'frecpx' {ASIMD}.
+ kIdFrint32x_v, //!< Instruction 'frint32x' {ASIMD}.
+ kIdFrint32z_v, //!< Instruction 'frint32z' {ASIMD}.
+ kIdFrint64x_v, //!< Instruction 'frint64x' {ASIMD}.
+ kIdFrint64z_v, //!< Instruction 'frint64z' {ASIMD}.
+ kIdFrinta_v, //!< Instruction 'frinta' {ASIMD}.
+ kIdFrinti_v, //!< Instruction 'frinti' {ASIMD}.
+ kIdFrintm_v, //!< Instruction 'frintm' {ASIMD}.
+ kIdFrintn_v, //!< Instruction 'frintn' {ASIMD}.
+ kIdFrintp_v, //!< Instruction 'frintp' {ASIMD}.
+ kIdFrintx_v, //!< Instruction 'frintx' {ASIMD}.
+ kIdFrintz_v, //!< Instruction 'frintz' {ASIMD}.
+ kIdFrsqrte_v, //!< Instruction 'frsqrte' {ASIMD}.
+ kIdFrsqrts_v, //!< Instruction 'frsqrts' {ASIMD}.
+ kIdFsqrt_v, //!< Instruction 'fsqrt' {ASIMD}.
+ kIdFsub_v, //!< Instruction 'fsub' {ASIMD}.
+ kIdIns_v, //!< Instruction 'ins' {ASIMD}.
+ kIdLd1_v, //!< Instruction 'ld1' {ASIMD}.
+ kIdLd1r_v, //!< Instruction 'ld1r' {ASIMD}.
+ kIdLd2_v, //!< Instruction 'ld2' {ASIMD}.
+ kIdLd2r_v, //!< Instruction 'ld2r' {ASIMD}.
+ kIdLd3_v, //!< Instruction 'ld3' {ASIMD}.
+ kIdLd3r_v, //!< Instruction 'ld3r' {ASIMD}.
+ kIdLd4_v, //!< Instruction 'ld4' {ASIMD}.
+ kIdLd4r_v, //!< Instruction 'ld4r' {ASIMD}.
+ kIdLdnp_v, //!< Instruction 'ldnp' {ASIMD}.
+ kIdLdp_v, //!< Instruction 'ldp' {ASIMD}.
+ kIdLdr_v, //!< Instruction 'ldr' {ASIMD}.
+ kIdLdur_v, //!< Instruction 'ldur' {ASIMD}.
+ kIdMla_v, //!< Instruction 'mla' {ASIMD}.
+ kIdMls_v, //!< Instruction 'mls' {ASIMD}.
+ kIdMov_v, //!< Instruction 'mov' {ASIMD}.
+ kIdMovi_v, //!< Instruction 'movi' {ASIMD}.
+ kIdMul_v, //!< Instruction 'mul' {ASIMD}.
+ kIdMvn_v, //!< Instruction 'mvn' {ASIMD}.
+ kIdMvni_v, //!< Instruction 'mvni' {ASIMD}.
+ kIdNeg_v, //!< Instruction 'neg' {ASIMD}.
+ kIdNot_v, //!< Instruction 'not' {ASIMD}.
+ kIdOrn_v, //!< Instruction 'orn' {ASIMD}.
+ kIdOrr_v, //!< Instruction 'orr' {ASIMD}.
+ kIdPmul_v, //!< Instruction 'pmul' {ASIMD}.
+ kIdPmull_v, //!< Instruction 'pmull' {ASIMD}.
+ kIdPmull2_v, //!< Instruction 'pmull2' {ASIMD}.
+ kIdRaddhn_v, //!< Instruction 'raddhn' {ASIMD}.
+ kIdRaddhn2_v, //!< Instruction 'raddhn2' {ASIMD}.
+ kIdRax1_v, //!< Instruction 'rax1' {ASIMD}.
+ kIdRbit_v, //!< Instruction 'rbit' {ASIMD}.
+ kIdRev16_v, //!< Instruction 'rev16' {ASIMD}.
+ kIdRev32_v, //!< Instruction 'rev32' {ASIMD}.
+ kIdRev64_v, //!< Instruction 'rev64' {ASIMD}.
+ kIdRshrn_v, //!< Instruction 'rshrn' {ASIMD}.
+ kIdRshrn2_v, //!< Instruction 'rshrn2' {ASIMD}.
+ kIdRsubhn_v, //!< Instruction 'rsubhn' {ASIMD}.
+ kIdRsubhn2_v, //!< Instruction 'rsubhn2' {ASIMD}.
+ kIdSaba_v, //!< Instruction 'saba' {ASIMD}.
+ kIdSabal_v, //!< Instruction 'sabal' {ASIMD}.
+ kIdSabal2_v, //!< Instruction 'sabal2' {ASIMD}.
+ kIdSabd_v, //!< Instruction 'sabd' {ASIMD}.
+ kIdSabdl_v, //!< Instruction 'sabdl' {ASIMD}.
+ kIdSabdl2_v, //!< Instruction 'sabdl2' {ASIMD}.
+ kIdSadalp_v, //!< Instruction 'sadalp' {ASIMD}.
+ kIdSaddl_v, //!< Instruction 'saddl' {ASIMD}.
+ kIdSaddl2_v, //!< Instruction 'saddl2' {ASIMD}.
+ kIdSaddlp_v, //!< Instruction 'saddlp' {ASIMD}.
+ kIdSaddlv_v, //!< Instruction 'saddlv' {ASIMD}.
+ kIdSaddw_v, //!< Instruction 'saddw' {ASIMD}.
+ kIdSaddw2_v, //!< Instruction 'saddw2' {ASIMD}.
+ kIdScvtf_v, //!< Instruction 'scvtf' {ASIMD}.
+ kIdSdot_v, //!< Instruction 'sdot' {ASIMD}.
+ kIdSha1c_v, //!< Instruction 'sha1c' {ASIMD}.
+ kIdSha1h_v, //!< Instruction 'sha1h' {ASIMD}.
+ kIdSha1m_v, //!< Instruction 'sha1m' {ASIMD}.
+ kIdSha1p_v, //!< Instruction 'sha1p' {ASIMD}.
+ kIdSha1su0_v, //!< Instruction 'sha1su0' {ASIMD}.
+ kIdSha1su1_v, //!< Instruction 'sha1su1' {ASIMD}.
+ kIdSha256h_v, //!< Instruction 'sha256h' {ASIMD}.
+ kIdSha256h2_v, //!< Instruction 'sha256h2' {ASIMD}.
+ kIdSha256su0_v, //!< Instruction 'sha256su0' {ASIMD}.
+ kIdSha256su1_v, //!< Instruction 'sha256su1' {ASIMD}.
+ kIdSha512h_v, //!< Instruction 'sha512h' {ASIMD}.
+ kIdSha512h2_v, //!< Instruction 'sha512h2' {ASIMD}.
+ kIdSha512su0_v, //!< Instruction 'sha512su0' {ASIMD}.
+ kIdSha512su1_v, //!< Instruction 'sha512su1' {ASIMD}.
+ kIdShadd_v, //!< Instruction 'shadd' {ASIMD}.
+ kIdShl_v, //!< Instruction 'shl' {ASIMD}.
+ kIdShll_v, //!< Instruction 'shll' {ASIMD}.
+ kIdShll2_v, //!< Instruction 'shll2' {ASIMD}.
+ kIdShrn_v, //!< Instruction 'shrn' {ASIMD}.
+ kIdShrn2_v, //!< Instruction 'shrn2' {ASIMD}.
+ kIdShsub_v, //!< Instruction 'shsub' {ASIMD}.
+ kIdSli_v, //!< Instruction 'sli' {ASIMD}.
+ kIdSm3partw1_v, //!< Instruction 'sm3partw1' {ASIMD}.
+ kIdSm3partw2_v, //!< Instruction 'sm3partw2' {ASIMD}.
+ kIdSm3ss1_v, //!< Instruction 'sm3ss1' {ASIMD}.
+ kIdSm3tt1a_v, //!< Instruction 'sm3tt1a' {ASIMD}.
+ kIdSm3tt1b_v, //!< Instruction 'sm3tt1b' {ASIMD}.
+ kIdSm3tt2a_v, //!< Instruction 'sm3tt2a' {ASIMD}.
+ kIdSm3tt2b_v, //!< Instruction 'sm3tt2b' {ASIMD}.
+ kIdSm4e_v, //!< Instruction 'sm4e' {ASIMD}.
+ kIdSm4ekey_v, //!< Instruction 'sm4ekey' {ASIMD}.
+ kIdSmax_v, //!< Instruction 'smax' {ASIMD}.
+ kIdSmaxp_v, //!< Instruction 'smaxp' {ASIMD}.
+ kIdSmaxv_v, //!< Instruction 'smaxv' {ASIMD}.
+ kIdSmin_v, //!< Instruction 'smin' {ASIMD}.
+ kIdSminp_v, //!< Instruction 'sminp' {ASIMD}.
+ kIdSminv_v, //!< Instruction 'sminv' {ASIMD}.
+ kIdSmlal_v, //!< Instruction 'smlal' {ASIMD}.
+ kIdSmlal2_v, //!< Instruction 'smlal2' {ASIMD}.
+ kIdSmlsl_v, //!< Instruction 'smlsl' {ASIMD}.
+ kIdSmlsl2_v, //!< Instruction 'smlsl2' {ASIMD}.
+ kIdSmmla_v, //!< Instruction 'smmla' {ASIMD}.
+ kIdSmov_v, //!< Instruction 'smov' {ASIMD}.
+ kIdSmull_v, //!< Instruction 'smull' {ASIMD}.
+ kIdSmull2_v, //!< Instruction 'smull2' {ASIMD}.
+ kIdSqabs_v, //!< Instruction 'sqabs' {ASIMD}.
+ kIdSqadd_v, //!< Instruction 'sqadd' {ASIMD}.
+ kIdSqdmlal_v, //!< Instruction 'sqdmlal' {ASIMD}.
+ kIdSqdmlal2_v, //!< Instruction 'sqdmlal2' {ASIMD}.
+ kIdSqdmlsl_v, //!< Instruction 'sqdmlsl' {ASIMD}.
+ kIdSqdmlsl2_v, //!< Instruction 'sqdmlsl2' {ASIMD}.
+ kIdSqdmulh_v, //!< Instruction 'sqdmulh' {ASIMD}.
+ kIdSqdmull_v, //!< Instruction 'sqdmull' {ASIMD}.
+ kIdSqdmull2_v, //!< Instruction 'sqdmull2' {ASIMD}.
+ kIdSqneg_v, //!< Instruction 'sqneg' {ASIMD}.
+ kIdSqrdmlah_v, //!< Instruction 'sqrdmlah' {ASIMD}.
+ kIdSqrdmlsh_v, //!< Instruction 'sqrdmlsh' {ASIMD}.
+ kIdSqrdmulh_v, //!< Instruction 'sqrdmulh' {ASIMD}.
+ kIdSqrshl_v, //!< Instruction 'sqrshl' {ASIMD}.
+ kIdSqrshrn_v, //!< Instruction 'sqrshrn' {ASIMD}.
+ kIdSqrshrn2_v, //!< Instruction 'sqrshrn2' {ASIMD}.
+ kIdSqrshrun_v, //!< Instruction 'sqrshrun' {ASIMD}.
+ kIdSqrshrun2_v, //!< Instruction 'sqrshrun2' {ASIMD}.
+ kIdSqshl_v, //!< Instruction 'sqshl' {ASIMD}.
+ kIdSqshlu_v, //!< Instruction 'sqshlu' {ASIMD}.
+ kIdSqshrn_v, //!< Instruction 'sqshrn' {ASIMD}.
+ kIdSqshrn2_v, //!< Instruction 'sqshrn2' {ASIMD}.
+ kIdSqshrun_v, //!< Instruction 'sqshrun' {ASIMD}.
+ kIdSqshrun2_v, //!< Instruction 'sqshrun2' {ASIMD}.
+ kIdSqsub_v, //!< Instruction 'sqsub' {ASIMD}.
+ kIdSqxtn_v, //!< Instruction 'sqxtn' {ASIMD}.
+ kIdSqxtn2_v, //!< Instruction 'sqxtn2' {ASIMD}.
+ kIdSqxtun_v, //!< Instruction 'sqxtun' {ASIMD}.
+ kIdSqxtun2_v, //!< Instruction 'sqxtun2' {ASIMD}.
+ kIdSrhadd_v, //!< Instruction 'srhadd' {ASIMD}.
+ kIdSri_v, //!< Instruction 'sri' {ASIMD}.
+ kIdSrshl_v, //!< Instruction 'srshl' {ASIMD}.
+ kIdSrshr_v, //!< Instruction 'srshr' {ASIMD}.
+ kIdSrsra_v, //!< Instruction 'srsra' {ASIMD}.
+ kIdSshl_v, //!< Instruction 'sshl' {ASIMD}.
+ kIdSshll_v, //!< Instruction 'sshll' {ASIMD}.
+ kIdSshll2_v, //!< Instruction 'sshll2' {ASIMD}.
+ kIdSshr_v, //!< Instruction 'sshr' {ASIMD}.
+ kIdSsra_v, //!< Instruction 'ssra' {ASIMD}.
+ kIdSsubl_v, //!< Instruction 'ssubl' {ASIMD}.
+ kIdSsubl2_v, //!< Instruction 'ssubl2' {ASIMD}.
+ kIdSsubw_v, //!< Instruction 'ssubw' {ASIMD}.
+ kIdSsubw2_v, //!< Instruction 'ssubw2' {ASIMD}.
+ kIdSt1_v, //!< Instruction 'st1' {ASIMD}.
+ kIdSt2_v, //!< Instruction 'st2' {ASIMD}.
+ kIdSt3_v, //!< Instruction 'st3' {ASIMD}.
+ kIdSt4_v, //!< Instruction 'st4' {ASIMD}.
+ kIdStnp_v, //!< Instruction 'stnp' {ASIMD}.
+ kIdStp_v, //!< Instruction 'stp' {ASIMD}.
+ kIdStr_v, //!< Instruction 'str' {ASIMD}.
+ kIdStur_v, //!< Instruction 'stur' {ASIMD}.
+ kIdSub_v, //!< Instruction 'sub' {ASIMD}.
+ kIdSubhn_v, //!< Instruction 'subhn' {ASIMD}.
+ kIdSubhn2_v, //!< Instruction 'subhn2' {ASIMD}.
+ kIdSudot_v, //!< Instruction 'sudot' {ASIMD}.
+ kIdSuqadd_v, //!< Instruction 'suqadd' {ASIMD}.
+ kIdSxtl_v, //!< Instruction 'sxtl' {ASIMD}.
+ kIdSxtl2_v, //!< Instruction 'sxtl2' {ASIMD}.
+ kIdTbl_v, //!< Instruction 'tbl' {ASIMD}.
+ kIdTbx_v, //!< Instruction 'tbx' {ASIMD}.
+ kIdTrn1_v, //!< Instruction 'trn1' {ASIMD}.
+ kIdTrn2_v, //!< Instruction 'trn2' {ASIMD}.
+ kIdUaba_v, //!< Instruction 'uaba' {ASIMD}.
+ kIdUabal_v, //!< Instruction 'uabal' {ASIMD}.
+ kIdUabal2_v, //!< Instruction 'uabal2' {ASIMD}.
+ kIdUabd_v, //!< Instruction 'uabd' {ASIMD}.
+ kIdUabdl_v, //!< Instruction 'uabdl' {ASIMD}.
+ kIdUabdl2_v, //!< Instruction 'uabdl2' {ASIMD}.
+ kIdUadalp_v, //!< Instruction 'uadalp' {ASIMD}.
+ kIdUaddl_v, //!< Instruction 'uaddl' {ASIMD}.
+ kIdUaddl2_v, //!< Instruction 'uaddl2' {ASIMD}.
+ kIdUaddlp_v, //!< Instruction 'uaddlp' {ASIMD}.
+ kIdUaddlv_v, //!< Instruction 'uaddlv' {ASIMD}.
+ kIdUaddw_v, //!< Instruction 'uaddw' {ASIMD}.
+ kIdUaddw2_v, //!< Instruction 'uaddw2' {ASIMD}.
+ kIdUcvtf_v, //!< Instruction 'ucvtf' {ASIMD}.
+ kIdUdot_v, //!< Instruction 'udot' {ASIMD}.
+ kIdUhadd_v, //!< Instruction 'uhadd' {ASIMD}.
+ kIdUhsub_v, //!< Instruction 'uhsub' {ASIMD}.
+ kIdUmax_v, //!< Instruction 'umax' {ASIMD}.
+ kIdUmaxp_v, //!< Instruction 'umaxp' {ASIMD}.
+ kIdUmaxv_v, //!< Instruction 'umaxv' {ASIMD}.
+ kIdUmin_v, //!< Instruction 'umin' {ASIMD}.
+ kIdUminp_v, //!< Instruction 'uminp' {ASIMD}.
+ kIdUminv_v, //!< Instruction 'uminv' {ASIMD}.
+ kIdUmlal_v, //!< Instruction 'umlal' {ASIMD}.
+ kIdUmlal2_v, //!< Instruction 'umlal2' {ASIMD}.
+ kIdUmlsl_v, //!< Instruction 'umlsl' {ASIMD}.
+ kIdUmlsl2_v, //!< Instruction 'umlsl2' {ASIMD}.
+ kIdUmmla_v, //!< Instruction 'ummla' {ASIMD}.
+ kIdUmov_v, //!< Instruction 'umov' {ASIMD}.
+ kIdUmull_v, //!< Instruction 'umull' {ASIMD}.
+ kIdUmull2_v, //!< Instruction 'umull2' {ASIMD}.
+ kIdUqadd_v, //!< Instruction 'uqadd' {ASIMD}.
+ kIdUqrshl_v, //!< Instruction 'uqrshl' {ASIMD}.
+ kIdUqrshrn_v, //!< Instruction 'uqrshrn' {ASIMD}.
+ kIdUqrshrn2_v, //!< Instruction 'uqrshrn2' {ASIMD}.
+ kIdUqshl_v, //!< Instruction 'uqshl' {ASIMD}.
+ kIdUqshrn_v, //!< Instruction 'uqshrn' {ASIMD}.
+ kIdUqshrn2_v, //!< Instruction 'uqshrn2' {ASIMD}.
+ kIdUqsub_v, //!< Instruction 'uqsub' {ASIMD}.
+ kIdUqxtn_v, //!< Instruction 'uqxtn' {ASIMD}.
+ kIdUqxtn2_v, //!< Instruction 'uqxtn2' {ASIMD}.
+ kIdUrecpe_v, //!< Instruction 'urecpe' {ASIMD}.
+ kIdUrhadd_v, //!< Instruction 'urhadd' {ASIMD}.
+ kIdUrshl_v, //!< Instruction 'urshl' {ASIMD}.
+ kIdUrshr_v, //!< Instruction 'urshr' {ASIMD}.
+ kIdUrsqrte_v, //!< Instruction 'ursqrte' {ASIMD}.
+ kIdUrsra_v, //!< Instruction 'ursra' {ASIMD}.
+ kIdUsdot_v, //!< Instruction 'usdot' {ASIMD}.
+ kIdUshl_v, //!< Instruction 'ushl' {ASIMD}.
+ kIdUshll_v, //!< Instruction 'ushll' {ASIMD}.
+ kIdUshll2_v, //!< Instruction 'ushll2' {ASIMD}.
+ kIdUshr_v, //!< Instruction 'ushr' {ASIMD}.
+ kIdUsmmla_v, //!< Instruction 'usmmla' {ASIMD}.
+ kIdUsqadd_v, //!< Instruction 'usqadd' {ASIMD}.
+ kIdUsra_v, //!< Instruction 'usra' {ASIMD}.
+ kIdUsubl_v, //!< Instruction 'usubl' {ASIMD}.
+ kIdUsubl2_v, //!< Instruction 'usubl2' {ASIMD}.
+ kIdUsubw_v, //!< Instruction 'usubw' {ASIMD}.
+ kIdUsubw2_v, //!< Instruction 'usubw2' {ASIMD}.
+ kIdUxtl_v, //!< Instruction 'uxtl' {ASIMD}.
+ kIdUxtl2_v, //!< Instruction 'uxtl2' {ASIMD}.
+ kIdUzp1_v, //!< Instruction 'uzp1' {ASIMD}.
+ kIdUzp2_v, //!< Instruction 'uzp2' {ASIMD}.
+ kIdXar_v, //!< Instruction 'xar' {ASIMD}.
+ kIdXtn_v, //!< Instruction 'xtn' {ASIMD}.
+ kIdXtn2_v, //!< Instruction 'xtn2' {ASIMD}.
+ kIdZip1_v, //!< Instruction 'zip1' {ASIMD}.
+ kIdZip2_v, //!< Instruction 'zip2' {ASIMD}.
+ _kIdCount
+ // ${InstId:End}
+ };
+
+ //! 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; }
+};
+
+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 {
+ return (op1 << 11) | (cRn << 7) | (cRm << 3) | (op2 << 0);
+ }
+
+ enum Value : uint32_t {
+ kS1E1R = encode(0b000, 0b0111, 0b1000, 0b000),
+ kS1E2R = encode(0b100, 0b0111, 0b1000, 0b000),
+ kS1E3R = encode(0b110, 0b0111, 0b1000, 0b000),
+ kS1E1W = encode(0b000, 0b0111, 0b1000, 0b001),
+ kS1E2W = encode(0b100, 0b0111, 0b1000, 0b001),
+ kS1E3W = encode(0b110, 0b0111, 0b1000, 0b001),
+ kS1E0R = encode(0b000, 0b0111, 0b1000, 0b010),
+ kS1E0W = encode(0b000, 0b0111, 0b1000, 0b011),
+ kS12E1R = encode(0b100, 0b0111, 0b1000, 0b100),
+ kS12E1W = encode(0b100, 0b0111, 0b1000, 0b101),
+ kS12E0R = encode(0b100, 0b0111, 0b1000, 0b110),
+ kS12E0W = encode(0b100, 0b0111, 0b1000, 0b111),
+ kS1E1RP = encode(0b000, 0b0111, 0b1001, 0b000),
+ kS1E1WP = encode(0b000, 0b0111, 0b1001, 0b001)
+ };
+}
+
+//! Data barrier options (DMB/DSB).
+namespace DB {
+ //! Data barrier immediate values.
+ enum Value : uint32_t {
+ //! Waits only for loads to complete, and only applies to the outer shareable domain.
+ kOSHLD = 0x01u,
+ //! Waits only for stores to complete, and only applies to the outer shareable domain.
+ kOSHST = 0x02u,
+ //! Only applies to the outer shareable domain.
+ kOSH = 0x03u,
+
+ //! Waits only for loads to complete and only applies out to the point of unification.
+ kNSHLD = 0x05u,
+ //! Waits only for stores to complete and only applies out to the point of unification.
+ kNSHST = 0x06u,
+ //! Only applies out to the point of unification.
+ kNSH = 0x07u,
+
+ //! Waits only for loads to complete, and only applies to the inner shareable domain.
+ kISHLD = 0x09u,
+ //! Waits only for stores to complete, and only applies to the inner shareable domain.
+ kISHST = 0x0Au,
+ //! Only applies to the inner shareable domain.
+ kISH = 0x0Bu,
+
+ //! Waits only for loads to complete.
+ kLD = 0x0Du,
+ //! Waits only for stores to complete.
+ kST = 0x0Eu,
+ //! Full system memory barrier operation.
+ kSY = 0x0Fu
+ };
+}
+
+//! 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 {
+ return (op1 << 11) | (cRn << 7) | (cRm << 3) | (op2 << 0);
+ }
+
+ //! Data cache maintenance immediate values.
+ enum Value : uint32_t {
+ kZVA = encode(0b011, 0b0111, 0b0100, 0b001),
+ kIVAC = encode(0b000, 0b0111, 0b0110, 0b001),
+ kISW = encode(0b000, 0b0111, 0b0110, 0b010),
+ kCVAC = encode(0b011, 0b0111, 0b1010, 0b001),
+ kCSW = encode(0b000, 0b0111, 0b1010, 0b010),
+ kCVAU = encode(0b011, 0b0111, 0b1011, 0b001),
+ kCIVAC = encode(0b011, 0b0111, 0b1110, 0b001),
+ kCISW = encode(0b000, 0b0111, 0b1110, 0b010),
+ kCVAP = encode(0b011, 0b0111, 0b1100, 0b001),
+ kCVADP = encode(0b011, 0b0111, 0b1101, 0b001),
+ kIGVAC = encode(0b000, 0b0111, 0b0110, 0b011),
+ kIGSW = encode(0b000, 0b0111, 0b0110, 0b100),
+ kCGSW = encode(0b000, 0b0111, 0b1010, 0b100),
+ kCIGSW = encode(0b000, 0b0111, 0b1110, 0b100),
+ kCGVAC = encode(0b011, 0b0111, 0b1010, 0b011),
+ kCGVAP = encode(0b011, 0b0111, 0b1100, 0b011),
+ kCGVADP = encode(0b011, 0b0111, 0b1101, 0b011),
+ kCIGVAC = encode(0b011, 0b0111, 0b1110, 0b011),
+ kGVA = encode(0b011, 0b0111, 0b0100, 0b011),
+ kIGDVAC = encode(0b000, 0b0111, 0b0110, 0b101),
+ kIGDSW = encode(0b000, 0b0111, 0b0110, 0b110),
+ kCGDSW = encode(0b000, 0b0111, 0b1010, 0b110),
+ kCIGDSW = encode(0b000, 0b0111, 0b1110, 0b110),
+ kCGDVAC = encode(0b011, 0b0111, 0b1010, 0b101),
+ kCGDVAP = encode(0b011, 0b0111, 0b1100, 0b101),
+ kCGDVADP = encode(0b011, 0b0111, 0b1101, 0b101),
+ kCIGDVAC = encode(0b011, 0b0111, 0b1110, 0b101),
+ kGZVA = encode(0b011, 0b0111, 0b0100, 0b100)
+ };
+}
+
+//! 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 {
+ return (op1 << 11) | (cRn << 7) | (cRm << 3) | (op2 << 0);
+ }
+
+ //! Instruction cache maintenance immediate values.
+ enum Value : uint32_t {
+ kIALLUIS = encode(0b000, 0b0111, 0b0001, 0b000),
+ kIALLU = encode(0b000, 0b0111, 0b0101, 0b000),
+ kIVAU = encode(0b011, 0b0111, 0b0101, 0b001)
+ };
+}
+
+//! Instruction-fetch barrier options.
+namespace ISB {
+ //! Instruction-fetch barrier immediate values.
+ enum Value : uint32_t {
+ kSY = 0xF
+ };
+}
+
+//! Prefetch options.
+namespace PRFOp {
+ //! Prefetch immediate values.
+ enum Value : uint32_t {
+ kPLDL1KEEP = 0x00,
+ kPLDL1STRM = 0x01,
+ kPLDL2KEEP = 0x02,
+ kPLDL2STRM = 0x03,
+ kPLDL3KEEP = 0x04,
+ kPLDL3STRM = 0x05,
+ kPLIL1KEEP = 0x08,
+ kPLIL1STRM = 0x09,
+ kPLIL2KEEP = 0x0A,
+ kPLIL2STRM = 0x0B,
+ kPLIL3KEEP = 0x0C,
+ kPLIL3STRM = 0x0D,
+ kPSTL1KEEP = 0x10,
+ kPSTL1STRM = 0x11,
+ kPSTL2KEEP = 0x12,
+ kPSTL2STRM = 0x13,
+ kPSTL3KEEP = 0x14,
+ kPSTL3STRM = 0x15
+ };
+}
+
+//! PSB instruction options.
+namespace PSB {
+ //! PSB immediate values.
+ enum Value : uint32_t {
+ kCSYNC = 0x11u
+ };
+}
+
+namespace TLBI {
+ static inline 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);
+ }
+
+ enum Value : uint32_t {
+ kIPAS2E1IS = encode(0b100, 0b1000, 0b0000, 0b001),
+ kIPAS2LE1IS = encode(0b100, 0b1000, 0b0000, 0b101),
+ kVMALLE1IS = encode(0b000, 0b1000, 0b0011, 0b000),
+ kALLE2IS = encode(0b100, 0b1000, 0b0011, 0b000),
+ kALLE3IS = encode(0b110, 0b1000, 0b0011, 0b000),
+ kVAE1IS = encode(0b000, 0b1000, 0b0011, 0b001),
+ kVAE2IS = encode(0b100, 0b1000, 0b0011, 0b001),
+ kVAE3IS = encode(0b110, 0b1000, 0b0011, 0b001),
+ kASIDE1IS = encode(0b000, 0b1000, 0b0011, 0b010),
+ kVAAE1IS = encode(0b000, 0b1000, 0b0011, 0b011),
+ kALLE1IS = encode(0b100, 0b1000, 0b0011, 0b100),
+ kVALE1IS = encode(0b000, 0b1000, 0b0011, 0b101),
+ kVALE2IS = encode(0b100, 0b1000, 0b0011, 0b101),
+ kVALE3IS = encode(0b110, 0b1000, 0b0011, 0b101),
+ kVMALLS12E1IS = encode(0b100, 0b1000, 0b0011, 0b110),
+ kVAALE1IS = encode(0b000, 0b1000, 0b0011, 0b111),
+ kIPAS2E1 = encode(0b100, 0b1000, 0b0100, 0b001),
+ kIPAS2LE1 = encode(0b100, 0b1000, 0b0100, 0b101),
+ kVMALLE1 = encode(0b000, 0b1000, 0b0111, 0b000),
+ kALLE2 = encode(0b100, 0b1000, 0b0111, 0b000),
+ kALLE3 = encode(0b110, 0b1000, 0b0111, 0b000),
+ kVAE1 = encode(0b000, 0b1000, 0b0111, 0b001),
+ kVAE2 = encode(0b100, 0b1000, 0b0111, 0b001),
+ kVAE3 = encode(0b110, 0b1000, 0b0111, 0b001),
+ kASIDE1 = encode(0b000, 0b1000, 0b0111, 0b010),
+ kVAAE1 = encode(0b000, 0b1000, 0b0111, 0b011),
+ kALLE1 = encode(0b100, 0b1000, 0b0111, 0b100),
+ kVALE1 = encode(0b000, 0b1000, 0b0111, 0b101),
+ kVALE2 = encode(0b100, 0b1000, 0b0111, 0b101),
+ kVALE3 = encode(0b110, 0b1000, 0b0111, 0b101),
+ kVMALLS12E1 = encode(0b100, 0b1000, 0b0111, 0b110),
+ kVAALE1 = encode(0b000, 0b1000, 0b0111, 0b111),
+
+ kVMALLE1OS = encode(0b000, 0b1000, 0b0001, 0b000),
+ kVAE1OS = encode(0b000, 0b1000, 0b0001, 0b001),
+ kASIDE1OS = encode(0b000, 0b1000, 0b0001, 0b010),
+ kVAAE1OS = encode(0b000, 0b1000, 0b0001, 0b011),
+ kVALE1OS = encode(0b000, 0b1000, 0b0001, 0b101),
+ kVAALE1OS = encode(0b000, 0b1000, 0b0001, 0b111),
+ kIPAS2E1OS = encode(0b100, 0b1000, 0b0100, 0b000),
+ kIPAS2LE1OS = encode(0b100, 0b1000, 0b0100, 0b100),
+ kVAE2OS = encode(0b100, 0b1000, 0b0001, 0b001),
+ kVALE2OS = encode(0b100, 0b1000, 0b0001, 0b101),
+ kVMALLS12E1OS = encode(0b100, 0b1000, 0b0001, 0b110),
+ kVAE3OS = encode(0b110, 0b1000, 0b0001, 0b001),
+ kVALE3OS = encode(0b110, 0b1000, 0b0001, 0b101),
+ kALLE2OS = encode(0b100, 0b1000, 0b0001, 0b000),
+ kALLE1OS = encode(0b100, 0b1000, 0b0001, 0b100),
+ kALLE3OS = encode(0b110, 0b1000, 0b0001, 0b000),
+
+ kRVAE1 = encode(0b000, 0b1000, 0b0110, 0b001),
+ kRVAAE1 = encode(0b000, 0b1000, 0b0110, 0b011),
+ kRVALE1 = encode(0b000, 0b1000, 0b0110, 0b101),
+ kRVAALE1 = encode(0b000, 0b1000, 0b0110, 0b111),
+ kRVAE1IS = encode(0b000, 0b1000, 0b0010, 0b001),
+ kRVAAE1IS = encode(0b000, 0b1000, 0b0010, 0b011),
+ kRVALE1IS = encode(0b000, 0b1000, 0b0010, 0b101),
+ kRVAALE1IS = encode(0b000, 0b1000, 0b0010, 0b111),
+ kRVAE1OS = encode(0b000, 0b1000, 0b0101, 0b001),
+ kRVAAE1OS = encode(0b000, 0b1000, 0b0101, 0b011),
+ kRVALE1OS = encode(0b000, 0b1000, 0b0101, 0b101),
+ kRVAALE1OS = encode(0b000, 0b1000, 0b0101, 0b111),
+ kRIPAS2E1IS = encode(0b100, 0b1000, 0b0000, 0b010),
+ kRIPAS2LE1IS = encode(0b100, 0b1000, 0b0000, 0b110),
+ kRIPAS2E1 = encode(0b100, 0b1000, 0b0100, 0b010),
+ kRIPAS2LE1 = encode(0b100, 0b1000, 0b0100, 0b110),
+ kRIPAS2E1OS = encode(0b100, 0b1000, 0b0100, 0b011),
+ kRIPAS2LE1OS = encode(0b100, 0b1000, 0b0100, 0b111),
+ kRVAE2 = encode(0b100, 0b1000, 0b0110, 0b001),
+ kRVALE2 = encode(0b100, 0b1000, 0b0110, 0b101),
+ kRVAE2IS = encode(0b100, 0b1000, 0b0010, 0b001),
+ kRVALE2IS = encode(0b100, 0b1000, 0b0010, 0b101),
+ kRVAE2OS = encode(0b100, 0b1000, 0b0101, 0b001),
+ kRVALE2OS = encode(0b100, 0b1000, 0b0101, 0b101),
+ kRVAE3 = encode(0b110, 0b1000, 0b0110, 0b001),
+ kRVALE3 = encode(0b110, 0b1000, 0b0110, 0b101),
+ kRVAE3IS = encode(0b110, 0b1000, 0b0010, 0b001),
+ kRVALE3IS = encode(0b110, 0b1000, 0b0010, 0b101),
+ kRVAE3OS = encode(0b110, 0b1000, 0b0101, 0b001),
+ kRVALE3OS = encode(0b110, 0b1000, 0b0101, 0b101),
+ };
+}
+
+//! Trace synchronization barrier options.
+namespace TSB {
+ //! Trace synchronization immediate values.
+ enum Value : uint32_t {
+ kCSYNC = 0
+ };
+}
+
+//! 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 {
+ return (op0 << 3) | (op1 << 0);
+ }
+
+ //! Processor state access immediates.
+ enum Value : uint32_t {
+ kSPSel = encode(0b000, 0b101),
+ kDAIFSet = encode(0b011, 0b110),
+ kDAIFClr = encode(0b011, 0b111),
+ kPAN = encode(0b000, 0b100),
+ kUAO = encode(0b000, 0b011),
+ kDIT = encode(0b011, 0b010),
+ kSSBS = encode(0b011, 0b001),
+ kTCO = encode(0b011, 0b100)
+ };
+};
+
+//! System register identifiers and utilities (MSR/MRS).
+namespace SysReg {
+ //! System register fields.
+ struct Fields {
+ uint8_t op0;
+ uint8_t op1;
+ uint8_t cRn;
+ uint8_t cRm;
+ uint8_t op2;
+ };
+
+ //! 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 {
+ 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 {
+ 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 {
+ return Fields {
+ uint8_t((id >> 14) & 0x3u),
+ uint8_t((id >> 11) & 0x7u),
+ uint8_t((id >> 7) & 0xFu),
+ uint8_t((id >> 3) & 0xFu),
+ uint8_t((id >> 0) & 0x7u)
+ };
+ }
+
+ //! System register identifiers.
+ enum Id : uint32_t {
+ kACTLR_EL1 = encode(0b11, 0b000, 0b0001, 0b0000, 0b001), // RW
+ kACTLR_EL2 = encode(0b11, 0b100, 0b0001, 0b0000, 0b001), // RW
+ kACTLR_EL3 = encode(0b11, 0b110, 0b0001, 0b0000, 0b001), // RW
+ kAFSR0_EL1 = encode(0b11, 0b000, 0b0101, 0b0001, 0b000), // RW
+ kAFSR0_EL12 = encode(0b11, 0b101, 0b0101, 0b0001, 0b000), // RW
+ kAFSR0_EL2 = encode(0b11, 0b100, 0b0101, 0b0001, 0b000), // RW
+ kAFSR0_EL3 = encode(0b11, 0b110, 0b0101, 0b0001, 0b000), // RW
+ kAFSR1_EL1 = encode(0b11, 0b000, 0b0101, 0b0001, 0b001), // RW
+ kAFSR1_EL12 = encode(0b11, 0b101, 0b0101, 0b0001, 0b001), // RW
+ kAFSR1_EL2 = encode(0b11, 0b100, 0b0101, 0b0001, 0b001), // RW
+ kAFSR1_EL3 = encode(0b11, 0b110, 0b0101, 0b0001, 0b001), // RW
+ kAIDR_EL1 = encode(0b11, 0b001, 0b0000, 0b0000, 0b111), // RO
+ kAMAIR_EL1 = encode(0b11, 0b000, 0b1010, 0b0011, 0b000), // RW
+ kAMAIR_EL12 = encode(0b11, 0b101, 0b1010, 0b0011, 0b000), // RW
+ kAMAIR_EL2 = encode(0b11, 0b100, 0b1010, 0b0011, 0b000), // RW
+ kAMAIR_EL3 = encode(0b11, 0b110, 0b1010, 0b0011, 0b000), // RW
+ kAMCFGR_EL0 = encode(0b11, 0b011, 0b1101, 0b0010, 0b001), // RO
+ kAMCGCR_EL0 = encode(0b11, 0b011, 0b1101, 0b0010, 0b010), // RO
+ kAMCNTENCLR0_EL0 = encode(0b11, 0b011, 0b1101, 0b0010, 0b100), // RW
+ kAMCNTENCLR1_EL0 = encode(0b11, 0b011, 0b1101, 0b0011, 0b000), // RW
+ kAMCNTENSET0_EL0 = encode(0b11, 0b011, 0b1101, 0b0010, 0b101), // RW
+ kAMCNTENSET1_EL0 = encode(0b11, 0b011, 0b1101, 0b0011, 0b001), // RW
+ kAMCR_EL0 = encode(0b11, 0b011, 0b1101, 0b0010, 0b000), // RW
+ kAMEVCNTR00_EL0 = encode(0b11, 0b011, 0b1101, 0b0100, 0b000), // RW
+ kAMEVCNTR01_EL0 = encode(0b11, 0b011, 0b1101, 0b0100, 0b001), // RW
+ kAMEVCNTR02_EL0 = encode(0b11, 0b011, 0b1101, 0b0100, 0b010), // RW
+ kAMEVCNTR03_EL0 = encode(0b11, 0b011, 0b1101, 0b0100, 0b011), // RW
+ kAMEVCNTR10_EL0 = encode(0b11, 0b011, 0b1101, 0b1100, 0b000), // RW
+ kAMEVCNTR110_EL0 = encode(0b11, 0b011, 0b1101, 0b1101, 0b010), // RW
+ kAMEVCNTR111_EL0 = encode(0b11, 0b011, 0b1101, 0b1101, 0b011), // RW
+ kAMEVCNTR112_EL0 = encode(0b11, 0b011, 0b1101, 0b1101, 0b100), // RW
+ kAMEVCNTR113_EL0 = encode(0b11, 0b011, 0b1101, 0b1101, 0b101), // RW
+ kAMEVCNTR114_EL0 = encode(0b11, 0b011, 0b1101, 0b1101, 0b110), // RW
+ kAMEVCNTR115_EL0 = encode(0b11, 0b011, 0b1101, 0b1101, 0b111), // RW
+ kAMEVCNTR11_EL0 = encode(0b11, 0b011, 0b1101, 0b1100, 0b001), // RW
+ kAMEVCNTR12_EL0 = encode(0b11, 0b011, 0b1101, 0b1100, 0b010), // RW
+ kAMEVCNTR13_EL0 = encode(0b11, 0b011, 0b1101, 0b1100, 0b011), // RW
+ kAMEVCNTR14_EL0 = encode(0b11, 0b011, 0b1101, 0b1100, 0b100), // RW
+ kAMEVCNTR15_EL0 = encode(0b11, 0b011, 0b1101, 0b1100, 0b101), // RW
+ kAMEVCNTR16_EL0 = encode(0b11, 0b011, 0b1101, 0b1100, 0b110), // RW
+ kAMEVCNTR17_EL0 = encode(0b11, 0b011, 0b1101, 0b1100, 0b111), // RW
+ kAMEVCNTR18_EL0 = encode(0b11, 0b011, 0b1101, 0b1101, 0b000), // RW
+ kAMEVCNTR19_EL0 = encode(0b11, 0b011, 0b1101, 0b1101, 0b001), // RW
+ kAMEVTYPER00_EL0 = encode(0b11, 0b011, 0b1101, 0b0110, 0b000), // RO
+ kAMEVTYPER01_EL0 = encode(0b11, 0b011, 0b1101, 0b0110, 0b001), // RO
+ kAMEVTYPER02_EL0 = encode(0b11, 0b011, 0b1101, 0b0110, 0b010), // RO
+ kAMEVTYPER03_EL0 = encode(0b11, 0b011, 0b1101, 0b0110, 0b011), // RO
+ kAMEVTYPER10_EL0 = encode(0b11, 0b011, 0b1101, 0b1110, 0b000), // RW
+ kAMEVTYPER110_EL0 = encode(0b11, 0b011, 0b1101, 0b1111, 0b010), // RW
+ kAMEVTYPER111_EL0 = encode(0b11, 0b011, 0b1101, 0b1111, 0b011), // RW
+ kAMEVTYPER112_EL0 = encode(0b11, 0b011, 0b1101, 0b1111, 0b100), // RW
+ kAMEVTYPER113_EL0 = encode(0b11, 0b011, 0b1101, 0b1111, 0b101), // RW
+ kAMEVTYPER114_EL0 = encode(0b11, 0b011, 0b1101, 0b1111, 0b110), // RW
+ kAMEVTYPER115_EL0 = encode(0b11, 0b011, 0b1101, 0b1111, 0b111), // RW
+ kAMEVTYPER11_EL0 = encode(0b11, 0b011, 0b1101, 0b1110, 0b001), // RW
+ kAMEVTYPER12_EL0 = encode(0b11, 0b011, 0b1101, 0b1110, 0b010), // RW
+ kAMEVTYPER13_EL0 = encode(0b11, 0b011, 0b1101, 0b1110, 0b011), // RW
+ kAMEVTYPER14_EL0 = encode(0b11, 0b011, 0b1101, 0b1110, 0b100), // RW
+ kAMEVTYPER15_EL0 = encode(0b11, 0b011, 0b1101, 0b1110, 0b101), // RW
+ kAMEVTYPER16_EL0 = encode(0b11, 0b011, 0b1101, 0b1110, 0b110), // RW
+ kAMEVTYPER17_EL0 = encode(0b11, 0b011, 0b1101, 0b1110, 0b111), // RW
+ kAMEVTYPER18_EL0 = encode(0b11, 0b011, 0b1101, 0b1111, 0b000), // RW
+ kAMEVTYPER19_EL0 = encode(0b11, 0b011, 0b1101, 0b1111, 0b001), // RW
+ kAMUSERENR_EL0 = encode(0b11, 0b011, 0b1101, 0b0010, 0b011), // RW
+ kAPDAKeyHi_EL1 = encode(0b11, 0b000, 0b0010, 0b0010, 0b001), // RW
+ kAPDAKeyLo_EL1 = encode(0b11, 0b000, 0b0010, 0b0010, 0b000), // RW
+ kAPDBKeyHi_EL1 = encode(0b11, 0b000, 0b0010, 0b0010, 0b011), // RW
+ kAPDBKeyLo_EL1 = encode(0b11, 0b000, 0b0010, 0b0010, 0b010), // RW
+ kAPGAKeyHi_EL1 = encode(0b11, 0b000, 0b0010, 0b0011, 0b001), // RW
+ kAPGAKeyLo_EL1 = encode(0b11, 0b000, 0b0010, 0b0011, 0b000), // RW
+ kAPIAKeyHi_EL1 = encode(0b11, 0b000, 0b0010, 0b0001, 0b001), // RW
+ kAPIAKeyLo_EL1 = encode(0b11, 0b000, 0b0010, 0b0001, 0b000), // RW
+ kAPIBKeyHi_EL1 = encode(0b11, 0b000, 0b0010, 0b0001, 0b011), // RW
+ kAPIBKeyLo_EL1 = encode(0b11, 0b000, 0b0010, 0b0001, 0b010), // RW
+ kCCSIDR2_EL1 = encode(0b11, 0b001, 0b0000, 0b0000, 0b010), // RO
+ kCCSIDR_EL1 = encode(0b11, 0b001, 0b0000, 0b0000, 0b000), // RO
+ kCLIDR_EL1 = encode(0b11, 0b001, 0b0000, 0b0000, 0b001), // RO
+ kCNTFRQ_EL0 = encode(0b11, 0b011, 0b1110, 0b0000, 0b000), // RW
+ kCNTHCTL_EL2 = encode(0b11, 0b100, 0b1110, 0b0001, 0b000), // RW
+ kCNTHPS_CTL_EL2 = encode(0b11, 0b100, 0b1110, 0b0101, 0b001), // RW
+ kCNTHPS_CVAL_EL2 = encode(0b11, 0b100, 0b1110, 0b0101, 0b010), // RW
+ kCNTHPS_TVAL_EL2 = encode(0b11, 0b100, 0b1110, 0b0101, 0b000), // RW
+ kCNTHP_CTL_EL2 = encode(0b11, 0b100, 0b1110, 0b0010, 0b001), // RW
+ kCNTHP_CVAL_EL2 = encode(0b11, 0b100, 0b1110, 0b0010, 0b010), // RW
+ kCNTHP_TVAL_EL2 = encode(0b11, 0b100, 0b1110, 0b0010, 0b000), // RW
+ kCNTHVS_CTL_EL2 = encode(0b11, 0b100, 0b1110, 0b0100, 0b001), // RW
+ kCNTHVS_CVAL_EL2 = encode(0b11, 0b100, 0b1110, 0b0100, 0b010), // RW
+ kCNTHVS_TVAL_EL2 = encode(0b11, 0b100, 0b1110, 0b0100, 0b000), // RW
+ kCNTHV_CTL_EL2 = encode(0b11, 0b100, 0b1110, 0b0011, 0b001), // RW
+ kCNTHV_CVAL_EL2 = encode(0b11, 0b100, 0b1110, 0b0011, 0b010), // RW
+ kCNTHV_TVAL_EL2 = encode(0b11, 0b100, 0b1110, 0b0011, 0b000), // RW
+ kCNTISCALE_EL2 = encode(0b11, 0b100, 0b1110, 0b0000, 0b101), // RW
+ kCNTKCTL_EL1 = encode(0b11, 0b000, 0b1110, 0b0001, 0b000), // RW
+ kCNTKCTL_EL12 = encode(0b11, 0b101, 0b1110, 0b0001, 0b000), // RW
+ kCNTPCTSS_EL0 = encode(0b11, 0b011, 0b1110, 0b0000, 0b101), // RW
+ kCNTPCT_EL0 = encode(0b11, 0b011, 0b1110, 0b0000, 0b001), // RO
+ kCNTPOFF_EL2 = encode(0b11, 0b100, 0b1110, 0b0000, 0b110), // RW
+ kCNTPS_CTL_EL1 = encode(0b11, 0b111, 0b1110, 0b0010, 0b001), // RW
+ kCNTPS_CVAL_EL1 = encode(0b11, 0b111, 0b1110, 0b0010, 0b010), // RW
+ kCNTPS_TVAL_EL1 = encode(0b11, 0b111, 0b1110, 0b0010, 0b000), // RW
+ kCNTP_CTL_EL0 = encode(0b11, 0b011, 0b1110, 0b0010, 0b001), // RW
+ kCNTP_CTL_EL02 = encode(0b11, 0b101, 0b1110, 0b0010, 0b001), // RW
+ kCNTP_CVAL_EL0 = encode(0b11, 0b011, 0b1110, 0b0010, 0b010), // RW
+ kCNTP_CVAL_EL02 = encode(0b11, 0b101, 0b1110, 0b0010, 0b010), // RW
+ kCNTP_TVAL_EL0 = encode(0b11, 0b011, 0b1110, 0b0010, 0b000), // RW
+ kCNTP_TVAL_EL02 = encode(0b11, 0b101, 0b1110, 0b0010, 0b000), // RW
+ kCNTSCALE_EL2 = encode(0b11, 0b100, 0b1110, 0b0000, 0b100), // RW
+ kCNTVCTSS_EL0 = encode(0b11, 0b011, 0b1110, 0b0000, 0b110), // RW
+ kCNTVCT_EL0 = encode(0b11, 0b011, 0b1110, 0b0000, 0b010), // RO
+ kCNTVFRQ_EL2 = encode(0b11, 0b100, 0b1110, 0b0000, 0b111), // RW
+ kCNTVOFF_EL2 = encode(0b11, 0b100, 0b1110, 0b0000, 0b011), // RW
+ kCNTV_CTL_EL0 = encode(0b11, 0b011, 0b1110, 0b0011, 0b001), // RW
+ kCNTV_CTL_EL02 = encode(0b11, 0b101, 0b1110, 0b0011, 0b001), // RW
+ kCNTV_CVAL_EL0 = encode(0b11, 0b011, 0b1110, 0b0011, 0b010), // RW
+ kCNTV_CVAL_EL02 = encode(0b11, 0b101, 0b1110, 0b0011, 0b010), // RW
+ kCNTV_TVAL_EL0 = encode(0b11, 0b011, 0b1110, 0b0011, 0b000), // RW
+ kCNTV_TVAL_EL02 = encode(0b11, 0b101, 0b1110, 0b0011, 0b000), // RW
+ kCONTEXTIDR_EL1 = encode(0b11, 0b000, 0b1101, 0b0000, 0b001), // RW
+ kCONTEXTIDR_EL12 = encode(0b11, 0b101, 0b1101, 0b0000, 0b001), // RW
+ kCONTEXTIDR_EL2 = encode(0b11, 0b100, 0b1101, 0b0000, 0b001), // RW
+ kCPACR_EL1 = encode(0b11, 0b000, 0b0001, 0b0000, 0b010), // RW
+ kCPACR_EL12 = encode(0b11, 0b101, 0b0001, 0b0000, 0b010), // RW
+ kCPM_IOACC_CTL_EL3 = encode(0b11, 0b111, 0b1111, 0b0010, 0b000), // RW
+ kCPTR_EL2 = encode(0b11, 0b100, 0b0001, 0b0001, 0b010), // RW
+ kCPTR_EL3 = encode(0b11, 0b110, 0b0001, 0b0001, 0b010), // RW
+ kCSSELR_EL1 = encode(0b11, 0b010, 0b0000, 0b0000, 0b000), // RW
+ kCTR_EL0 = encode(0b11, 0b011, 0b0000, 0b0000, 0b001), // RO
+ kCurrentEL = encode(0b11, 0b000, 0b0100, 0b0010, 0b010), // RO
+ kDACR32_EL2 = encode(0b11, 0b100, 0b0011, 0b0000, 0b000), // RW
+ kDAIF = encode(0b11, 0b011, 0b0100, 0b0010, 0b001), // RW
+ kDBGAUTHSTATUS_EL1 = encode(0b10, 0b000, 0b0111, 0b1110, 0b110), // RO
+ kDBGBCR0_EL1 = encode(0b10, 0b000, 0b0000, 0b0000, 0b101), // RW
+ kDBGBCR10_EL1 = encode(0b10, 0b000, 0b0000, 0b1010, 0b101), // RW
+ kDBGBCR11_EL1 = encode(0b10, 0b000, 0b0000, 0b1011, 0b101), // RW
+ kDBGBCR12_EL1 = encode(0b10, 0b000, 0b0000, 0b1100, 0b101), // RW
+ kDBGBCR13_EL1 = encode(0b10, 0b000, 0b0000, 0b1101, 0b101), // RW
+ kDBGBCR14_EL1 = encode(0b10, 0b000, 0b0000, 0b1110, 0b101), // RW
+ kDBGBCR15_EL1 = encode(0b10, 0b000, 0b0000, 0b1111, 0b101), // RW
+ kDBGBCR1_EL1 = encode(0b10, 0b000, 0b0000, 0b0001, 0b101), // RW
+ kDBGBCR2_EL1 = encode(0b10, 0b000, 0b0000, 0b0010, 0b101), // RW
+ kDBGBCR3_EL1 = encode(0b10, 0b000, 0b0000, 0b0011, 0b101), // RW
+ kDBGBCR4_EL1 = encode(0b10, 0b000, 0b0000, 0b0100, 0b101), // RW
+ kDBGBCR5_EL1 = encode(0b10, 0b000, 0b0000, 0b0101, 0b101), // RW
+ kDBGBCR6_EL1 = encode(0b10, 0b000, 0b0000, 0b0110, 0b101), // RW
+ kDBGBCR7_EL1 = encode(0b10, 0b000, 0b0000, 0b0111, 0b101), // RW
+ kDBGBCR8_EL1 = encode(0b10, 0b000, 0b0000, 0b1000, 0b101), // RW
+ kDBGBCR9_EL1 = encode(0b10, 0b000, 0b0000, 0b1001, 0b101), // RW
+ kDBGBVR0_EL1 = encode(0b10, 0b000, 0b0000, 0b0000, 0b100), // RW
+ kDBGBVR10_EL1 = encode(0b10, 0b000, 0b0000, 0b1010, 0b100), // RW
+ kDBGBVR11_EL1 = encode(0b10, 0b000, 0b0000, 0b1011, 0b100), // RW
+ kDBGBVR12_EL1 = encode(0b10, 0b000, 0b0000, 0b1100, 0b100), // RW
+ kDBGBVR13_EL1 = encode(0b10, 0b000, 0b0000, 0b1101, 0b100), // RW
+ kDBGBVR14_EL1 = encode(0b10, 0b000, 0b0000, 0b1110, 0b100), // RW
+ kDBGBVR15_EL1 = encode(0b10, 0b000, 0b0000, 0b1111, 0b100), // RW
+ kDBGBVR1_EL1 = encode(0b10, 0b000, 0b0000, 0b0001, 0b100), // RW
+ kDBGBVR2_EL1 = encode(0b10, 0b000, 0b0000, 0b0010, 0b100), // RW
+ kDBGBVR3_EL1 = encode(0b10, 0b000, 0b0000, 0b0011, 0b100), // RW
+ kDBGBVR4_EL1 = encode(0b10, 0b000, 0b0000, 0b0100, 0b100), // RW
+ kDBGBVR5_EL1 = encode(0b10, 0b000, 0b0000, 0b0101, 0b100), // RW
+ kDBGBVR6_EL1 = encode(0b10, 0b000, 0b0000, 0b0110, 0b100), // RW
+ kDBGBVR7_EL1 = encode(0b10, 0b000, 0b0000, 0b0111, 0b100), // RW
+ kDBGBVR8_EL1 = encode(0b10, 0b000, 0b0000, 0b1000, 0b100), // RW
+ kDBGBVR9_EL1 = encode(0b10, 0b000, 0b0000, 0b1001, 0b100), // RW
+ kDBGCLAIMCLR_EL1 = encode(0b10, 0b000, 0b0111, 0b1001, 0b110), // RW
+ kDBGCLAIMSET_EL1 = encode(0b10, 0b000, 0b0111, 0b1000, 0b110), // RW
+ kDBGDTRRX_EL0 = encode(0b10, 0b011, 0b0000, 0b0101, 0b000), // RO
+ kDBGDTRTX_EL0 = encode(0b10, 0b011, 0b0000, 0b0101, 0b000), // WO
+ kDBGDTR_EL0 = encode(0b10, 0b011, 0b0000, 0b0100, 0b000), // RW
+ kDBGPRCR_EL1 = encode(0b10, 0b000, 0b0001, 0b0100, 0b100), // RW
+ kDBGVCR32_EL2 = encode(0b10, 0b100, 0b0000, 0b0111, 0b000), // RW
+ kDBGWCR0_EL1 = encode(0b10, 0b000, 0b0000, 0b0000, 0b111), // RW
+ kDBGWCR10_EL1 = encode(0b10, 0b000, 0b0000, 0b1010, 0b111), // RW
+ kDBGWCR11_EL1 = encode(0b10, 0b000, 0b0000, 0b1011, 0b111), // RW
+ kDBGWCR12_EL1 = encode(0b10, 0b000, 0b0000, 0b1100, 0b111), // RW
+ kDBGWCR13_EL1 = encode(0b10, 0b000, 0b0000, 0b1101, 0b111), // RW
+ kDBGWCR14_EL1 = encode(0b10, 0b000, 0b0000, 0b1110, 0b111), // RW
+ kDBGWCR15_EL1 = encode(0b10, 0b000, 0b0000, 0b1111, 0b111), // RW
+ kDBGWCR1_EL1 = encode(0b10, 0b000, 0b0000, 0b0001, 0b111), // RW
+ kDBGWCR2_EL1 = encode(0b10, 0b000, 0b0000, 0b0010, 0b111), // RW
+ kDBGWCR3_EL1 = encode(0b10, 0b000, 0b0000, 0b0011, 0b111), // RW
+ kDBGWCR4_EL1 = encode(0b10, 0b000, 0b0000, 0b0100, 0b111), // RW
+ kDBGWCR5_EL1 = encode(0b10, 0b000, 0b0000, 0b0101, 0b111), // RW
+ kDBGWCR6_EL1 = encode(0b10, 0b000, 0b0000, 0b0110, 0b111), // RW
+ kDBGWCR7_EL1 = encode(0b10, 0b000, 0b0000, 0b0111, 0b111), // RW
+ kDBGWCR8_EL1 = encode(0b10, 0b000, 0b0000, 0b1000, 0b111), // RW
+ kDBGWCR9_EL1 = encode(0b10, 0b000, 0b0000, 0b1001, 0b111), // RW
+ kDBGWVR0_EL1 = encode(0b10, 0b000, 0b0000, 0b0000, 0b110), // RW
+ kDBGWVR10_EL1 = encode(0b10, 0b000, 0b0000, 0b1010, 0b110), // RW
+ kDBGWVR11_EL1 = encode(0b10, 0b000, 0b0000, 0b1011, 0b110), // RW
+ kDBGWVR12_EL1 = encode(0b10, 0b000, 0b0000, 0b1100, 0b110), // RW
+ kDBGWVR13_EL1 = encode(0b10, 0b000, 0b0000, 0b1101, 0b110), // RW
+ kDBGWVR14_EL1 = encode(0b10, 0b000, 0b0000, 0b1110, 0b110), // RW
+ kDBGWVR15_EL1 = encode(0b10, 0b000, 0b0000, 0b1111, 0b110), // RW
+ kDBGWVR1_EL1 = encode(0b10, 0b000, 0b0000, 0b0001, 0b110), // RW
+ kDBGWVR2_EL1 = encode(0b10, 0b000, 0b0000, 0b0010, 0b110), // RW
+ kDBGWVR3_EL1 = encode(0b10, 0b000, 0b0000, 0b0011, 0b110), // RW
+ kDBGWVR4_EL1 = encode(0b10, 0b000, 0b0000, 0b0100, 0b110), // RW
+ kDBGWVR5_EL1 = encode(0b10, 0b000, 0b0000, 0b0101, 0b110), // RW
+ kDBGWVR6_EL1 = encode(0b10, 0b000, 0b0000, 0b0110, 0b110), // RW
+ kDBGWVR7_EL1 = encode(0b10, 0b000, 0b0000, 0b0111, 0b110), // RW
+ kDBGWVR8_EL1 = encode(0b10, 0b000, 0b0000, 0b1000, 0b110), // RW
+ kDBGWVR9_EL1 = encode(0b10, 0b000, 0b0000, 0b1001, 0b110), // RW
+ kDCZID_EL0 = encode(0b11, 0b011, 0b0000, 0b0000, 0b111), // RO
+ kDISR_EL1 = encode(0b11, 0b000, 0b1100, 0b0001, 0b001), // RW
+ kDIT = encode(0b11, 0b011, 0b0100, 0b0010, 0b101), // RW
+ kDLR_EL0 = encode(0b11, 0b011, 0b0100, 0b0101, 0b001), // RW
+ kDSPSR_EL0 = encode(0b11, 0b011, 0b0100, 0b0101, 0b000), // RW
+ kELR_EL1 = encode(0b11, 0b000, 0b0100, 0b0000, 0b001), // RW
+ kELR_EL12 = encode(0b11, 0b101, 0b0100, 0b0000, 0b001), // RW
+ kELR_EL2 = encode(0b11, 0b100, 0b0100, 0b0000, 0b001), // RW
+ kELR_EL3 = encode(0b11, 0b110, 0b0100, 0b0000, 0b001), // RW
+ kERRIDR_EL1 = encode(0b11, 0b000, 0b0101, 0b0011, 0b000), // RO
+ kERRSELR_EL1 = encode(0b11, 0b000, 0b0101, 0b0011, 0b001), // RW
+ kERXADDR_EL1 = encode(0b11, 0b000, 0b0101, 0b0100, 0b011), // RW
+ kERXCTLR_EL1 = encode(0b11, 0b000, 0b0101, 0b0100, 0b001), // RW
+ kERXFR_EL1 = encode(0b11, 0b000, 0b0101, 0b0100, 0b000), // RO
+ kERXMISC0_EL1 = encode(0b11, 0b000, 0b0101, 0b0101, 0b000), // RW
+ kERXMISC1_EL1 = encode(0b11, 0b000, 0b0101, 0b0101, 0b001), // RW
+ kERXMISC2_EL1 = encode(0b11, 0b000, 0b0101, 0b0101, 0b010), // RW
+ kERXMISC3_EL1 = encode(0b11, 0b000, 0b0101, 0b0101, 0b011), // RW
+ kERXPFGCDN_EL1 = encode(0b11, 0b000, 0b0101, 0b0100, 0b110), // RW
+ kERXPFGCTL_EL1 = encode(0b11, 0b000, 0b0101, 0b0100, 0b101), // RW
+ kERXPFGF_EL1 = encode(0b11, 0b000, 0b0101, 0b0100, 0b100), // RO
+ kERXSTATUS_EL1 = encode(0b11, 0b000, 0b0101, 0b0100, 0b010), // RW
+ kESR_EL1 = encode(0b11, 0b000, 0b0101, 0b0010, 0b000), // RW
+ kESR_EL12 = encode(0b11, 0b101, 0b0101, 0b0010, 0b000), // RW
+ kESR_EL2 = encode(0b11, 0b100, 0b0101, 0b0010, 0b000), // RW
+ kESR_EL3 = encode(0b11, 0b110, 0b0101, 0b0010, 0b000), // RW
+ kFAR_EL1 = encode(0b11, 0b000, 0b0110, 0b0000, 0b000), // RW
+ kFAR_EL12 = encode(0b11, 0b101, 0b0110, 0b0000, 0b000), // RW
+ kFAR_EL2 = encode(0b11, 0b100, 0b0110, 0b0000, 0b000), // RW
+ kFAR_EL3 = encode(0b11, 0b110, 0b0110, 0b0000, 0b000), // RW
+ kFPCR = encode(0b11, 0b011, 0b0100, 0b0100, 0b000), // RW
+ kFPEXC32_EL2 = encode(0b11, 0b100, 0b0101, 0b0011, 0b000), // RW
+ kFPSR = encode(0b11, 0b011, 0b0100, 0b0100, 0b001), // RW
+ kGCR_EL1 = encode(0b11, 0b000, 0b0001, 0b0000, 0b110), // RW
+ kGMID_EL1 = encode(0b11, 0b001, 0b0000, 0b0000, 0b100), // RO
+ kHACR_EL2 = encode(0b11, 0b100, 0b0001, 0b0001, 0b111), // RW
+ kHCR_EL2 = encode(0b11, 0b100, 0b0001, 0b0001, 0b000), // RW
+ kHDFGRTR_EL2 = encode(0b11, 0b100, 0b0011, 0b0001, 0b100), // RW
+ kHDFGWTR_EL2 = encode(0b11, 0b100, 0b0011, 0b0001, 0b101), // RW
+ kHFGITR_EL2 = encode(0b11, 0b100, 0b0001, 0b0001, 0b110), // RW
+ kHFGRTR_EL2 = encode(0b11, 0b100, 0b0001, 0b0001, 0b100), // RW
+ kHFGWTR_EL2 = encode(0b11, 0b100, 0b0001, 0b0001, 0b101), // RW
+ kHPFAR_EL2 = encode(0b11, 0b100, 0b0110, 0b0000, 0b100), // RW
+ kHSTR_EL2 = encode(0b11, 0b100, 0b0001, 0b0001, 0b011), // RW
+ kICC_AP0R0_EL1 = encode(0b11, 0b000, 0b1100, 0b1000, 0b100), // RW
+ kICC_AP0R1_EL1 = encode(0b11, 0b000, 0b1100, 0b1000, 0b101), // RW
+ kICC_AP0R2_EL1 = encode(0b11, 0b000, 0b1100, 0b1000, 0b110), // RW
+ kICC_AP0R3_EL1 = encode(0b11, 0b000, 0b1100, 0b1000, 0b111), // RW
+ kICC_AP1R0_EL1 = encode(0b11, 0b000, 0b1100, 0b1001, 0b000), // RW
+ kICC_AP1R1_EL1 = encode(0b11, 0b000, 0b1100, 0b1001, 0b001), // RW
+ kICC_AP1R2_EL1 = encode(0b11, 0b000, 0b1100, 0b1001, 0b010), // RW
+ kICC_AP1R3_EL1 = encode(0b11, 0b000, 0b1100, 0b1001, 0b011), // RW
+ kICC_ASGI1R_EL1 = encode(0b11, 0b000, 0b1100, 0b1011, 0b110), // WO
+ kICC_BPR0_EL1 = encode(0b11, 0b000, 0b1100, 0b1000, 0b011), // RW
+ kICC_BPR1_EL1 = encode(0b11, 0b000, 0b1100, 0b1100, 0b011), // RW
+ kICC_CTLR_EL1 = encode(0b11, 0b000, 0b1100, 0b1100, 0b100), // RW
+ kICC_CTLR_EL3 = encode(0b11, 0b110, 0b1100, 0b1100, 0b100), // RW
+ kICC_DIR_EL1 = encode(0b11, 0b000, 0b1100, 0b1011, 0b001), // WO
+ kICC_EOIR0_EL1 = encode(0b11, 0b000, 0b1100, 0b1000, 0b001), // WO
+ kICC_EOIR1_EL1 = encode(0b11, 0b000, 0b1100, 0b1100, 0b001), // WO
+ kICC_HPPIR0_EL1 = encode(0b11, 0b000, 0b1100, 0b1000, 0b010), // RO
+ kICC_HPPIR1_EL1 = encode(0b11, 0b000, 0b1100, 0b1100, 0b010), // RO
+ kICC_IAR0_EL1 = encode(0b11, 0b000, 0b1100, 0b1000, 0b000), // RO
+ kICC_IAR1_EL1 = encode(0b11, 0b000, 0b1100, 0b1100, 0b000), // RO
+ kICC_IGRPEN0_EL1 = encode(0b11, 0b000, 0b1100, 0b1100, 0b110), // RW
+ kICC_IGRPEN1_EL1 = encode(0b11, 0b000, 0b1100, 0b1100, 0b111), // RW
+ kICC_IGRPEN1_EL3 = encode(0b11, 0b110, 0b1100, 0b1100, 0b111), // RW
+ kICC_PMR_EL1 = encode(0b11, 0b000, 0b0100, 0b0110, 0b000), // RW
+ kICC_RPR_EL1 = encode(0b11, 0b000, 0b1100, 0b1011, 0b011), // RO
+ kICC_SGI0R_EL1 = encode(0b11, 0b000, 0b1100, 0b1011, 0b111), // WO
+ kICC_SGI1R_EL1 = encode(0b11, 0b000, 0b1100, 0b1011, 0b101), // WO
+ kICC_SRE_EL1 = encode(0b11, 0b000, 0b1100, 0b1100, 0b101), // RW
+ kICC_SRE_EL2 = encode(0b11, 0b100, 0b1100, 0b1001, 0b101), // RW
+ kICC_SRE_EL3 = encode(0b11, 0b110, 0b1100, 0b1100, 0b101), // RW
+ kICH_AP0R0_EL2 = encode(0b11, 0b100, 0b1100, 0b1000, 0b000), // RW
+ kICH_AP0R1_EL2 = encode(0b11, 0b100, 0b1100, 0b1000, 0b001), // RW
+ kICH_AP0R2_EL2 = encode(0b11, 0b100, 0b1100, 0b1000, 0b010), // RW
+ kICH_AP0R3_EL2 = encode(0b11, 0b100, 0b1100, 0b1000, 0b011), // RW
+ kICH_AP1R0_EL2 = encode(0b11, 0b100, 0b1100, 0b1001, 0b000), // RW
+ kICH_AP1R1_EL2 = encode(0b11, 0b100, 0b1100, 0b1001, 0b001), // RW
+ kICH_AP1R2_EL2 = encode(0b11, 0b100, 0b1100, 0b1001, 0b010), // RW
+ kICH_AP1R3_EL2 = encode(0b11, 0b100, 0b1100, 0b1001, 0b011), // RW
+ kICH_EISR_EL2 = encode(0b11, 0b100, 0b1100, 0b1011, 0b011), // RO
+ kICH_ELRSR_EL2 = encode(0b11, 0b100, 0b1100, 0b1011, 0b101), // RO
+ kICH_HCR_EL2 = encode(0b11, 0b100, 0b1100, 0b1011, 0b000), // RW
+ kICH_LR0_EL2 = encode(0b11, 0b100, 0b1100, 0b1100, 0b000), // RW
+ kICH_LR10_EL2 = encode(0b11, 0b100, 0b1100, 0b1101, 0b010), // RW
+ kICH_LR11_EL2 = encode(0b11, 0b100, 0b1100, 0b1101, 0b011), // RW
+ kICH_LR12_EL2 = encode(0b11, 0b100, 0b1100, 0b1101, 0b100), // RW
+ kICH_LR13_EL2 = encode(0b11, 0b100, 0b1100, 0b1101, 0b101), // RW
+ kICH_LR14_EL2 = encode(0b11, 0b100, 0b1100, 0b1101, 0b110), // RW
+ kICH_LR15_EL2 = encode(0b11, 0b100, 0b1100, 0b1101, 0b111), // RW
+ kICH_LR1_EL2 = encode(0b11, 0b100, 0b1100, 0b1100, 0b001), // RW
+ kICH_LR2_EL2 = encode(0b11, 0b100, 0b1100, 0b1100, 0b010), // RW
+ kICH_LR3_EL2 = encode(0b11, 0b100, 0b1100, 0b1100, 0b011), // RW
+ kICH_LR4_EL2 = encode(0b11, 0b100, 0b1100, 0b1100, 0b100), // RW
+ kICH_LR5_EL2 = encode(0b11, 0b100, 0b1100, 0b1100, 0b101), // RW
+ kICH_LR6_EL2 = encode(0b11, 0b100, 0b1100, 0b1100, 0b110), // RW
+ kICH_LR7_EL2 = encode(0b11, 0b100, 0b1100, 0b1100, 0b111), // RW
+ kICH_LR8_EL2 = encode(0b11, 0b100, 0b1100, 0b1101, 0b000), // RW
+ kICH_LR9_EL2 = encode(0b11, 0b100, 0b1100, 0b1101, 0b001), // RW
+ kICH_MISR_EL2 = encode(0b11, 0b100, 0b1100, 0b1011, 0b010), // RO
+ kICH_VMCR_EL2 = encode(0b11, 0b100, 0b1100, 0b1011, 0b111), // RW
+ kICH_VTR_EL2 = encode(0b11, 0b100, 0b1100, 0b1011, 0b001), // RO
+ kID_AA64AFR0_EL1 = encode(0b11, 0b000, 0b0000, 0b0101, 0b100), // RO
+ kID_AA64AFR1_EL1 = encode(0b11, 0b000, 0b0000, 0b0101, 0b101), // RO
+ kID_AA64DFR0_EL1 = encode(0b11, 0b000, 0b0000, 0b0101, 0b000), // RO
+ 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_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_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
+ kID_AFR0_EL1 = encode(0b11, 0b000, 0b0000, 0b0001, 0b011), // RO
+ kID_DFR0_EL1 = encode(0b11, 0b000, 0b0000, 0b0001, 0b010), // RO
+ kID_ISAR0_EL1 = encode(0b11, 0b000, 0b0000, 0b0010, 0b000), // RO
+ kID_ISAR1_EL1 = encode(0b11, 0b000, 0b0000, 0b0010, 0b001), // RO
+ kID_ISAR2_EL1 = encode(0b11, 0b000, 0b0000, 0b0010, 0b010), // RO
+ kID_ISAR3_EL1 = encode(0b11, 0b000, 0b0000, 0b0010, 0b011), // RO
+ kID_ISAR4_EL1 = encode(0b11, 0b000, 0b0000, 0b0010, 0b100), // RO
+ kID_ISAR5_EL1 = encode(0b11, 0b000, 0b0000, 0b0010, 0b101), // RO
+ kID_ISAR6_EL1 = encode(0b11, 0b000, 0b0000, 0b0010, 0b111), // RO
+ kID_MMFR0_EL1 = encode(0b11, 0b000, 0b0000, 0b0001, 0b100), // RO
+ kID_MMFR1_EL1 = encode(0b11, 0b000, 0b0000, 0b0001, 0b101), // RO
+ kID_MMFR2_EL1 = encode(0b11, 0b000, 0b0000, 0b0001, 0b110), // RO
+ kID_MMFR3_EL1 = encode(0b11, 0b000, 0b0000, 0b0001, 0b111), // RO
+ kID_MMFR4_EL1 = encode(0b11, 0b000, 0b0000, 0b0010, 0b110), // RO
+ kID_MMFR5_EL1 = encode(0b11, 0b000, 0b0000, 0b0011, 0b110), // RO
+ kID_PFR0_EL1 = encode(0b11, 0b000, 0b0000, 0b0001, 0b000), // RO
+ kID_PFR1_EL1 = encode(0b11, 0b000, 0b0000, 0b0001, 0b001), // RO
+ kID_PFR2_EL1 = encode(0b11, 0b000, 0b0000, 0b0011, 0b100), // RO
+ kIFSR32_EL2 = encode(0b11, 0b100, 0b0101, 0b0000, 0b001), // RW
+ kISR_EL1 = encode(0b11, 0b000, 0b1100, 0b0001, 0b000), // RO
+ kLORC_EL1 = encode(0b11, 0b000, 0b1010, 0b0100, 0b011), // RW
+ kLOREA_EL1 = encode(0b11, 0b000, 0b1010, 0b0100, 0b001), // RW
+ kLORID_EL1 = encode(0b11, 0b000, 0b1010, 0b0100, 0b111), // RO
+ kLORN_EL1 = encode(0b11, 0b000, 0b1010, 0b0100, 0b010), // RW
+ kLORSA_EL1 = encode(0b11, 0b000, 0b1010, 0b0100, 0b000), // RW
+ kMAIR_EL1 = encode(0b11, 0b000, 0b1010, 0b0010, 0b000), // RW
+ kMAIR_EL12 = encode(0b11, 0b101, 0b1010, 0b0010, 0b000), // RW
+ kMAIR_EL2 = encode(0b11, 0b100, 0b1010, 0b0010, 0b000), // RW
+ kMAIR_EL3 = encode(0b11, 0b110, 0b1010, 0b0010, 0b000), // RW
+ kMDCCINT_EL1 = encode(0b10, 0b000, 0b0000, 0b0010, 0b000), // RW
+ kMDCCSR_EL0 = encode(0b10, 0b011, 0b0000, 0b0001, 0b000), // RO
+ kMDCR_EL2 = encode(0b11, 0b100, 0b0001, 0b0001, 0b001), // RW
+ kMDCR_EL3 = encode(0b11, 0b110, 0b0001, 0b0011, 0b001), // RW
+ kMDRAR_EL1 = encode(0b10, 0b000, 0b0001, 0b0000, 0b000), // RO
+ kMDSCR_EL1 = encode(0b10, 0b000, 0b0000, 0b0010, 0b010), // RW
+ kMIDR_EL1 = encode(0b11, 0b000, 0b0000, 0b0000, 0b000), // RO
+ kMPAM0_EL1 = encode(0b11, 0b000, 0b1010, 0b0101, 0b001), // RW
+ kMPAM1_EL1 = encode(0b11, 0b000, 0b1010, 0b0101, 0b000), // RW
+ kMPAM1_EL12 = encode(0b11, 0b101, 0b1010, 0b0101, 0b000), // RW
+ kMPAM2_EL2 = encode(0b11, 0b100, 0b1010, 0b0101, 0b000), // RW
+ kMPAM3_EL3 = encode(0b11, 0b110, 0b1010, 0b0101, 0b000), // RW
+ kMPAMHCR_EL2 = encode(0b11, 0b100, 0b1010, 0b0100, 0b000), // RW
+ kMPAMIDR_EL1 = encode(0b11, 0b000, 0b1010, 0b0100, 0b100), // RO
+ kMPAMVPM0_EL2 = encode(0b11, 0b100, 0b1010, 0b0110, 0b000), // RW
+ kMPAMVPM1_EL2 = encode(0b11, 0b100, 0b1010, 0b0110, 0b001), // RW
+ kMPAMVPM2_EL2 = encode(0b11, 0b100, 0b1010, 0b0110, 0b010), // RW
+ kMPAMVPM3_EL2 = encode(0b11, 0b100, 0b1010, 0b0110, 0b011), // RW
+ kMPAMVPM4_EL2 = encode(0b11, 0b100, 0b1010, 0b0110, 0b100), // RW
+ kMPAMVPM5_EL2 = encode(0b11, 0b100, 0b1010, 0b0110, 0b101), // RW
+ kMPAMVPM6_EL2 = encode(0b11, 0b100, 0b1010, 0b0110, 0b110), // RW
+ kMPAMVPM7_EL2 = encode(0b11, 0b100, 0b1010, 0b0110, 0b111), // RW
+ kMPAMVPMV_EL2 = encode(0b11, 0b100, 0b1010, 0b0100, 0b001), // RW
+ kMPIDR_EL1 = encode(0b11, 0b000, 0b0000, 0b0000, 0b101), // RO
+ kMVFR0_EL1 = encode(0b11, 0b000, 0b0000, 0b0011, 0b000), // RO
+ kMVFR1_EL1 = encode(0b11, 0b000, 0b0000, 0b0011, 0b001), // RO
+ kMVFR2_EL1 = encode(0b11, 0b000, 0b0000, 0b0011, 0b010), // RO
+ kNZCV = encode(0b11, 0b011, 0b0100, 0b0010, 0b000), // RW
+ kOSDLR_EL1 = encode(0b10, 0b000, 0b0001, 0b0011, 0b100), // RW
+ kOSDTRRX_EL1 = encode(0b10, 0b000, 0b0000, 0b0000, 0b010), // RW
+ kOSDTRTX_EL1 = encode(0b10, 0b000, 0b0000, 0b0011, 0b010), // RW
+ kOSECCR_EL1 = encode(0b10, 0b000, 0b0000, 0b0110, 0b010), // RW
+ kOSLAR_EL1 = encode(0b10, 0b000, 0b0001, 0b0000, 0b100), // WO
+ kOSLSR_EL1 = encode(0b10, 0b000, 0b0001, 0b0001, 0b100), // RO
+ kPAN = encode(0b11, 0b000, 0b0100, 0b0010, 0b011), // RW
+ kPAR_EL1 = encode(0b11, 0b000, 0b0111, 0b0100, 0b000), // RW
+ kPMBIDR_EL1 = encode(0b11, 0b000, 0b1001, 0b1010, 0b111), // RO
+ kPMBLIMITR_EL1 = encode(0b11, 0b000, 0b1001, 0b1010, 0b000), // RW
+ kPMBPTR_EL1 = encode(0b11, 0b000, 0b1001, 0b1010, 0b001), // RW
+ kPMBSR_EL1 = encode(0b11, 0b000, 0b1001, 0b1010, 0b011), // RW
+ kPMCCFILTR_EL0 = encode(0b11, 0b011, 0b1110, 0b1111, 0b111), // RW
+ kPMCCNTR_EL0 = encode(0b11, 0b011, 0b1001, 0b1101, 0b000), // RW
+ kPMCEID0_EL0 = encode(0b11, 0b011, 0b1001, 0b1100, 0b110), // RO
+ kPMCEID1_EL0 = encode(0b11, 0b011, 0b1001, 0b1100, 0b111), // RO
+ kPMCNTENCLR_EL0 = encode(0b11, 0b011, 0b1001, 0b1100, 0b010), // RW
+ kPMCNTENSET_EL0 = encode(0b11, 0b011, 0b1001, 0b1100, 0b001), // RW
+ kPMCR_EL0 = encode(0b11, 0b011, 0b1001, 0b1100, 0b000), // RW
+ kPMEVCNTR0_EL0 = encode(0b11, 0b011, 0b1110, 0b1000, 0b000), // RW
+ kPMEVCNTR10_EL0 = encode(0b11, 0b011, 0b1110, 0b1001, 0b010), // RW
+ kPMEVCNTR11_EL0 = encode(0b11, 0b011, 0b1110, 0b1001, 0b011), // RW
+ kPMEVCNTR12_EL0 = encode(0b11, 0b011, 0b1110, 0b1001, 0b100), // RW
+ kPMEVCNTR13_EL0 = encode(0b11, 0b011, 0b1110, 0b1001, 0b101), // RW
+ kPMEVCNTR14_EL0 = encode(0b11, 0b011, 0b1110, 0b1001, 0b110), // RW
+ kPMEVCNTR15_EL0 = encode(0b11, 0b011, 0b1110, 0b1001, 0b111), // RW
+ kPMEVCNTR16_EL0 = encode(0b11, 0b011, 0b1110, 0b1010, 0b000), // RW
+ kPMEVCNTR17_EL0 = encode(0b11, 0b011, 0b1110, 0b1010, 0b001), // RW
+ kPMEVCNTR18_EL0 = encode(0b11, 0b011, 0b1110, 0b1010, 0b010), // RW
+ kPMEVCNTR19_EL0 = encode(0b11, 0b011, 0b1110, 0b1010, 0b011), // RW
+ kPMEVCNTR1_EL0 = encode(0b11, 0b011, 0b1110, 0b1000, 0b001), // RW
+ kPMEVCNTR20_EL0 = encode(0b11, 0b011, 0b1110, 0b1010, 0b100), // RW
+ kPMEVCNTR21_EL0 = encode(0b11, 0b011, 0b1110, 0b1010, 0b101), // RW
+ kPMEVCNTR22_EL0 = encode(0b11, 0b011, 0b1110, 0b1010, 0b110), // RW
+ kPMEVCNTR23_EL0 = encode(0b11, 0b011, 0b1110, 0b1010, 0b111), // RW
+ kPMEVCNTR24_EL0 = encode(0b11, 0b011, 0b1110, 0b1011, 0b000), // RW
+ kPMEVCNTR25_EL0 = encode(0b11, 0b011, 0b1110, 0b1011, 0b001), // RW
+ kPMEVCNTR26_EL0 = encode(0b11, 0b011, 0b1110, 0b1011, 0b010), // RW
+ kPMEVCNTR27_EL0 = encode(0b11, 0b011, 0b1110, 0b1011, 0b011), // RW
+ kPMEVCNTR28_EL0 = encode(0b11, 0b011, 0b1110, 0b1011, 0b100), // RW
+ kPMEVCNTR29_EL0 = encode(0b11, 0b011, 0b1110, 0b1011, 0b101), // RW
+ kPMEVCNTR2_EL0 = encode(0b11, 0b011, 0b1110, 0b1000, 0b010), // RW
+ kPMEVCNTR30_EL0 = encode(0b11, 0b011, 0b1110, 0b1011, 0b110), // RW
+ kPMEVCNTR3_EL0 = encode(0b11, 0b011, 0b1110, 0b1000, 0b011), // RW
+ kPMEVCNTR4_EL0 = encode(0b11, 0b011, 0b1110, 0b1000, 0b100), // RW
+ kPMEVCNTR5_EL0 = encode(0b11, 0b011, 0b1110, 0b1000, 0b101), // RW
+ kPMEVCNTR6_EL0 = encode(0b11, 0b011, 0b1110, 0b1000, 0b110), // RW
+ kPMEVCNTR7_EL0 = encode(0b11, 0b011, 0b1110, 0b1000, 0b111), // RW
+ kPMEVCNTR8_EL0 = encode(0b11, 0b011, 0b1110, 0b1001, 0b000), // RW
+ kPMEVCNTR9_EL0 = encode(0b11, 0b011, 0b1110, 0b1001, 0b001), // RW
+ kPMEVTYPER0_EL0 = encode(0b11, 0b011, 0b1110, 0b1100, 0b000), // RW
+ kPMEVTYPER10_EL0 = encode(0b11, 0b011, 0b1110, 0b1101, 0b010), // RW
+ kPMEVTYPER11_EL0 = encode(0b11, 0b011, 0b1110, 0b1101, 0b011), // RW
+ kPMEVTYPER12_EL0 = encode(0b11, 0b011, 0b1110, 0b1101, 0b100), // RW
+ kPMEVTYPER13_EL0 = encode(0b11, 0b011, 0b1110, 0b1101, 0b101), // RW
+ kPMEVTYPER14_EL0 = encode(0b11, 0b011, 0b1110, 0b1101, 0b110), // RW
+ kPMEVTYPER15_EL0 = encode(0b11, 0b011, 0b1110, 0b1101, 0b111), // RW
+ kPMEVTYPER16_EL0 = encode(0b11, 0b011, 0b1110, 0b1110, 0b000), // RW
+ kPMEVTYPER17_EL0 = encode(0b11, 0b011, 0b1110, 0b1110, 0b001), // RW
+ kPMEVTYPER18_EL0 = encode(0b11, 0b011, 0b1110, 0b1110, 0b010), // RW
+ kPMEVTYPER19_EL0 = encode(0b11, 0b011, 0b1110, 0b1110, 0b011), // RW
+ kPMEVTYPER1_EL0 = encode(0b11, 0b011, 0b1110, 0b1100, 0b001), // RW
+ kPMEVTYPER20_EL0 = encode(0b11, 0b011, 0b1110, 0b1110, 0b100), // RW
+ kPMEVTYPER21_EL0 = encode(0b11, 0b011, 0b1110, 0b1110, 0b101), // RW
+ kPMEVTYPER22_EL0 = encode(0b11, 0b011, 0b1110, 0b1110, 0b110), // RW
+ kPMEVTYPER23_EL0 = encode(0b11, 0b011, 0b1110, 0b1110, 0b111), // RW
+ kPMEVTYPER24_EL0 = encode(0b11, 0b011, 0b1110, 0b1111, 0b000), // RW
+ kPMEVTYPER25_EL0 = encode(0b11, 0b011, 0b1110, 0b1111, 0b001), // RW
+ kPMEVTYPER26_EL0 = encode(0b11, 0b011, 0b1110, 0b1111, 0b010), // RW
+ kPMEVTYPER27_EL0 = encode(0b11, 0b011, 0b1110, 0b1111, 0b011), // RW
+ kPMEVTYPER28_EL0 = encode(0b11, 0b011, 0b1110, 0b1111, 0b100), // RW
+ kPMEVTYPER29_EL0 = encode(0b11, 0b011, 0b1110, 0b1111, 0b101), // RW
+ kPMEVTYPER2_EL0 = encode(0b11, 0b011, 0b1110, 0b1100, 0b010), // RW
+ kPMEVTYPER30_EL0 = encode(0b11, 0b011, 0b1110, 0b1111, 0b110), // RW
+ kPMEVTYPER3_EL0 = encode(0b11, 0b011, 0b1110, 0b1100, 0b011), // RW
+ kPMEVTYPER4_EL0 = encode(0b11, 0b011, 0b1110, 0b1100, 0b100), // RW
+ kPMEVTYPER5_EL0 = encode(0b11, 0b011, 0b1110, 0b1100, 0b101), // RW
+ kPMEVTYPER6_EL0 = encode(0b11, 0b011, 0b1110, 0b1100, 0b110), // RW
+ kPMEVTYPER7_EL0 = encode(0b11, 0b011, 0b1110, 0b1100, 0b111), // RW
+ kPMEVTYPER8_EL0 = encode(0b11, 0b011, 0b1110, 0b1101, 0b000), // RW
+ kPMEVTYPER9_EL0 = encode(0b11, 0b011, 0b1110, 0b1101, 0b001), // RW
+ kPMINTENCLR_EL1 = encode(0b11, 0b000, 0b1001, 0b1110, 0b010), // RW
+ kPMINTENSET_EL1 = encode(0b11, 0b000, 0b1001, 0b1110, 0b001), // RW
+ kPMMIR_EL1 = encode(0b11, 0b000, 0b1001, 0b1110, 0b110), // RW
+ kPMOVSCLR_EL0 = encode(0b11, 0b011, 0b1001, 0b1100, 0b011), // RW
+ kPMOVSSET_EL0 = encode(0b11, 0b011, 0b1001, 0b1110, 0b011), // RW
+ kPMSCR_EL1 = encode(0b11, 0b000, 0b1001, 0b1001, 0b000), // RW
+ kPMSCR_EL12 = encode(0b11, 0b101, 0b1001, 0b1001, 0b000), // RW
+ kPMSCR_EL2 = encode(0b11, 0b100, 0b1001, 0b1001, 0b000), // RW
+ kPMSELR_EL0 = encode(0b11, 0b011, 0b1001, 0b1100, 0b101), // RW
+ kPMSEVFR_EL1 = encode(0b11, 0b000, 0b1001, 0b1001, 0b101), // RW
+ kPMSFCR_EL1 = encode(0b11, 0b000, 0b1001, 0b1001, 0b100), // RW
+ kPMSICR_EL1 = encode(0b11, 0b000, 0b1001, 0b1001, 0b010), // RW
+ kPMSIDR_EL1 = encode(0b11, 0b000, 0b1001, 0b1001, 0b111), // RO
+ kPMSIRR_EL1 = encode(0b11, 0b000, 0b1001, 0b1001, 0b011), // RW
+ kPMSLATFR_EL1 = encode(0b11, 0b000, 0b1001, 0b1001, 0b110), // RW
+ kPMSWINC_EL0 = encode(0b11, 0b011, 0b1001, 0b1100, 0b100), // WO
+ kPMUSERENR_EL0 = encode(0b11, 0b011, 0b1001, 0b1110, 0b000), // RW
+ kPMXEVCNTR_EL0 = encode(0b11, 0b011, 0b1001, 0b1101, 0b010), // RW
+ kPMXEVTYPER_EL0 = encode(0b11, 0b011, 0b1001, 0b1101, 0b001), // RW
+ kREVIDR_EL1 = encode(0b11, 0b000, 0b0000, 0b0000, 0b110), // RO
+ kRGSR_EL1 = encode(0b11, 0b000, 0b0001, 0b0000, 0b101), // RW
+ kRMR_EL1 = encode(0b11, 0b000, 0b1100, 0b0000, 0b010), // RW
+ kRMR_EL2 = encode(0b11, 0b100, 0b1100, 0b0000, 0b010), // RW
+ kRMR_EL3 = encode(0b11, 0b110, 0b1100, 0b0000, 0b010), // RW
+ kRNDR = encode(0b11, 0b011, 0b0010, 0b0100, 0b000), // RO
+ kRNDRRS = encode(0b11, 0b011, 0b0010, 0b0100, 0b001), // RO
+ kRVBAR_EL1 = encode(0b11, 0b000, 0b1100, 0b0000, 0b001), // RO
+ kRVBAR_EL2 = encode(0b11, 0b100, 0b1100, 0b0000, 0b001), // RO
+ kRVBAR_EL3 = encode(0b11, 0b110, 0b1100, 0b0000, 0b001), // RO
+ kSCR_EL3 = encode(0b11, 0b110, 0b0001, 0b0001, 0b000), // RW
+ kSCTLR_EL1 = encode(0b11, 0b000, 0b0001, 0b0000, 0b000), // RW
+ kSCTLR_EL12 = encode(0b11, 0b101, 0b0001, 0b0000, 0b000), // RW
+ kSCTLR_EL2 = encode(0b11, 0b100, 0b0001, 0b0000, 0b000), // RW
+ kSCTLR_EL3 = encode(0b11, 0b110, 0b0001, 0b0000, 0b000), // RW
+ kSCXTNUM_EL0 = encode(0b11, 0b011, 0b1101, 0b0000, 0b111), // RW
+ kSCXTNUM_EL1 = encode(0b11, 0b000, 0b1101, 0b0000, 0b111), // RW
+ kSCXTNUM_EL12 = encode(0b11, 0b101, 0b1101, 0b0000, 0b111), // RW
+ kSCXTNUM_EL2 = encode(0b11, 0b100, 0b1101, 0b0000, 0b111), // RW
+ kSCXTNUM_EL3 = encode(0b11, 0b110, 0b1101, 0b0000, 0b111), // RW
+ kSDER32_EL2 = encode(0b11, 0b100, 0b0001, 0b0011, 0b001), // RW
+ kSDER32_EL3 = encode(0b11, 0b110, 0b0001, 0b0001, 0b001), // RW
+ kSPSR_EL1 = encode(0b11, 0b000, 0b0100, 0b0000, 0b000), // RW
+ kSPSR_EL12 = encode(0b11, 0b101, 0b0100, 0b0000, 0b000), // RW
+ kSPSR_EL2 = encode(0b11, 0b100, 0b0100, 0b0000, 0b000), // RW
+ kSPSR_EL3 = encode(0b11, 0b110, 0b0100, 0b0000, 0b000), // RW
+ kSPSR_abt = encode(0b11, 0b100, 0b0100, 0b0011, 0b001), // RW
+ kSPSR_fiq = encode(0b11, 0b100, 0b0100, 0b0011, 0b011), // RW
+ kSPSR_irq = encode(0b11, 0b100, 0b0100, 0b0011, 0b000), // RW
+ kSPSR_und = encode(0b11, 0b100, 0b0100, 0b0011, 0b010), // RW
+ kSPSel = encode(0b11, 0b000, 0b0100, 0b0010, 0b000), // RW
+ kSP_EL0 = encode(0b11, 0b000, 0b0100, 0b0001, 0b000), // RW
+ kSP_EL1 = encode(0b11, 0b100, 0b0100, 0b0001, 0b000), // RW
+ kSP_EL2 = encode(0b11, 0b110, 0b0100, 0b0001, 0b000), // RW
+ kSSBS = encode(0b11, 0b011, 0b0100, 0b0010, 0b110), // RW
+ kTCO = encode(0b11, 0b011, 0b0100, 0b0010, 0b111), // RW
+ kTCR_EL1 = encode(0b11, 0b000, 0b0010, 0b0000, 0b010), // RW
+ kTCR_EL12 = encode(0b11, 0b101, 0b0010, 0b0000, 0b010), // RW
+ kTCR_EL2 = encode(0b11, 0b100, 0b0010, 0b0000, 0b010), // RW
+ kTCR_EL3 = encode(0b11, 0b110, 0b0010, 0b0000, 0b010), // RW
+ kTEECR32_EL1 = encode(0b10, 0b010, 0b0000, 0b0000, 0b000), // RW
+ kTEEHBR32_EL1 = encode(0b10, 0b010, 0b0001, 0b0000, 0b000), // RW
+ kTFSRE0_EL1 = encode(0b11, 0b000, 0b0101, 0b0110, 0b001), // RW
+ kTFSR_EL1 = encode(0b11, 0b000, 0b0101, 0b0110, 0b000), // RW
+ kTFSR_EL12 = encode(0b11, 0b101, 0b0101, 0b0110, 0b000), // RW
+ kTFSR_EL2 = encode(0b11, 0b100, 0b0101, 0b0110, 0b000), // RW
+ kTFSR_EL3 = encode(0b11, 0b110, 0b0101, 0b0110, 0b000), // RW
+ kTPIDRRO_EL0 = encode(0b11, 0b011, 0b1101, 0b0000, 0b011), // RW
+ kTPIDR_EL0 = encode(0b11, 0b011, 0b1101, 0b0000, 0b010), // RW
+ kTPIDR_EL1 = encode(0b11, 0b000, 0b1101, 0b0000, 0b100), // RW
+ kTPIDR_EL2 = encode(0b11, 0b100, 0b1101, 0b0000, 0b010), // RW
+ kTPIDR_EL3 = encode(0b11, 0b110, 0b1101, 0b0000, 0b010), // RW
+ kTRBBASER_EL1 = encode(0b11, 0b000, 0b1001, 0b1011, 0b010), // RW
+ kTRBIDR_EL1 = encode(0b11, 0b000, 0b1001, 0b1011, 0b111), // RO
+ kTRBLIMITR_EL1 = encode(0b11, 0b000, 0b1001, 0b1011, 0b000), // RW
+ kTRBMAR_EL1 = encode(0b11, 0b000, 0b1001, 0b1011, 0b100), // RW
+ kTRBPTR_EL1 = encode(0b11, 0b000, 0b1001, 0b1011, 0b001), // RW
+ kTRBSR_EL1 = encode(0b11, 0b000, 0b1001, 0b1011, 0b011), // RW
+ kTRBTRG_EL1 = encode(0b11, 0b000, 0b1001, 0b1011, 0b110), // RW
+ kTRCACATR0 = encode(0b10, 0b001, 0b0010, 0b0000, 0b010), // RW
+ kTRCACATR1 = encode(0b10, 0b001, 0b0010, 0b0010, 0b010), // RW
+ kTRCACATR10 = encode(0b10, 0b001, 0b0010, 0b0100, 0b011), // RW
+ kTRCACATR11 = encode(0b10, 0b001, 0b0010, 0b0110, 0b011), // RW
+ kTRCACATR12 = encode(0b10, 0b001, 0b0010, 0b1000, 0b011), // RW
+ kTRCACATR13 = encode(0b10, 0b001, 0b0010, 0b1010, 0b011), // RW
+ kTRCACATR14 = encode(0b10, 0b001, 0b0010, 0b1100, 0b011), // RW
+ kTRCACATR15 = encode(0b10, 0b001, 0b0010, 0b1110, 0b011), // RW
+ kTRCACATR2 = encode(0b10, 0b001, 0b0010, 0b0100, 0b010), // RW
+ kTRCACATR3 = encode(0b10, 0b001, 0b0010, 0b0110, 0b010), // RW
+ kTRCACATR4 = encode(0b10, 0b001, 0b0010, 0b1000, 0b010), // RW
+ kTRCACATR5 = encode(0b10, 0b001, 0b0010, 0b1010, 0b010), // RW
+ kTRCACATR6 = encode(0b10, 0b001, 0b0010, 0b1100, 0b010), // RW
+ kTRCACATR7 = encode(0b10, 0b001, 0b0010, 0b1110, 0b010), // RW
+ kTRCACATR8 = encode(0b10, 0b001, 0b0010, 0b0000, 0b011), // RW
+ kTRCACATR9 = encode(0b10, 0b001, 0b0010, 0b0010, 0b011), // RW
+ kTRCACVR0 = encode(0b10, 0b001, 0b0010, 0b0000, 0b000), // RW
+ kTRCACVR1 = encode(0b10, 0b001, 0b0010, 0b0010, 0b000), // RW
+ kTRCACVR10 = encode(0b10, 0b001, 0b0010, 0b0100, 0b001), // RW
+ kTRCACVR11 = encode(0b10, 0b001, 0b0010, 0b0110, 0b001), // RW
+ kTRCACVR12 = encode(0b10, 0b001, 0b0010, 0b1000, 0b001), // RW
+ kTRCACVR13 = encode(0b10, 0b001, 0b0010, 0b1010, 0b001), // RW
+ kTRCACVR14 = encode(0b10, 0b001, 0b0010, 0b1100, 0b001), // RW
+ kTRCACVR15 = encode(0b10, 0b001, 0b0010, 0b1110, 0b001), // RW
+ kTRCACVR2 = encode(0b10, 0b001, 0b0010, 0b0100, 0b000), // RW
+ kTRCACVR3 = encode(0b10, 0b001, 0b0010, 0b0110, 0b000), // RW
+ kTRCACVR4 = encode(0b10, 0b001, 0b0010, 0b1000, 0b000), // RW
+ kTRCACVR5 = encode(0b10, 0b001, 0b0010, 0b1010, 0b000), // RW
+ kTRCACVR6 = encode(0b10, 0b001, 0b0010, 0b1100, 0b000), // RW
+ kTRCACVR7 = encode(0b10, 0b001, 0b0010, 0b1110, 0b000), // RW
+ kTRCACVR8 = encode(0b10, 0b001, 0b0010, 0b0000, 0b001), // RW
+ kTRCACVR9 = encode(0b10, 0b001, 0b0010, 0b0010, 0b001), // RW
+ kTRCAUTHSTATUS = encode(0b10, 0b001, 0b0111, 0b1110, 0b110), // RO
+ kTRCAUXCTLR = encode(0b10, 0b001, 0b0000, 0b0110, 0b000), // RW
+ kTRCBBCTLR = encode(0b10, 0b001, 0b0000, 0b1111, 0b000), // RW
+ kTRCCCCTLR = encode(0b10, 0b001, 0b0000, 0b1110, 0b000), // RW
+ kTRCCIDCCTLR0 = encode(0b10, 0b001, 0b0011, 0b0000, 0b010), // RW
+ kTRCCIDCCTLR1 = encode(0b10, 0b001, 0b0011, 0b0001, 0b010), // RW
+ kTRCCIDCVR0 = encode(0b10, 0b001, 0b0011, 0b0000, 0b000), // RW
+ kTRCCIDCVR1 = encode(0b10, 0b001, 0b0011, 0b0010, 0b000), // RW
+ kTRCCIDCVR2 = encode(0b10, 0b001, 0b0011, 0b0100, 0b000), // RW
+ kTRCCIDCVR3 = encode(0b10, 0b001, 0b0011, 0b0110, 0b000), // RW
+ kTRCCIDCVR4 = encode(0b10, 0b001, 0b0011, 0b1000, 0b000), // RW
+ kTRCCIDCVR5 = encode(0b10, 0b001, 0b0011, 0b1010, 0b000), // RW
+ kTRCCIDCVR6 = encode(0b10, 0b001, 0b0011, 0b1100, 0b000), // RW
+ kTRCCIDCVR7 = encode(0b10, 0b001, 0b0011, 0b1110, 0b000), // RW
+ kTRCCIDR0 = encode(0b10, 0b001, 0b0111, 0b1100, 0b111), // RO
+ kTRCCIDR1 = encode(0b10, 0b001, 0b0111, 0b1101, 0b111), // RO
+ kTRCCIDR2 = encode(0b10, 0b001, 0b0111, 0b1110, 0b111), // RO
+ kTRCCIDR3 = encode(0b10, 0b001, 0b0111, 0b1111, 0b111), // RO
+ kTRCCLAIMCLR = encode(0b10, 0b001, 0b0111, 0b1001, 0b110), // RW
+ kTRCCLAIMSET = encode(0b10, 0b001, 0b0111, 0b1000, 0b110), // RW
+ kTRCCNTCTLR0 = encode(0b10, 0b001, 0b0000, 0b0100, 0b101), // RW
+ kTRCCNTCTLR1 = encode(0b10, 0b001, 0b0000, 0b0101, 0b101), // RW
+ kTRCCNTCTLR2 = encode(0b10, 0b001, 0b0000, 0b0110, 0b101), // RW
+ kTRCCNTCTLR3 = encode(0b10, 0b001, 0b0000, 0b0111, 0b101), // RW
+ kTRCCNTRLDVR0 = encode(0b10, 0b001, 0b0000, 0b0000, 0b101), // RW
+ kTRCCNTRLDVR1 = encode(0b10, 0b001, 0b0000, 0b0001, 0b101), // RW
+ kTRCCNTRLDVR2 = encode(0b10, 0b001, 0b0000, 0b0010, 0b101), // RW
+ kTRCCNTRLDVR3 = encode(0b10, 0b001, 0b0000, 0b0011, 0b101), // RW
+ kTRCCNTVR0 = encode(0b10, 0b001, 0b0000, 0b1000, 0b101), // RW
+ kTRCCNTVR1 = encode(0b10, 0b001, 0b0000, 0b1001, 0b101), // RW
+ kTRCCNTVR2 = encode(0b10, 0b001, 0b0000, 0b1010, 0b101), // RW
+ kTRCCNTVR3 = encode(0b10, 0b001, 0b0000, 0b1011, 0b101), // RW
+ kTRCCONFIGR = encode(0b10, 0b001, 0b0000, 0b0100, 0b000), // RW
+ kTRCDEVAFF0 = encode(0b10, 0b001, 0b0111, 0b1010, 0b110), // RO
+ kTRCDEVAFF1 = encode(0b10, 0b001, 0b0111, 0b1011, 0b110), // RO
+ kTRCDEVARCH = encode(0b10, 0b001, 0b0111, 0b1111, 0b110), // RO
+ kTRCDEVID = encode(0b10, 0b001, 0b0111, 0b0010, 0b111), // RO
+ kTRCDEVTYPE = encode(0b10, 0b001, 0b0111, 0b0011, 0b111), // RO
+ kTRCDVCMR0 = encode(0b10, 0b001, 0b0010, 0b0000, 0b110), // RW
+ kTRCDVCMR1 = encode(0b10, 0b001, 0b0010, 0b0100, 0b110), // RW
+ kTRCDVCMR2 = encode(0b10, 0b001, 0b0010, 0b1000, 0b110), // RW
+ kTRCDVCMR3 = encode(0b10, 0b001, 0b0010, 0b1100, 0b110), // RW
+ kTRCDVCMR4 = encode(0b10, 0b001, 0b0010, 0b0000, 0b111), // RW
+ kTRCDVCMR5 = encode(0b10, 0b001, 0b0010, 0b0100, 0b111), // RW
+ kTRCDVCMR6 = encode(0b10, 0b001, 0b0010, 0b1000, 0b111), // RW
+ kTRCDVCMR7 = encode(0b10, 0b001, 0b0010, 0b1100, 0b111), // RW
+ kTRCDVCVR0 = encode(0b10, 0b001, 0b0010, 0b0000, 0b100), // RW
+ kTRCDVCVR1 = encode(0b10, 0b001, 0b0010, 0b0100, 0b100), // RW
+ kTRCDVCVR2 = encode(0b10, 0b001, 0b0010, 0b1000, 0b100), // RW
+ kTRCDVCVR3 = encode(0b10, 0b001, 0b0010, 0b1100, 0b100), // RW
+ kTRCDVCVR4 = encode(0b10, 0b001, 0b0010, 0b0000, 0b101), // RW
+ kTRCDVCVR5 = encode(0b10, 0b001, 0b0010, 0b0100, 0b101), // RW
+ kTRCDVCVR6 = encode(0b10, 0b001, 0b0010, 0b1000, 0b101), // RW
+ kTRCDVCVR7 = encode(0b10, 0b001, 0b0010, 0b1100, 0b101), // RW
+ kTRCEVENTCTL0R = encode(0b10, 0b001, 0b0000, 0b1000, 0b000), // RW
+ kTRCEVENTCTL1R = encode(0b10, 0b001, 0b0000, 0b1001, 0b000), // RW
+ kTRCEXTINSELR = encode(0b10, 0b001, 0b0000, 0b1000, 0b100), // RW
+ kTRCEXTINSELR0 = encode(0b10, 0b001, 0b0000, 0b1000, 0b100), // RW
+ kTRCEXTINSELR1 = encode(0b10, 0b001, 0b0000, 0b1001, 0b100), // RW
+ kTRCEXTINSELR2 = encode(0b10, 0b001, 0b0000, 0b1010, 0b100), // RW
+ kTRCEXTINSELR3 = encode(0b10, 0b001, 0b0000, 0b1011, 0b100), // RW
+ kTRCIDR0 = encode(0b10, 0b001, 0b0000, 0b1000, 0b111), // RO
+ kTRCIDR1 = encode(0b10, 0b001, 0b0000, 0b1001, 0b111), // RO
+ kTRCIDR10 = encode(0b10, 0b001, 0b0000, 0b0010, 0b110), // RO
+ kTRCIDR11 = encode(0b10, 0b001, 0b0000, 0b0011, 0b110), // RO
+ kTRCIDR12 = encode(0b10, 0b001, 0b0000, 0b0100, 0b110), // RO
+ kTRCIDR13 = encode(0b10, 0b001, 0b0000, 0b0101, 0b110), // RO
+ kTRCIDR2 = encode(0b10, 0b001, 0b0000, 0b1010, 0b111), // RO
+ kTRCIDR3 = encode(0b10, 0b001, 0b0000, 0b1011, 0b111), // RO
+ kTRCIDR4 = encode(0b10, 0b001, 0b0000, 0b1100, 0b111), // RO
+ kTRCIDR5 = encode(0b10, 0b001, 0b0000, 0b1101, 0b111), // RO
+ kTRCIDR6 = encode(0b10, 0b001, 0b0000, 0b1110, 0b111), // RO
+ kTRCIDR7 = encode(0b10, 0b001, 0b0000, 0b1111, 0b111), // RO
+ kTRCIDR8 = encode(0b10, 0b001, 0b0000, 0b0000, 0b110), // RO
+ kTRCIDR9 = encode(0b10, 0b001, 0b0000, 0b0001, 0b110), // RO
+ kTRCIMSPEC0 = encode(0b10, 0b001, 0b0000, 0b0000, 0b111), // RW
+ kTRCIMSPEC1 = encode(0b10, 0b001, 0b0000, 0b0001, 0b111), // RW
+ kTRCIMSPEC2 = encode(0b10, 0b001, 0b0000, 0b0010, 0b111), // RW
+ kTRCIMSPEC3 = encode(0b10, 0b001, 0b0000, 0b0011, 0b111), // RW
+ kTRCIMSPEC4 = encode(0b10, 0b001, 0b0000, 0b0100, 0b111), // RW
+ kTRCIMSPEC5 = encode(0b10, 0b001, 0b0000, 0b0101, 0b111), // RW
+ kTRCIMSPEC6 = encode(0b10, 0b001, 0b0000, 0b0110, 0b111), // RW
+ kTRCIMSPEC7 = encode(0b10, 0b001, 0b0000, 0b0111, 0b111), // RW
+ kTRCITCTRL = encode(0b10, 0b001, 0b0111, 0b0000, 0b100), // RW
+ kTRCLAR = encode(0b10, 0b001, 0b0111, 0b1100, 0b110), // WO
+ kTRCLSR = encode(0b10, 0b001, 0b0111, 0b1101, 0b110), // RO
+ kTRCOSLAR = encode(0b10, 0b001, 0b0001, 0b0000, 0b100), // WO
+ kTRCOSLSR = encode(0b10, 0b001, 0b0001, 0b0001, 0b100), // RO
+ kTRCPDCR = encode(0b10, 0b001, 0b0001, 0b0100, 0b100), // RW
+ kTRCPDSR = encode(0b10, 0b001, 0b0001, 0b0101, 0b100), // RO
+ kTRCPIDR0 = encode(0b10, 0b001, 0b0111, 0b1000, 0b111), // RO
+ kTRCPIDR1 = encode(0b10, 0b001, 0b0111, 0b1001, 0b111), // RO
+ kTRCPIDR2 = encode(0b10, 0b001, 0b0111, 0b1010, 0b111), // RO
+ kTRCPIDR3 = encode(0b10, 0b001, 0b0111, 0b1011, 0b111), // RO
+ kTRCPIDR4 = encode(0b10, 0b001, 0b0111, 0b0100, 0b111), // RO
+ kTRCPIDR5 = encode(0b10, 0b001, 0b0111, 0b0101, 0b111), // RO
+ kTRCPIDR6 = encode(0b10, 0b001, 0b0111, 0b0110, 0b111), // RO
+ kTRCPIDR7 = encode(0b10, 0b001, 0b0111, 0b0111, 0b111), // RO
+ kTRCPRGCTLR = encode(0b10, 0b001, 0b0000, 0b0001, 0b000), // RW
+ kTRCPROCSELR = encode(0b10, 0b001, 0b0000, 0b0010, 0b000), // RW
+ kTRCQCTLR = encode(0b10, 0b001, 0b0000, 0b0001, 0b001), // RW
+ kTRCRSCTLR10 = encode(0b10, 0b001, 0b0001, 0b1010, 0b000), // RW
+ kTRCRSCTLR11 = encode(0b10, 0b001, 0b0001, 0b1011, 0b000), // RW
+ kTRCRSCTLR12 = encode(0b10, 0b001, 0b0001, 0b1100, 0b000), // RW
+ kTRCRSCTLR13 = encode(0b10, 0b001, 0b0001, 0b1101, 0b000), // RW
+ kTRCRSCTLR14 = encode(0b10, 0b001, 0b0001, 0b1110, 0b000), // RW
+ kTRCRSCTLR15 = encode(0b10, 0b001, 0b0001, 0b1111, 0b000), // RW
+ kTRCRSCTLR16 = encode(0b10, 0b001, 0b0001, 0b0000, 0b001), // RW
+ kTRCRSCTLR17 = encode(0b10, 0b001, 0b0001, 0b0001, 0b001), // RW
+ kTRCRSCTLR18 = encode(0b10, 0b001, 0b0001, 0b0010, 0b001), // RW
+ kTRCRSCTLR19 = encode(0b10, 0b001, 0b0001, 0b0011, 0b001), // RW
+ kTRCRSCTLR2 = encode(0b10, 0b001, 0b0001, 0b0010, 0b000), // RW
+ kTRCRSCTLR20 = encode(0b10, 0b001, 0b0001, 0b0100, 0b001), // RW
+ kTRCRSCTLR21 = encode(0b10, 0b001, 0b0001, 0b0101, 0b001), // RW
+ kTRCRSCTLR22 = encode(0b10, 0b001, 0b0001, 0b0110, 0b001), // RW
+ kTRCRSCTLR23 = encode(0b10, 0b001, 0b0001, 0b0111, 0b001), // RW
+ kTRCRSCTLR24 = encode(0b10, 0b001, 0b0001, 0b1000, 0b001), // RW
+ kTRCRSCTLR25 = encode(0b10, 0b001, 0b0001, 0b1001, 0b001), // RW
+ kTRCRSCTLR26 = encode(0b10, 0b001, 0b0001, 0b1010, 0b001), // RW
+ kTRCRSCTLR27 = encode(0b10, 0b001, 0b0001, 0b1011, 0b001), // RW
+ kTRCRSCTLR28 = encode(0b10, 0b001, 0b0001, 0b1100, 0b001), // RW
+ kTRCRSCTLR29 = encode(0b10, 0b001, 0b0001, 0b1101, 0b001), // RW
+ kTRCRSCTLR3 = encode(0b10, 0b001, 0b0001, 0b0011, 0b000), // RW
+ kTRCRSCTLR30 = encode(0b10, 0b001, 0b0001, 0b1110, 0b001), // RW
+ kTRCRSCTLR31 = encode(0b10, 0b001, 0b0001, 0b1111, 0b001), // RW
+ kTRCRSCTLR4 = encode(0b10, 0b001, 0b0001, 0b0100, 0b000), // RW
+ kTRCRSCTLR5 = encode(0b10, 0b001, 0b0001, 0b0101, 0b000), // RW
+ kTRCRSCTLR6 = encode(0b10, 0b001, 0b0001, 0b0110, 0b000), // RW
+ kTRCRSCTLR7 = encode(0b10, 0b001, 0b0001, 0b0111, 0b000), // RW
+ kTRCRSCTLR8 = encode(0b10, 0b001, 0b0001, 0b1000, 0b000), // RW
+ kTRCRSCTLR9 = encode(0b10, 0b001, 0b0001, 0b1001, 0b000), // RW
+ kTRCRSR = encode(0b10, 0b001, 0b0000, 0b1010, 0b000), // RW
+ kTRCSEQEVR0 = encode(0b10, 0b001, 0b0000, 0b0000, 0b100), // RW
+ kTRCSEQEVR1 = encode(0b10, 0b001, 0b0000, 0b0001, 0b100), // RW
+ kTRCSEQEVR2 = encode(0b10, 0b001, 0b0000, 0b0010, 0b100), // RW
+ kTRCSEQRSTEVR = encode(0b10, 0b001, 0b0000, 0b0110, 0b100), // RW
+ kTRCSEQSTR = encode(0b10, 0b001, 0b0000, 0b0111, 0b100), // RW
+ kTRCSSCCR0 = encode(0b10, 0b001, 0b0001, 0b0000, 0b010), // RW
+ kTRCSSCCR1 = encode(0b10, 0b001, 0b0001, 0b0001, 0b010), // RW
+ kTRCSSCCR2 = encode(0b10, 0b001, 0b0001, 0b0010, 0b010), // RW
+ kTRCSSCCR3 = encode(0b10, 0b001, 0b0001, 0b0011, 0b010), // RW
+ kTRCSSCCR4 = encode(0b10, 0b001, 0b0001, 0b0100, 0b010), // RW
+ kTRCSSCCR5 = encode(0b10, 0b001, 0b0001, 0b0101, 0b010), // RW
+ kTRCSSCCR6 = encode(0b10, 0b001, 0b0001, 0b0110, 0b010), // RW
+ kTRCSSCCR7 = encode(0b10, 0b001, 0b0001, 0b0111, 0b010), // RW
+ kTRCSSCSR0 = encode(0b10, 0b001, 0b0001, 0b1000, 0b010), // RW
+ kTRCSSCSR1 = encode(0b10, 0b001, 0b0001, 0b1001, 0b010), // RW
+ kTRCSSCSR2 = encode(0b10, 0b001, 0b0001, 0b1010, 0b010), // RW
+ kTRCSSCSR3 = encode(0b10, 0b001, 0b0001, 0b1011, 0b010), // RW
+ kTRCSSCSR4 = encode(0b10, 0b001, 0b0001, 0b1100, 0b010), // RW
+ kTRCSSCSR5 = encode(0b10, 0b001, 0b0001, 0b1101, 0b010), // RW
+ kTRCSSCSR6 = encode(0b10, 0b001, 0b0001, 0b1110, 0b010), // RW
+ kTRCSSCSR7 = encode(0b10, 0b001, 0b0001, 0b1111, 0b010), // RW
+ kTRCSSPCICR0 = encode(0b10, 0b001, 0b0001, 0b0000, 0b011), // RW
+ kTRCSSPCICR1 = encode(0b10, 0b001, 0b0001, 0b0001, 0b011), // RW
+ kTRCSSPCICR2 = encode(0b10, 0b001, 0b0001, 0b0010, 0b011), // RW
+ kTRCSSPCICR3 = encode(0b10, 0b001, 0b0001, 0b0011, 0b011), // RW
+ kTRCSSPCICR4 = encode(0b10, 0b001, 0b0001, 0b0100, 0b011), // RW
+ kTRCSSPCICR5 = encode(0b10, 0b001, 0b0001, 0b0101, 0b011), // RW
+ kTRCSSPCICR6 = encode(0b10, 0b001, 0b0001, 0b0110, 0b011), // RW
+ kTRCSSPCICR7 = encode(0b10, 0b001, 0b0001, 0b0111, 0b011), // RW
+ kTRCSTALLCTLR = encode(0b10, 0b001, 0b0000, 0b1011, 0b000), // RW
+ kTRCSTATR = encode(0b10, 0b001, 0b0000, 0b0011, 0b000), // RO
+ kTRCSYNCPR = encode(0b10, 0b001, 0b0000, 0b1101, 0b000), // RW
+ kTRCTRACEIDR = encode(0b10, 0b001, 0b0000, 0b0000, 0b001), // RW
+ kTRCTSCTLR = encode(0b10, 0b001, 0b0000, 0b1100, 0b000), // RW
+ kTRCVDARCCTLR = encode(0b10, 0b001, 0b0000, 0b1010, 0b010), // RW
+ kTRCVDCTLR = encode(0b10, 0b001, 0b0000, 0b1000, 0b010), // RW
+ kTRCVDSACCTLR = encode(0b10, 0b001, 0b0000, 0b1001, 0b010), // RW
+ kTRCVICTLR = encode(0b10, 0b001, 0b0000, 0b0000, 0b010), // RW
+ kTRCVIIECTLR = encode(0b10, 0b001, 0b0000, 0b0001, 0b010), // RW
+ kTRCVIPCSSCTLR = encode(0b10, 0b001, 0b0000, 0b0011, 0b010), // RW
+ kTRCVISSCTLR = encode(0b10, 0b001, 0b0000, 0b0010, 0b010), // RW
+ kTRCVMIDCCTLR0 = encode(0b10, 0b001, 0b0011, 0b0010, 0b010), // RW
+ kTRCVMIDCCTLR1 = encode(0b10, 0b001, 0b0011, 0b0011, 0b010), // RW
+ kTRCVMIDCVR0 = encode(0b10, 0b001, 0b0011, 0b0000, 0b001), // RW
+ kTRCVMIDCVR1 = encode(0b10, 0b001, 0b0011, 0b0010, 0b001), // RW
+ kTRCVMIDCVR2 = encode(0b10, 0b001, 0b0011, 0b0100, 0b001), // RW
+ kTRCVMIDCVR3 = encode(0b10, 0b001, 0b0011, 0b0110, 0b001), // RW
+ kTRCVMIDCVR4 = encode(0b10, 0b001, 0b0011, 0b1000, 0b001), // RW
+ kTRCVMIDCVR5 = encode(0b10, 0b001, 0b0011, 0b1010, 0b001), // RW
+ kTRCVMIDCVR6 = encode(0b10, 0b001, 0b0011, 0b1100, 0b001), // RW
+ kTRCVMIDCVR7 = encode(0b10, 0b001, 0b0011, 0b1110, 0b001), // RW
+ kTRFCR_EL1 = encode(0b11, 0b000, 0b0001, 0b0010, 0b001), // RW
+ kTRFCR_EL12 = encode(0b11, 0b101, 0b0001, 0b0010, 0b001), // RW
+ kTRFCR_EL2 = encode(0b11, 0b100, 0b0001, 0b0010, 0b001), // RW
+ kTTBR0_EL1 = encode(0b11, 0b000, 0b0010, 0b0000, 0b000), // RW
+ kTTBR0_EL12 = encode(0b11, 0b101, 0b0010, 0b0000, 0b000), // RW
+ kTTBR0_EL2 = encode(0b11, 0b100, 0b0010, 0b0000, 0b000), // RW
+ kTTBR0_EL3 = encode(0b11, 0b110, 0b0010, 0b0000, 0b000), // RW
+ kTTBR1_EL1 = encode(0b11, 0b000, 0b0010, 0b0000, 0b001), // RW
+ kTTBR1_EL12 = encode(0b11, 0b101, 0b0010, 0b0000, 0b001), // RW
+ kTTBR1_EL2 = encode(0b11, 0b100, 0b0010, 0b0000, 0b001), // RW
+ kUAO = encode(0b11, 0b000, 0b0100, 0b0010, 0b100), // RW
+ kVBAR_EL1 = encode(0b11, 0b000, 0b1100, 0b0000, 0b000), // RW
+ kVBAR_EL12 = encode(0b11, 0b101, 0b1100, 0b0000, 0b000), // RW
+ kVBAR_EL2 = encode(0b11, 0b100, 0b1100, 0b0000, 0b000), // RW
+ kVBAR_EL3 = encode(0b11, 0b110, 0b1100, 0b0000, 0b000), // RW
+ kVDISR_EL2 = encode(0b11, 0b100, 0b1100, 0b0001, 0b001), // RW
+ kVMPIDR_EL2 = encode(0b11, 0b100, 0b0000, 0b0000, 0b101), // RW
+ kVNCR_EL2 = encode(0b11, 0b100, 0b0010, 0b0010, 0b000), // RW
+ kVPIDR_EL2 = encode(0b11, 0b100, 0b0000, 0b0000, 0b000), // RW
+ kVSESR_EL2 = encode(0b11, 0b100, 0b0101, 0b0010, 0b011), // RW
+ kVSTCR_EL2 = encode(0b11, 0b100, 0b0010, 0b0110, 0b010), // RW
+ kVSTTBR_EL2 = encode(0b11, 0b100, 0b0010, 0b0110, 0b000), // RW
+ kVTCR_EL2 = encode(0b11, 0b100, 0b0010, 0b0001, 0b010), // RW
+ kVTTBR_EL2 = encode(0b11, 0b100, 0b0010, 0b0001, 0b000), // RW
+ kZCR_EL1 = encode(0b11, 0b000, 0b0001, 0b0010, 0b000), // RW
+ kZCR_EL12 = encode(0b11, 0b101, 0b0001, 0b0010, 0b000), // RW
+ kZCR_EL2 = encode(0b11, 0b100, 0b0001, 0b0010, 0b000), // RW
+ kZCR_EL3 = encode(0b11, 0b110, 0b0001, 0b0010, 0b000) // RW
+ };
+};
+
+} // {Predicate}
+
+//! \}
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // ASMJIT_ARM_A64GLOBALS_H_INCLUDED
diff --git a/src/asmjit/arm/a64instapi.cpp b/src/asmjit/arm/a64instapi.cpp
new file mode 100644
index 0000000..dc98bc8
--- /dev/null
+++ b/src/asmjit/arm/a64instapi.cpp
@@ -0,0 +1,278 @@
+// 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"
+#if !defined(ASMJIT_NO_AARCH64)
+
+#include "../core/cpuinfo.h"
+#include "../core/misc_p.h"
+#include "../core/support.h"
+#include "../arm/a64instapi_p.h"
+#include "../arm/a64instdb_p.h"
+#include "../arm/a64operand.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+
+// a64::InstInternal - Text
+// ========================
+
+#ifndef ASMJIT_NO_TEXT
+Error InstInternal::instIdToString(Arch arch, 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);
+}
+
+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;
+}
+#endif // !ASMJIT_NO_TEXT
+
+// a64::InstInternal - Validate
+// ============================
+
+#ifndef ASMJIT_NO_VALIDATION
+ASMJIT_FAVOR_SIZE Error InstInternal::validate(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, ValidationFlags validationFlags) noexcept {
+ // TODO:
+ DebugUtils::unused(arch, inst, operands, opCount, validationFlags);
+ return kErrorOk;
+}
+#endif // !ASMJIT_NO_VALIDATION
+
+// a64::InstInternal - QueryRWInfo
+// ===============================
+
+#ifndef ASMJIT_NO_INTROSPECTION
+struct InstRWInfoData {
+ uint8_t rwx[Globals::kMaxOpCount];
+};
+
+static const InstRWInfoData instRWInfoData[] = {
+ #define R uint8_t(OpRWFlags::kRead)
+ #define W uint8_t(OpRWFlags::kWrite)
+ #define X uint8_t(OpRWFlags::kRW)
+
+ {{ R, R, R, R, R, R }}, // kRWI_R
+ {{ R, W, R, R, R, R }}, // kRWI_RW
+ {{ R, X, R, R, R, R }}, // kRWI_RX
+ {{ R, R, W, R, R, R }}, // kRWI_RRW
+ {{ R, W, X, R, R, R }}, // kRWI_RWX
+ {{ W, R, R, R, R, R }}, // kRWI_W
+ {{ W, R, W, R, R, R }}, // kRWI_WRW
+ {{ W, R, X, R, R, R }}, // kRWI_WRX
+ {{ W, R, R, W, R, R }}, // kRWI_WRRW
+ {{ W, R, R, X, R, R }}, // kRWI_WRRX
+ {{ W, W, R, R, R, R }}, // kRWI_WW
+ {{ X, R, R, R, R, R }}, // kRWI_X
+ {{ X, R, X, R, R, R }}, // kRWI_XRX
+ {{ X, X, R, R, X, R }}, // kRWI_XXRRX
+
+ {{ W, R, R, R, R, R }}, // kRWI_LDn
+ {{ R, W, R, R, R, R }}, // kRWI_STn
+ {{ R, R, R, R, R, R }} // kRWI_TODO
+
+ #undef R
+ #undef W
+ #undef X
+};
+
+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));
+
+ // Get the instruction data.
+ uint32_t realId = inst.id() & uint32_t(InstIdParts::kRealId);
+
+ if (ASMJIT_UNLIKELY(!Inst::isDefinedId(realId)))
+ return DebugUtils::errored(kErrorInvalidInstruction);
+
+ out->_instFlags = 0;
+ out->_opCount = uint8_t(opCount);
+ out->_rmFeature = 0;
+ out->_extraReg.reset();
+ out->_readFlags = CpuRWFlags::kNone; // TODO: [ARM] Read PSTATUS.
+ out->_writeFlags = CpuRWFlags::kNone; // TODO: [ARM] Write PSTATUS
+
+ const InstDB::InstInfo& instInfo = InstDB::_instInfoTable[realId];
+ const InstRWInfoData& rwInfo = instRWInfoData[instInfo.rwInfoIndex()];
+
+ if (instInfo.hasFlag(InstDB::kInstFlagConsecutive) && opCount > 2) {
+ for (uint32_t i = 0; i < opCount; i++) {
+ OpRWInfo& op = out->_operands[i];
+ const Operand_& srcOp = operands[i];
+
+ if (!srcOp.isRegOrMem()) {
+ op.reset();
+ continue;
+ }
+
+ OpRWFlags rwFlags = i < opCount - 1 ? (OpRWFlags)rwInfo.rwx[0] : (OpRWFlags)rwInfo.rwx[1];
+
+ op._opFlags = rwFlags & ~(OpRWFlags::kZExt);
+ op._physId = BaseReg::kIdBad;
+ op._rmSize = 0;
+ op._resetReserved();
+
+ uint64_t rByteMask = op.isRead() ? 0xFFFFFFFFFFFFFFFFu : 0x0000000000000000u;
+ uint64_t wByteMask = op.isWrite() ? 0xFFFFFFFFFFFFFFFFu : 0x0000000000000000u;
+
+ op._readByteMask = rByteMask;
+ op._writeByteMask = wByteMask;
+ op._extendByteMask = 0;
+ op._consecutiveLeadCount = 0;
+
+ if (srcOp.isReg()) {
+ if (i == 0)
+ op._consecutiveLeadCount = uint8_t(opCount - 1);
+ else
+ op.addOpFlags(OpRWFlags::kConsecutive);
+ }
+ else {
+ const Mem& memOp = srcOp.as<Mem>();
+
+ if (memOp.hasBase()) {
+ op.addOpFlags(OpRWFlags::kMemBaseRead);
+ }
+
+ if (memOp.hasIndex()) {
+ op.addOpFlags(OpRWFlags::kMemIndexRead);
+ op.addOpFlags(memOp.isPreOrPost() ? OpRWFlags::kMemIndexWrite : OpRWFlags::kNone);
+ }
+ }
+ }
+ }
+ else {
+ for (uint32_t i = 0; i < opCount; i++) {
+ OpRWInfo& op = out->_operands[i];
+ const Operand_& srcOp = operands[i];
+
+ if (!srcOp.isRegOrMem()) {
+ op.reset();
+ continue;
+ }
+
+ OpRWFlags rwFlags = (OpRWFlags)rwInfo.rwx[i];
+
+ op._opFlags = rwFlags & ~(OpRWFlags::kZExt);
+ op._physId = BaseReg::kIdBad;
+ op._rmSize = 0;
+ op._resetReserved();
+
+ uint64_t rByteMask = op.isRead() ? 0xFFFFFFFFFFFFFFFFu : 0x0000000000000000u;
+ uint64_t wByteMask = op.isWrite() ? 0xFFFFFFFFFFFFFFFFu : 0x0000000000000000u;
+
+ op._readByteMask = rByteMask;
+ op._writeByteMask = wByteMask;
+ op._extendByteMask = 0;
+ op._consecutiveLeadCount = 0;
+
+ 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();
+ uint32_t elementIndex = srcOp.as<Vec>().elementIndex();
+
+ uint32_t elementSize = elementTypeSize[elementType];
+ uint64_t accessMask = uint64_t(Support::lsbMask<uint32_t>(elementSize)) << (elementIndex * elementSize);
+
+ op._readByteMask &= accessMask;
+ op._writeByteMask &= accessMask;
+ }
+
+ // TODO: [ARM] RW info is not finished.
+ }
+ else {
+ const Mem& memOp = srcOp.as<Mem>();
+
+ if (memOp.hasBase()) {
+ op.addOpFlags(OpRWFlags::kMemBaseRead);
+ }
+
+ if (memOp.hasIndex()) {
+ op.addOpFlags(OpRWFlags::kMemIndexRead);
+ op.addOpFlags(memOp.isPreOrPost() ? OpRWFlags::kMemIndexWrite : OpRWFlags::kNone);
+ }
+ }
+ }
+ }
+
+ return kErrorOk;
+}
+#endif // !ASMJIT_NO_INTROSPECTION
+
+// a64::InstInternal - QueryFeatures
+// =================================
+
+#ifndef ASMJIT_NO_INTROSPECTION
+Error InstInternal::queryFeatures(Arch arch, 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);
+ return kErrorOk;
+}
+#endif // !ASMJIT_NO_INTROSPECTION
+
+// a64::InstInternal - Unit
+// ========================
+
+#if defined(ASMJIT_TEST)
+UNIT(arm_inst_api_text) {
+ // TODO:
+}
+#endif
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // !ASMJIT_NO_AARCH64
diff --git a/src/asmjit/arm/a64instapi_p.h b/src/asmjit/arm/a64instapi_p.h
new file mode 100644
index 0000000..320a3e8
--- /dev/null
+++ b/src/asmjit/arm/a64instapi_p.h
@@ -0,0 +1,41 @@
+// 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_ARM_A64INSTAPI_P_H_INCLUDED
+#define ASMJIT_ARM_A64INSTAPI_P_H_INCLUDED
+
+#include "../core/inst.h"
+#include "../core/operand.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+
+//! \cond INTERNAL
+//! \addtogroup asmjit_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;
+#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;
+#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;
+#endif // !ASMJIT_NO_INTROSPECTION
+
+} // {InstInternal}
+
+//! \}
+//! \endcond
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // ASMJIT_ARM_A64INSTAPI_P_H_INCLUDED
diff --git a/src/asmjit/arm/a64instdb.cpp b/src/asmjit/arm/a64instdb.cpp
new file mode 100644
index 0000000..64709b5
--- /dev/null
+++ b/src/asmjit/arm/a64instdb.cpp
@@ -0,0 +1,1957 @@
+// 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"
+#if !defined(ASMJIT_NO_AARCH64)
+
+#include "../core/codeholder.h"
+#include "../core/support.h"
+#include "../arm/a64instdb_p.h"
+#include "../arm/a64operand.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+
+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) { \
+ uint32_t(kEncoding##opcodeEncoding), \
+ uint32_t(opcodeDataIndex), \
+ 0, \
+ uint32_t(NAME_DATA_INDEX(nameDataIndex)), \
+ uint16_t(rwInfoIndex), \
+ uint16_t(flags) \
+}
+
+#define F(flag) kInstFlag##flag
+
+// TODO: [ARM] Missing Instructions:
+/*
+BLRAA, BLRAAZ, BLRAB, BLRABZ: Branch with Link to Register, with pointer authentication.
+BRAA, BRAAZ, BRAB, BRABZ: Branch to Register, with pointer authentication.
+
+CFP: Control Flow Prediction Restriction by Context: an alias of SYS.
+CPP: Cache Prefetch Prediction Restriction by Context: an alias of SYS.
+DVP: Data Value Prediction Restriction by Context: an alias of SYS.
+PSB CSYNC: Profiling Synchronization Barrier.
+
+ERETAA, ERETAB: Exception Return, with pointer authentication.
+LDAPxxx
+PACIA, PACIA1716, PACIASP, PACIAZ, PACIZA: Pointer Authentication Code for Instruction address, using key A.
+PACIB, PACIB1716, PACIBSP, PACIBZ, PACIZB: Pointer Authentication Code for Instruction address, using key B.
+PRFM (immediate): Prefetch Memory (immediate).
+PRFM (literal): Prefetch Memory (literal).
+PRFM (register): Prefetch Memory (register).
+PRFUM: Prefetch Memory (unscaled offset).
+RETAA, RETAB: Return from subroutine, with pointer authentication.
+RMIF: Rotate, Mask Insert Flags.
+SYSL
+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|
+ // +------------------+---------------------+--------------------------------------------------------------------------------------+-----------+---------------------------+----+-----+
+ // ${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
+ // ${InstInfo:End}
+};
+
+#undef F
+#undef INST
+#undef NAME_DATA_INDEX
+
+namespace EncodingData {
+
+// ${EncodingData:Begin}
+// ------------------- Automatically generated, do not edit -------------------
+const BaseAddSub baseAddSub[4] = {
+ { 0b0001011000, 0b0001011001, 0b0010001 }, // add
+ { 0b0101011000, 0b0101011001, 0b0110001 }, // adds
+ { 0b1001011000, 0b1001011001, 0b1010001 }, // sub
+ { 0b1101011000, 0b1101011001, 0b1110001 } // subs
+};
+
+const BaseAdr baseAdr[2] = {
+ { 0b0001000000000000000000, OffsetType::kAArch64_ADR }, // adr
+ { 0b1001000000000000000000, OffsetType::kAArch64_ADRP } // adrp
+};
+
+const BaseAtDcIcTlbi baseAtDcIcTlbi[4] = {
+ { 0b00011111110000, 0b00001111000000, true }, // at
+ { 0b00011110000000, 0b00001110000000, true }, // dc
+ { 0b00011110000000, 0b00001110000000, false }, // ic
+ { 0b00011110000000, 0b00010000000000, false } // tlbi
+};
+
+const BaseAtomicCasp baseAtomicCasp[4] = {
+ { 0b0000100000100000011111, kWX, 30 }, // casp
+ { 0b0000100001100000011111, kWX, 30 }, // caspa
+ { 0b0000100001100000111111, kWX, 30 }, // caspal
+ { 0b0000100000100000111111, kWX, 30 } // caspl
+};
+
+const BaseAtomicOp baseAtomicOp[123] = {
+ { 0b1000100010100000011111, kWX, 30, 0 }, // cas
+ { 0b1000100011100000011111, kWX, 30, 1 }, // casa
+ { 0b0000100011100000011111, kW , 0 , 1 }, // casab
+ { 0b0100100011100000011111, kW , 0 , 1 }, // casah
+ { 0b1000100011100000111111, kWX, 30, 1 }, // casal
+ { 0b0000100011100000111111, kW , 0 , 1 }, // casalb
+ { 0b0100100011100000111111, kW , 0 , 1 }, // casalh
+ { 0b0000100010100000011111, kW , 0 , 0 }, // casb
+ { 0b0100100010100000011111, kW , 0 , 0 }, // cash
+ { 0b1000100010100000111111, kWX, 30, 0 }, // casl
+ { 0b0000100010100000111111, kW , 0 , 0 }, // caslb
+ { 0b0100100010100000111111, kW , 0 , 0 }, // caslh
+ { 0b1011100000100000000000, kWX, 30, 0 }, // ldadd
+ { 0b1011100010100000000000, kWX, 30, 1 }, // ldadda
+ { 0b0011100010100000000000, kW , 0 , 1 }, // ldaddab
+ { 0b0111100010100000000000, kW , 0 , 1 }, // ldaddah
+ { 0b1011100011100000000000, kWX, 30, 1 }, // ldaddal
+ { 0b0011100011100000000000, kW , 0 , 1 }, // ldaddalb
+ { 0b0111100011100000000000, kW , 0 , 1 }, // ldaddalh
+ { 0b0011100000100000000000, kW , 0 , 0 }, // ldaddb
+ { 0b0111100000100000000000, kW , 0 , 0 }, // ldaddh
+ { 0b1011100001100000000000, kWX, 30, 0 }, // ldaddl
+ { 0b0011100001100000000000, kW , 0 , 0 }, // ldaddlb
+ { 0b0111100001100000000000, kW , 0 , 0 }, // ldaddlh
+ { 0b1011100000100000000100, kWX, 30, 0 }, // ldclr
+ { 0b1011100010100000000100, kWX, 30, 1 }, // ldclra
+ { 0b0011100010100000000100, kW , 0 , 1 }, // ldclrab
+ { 0b0111100010100000000100, kW , 0 , 1 }, // ldclrah
+ { 0b1011100011100000000100, kWX, 30, 1 }, // ldclral
+ { 0b0011100011100000000100, kW , 0 , 1 }, // ldclralb
+ { 0b0111100011100000000100, kW , 0 , 1 }, // ldclralh
+ { 0b0011100000100000000100, kW , 0 , 0 }, // ldclrb
+ { 0b0111100000100000000100, kW , 0 , 0 }, // ldclrh
+ { 0b1011100001100000000100, kWX, 30, 0 }, // ldclrl
+ { 0b0011100001100000000100, kW , 0 , 0 }, // ldclrlb
+ { 0b0111100001100000000100, kW , 0 , 0 }, // ldclrlh
+ { 0b1011100000100000001000, kWX, 30, 0 }, // ldeor
+ { 0b1011100010100000001000, kWX, 30, 1 }, // ldeora
+ { 0b0011100010100000001000, kW , 0 , 1 }, // ldeorab
+ { 0b0111100010100000001000, kW , 0 , 1 }, // ldeorah
+ { 0b1011100011100000001000, kWX, 30, 1 }, // ldeoral
+ { 0b0011100011100000001000, kW , 0 , 1 }, // ldeoralb
+ { 0b0111100011100000001000, kW , 0 , 1 }, // ldeoralh
+ { 0b0011100000100000001000, kW , 0 , 0 }, // ldeorb
+ { 0b0111100000100000001000, kW , 0 , 0 }, // ldeorh
+ { 0b1011100001100000001000, kWX, 30, 0 }, // ldeorl
+ { 0b0011100001100000001000, kW , 0 , 0 }, // ldeorlb
+ { 0b0111100001100000001000, kW , 0 , 0 }, // ldeorlh
+ { 0b1011100000100000001100, kWX, 30, 0 }, // ldset
+ { 0b1011100010100000001100, kWX, 30, 1 }, // ldseta
+ { 0b0011100010100000001100, kW , 0 , 1 }, // ldsetab
+ { 0b0111100010100000001100, kW , 0 , 1 }, // ldsetah
+ { 0b1011100011100000001100, kWX, 30, 1 }, // ldsetal
+ { 0b0011100011100000001100, kW , 0 , 1 }, // ldsetalb
+ { 0b0111100011100000001100, kW , 0 , 1 }, // ldsetalh
+ { 0b0011100000100000001100, kW , 0 , 0 }, // ldsetb
+ { 0b0111100000100000001100, kW , 0 , 0 }, // ldseth
+ { 0b1011100001100000001100, kWX, 30, 0 }, // ldsetl
+ { 0b0011100001100000001100, kW , 0 , 0 }, // ldsetlb
+ { 0b0111100001100000001100, kW , 0 , 0 }, // ldsetlh
+ { 0b1011100000100000010000, kWX, 30, 0 }, // ldsmax
+ { 0b1011100010100000010000, kWX, 30, 1 }, // ldsmaxa
+ { 0b0011100010100000010000, kW , 0 , 1 }, // ldsmaxab
+ { 0b0111100010100000010000, kW , 0 , 1 }, // ldsmaxah
+ { 0b1011100011100000010000, kWX, 30, 1 }, // ldsmaxal
+ { 0b0011100011100000010000, kW , 0 , 1 }, // ldsmaxalb
+ { 0b0111100011100000010000, kW , 0 , 1 }, // ldsmaxalh
+ { 0b0011100000100000010000, kW , 0 , 0 }, // ldsmaxb
+ { 0b0111100000100000010000, kW , 0 , 0 }, // ldsmaxh
+ { 0b1011100001100000010000, kWX, 30, 0 }, // ldsmaxl
+ { 0b0011100001100000010000, kW , 0 , 0 }, // ldsmaxlb
+ { 0b0111100001100000010000, kW , 0 , 0 }, // ldsmaxlh
+ { 0b1011100000100000010100, kWX, 30, 0 }, // ldsmin
+ { 0b1011100010100000010100, kWX, 30, 1 }, // ldsmina
+ { 0b0011100010100000010100, kW , 0 , 1 }, // ldsminab
+ { 0b0111100010100000010100, kW , 0 , 1 }, // ldsminah
+ { 0b1011100011100000010100, kWX, 30, 1 }, // ldsminal
+ { 0b0011100011100000010100, kW , 0 , 1 }, // ldsminalb
+ { 0b0111100011100000010100, kW , 0 , 1 }, // ldsminalh
+ { 0b0011100000100000010100, kW , 0 , 0 }, // ldsminb
+ { 0b0111100000100000010100, kW , 0 , 0 }, // ldsminh
+ { 0b1011100001100000010100, kWX, 30, 0 }, // ldsminl
+ { 0b0011100001100000010100, kW , 0 , 0 }, // ldsminlb
+ { 0b0111100001100000010100, kW , 0 , 0 }, // ldsminlh
+ { 0b1011100000100000011000, kWX, 30, 0 }, // ldumax
+ { 0b1011100010100000011000, kWX, 30, 1 }, // ldumaxa
+ { 0b0011100010100000011000, kW , 0 , 1 }, // ldumaxab
+ { 0b0111100010100000011000, kW , 0 , 1 }, // ldumaxah
+ { 0b1011100011100000011000, kWX, 30, 1 }, // ldumaxal
+ { 0b0011100011100000011000, kW , 0 , 1 }, // ldumaxalb
+ { 0b0111100011100000011000, kW , 0 , 1 }, // ldumaxalh
+ { 0b0011100000100000011000, kW , 0 , 0 }, // ldumaxb
+ { 0b0111100000100000011000, kW , 0 , 0 }, // ldumaxh
+ { 0b1011100001100000011000, kWX, 30, 0 }, // ldumaxl
+ { 0b0011100001100000011000, kW , 0 , 0 }, // ldumaxlb
+ { 0b0111100001100000011000, kW , 0 , 0 }, // ldumaxlh
+ { 0b1011100000100000011100, kWX, 30, 0 }, // ldumin
+ { 0b1011100010100000011100, kWX, 30, 1 }, // ldumina
+ { 0b0011100010100000011100, kW , 0 , 1 }, // lduminab
+ { 0b0111100010100000011100, kW , 0 , 1 }, // lduminah
+ { 0b1011100011100000011100, kWX, 30, 1 }, // lduminal
+ { 0b0011100011100000011100, kW , 0 , 1 }, // lduminalb
+ { 0b0111100011100000011100, kW , 0 , 1 }, // lduminalh
+ { 0b0011100000100000011100, kW , 0 , 0 }, // lduminb
+ { 0b0111100000100000011100, kW , 0 , 0 }, // lduminh
+ { 0b1011100001100000011100, kWX, 30, 0 }, // lduminl
+ { 0b0011100001100000011100, kW , 0 , 0 }, // lduminlb
+ { 0b0111100001100000011100, kW , 0 , 0 }, // lduminlh
+ { 0b1000100000000000111111, kWX, 30, 1 }, // stlxr
+ { 0b0000100000000000111111, kW , 0 , 1 }, // stlxrb
+ { 0b0100100000000000111111, kW , 0 , 1 }, // stlxrh
+ { 0b1011100000100000100000, kWX, 30, 1 }, // swp
+ { 0b1011100010100000100000, kWX, 30, 1 }, // swpa
+ { 0b0011100010100000100000, kW , 0 , 1 }, // swpab
+ { 0b0111100010100000100000, kW , 0 , 1 }, // swpah
+ { 0b1011100011100000100000, kWX, 30, 1 }, // swpal
+ { 0b0011100011100000100000, kW , 0 , 1 }, // swpalb
+ { 0b0111100011100000100000, kW , 0 , 1 }, // swpalh
+ { 0b0011100000100000100000, kW , 0 , 1 }, // swpb
+ { 0b0111100000100000100000, kW , 0 , 1 }, // swph
+ { 0b1011100001100000100000, kWX, 30, 1 }, // swpl
+ { 0b0011100001100000100000, kW , 0 , 1 }, // swplb
+ { 0b0111100001100000100000, kW , 0 , 1 } // swplh
+};
+
+const BaseAtomicSt baseAtomicSt[48] = {
+ { 0b1011100000100000000000, kWX, 30 }, // stadd
+ { 0b1011100001100000000000, kWX, 30 }, // staddl
+ { 0b0011100000100000000000, kW , 0 }, // staddb
+ { 0b0011100001100000000000, kW , 0 }, // staddlb
+ { 0b0111100000100000000000, kW , 0 }, // staddh
+ { 0b0111100001100000000000, kW , 0 }, // staddlh
+ { 0b1011100000100000000100, kWX, 30 }, // stclr
+ { 0b1011100001100000000100, kWX, 30 }, // stclrl
+ { 0b0011100000100000000100, kW , 0 }, // stclrb
+ { 0b0011100001100000000100, kW , 0 }, // stclrlb
+ { 0b0111100000100000000100, kW , 0 }, // stclrh
+ { 0b0111100001100000000100, kW , 0 }, // stclrlh
+ { 0b1011100000100000001000, kWX, 30 }, // steor
+ { 0b1011100001100000001000, kWX, 30 }, // steorl
+ { 0b0011100000100000001000, kW , 0 }, // steorb
+ { 0b0011100001100000001000, kW , 0 }, // steorlb
+ { 0b0111100000100000001000, kW , 0 }, // steorh
+ { 0b0111100001100000001000, kW , 0 }, // steorlh
+ { 0b1011100000100000001100, kWX, 30 }, // stset
+ { 0b1011100001100000001100, kWX, 30 }, // stsetl
+ { 0b0011100000100000001100, kW , 0 }, // stsetb
+ { 0b0011100001100000001100, kW , 0 }, // stsetlb
+ { 0b0111100000100000001100, kW , 0 }, // stseth
+ { 0b0111100001100000001100, kW , 0 }, // stsetlh
+ { 0b1011100000100000010000, kWX, 30 }, // stsmax
+ { 0b1011100001100000010000, kWX, 30 }, // stsmaxl
+ { 0b0011100000100000010000, kW , 0 }, // stsmaxb
+ { 0b0011100001100000010000, kW , 0 }, // stsmaxlb
+ { 0b0111100000100000010000, kW , 0 }, // stsmaxh
+ { 0b0111100001100000010000, kW , 0 }, // stsmaxlh
+ { 0b1011100000100000010100, kWX, 30 }, // stsmin
+ { 0b1011100001100000010100, kWX, 30 }, // stsminl
+ { 0b0011100000100000010100, kW , 0 }, // stsminb
+ { 0b0011100001100000010100, kW , 0 }, // stsminlb
+ { 0b0111100000100000010100, kW , 0 }, // stsminh
+ { 0b0111100001100000010100, kW , 0 }, // stsminlh
+ { 0b1011100000100000011000, kWX, 30 }, // stumax
+ { 0b1011100001100000011000, kWX, 30 }, // stumaxl
+ { 0b0011100000100000011000, kW , 0 }, // stumaxb
+ { 0b0011100001100000011000, kW , 0 }, // stumaxlb
+ { 0b0111100000100000011000, kW , 0 }, // stumaxh
+ { 0b0111100001100000011000, kW , 0 }, // stumaxlh
+ { 0b1011100000100000011100, kWX, 30 }, // stumin
+ { 0b1011100001100000011100, kWX, 30 }, // stuminl
+ { 0b0011100000100000011100, kW , 0 }, // stuminb
+ { 0b0011100001100000011100, kW , 0 }, // stuminlb
+ { 0b0111100000100000011100, kW , 0 }, // stuminh
+ { 0b0111100001100000011100, kW , 0 } // stuminlh
+};
+
+const BaseBfc baseBfc[1] = {
+ { 0b00110011000000000000001111100000 } // bfc
+};
+
+const BaseBfi baseBfi[3] = {
+ { 0b00110011000000000000000000000000 }, // bfi
+ { 0b00010011000000000000000000000000 }, // sbfiz
+ { 0b01010011000000000000000000000000 } // ubfiz
+};
+
+const BaseBfm baseBfm[3] = {
+ { 0b00110011000000000000000000000000 }, // bfm
+ { 0b00010011000000000000000000000000 }, // sbfm
+ { 0b01010011000000000000000000000000 } // ubfm
+};
+
+const BaseBfx baseBfx[3] = {
+ { 0b00110011000000000000000000000000 }, // bfxil
+ { 0b00010011000000000000000000000000 }, // sbfx
+ { 0b01010011000000000000000000000000 } // ubfx
+};
+
+const BaseBranchCmp baseBranchCmp[2] = {
+ { 0b00110101000000000000000000000000 }, // cbnz
+ { 0b00110100000000000000000000000000 } // cbz
+};
+
+const BaseBranchReg baseBranchReg[3] = {
+ { 0b11010110001111110000000000000000 }, // blr
+ { 0b11010110000111110000000000000000 }, // br
+ { 0b11010110010111110000000000000000 } // ret
+};
+
+const BaseBranchRel baseBranchRel[2] = {
+ { 0b00010100000000000000000000000000 }, // b
+ { 0b10010100000000000000000000000000 } // bl
+};
+
+const BaseBranchTst baseBranchTst[2] = {
+ { 0b00110111000000000000000000000000 }, // tbnz
+ { 0b00110110000000000000000000000000 } // tbz
+};
+
+const BaseCCmp baseCCmp[2] = {
+ { 0b00111010010000000000000000000000 }, // ccmn
+ { 0b01111010010000000000000000000000 } // ccmp
+};
+
+const BaseCInc baseCInc[3] = {
+ { 0b00011010100000000000010000000000 }, // cinc
+ { 0b01011010100000000000000000000000 }, // cinv
+ { 0b01011010100000000000010000000000 } // cneg
+};
+
+const BaseCSel baseCSel[4] = {
+ { 0b00011010100000000000000000000000 }, // csel
+ { 0b00011010100000000000010000000000 }, // csinc
+ { 0b01011010100000000000000000000000 }, // csinv
+ { 0b01011010100000000000010000000000 } // csneg
+};
+
+const BaseCSet baseCSet[2] = {
+ { 0b00011010100111110000011111100000 }, // cset
+ { 0b01011010100111110000001111100000 } // csetm
+};
+
+const BaseCmpCmn baseCmpCmn[2] = {
+ { 0b0101011000, 0b0101011001, 0b0110001 }, // cmn
+ { 0b1101011000, 0b1101011001, 0b1110001 } // cmp
+};
+
+const BaseExtend baseExtend[5] = {
+ { 0b0001001100000000000111, kWX, 0 }, // sxtb
+ { 0b0001001100000000001111, kWX, 0 }, // sxth
+ { 0b1001001101000000011111, kX , 0 }, // sxtw
+ { 0b0101001100000000000111, kW, 1 }, // uxtb
+ { 0b0101001100000000001111, kW, 1 } // uxth
+};
+
+const BaseExtract baseExtract[1] = {
+ { 0b00010011100000000000000000000000 } // extr
+};
+
+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
+ { 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
+ { 0b0111100100, 0b01111000000, 0b01111000001, 0 , kWX, 30, 1, Inst::kIdSturh } // strh
+};
+
+const BaseLdpStp baseLdpStp[6] = {
+ { 0b0010100001, 0 , kWX, 31, 2 }, // ldnp
+ { 0b0010100101, 0b0010100011, kWX, 31, 2 }, // ldp
+ { 0b0110100101, 0b0110100011, kX , 0 , 2 }, // ldpsw
+ { 0b0110100100, 0b0110100010, kX, 0, 4 }, // stgp
+ { 0b0010100000, 0 , kWX, 31, 2 }, // stnp
+ { 0b0010100100, 0b0010100010, kWX, 31, 2 } // stp
+};
+
+const BaseLdxp baseLdxp[2] = {
+ { 0b1000100001111111100000, kWX, 30 }, // ldaxp
+ { 0b1000100001111111000000, kWX, 30 } // ldxp
+};
+
+const BaseLogical baseLogical[8] = {
+ { 0b0001010000, 0b00100100, 0 }, // and
+ { 0b1101010000, 0b11100100, 0 }, // ands
+ { 0b0001010001, 0b00100100, 1 }, // bic
+ { 0b1101010001, 0b11100100, 1 }, // bics
+ { 0b1001010001, 0b10100100, 1 }, // eon
+ { 0b1001010000, 0b10100100, 0 }, // eor
+ { 0b0101010001, 0b01100100, 1 }, // orn
+ { 0b0101010000, 0b01100100, 0 } // orr
+};
+
+const BaseMovKNZ baseMovKNZ[3] = {
+ { 0b01110010100000000000000000000000 }, // movk
+ { 0b00010010100000000000000000000000 }, // movn
+ { 0b01010010100000000000000000000000 } // movz
+};
+
+const BaseMvnNeg baseMvnNeg[3] = {
+ { 0b00101010001000000000001111100000 }, // mvn
+ { 0b01001011000000000000001111100000 }, // neg
+ { 0b01101011000000000000001111100000 } // negs
+};
+
+const BaseOp baseOp[23] = {
+ { 0b11010101000000110010000110011111 }, // autia1716
+ { 0b11010101000000110010001110111111 }, // autiasp
+ { 0b11010101000000110010001110011111 }, // autiaz
+ { 0b11010101000000110010000111011111 }, // autib1716
+ { 0b11010101000000110010001111111111 }, // autibsp
+ { 0b11010101000000110010001111011111 }, // autibz
+ { 0b11010101000000000100000001011111 }, // axflag
+ { 0b11010101000000000100000000011111 }, // cfinv
+ { 0b11010101000000110010001010011111 }, // csdb
+ { 0b11010101000000110010000011011111 }, // dgh
+ { 0b11010110101111110000001111100000 }, // drps
+ { 0b11010101000000110010001000011111 }, // esb
+ { 0b11010110100111110000001111100000 }, // eret
+ { 0b11010101000000110010000000011111 }, // nop
+ { 0b11010101000000110011010010011111 }, // pssbb
+ { 0b11010101000000110010000010011111 }, // sev
+ { 0b11010101000000110010000010111111 }, // sevl
+ { 0b11010101000000110011000010011111 }, // ssbb
+ { 0b11010101000000110010000001011111 }, // wfe
+ { 0b11010101000000110010000001111111 }, // wfi
+ { 0b11010101000000000100000000111111 }, // xaflag
+ { 0b11010101000000110010000011111111 }, // xpaclri
+ { 0b11010101000000110010000000111111 } // yield
+};
+
+const BaseOpImm baseOpImm[14] = {
+ { 0b11010100001000000000000000000000, 16, 5 }, // brk
+ { 0b11010101000000110011000001011111, 4, 8 }, // clrex
+ { 0b11010100101000000000000000000001, 16, 5 }, // dcps1
+ { 0b11010100101000000000000000000010, 16, 5 }, // dcps2
+ { 0b11010100101000000000000000000011, 16, 5 }, // dcps3
+ { 0b11010101000000110011000010111111, 4, 8 }, // dmb
+ { 0b11010101000000110011000010011111, 4, 8 }, // dsb
+ { 0b11010101000000110010000000011111, 7, 5 }, // hint
+ { 0b11010100010000000000000000000000, 16, 5 }, // hlt
+ { 0b11010100000000000000000000000010, 16, 5 }, // hvc
+ { 0b11010101000000110011000011011111, 4, 8 }, // isb
+ { 0b11010100000000000000000000000011, 16, 5 }, // smc
+ { 0b11010100000000000000000000000001, 16, 5 }, // svc
+ { 0b00000000000000000000000000000000, 16, 0 } // udf
+};
+
+const BaseR baseR[10] = {
+ { 0b11011010110000010011101111100000, kX, kZR, 0 }, // autdza
+ { 0b11011010110000010011111111100000, kX, kZR, 0 }, // autdzb
+ { 0b11011010110000010011001111100000, kX, kZR, 0 }, // autiza
+ { 0b11011010110000010011011111100000, kX, kZR, 0 }, // autizb
+ { 0b11011010110000010010101111100000, kX, kZR, 0 }, // pacdza
+ { 0b11011010110000010010111111100000, kX, kZR, 0 }, // pacdzb
+ { 0b00111010000000000000100000001101, kW, kZR, 5 }, // setf8
+ { 0b00111010000000000100100000001101, kW, kZR, 5 }, // setf16
+ { 0b11011010110000010100011111100000, kX, kZR, 0 }, // xpacd
+ { 0b11011010110000010100001111100000, kX, kZR, 0 } // xpaci
+};
+
+const BaseRM_NoImm baseRM_NoImm[21] = {
+ { 0b1000100011011111111111, kWX, kZR, 30 }, // ldar
+ { 0b0000100011011111111111, kW , kZR, 0 }, // ldarb
+ { 0b0100100011011111111111, kW , kZR, 0 }, // ldarh
+ { 0b1000100001011111111111, kWX, kZR, 30 }, // ldaxr
+ { 0b0000100001011111111111, kW , kZR, 0 }, // ldaxrb
+ { 0b0100100001011111111111, kW , kZR, 0 }, // ldaxrh
+ { 0b1101100111100000000000, kX , kZR, 0 }, // ldgm
+ { 0b1000100011011111011111, kWX, kZR, 30 }, // ldlar
+ { 0b0000100011011111011111, kW , kZR, 0 }, // ldlarb
+ { 0b0100100011011111011111, kW , kZR, 0 }, // ldlarh
+ { 0b1000100001011111011111, kWX, kZR, 30 }, // ldxr
+ { 0b0000100001011111011111, kW , kZR, 0 }, // ldxrb
+ { 0b0100100001011111011111, kW , kZR, 0 }, // ldxrh
+ { 0b1101100110100000000000, kX , kZR, 0 }, // stgm
+ { 0b1000100010011111011111, kWX, kZR, 30 }, // stllr
+ { 0b0000100010011111011111, kW , kZR, 0 }, // stllrb
+ { 0b0100100010011111011111, kW , kZR, 0 }, // stllrh
+ { 0b1000100010011111111111, kWX, kZR, 30 }, // stlr
+ { 0b0000100010011111111111, kW , kZR, 0 }, // stlrb
+ { 0b0100100010011111111111, kW , kZR, 0 }, // stlrh
+ { 0b1101100100100000000000, kX , kZR, 0 } // stzgm
+};
+
+const BaseRM_SImm10 baseRM_SImm10[2] = {
+ { 0b1111100000100000000001, kX , kZR, 0, 3 }, // ldraa
+ { 0b1111100010100000000001, kX , kZR, 0, 3 } // ldrab
+};
+
+const BaseRM_SImm9 baseRM_SImm9[23] = {
+ { 0b1101100101100000000000, 0b0000000000000000000000, kX , kZR, 0, 4 }, // ldg
+ { 0b1011100001000000000010, 0b0000000000000000000000, kWX, kZR, 30, 0 }, // ldtr
+ { 0b0011100001000000000010, 0b0000000000000000000000, kW , kZR, 0 , 0 }, // ldtrb
+ { 0b0111100001000000000010, 0b0000000000000000000000, kW , kZR, 0 , 0 }, // ldtrh
+ { 0b0011100011000000000010, 0b0000000000000000000000, kWX, kZR, 22, 0 }, // ldtrsb
+ { 0b0111100011000000000010, 0b0000000000000000000000, kWX, kZR, 22, 0 }, // ldtrsh
+ { 0b1011100010000000000010, 0b0000000000000000000000, kX , kZR, 0 , 0 }, // ldtrsw
+ { 0b1011100001000000000000, 0b0000000000000000000000, kWX, kZR, 30, 0 }, // ldur
+ { 0b0011100001000000000000, 0b0000000000000000000000, kW , kZR, 0 , 0 }, // ldurb
+ { 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
+ { 0b1101100110100000000010, 0b1101100110100000000001, kX, kSP, 0, 4 }, // st2g
+ { 0b1101100100100000000010, 0b1101100100100000000001, kX, kSP, 0, 4 }, // stg
+ { 0b1011100000000000000010, 0b0000000000000000000000, kWX, kZR, 30, 0 }, // sttr
+ { 0b0011100000000000000010, 0b0000000000000000000000, kW , kZR, 0 , 0 }, // sttrb
+ { 0b0111100000000000000010, 0b0000000000000000000000, kW , kZR, 0 , 0 }, // sttrh
+ { 0b1011100000000000000000, 0b0000000000000000000000, kWX, kZR, 30, 0 }, // stur
+ { 0b0011100000000000000000, 0b0000000000000000000000, kW , kZR, 0 , 0 }, // sturb
+ { 0b0111100000000000000000, 0b0000000000000000000000, kW , kZR, 0 , 0 }, // sturh
+ { 0b1101100111100000000010, 0b1101100111100000000001, kX , kSP, 0, 4 }, // stz2g
+ { 0b1101100101100000000010, 0b1101100101100000000001, kX , kSP, 0, 4 } // stzg
+};
+
+const BaseRR baseRR[15] = {
+ { 0b11011010110000010001100000000000, kX, kZR, 0, kX, kSP, 5, true }, // autda
+ { 0b11011010110000010001110000000000, kX, kZR, 0, kX, kSP, 5, true }, // autdb
+ { 0b11011010110000010001000000000000, kX, kZR, 0, kX, kSP, 5, true }, // autia
+ { 0b11011010110000010001010000000000, kX, kZR, 0, kX, kSP, 5, true }, // autib
+ { 0b01011010110000000001010000000000, kWX, kZR, 0, kWX, kZR, 5, true }, // cls
+ { 0b01011010110000000001000000000000, kWX, kZR, 0, kWX, kZR, 5, true }, // clz
+ { 0b10111010110000000000000000011111, kX, kSP, 5, kX, kSP, 16, true }, // cmpp
+ { 0b01011010000000000000001111100000, kWX, kZR, 0, kWX, kZR, 16, true }, // ngc
+ { 0b01111010000000000000001111100000, kWX, kZR, 0, kWX, kZR, 16, true }, // ngcs
+ { 0b11011010110000010000100000000000, kX, kZR, 0, kX, kSP, 5, true }, // pacda
+ { 0b11011010110000010000110000000000, kX, kZR, 0, kX, kSP, 5, true }, // pacdb
+ { 0b01011010110000000000000000000000, kWX, kZR, 0, kWX, kZR, 5, true }, // rbit
+ { 0b01011010110000000000010000000000, kWX, kZR, 0, kWX, kZR, 5, true }, // rev16
+ { 0b11011010110000000000100000000000, kWX, kZR, 0, kWX, kZR, 5, true }, // rev32
+ { 0b11011010110000000000110000000000, kWX, kZR, 0, kWX, kZR, 5, true } // rev64
+};
+
+const BaseRRII baseRRII[2] = {
+ { 0b1001000110000000000000, kX, kSP, kX, kSP, 6, 4, 16, 4, 0, 10 }, // addg
+ { 0b1101000110000000000000, kX, kSP, kX, kSP, 6, 4, 16, 4, 0, 10 } // subg
+};
+
+const BaseRRR baseRRR[26] = {
+ { 0b0001101000000000000000, kWX, kZR, kWX, kZR, kWX, kZR, true }, // adc
+ { 0b0011101000000000000000, kWX, kZR, kWX, kZR, kWX, kZR, true }, // adcs
+ { 0b0001101011000000010000, kW, kZR, kW, kZR, kW, kZR, false }, // crc32b
+ { 0b0001101011000000010100, kW, kZR, kW, kZR, kW, kZR, false }, // crc32cb
+ { 0b0001101011000000010101, kW, kZR, kW, kZR, kW, kZR, false }, // crc32ch
+ { 0b0001101011000000010110, kW, kZR, kW, kZR, kW, kZR, false }, // crc32cw
+ { 0b1001101011000000010111, kW, kZR, kW, kZR, kX, kZR, false }, // crc32cx
+ { 0b0001101011000000010001, kW, kZR, kW, kZR, kW, kZR, false }, // crc32h
+ { 0b0001101011000000010010, kW, kZR, kW, kZR, kW, kZR, false }, // crc32w
+ { 0b1001101011000000010011, kW, kZR, kW, kZR, kX, kZR, false }, // crc32x
+ { 0b1001101011000000000101, kX , kZR, kX , kSP, kX , kZR, true }, // gmi
+ { 0b0001101100000000111111, kWX, kZR, kWX, kZR, kWX, kZR, true }, // mneg
+ { 0b0001101100000000011111, kWX, kZR, kWX, kZR, kWX, kZR, true }, // mul
+ { 0b1001101011000000001100, kX, kZR, kX, kZR, kX, kSP, false }, // pacga
+ { 0b0101101000000000000000, kWX, kZR, kWX, kZR, kWX, kZR, true }, // sbc
+ { 0b0111101000000000000000, kWX, kZR, kWX, kZR, kWX, kZR, true }, // sbcs
+ { 0b0001101011000000000011, kWX, kZR, kWX, kZR, kWX, kZR, true }, // sdiv
+ { 0b1001101100100000111111, kX , kZR, kW , kZR, kW , kZR, false }, // smnegl
+ { 0b1001101101000000011111, kX , kZR, kX , kZR, kX , kZR, true }, // smulh
+ { 0b1001101100100000011111, kX , kZR, kW , kZR, kW , kZR, false }, // smull
+ { 0b1001101011000000000000, kX, kZR, kX, kSP, kX, kSP, false }, // subp
+ { 0b1011101011000000000000, kX, kZR, kX, kSP, kX, kSP, false }, // subps
+ { 0b0001101011000000000010, kWX, kZR, kWX, kZR, kWX, kZR, true }, // udiv
+ { 0b1001101110100000111111, kX , kZR, kW , kZR, kW , kZR, false }, // umnegl
+ { 0b1001101110100000011111, kX , kZR, kW , kZR, kW , kZR, false }, // umull
+ { 0b1001101111000000011111, kX , kZR, kX , kZR, kX , kZR, false } // umulh
+};
+
+const BaseRRRR baseRRRR[6] = {
+ { 0b0001101100000000000000, kWX, kZR, kWX, kZR, kWX, kZR, kWX, kZR, true }, // madd
+ { 0b0001101100000000100000, kWX, kZR, kWX, kZR, kWX, kZR, kWX, kZR, true }, // msub
+ { 0b1001101100100000000000, kX , kZR, kW , kZR, kW , kZR, kX , kZR, false }, // smaddl
+ { 0b1001101100100000100000, kX , kZR, kW , kZR, kW , kZR, kX , kZR, false }, // smsubl
+ { 0b1001101110100000000000, kX , kZR, kW , kZR, kW , kZR, kX , kZR, false }, // umaddl
+ { 0b1001101110100000100000, kX , kZR, kW , kZR, kW , kZR, kX , kZR, false } // umsubl
+};
+
+const BaseShift baseShift[8] = {
+ { 0b0001101011000000001010, 0b0001001100000000011111, 0 }, // asr
+ { 0b0001101011000000001010, 0b0000000000000000000000, 0 }, // asrv
+ { 0b0001101011000000001000, 0b0101001100000000000000, 0 }, // lsl
+ { 0b0001101011000000001000, 0b0000000000000000000000, 0 }, // lslv
+ { 0b0001101011000000001001, 0b0101001100000000011111, 0 }, // lsr
+ { 0b0001101011000000001001, 0b0000000000000000000000, 0 }, // lsrv
+ { 0b0001101011000000001011, 0b0001001110000000000000, 1 }, // ror
+ { 0b0001101011000000001011, 0b0000000000000000000000, 1 } // rorv
+};
+
+const BaseStx baseStx[3] = {
+ { 0b1000100000000000011111, kWX, 30 }, // stxr
+ { 0b0000100000000000011111, kW , 0 }, // stxrb
+ { 0b0100100000000000011111, kW , 0 } // stxrh
+};
+
+const BaseStxp baseStxp[2] = {
+ { 0b1000100000100000100000, kWX, 30 }, // stlxp
+ { 0b1000100000100000000000, kWX, 30 } // stxp
+};
+
+const BaseTst baseTst[1] = {
+ { 0b1101010000, 0b111001000 } // tst
+};
+
+const FSimdPair fSimdPair[5] = {
+ { 0b0111111000110000110110, 0b0010111000100000110101 }, // faddp_v
+ { 0b0111111000110000110010, 0b0010111000100000110001 }, // fmaxnmp_v
+ { 0b0111111000110000111110, 0b0010111000100000111101 }, // fmaxp_v
+ { 0b0111111010110000110010, 0b0010111010100000110001 }, // fminnmp_v
+ { 0b0111111010110000111110, 0b0010111010100000111101 } // fminp_v
+};
+
+const FSimdSV fSimdSV[4] = {
+ { 0b0010111000110000110010 }, // fmaxnmv_v
+ { 0b0010111000110000111110 }, // fmaxv_v
+ { 0b0010111010110000110010 }, // fminnmv_v
+ { 0b0010111010110000111110 } // fminv_v
+};
+
+const FSimdVV fSimdVV[17] = {
+ { 0b0001111000100000110000, kHF_A, 0b0000111010100000111110, kHF_B }, // fabs_v
+ { 0b0001111000100001010000, kHF_A, 0b0010111010100000111110, kHF_B }, // fneg_v
+ { 0b0101111010100001110110, kHF_B, 0b0000111010100001110110, kHF_B }, // frecpe_v
+ { 0b0101111010100001111110, kHF_B, 0b0000000000000000000000, kHF_N }, // frecpx_v
+ { 0b0001111000101000110000, kHF_N, 0b0010111000100001111010, kHF_N }, // frint32x_v
+ { 0b0001111000101000010000, kHF_N, 0b0000111000100001111010, kHF_N }, // frint32z_v
+ { 0b0001111000101001110000, kHF_N, 0b0010111000100001111110, kHF_N }, // frint64x_v
+ { 0b0001111000101001010000, kHF_N, 0b0000111000100001111110, kHF_N }, // frint64z_v
+ { 0b0001111000100110010000, kHF_A, 0b0010111000100001100010, kHF_B }, // frinta_v
+ { 0b0001111000100111110000, kHF_A, 0b0010111010100001100110, kHF_B }, // frinti_v
+ { 0b0001111000100101010000, kHF_A, 0b0000111000100001100110, kHF_B }, // frintm_v
+ { 0b0001111000100100010000, kHF_A, 0b0000111000100001100010, kHF_B }, // frintn_v
+ { 0b0001111000100100110000, kHF_A, 0b0000111010100001100010, kHF_B }, // frintp_v
+ { 0b0001111000100111010000, kHF_A, 0b0010111000100001100110, kHF_B }, // frintx_v
+ { 0b0001111000100101110000, kHF_A, 0b0000111010100001100110, kHF_B }, // frintz_v
+ { 0b0111111010100001110110, kHF_B, 0b0010111010100001110110, kHF_B }, // frsqrte_v
+ { 0b0001111000100001110000, kHF_A, 0b0010111010100001111110, kHF_B } // fsqrt_v
+};
+
+const FSimdVVV fSimdVVV[13] = {
+ { 0b0111111010100000110101, kHF_C, 0b0010111010100000110101, kHF_C }, // fabd_v
+ { 0b0111111000100000111011, kHF_C, 0b0010111000100000111011, kHF_C }, // facge_v
+ { 0b0111111010100000111011, kHF_C, 0b0010111010100000111011, kHF_C }, // facgt_v
+ { 0b0001111000100000001010, kHF_A, 0b0000111000100000110101, kHF_C }, // fadd_v
+ { 0b0001111000100000000110, kHF_A, 0b0010111000100000111111, kHF_C }, // fdiv_v
+ { 0b0001111000100000010010, kHF_A, 0b0000111000100000111101, kHF_C }, // fmax_v
+ { 0b0001111000100000011010, kHF_A, 0b0000111000100000110001, kHF_C }, // fmaxnm_v
+ { 0b0001111000100000010110, kHF_A, 0b0000111010100000111101, kHF_C }, // fmin_v
+ { 0b0001111000100000011110, kHF_A, 0b0000111010100000110001, kHF_C }, // fminnm_v
+ { 0b0001111000100000100010, kHF_A, 0b0000000000000000000000, kHF_N }, // fnmul_v
+ { 0b0101111000100000111111, kHF_C, 0b0000111000100000111111, kHF_C }, // frecps_v
+ { 0b0101111010100000111111, kHF_C, 0b0000111010100000111111, kHF_C }, // frsqrts_v
+ { 0b0001111000100000001110, kHF_A, 0b0000111010100000110101, kHF_C } // fsub_v
+};
+
+const FSimdVVVV fSimdVVVV[4] = {
+ { 0b0001111100000000000000, kHF_A, 0b0000000000000000000000, kHF_N }, // fmadd_v
+ { 0b0001111100000000100000, kHF_A, 0b0000000000000000000000, kHF_N }, // fmsub_v
+ { 0b0001111100100000000000, kHF_A, 0b0000000000000000000000, kHF_N }, // fnmadd_v
+ { 0b0001111100100000100000, kHF_A, 0b0000000000000000000000, kHF_N } // fnmsub_v
+};
+
+const FSimdVVVe fSimdVVVe[4] = {
+ { 0b0000000000000000000000, kHF_N, 0b0000111000100000110011, 0b0000111110000000000100 }, // fmla_v
+ { 0b0000000000000000000000, kHF_N, 0b0000111010100000110011, 0b0000111110000000010100 }, // fmls_v
+ { 0b0001111000100000000010, kHF_A, 0b0010111000100000110111, 0b0000111110000000100100 }, // fmul_v
+ { 0b0101111000100000110111, kHF_C, 0b0000111000100000110111, 0b0010111110000000100100 } // fmulx_v
+};
+
+const ISimdPair iSimdPair[1] = {
+ { 0b0101111000110001101110, 0b0000111000100000101111, kVO_V_Any } // addp_v
+};
+
+const ISimdSV iSimdSV[7] = {
+ { 0b0000111000110001101110, kVO_V_BH_4S }, // addv_v
+ { 0b0000111000110000001110, kVO_V_BH_4S }, // saddlv_v
+ { 0b0000111000110000101010, kVO_V_BH_4S }, // smaxv_v
+ { 0b0000111000110001101010, kVO_V_BH_4S }, // sminv_v
+ { 0b0010111000110000001110, kVO_V_BH_4S }, // uaddlv_v
+ { 0b0010111000110000101010, kVO_V_BH_4S }, // umaxv_v
+ { 0b0010111000110001101010, kVO_V_BH_4S } // uminv_v
+};
+
+const ISimdVV iSimdVV[29] = {
+ { 0b0000111000100000101110, kVO_V_Any }, // abs_v
+ { 0b0000111000100000010010, kVO_V_BHS }, // cls_v
+ { 0b0010111000100000010010, kVO_V_BHS }, // clz_v
+ { 0b0000111000100000010110, kVO_V_B }, // cnt_v
+ { 0b0010111000100000010110, kVO_V_B }, // mvn_v
+ { 0b0010111000100000101110, kVO_V_Any }, // neg_v
+ { 0b0010111000100000010110, kVO_V_B }, // not_v
+ { 0b0010111001100000010110, kVO_V_B }, // rbit_v
+ { 0b0000111000100000000110, kVO_V_B }, // rev16_v
+ { 0b0010111000100000000010, kVO_V_BH }, // rev32_v
+ { 0b0000111000100000000010, kVO_V_BHS }, // rev64_v
+ { 0b0000111000100000011010, kVO_V_BHS }, // sadalp_v
+ { 0b0000111000100000001010, kVO_V_BHS }, // saddlp_v
+ { 0b0000111000100000011110, kVO_SV_Any }, // sqabs_v
+ { 0b0010111000100000011110, kVO_SV_Any }, // sqneg_v
+ { 0b0000111000100001010010, kVO_SV_B8H4S2 }, // sqxtn_v
+ { 0b0100111000100001010010, kVO_V_B16H8S4 }, // sqxtn2_v
+ { 0b0010111000100001001010, kVO_SV_B8H4S2 }, // sqxtun_v
+ { 0b0110111000100001001010, kVO_V_B16H8S4 }, // sqxtun2_v
+ { 0b0000111000100000001110, kVO_SV_Any }, // suqadd_v
+ { 0b0010111000100000011010, kVO_V_BHS }, // uadalp_v
+ { 0b0010111000100000001010, kVO_V_BHS }, // uaddlp_v
+ { 0b0010111000100001010010, kVO_SV_B8H4S2 }, // uqxtn_v
+ { 0b0110111000100001010010, kVO_V_B16H8S4 }, // uqxtn2_v
+ { 0b0000111010100001110010, kVO_V_S }, // urecpe_v
+ { 0b0010111010100001110010, kVO_V_S }, // ursqrte_v
+ { 0b0010111000100000001110, kVO_SV_Any }, // usqadd_v
+ { 0b0000111000100001001010, kVO_V_B8H4S2 }, // xtn_v
+ { 0b0100111000100001001010, kVO_V_B16H8S4 } // xtn2_v
+};
+
+const ISimdVVV iSimdVVV[65] = {
+ { 0b0000111000100000100001, kVO_V_Any }, // add_v
+ { 0b0000111000100000010000, kVO_V_B8H4S2 }, // addhn_v
+ { 0b0100111000100000010000, kVO_V_B16H8S4 }, // addhn2_v
+ { 0b0000111000100000000111, kVO_V_B }, // and_v
+ { 0b0010111011100000000111, kVO_V_B }, // bif_v
+ { 0b0010111010100000000111, kVO_V_B }, // bit_v
+ { 0b0010111001100000000111, kVO_V_B }, // bsl_v
+ { 0b0000111000100000100011, kVO_V_Any }, // cmtst_v
+ { 0b0010111000100000000111, kVO_V_B }, // eor_v
+ { 0b0000111011100000000111, kVO_V_B }, // orn_v
+ { 0b0010111000100000100111, kVO_V_B }, // pmul_v
+ { 0b0000111000100000111000, kVO_V_B8D1 }, // pmull_v
+ { 0b0100111000100000111000, kVO_V_B16D2 }, // pmull2_v
+ { 0b0010111000100000010000, kVO_V_B8H4S2 }, // raddhn_v
+ { 0b0110111000100000010000, kVO_V_B16H8S4 }, // raddhn2_v
+ { 0b1100111001100000100011, kVO_V_D2 }, // rax1_v
+ { 0b0010111000100000011000, kVO_V_B8H4S2 }, // rsubhn_v
+ { 0b0110111000100000011000, kVO_V_B16H8S4 }, // rsubhn2_v
+ { 0b0000111000100000011111, kVO_V_BHS }, // saba_v
+ { 0b0000111000100000010100, kVO_V_B8H4S2 }, // sabal_v
+ { 0b0100111000100000010100, kVO_V_B16H8S4 }, // sabal2_v
+ { 0b0000111000100000011101, kVO_V_BHS }, // sabd_v
+ { 0b0000111000100000011100, kVO_V_B8H4S2 }, // sabdl_v
+ { 0b0100111000100000011100, kVO_V_B16H8S4 }, // sabdl2_v
+ { 0b0000111000100000000000, kVO_V_B8H4S2 }, // saddl_v
+ { 0b0100111000100000000000, kVO_V_B16H8S4 }, // saddl2_v
+ { 0b0000111000100000000001, kVO_V_BHS }, // shadd_v
+ { 0b0000111000100000001001, kVO_V_BHS }, // shsub_v
+ { 0b0000111000100000011001, kVO_V_BHS }, // smax_v
+ { 0b0000111000100000101001, kVO_V_BHS }, // smaxp_v
+ { 0b0000111000100000011011, kVO_V_BHS }, // smin_v
+ { 0b0000111000100000101011, kVO_V_BHS }, // sminp_v
+ { 0b0000111000100000000011, kVO_SV_Any }, // sqadd_v
+ { 0b0000111000100000001011, kVO_SV_Any }, // sqsub_v
+ { 0b0000111000100000000101, kVO_V_BHS }, // srhadd_v
+ { 0b0000111000100000001000, kVO_V_B8H4S2 }, // ssubl_v
+ { 0b0100111000100000001000, kVO_V_B16H8S4 }, // ssubl2_v
+ { 0b0010111000100000100001, kVO_V_Any }, // sub_v
+ { 0b0000111000100000011000, kVO_V_B8H4S2 }, // subhn_v
+ { 0b0000111000100000011000, kVO_V_B16H8S4 }, // subhn2_v
+ { 0b0000111000000000001010, kVO_V_BHS_D2 }, // trn1_v
+ { 0b0000111000000000011010, kVO_V_BHS_D2 }, // trn2_v
+ { 0b0010111000100000011111, kVO_V_BHS }, // uaba_v
+ { 0b0010111000100000010100, kVO_V_B8H4S2 }, // uabal_v
+ { 0b0110111000100000010100, kVO_V_B16H8S4 }, // uabal2_v
+ { 0b0010111000100000011101, kVO_V_BHS }, // uabd_v
+ { 0b0010111000100000011100, kVO_V_B8H4S2 }, // uabdl_v
+ { 0b0110111000100000011100, kVO_V_B16H8S4 }, // uabdl2_v
+ { 0b0010111000100000000000, kVO_V_B8H4S2 }, // uaddl_v
+ { 0b0110111000100000000000, kVO_V_B16H8S4 }, // uaddl2_v
+ { 0b0010111000100000000001, kVO_V_BHS }, // uhadd_v
+ { 0b0010111000100000001001, kVO_V_BHS }, // uhsub_v
+ { 0b0010111000100000011001, kVO_V_BHS }, // umax_v
+ { 0b0010111000100000101001, kVO_V_BHS }, // umaxp_v
+ { 0b0010111000100000011011, kVO_V_BHS }, // umin_v
+ { 0b0010111000100000101011, kVO_V_BHS }, // uminp_v
+ { 0b0010111000100000000011, kVO_SV_Any }, // uqadd_v
+ { 0b0010111000100000001011, kVO_SV_Any }, // uqsub_v
+ { 0b0010111000100000000101, kVO_V_BHS }, // urhadd_v
+ { 0b0010111000100000001000, kVO_V_B8H4S2 }, // usubl_v
+ { 0b0110111000100000001000, kVO_V_B16H8S4 }, // usubl2_v
+ { 0b0000111000000000000110, kVO_V_BHS_D2 }, // uzp1_v
+ { 0b0000111000000000010110, kVO_V_BHS_D2 }, // uzp2_v
+ { 0b0000111000000000001110, kVO_V_BHS_D2 }, // zip1_v
+ { 0b0000111000000000011110, kVO_V_BHS_D2 } // zip2_v
+};
+
+const ISimdVVVI iSimdVVVI[2] = {
+ { 0b0010111000000000000000, kVO_V_B, 4, 11, 1 }, // ext_v
+ { 0b1100111001100000100011, kVO_V_D2, 6, 10, 0 } // xar_v
+};
+
+const ISimdVVVV iSimdVVVV[2] = {
+ { 0b1100111000100000000000, kVO_V_B16 }, // bcax_v
+ { 0b1100111000000000000000, kVO_V_B16 } // eor3_v
+};
+
+const ISimdVVVVx iSimdVVVVx[1] = {
+ { 0b1100111001000000000000, kOp_V4S, kOp_V4S, kOp_V4S, kOp_V4S } // sm3ss1_v
+};
+
+const ISimdVVVe iSimdVVVe[25] = {
+ { 0b0000111000100000100101, kVO_V_BHS, 0b0010111100000000000000, kVO_V_HS }, // mla_v
+ { 0b0010111000100000100101, kVO_V_BHS, 0b0010111100000000010000, kVO_V_HS }, // mls_v
+ { 0b0000111000100000100111, kVO_V_BHS, 0b0000111100000000100000, kVO_V_HS }, // mul_v
+ { 0b0000111000100000100000, kVO_V_B8H4S2, 0b0000111100000000001000, kVO_V_H4S2 }, // smlal_v
+ { 0b0100111000100000100000, kVO_V_B16H8S4, 0b0100111100000000001000, kVO_V_H8S4 }, // smlal2_v
+ { 0b0000111000100000101000, kVO_V_B8H4S2, 0b0000111100000000011000, kVO_V_H4S2 }, // smlsl_v
+ { 0b0100111000100000101000, kVO_V_B16H8S4, 0b0100111100000000011000, kVO_V_H8S4 }, // smlsl2_v
+ { 0b0000111000100000110000, kVO_V_B8H4S2, 0b0000111100000000101000, kVO_V_H4S2 }, // smull_v
+ { 0b0100111000100000110000, kVO_V_B16H8S4, 0b0100111100000000101000, kVO_V_H8S4 }, // smull2_v
+ { 0b0000111000100000100100, kVO_SV_BHS, 0b0000111100000000001100, kVO_V_H4S2 }, // sqdmlal_v
+ { 0b0100111000100000100100, kVO_V_B16H8S4, 0b0100111100000000001100, kVO_V_H8S4 }, // sqdmlal2_v
+ { 0b0000111000100000101100, kVO_SV_BHS, 0b0000111100000000011100, kVO_V_H4S2 }, // sqdmlsl_v
+ { 0b0100111000100000101100, kVO_V_B16H8S4, 0b0100111100000000011100, kVO_V_H8S4 }, // sqdmlsl2_v
+ { 0b0000111000100000101101, kVO_SV_HS, 0b0000111100000000110000, kVO_SV_HS }, // sqdmulh_v
+ { 0b0000111000100000110100, kVO_SV_BHS, 0b0000111100000000101100, kVO_V_H4S2 }, // sqdmull_v
+ { 0b0100111000100000110100, kVO_V_B16H8S4, 0b0100111100000000101100, kVO_V_H8S4 }, // sqdmull2_v
+ { 0b0010111000000000100001, kVO_SV_HS, 0b0010111100000000110100, kVO_SV_HS }, // sqrdmlah_v
+ { 0b0010111000000000100011, kVO_SV_HS, 0b0010111100000000111100, kVO_SV_HS }, // sqrdmlsh_v
+ { 0b0010111000100000101101, kVO_SV_HS, 0b0000111100000000110100, kVO_SV_HS }, // sqrdmulh_v
+ { 0b0010111000100000100000, kVO_V_B8H4S2, 0b0010111100000000001000, kVO_V_H4S2 }, // umlal_v
+ { 0b0110111000100000100000, kVO_V_B16H8S4, 0b0010111100000000001000, kVO_V_H8S4 }, // umlal2_v
+ { 0b0010111000100000101000, kVO_V_B8H4S2, 0b0010111100000000011000, kVO_V_H4S2 }, // umlsl_v
+ { 0b0110111000100000101000, kVO_V_B16H8S4, 0b0110111100000000011000, kVO_V_H8S4 }, // umlsl2_v
+ { 0b0010111000100000110000, kVO_V_B8H4S2, 0b0010111100000000101000, kVO_V_H4S2 }, // umull_v
+ { 0b0110111000100000110000, kVO_V_B16H8S4, 0b0110111100000000101000, kVO_V_H8S4 } // umull2_v
+};
+
+const ISimdVVVx iSimdVVVx[17] = {
+ { 0b0110111001000000111011, kOp_V4S, kOp_V8H, kOp_V8H }, // bfmmla_v
+ { 0b0101111000000000000000, kOp_Q, kOp_S, kOp_V4S }, // sha1c_v
+ { 0b0101111000000000001000, kOp_Q, kOp_S, kOp_V4S }, // sha1m_v
+ { 0b0101111000000000000100, kOp_Q, kOp_S, kOp_V4S }, // sha1p_v
+ { 0b0101111000000000001100, kOp_V4S, kOp_V4S, kOp_V4S }, // sha1su0_v
+ { 0b0101111000000000010000, kOp_Q, kOp_Q, kOp_V4S }, // sha256h_v
+ { 0b0101111000000000010100, kOp_Q, kOp_Q, kOp_V4S }, // sha256h2_v
+ { 0b0101111000000000011000, kOp_V4S, kOp_V4S, kOp_V4S }, // sha256su1_v
+ { 0b1100111001100000100000, kOp_Q, kOp_Q, kOp_V2D }, // sha512h_v
+ { 0b1100111001100000100001, kOp_Q, kOp_Q, kOp_V2D }, // sha512h2_v
+ { 0b1100111001100000100010, kOp_V2D, kOp_V2D, kOp_V2D }, // sha512su1_v
+ { 0b1100111001100000110000, kOp_V4S, kOp_V4S, kOp_V4S }, // sm3partw1_v
+ { 0b1100111001100000110001, kOp_V4S, kOp_V4S, kOp_V4S }, // sm3partw2_v
+ { 0b1100111001100000110010, kOp_V4S, kOp_V4S, kOp_V4S }, // sm4ekey_v
+ { 0b0100111010000000101001, kOp_V4S, kOp_V16B, kOp_V16B }, // smmla_v
+ { 0b0110111010000000101001, kOp_V4S, kOp_V16B, kOp_V16B }, // ummla_v
+ { 0b0100111010000000101011, kOp_V4S, kOp_V16B, kOp_V16B } // usmmla_v
+};
+
+const ISimdVVx iSimdVVx[13] = {
+ { 0b0100111000101000010110, kOp_V16B, kOp_V16B }, // aesd_v
+ { 0b0100111000101000010010, kOp_V16B, kOp_V16B }, // aese_v
+ { 0b0100111000101000011110, kOp_V16B, kOp_V16B }, // aesimc_v
+ { 0b0100111000101000011010, kOp_V16B, kOp_V16B }, // aesmc_v
+ { 0b0001111001100011010000, kOp_H, kOp_S }, // bfcvt_v
+ { 0b0000111010100001011010, kOp_V4H, kOp_V4S }, // bfcvtn_v
+ { 0b0100111010100001011010, kOp_V8H, kOp_V4S }, // bfcvtn2_v
+ { 0b0001111001111110000000, kOp_GpW, kOp_D }, // fjcvtzs_v
+ { 0b0101111000101000000010, kOp_S, kOp_S }, // sha1h_v
+ { 0b0101111000101000000110, kOp_V4S, kOp_V4S }, // sha1su1_v
+ { 0b0101111000101000001010, kOp_V4S, kOp_V4S }, // sha256su0_v
+ { 0b1100111011000000100000, kOp_V2D, kOp_V2D }, // sha512su0_v
+ { 0b1100111011000000100001, kOp_V4S, kOp_V4S } // sm4e_v
+};
+
+const ISimdWWV iSimdWWV[8] = {
+ { 0b0000111000100000000100, kVO_V_B8H4S2 }, // saddw_v
+ { 0b0000111000100000000100, kVO_V_B16H8S4 }, // saddw2_v
+ { 0b0000111000100000001100, kVO_V_B8H4S2 }, // ssubw_v
+ { 0b0000111000100000001100, kVO_V_B16H8S4 }, // ssubw2_v
+ { 0b0010111000100000000100, kVO_V_B8H4S2 }, // uaddw_v
+ { 0b0010111000100000000100, kVO_V_B16H8S4 }, // uaddw2_v
+ { 0b0010111000100000001100, kVO_V_B8H4S2 }, // usubw_v
+ { 0b0010111000100000001100, kVO_V_B16H8S4 } // usubw2_v
+};
+
+const SimdBicOrr simdBicOrr[2] = {
+ { 0b0000111001100000000111, 0b0010111100000000000001 }, // bic_v
+ { 0b0000111010100000000111, 0b0000111100000000000001 } // orr_v
+};
+
+const SimdCmp simdCmp[7] = {
+ { 0b0010111000100000100011, 0b0000111000100000100110, kVO_V_Any }, // cmeq_v
+ { 0b0000111000100000001111, 0b0010111000100000100010, kVO_V_Any }, // cmge_v
+ { 0b0000111000100000001101, 0b0000111000100000100010, kVO_V_Any }, // cmgt_v
+ { 0b0010111000100000001101, 0b0000000000000000000000, kVO_V_Any }, // cmhi_v
+ { 0b0010111000100000001111, 0b0000000000000000000000, kVO_V_Any }, // cmhs_v
+ { 0b0000000000000000000000, 0b0010111000100000100110, kVO_V_Any }, // cmle_v
+ { 0b0000000000000000000000, 0b0000111000100000101010, kVO_V_Any } // cmlt_v
+};
+
+const SimdDot simdDot[5] = {
+ { 0b0010111001000000111111, 0b0000111101000000111100, kET_S, kET_H, kET_2H }, // bfdot_v
+ { 0b0000111010000000100101, 0b0000111110000000111000, kET_S, kET_B, kET_4B }, // sdot_v
+ { 0b0000000000000000000000, 0b0000111100000000111100, kET_S, kET_B, kET_4B }, // sudot_v
+ { 0b0010111010000000100101, 0b0010111110000000111000, kET_S, kET_B, kET_4B }, // udot_v
+ { 0b0000111010000000100111, 0b0000111110000000111100, kET_S, kET_B, kET_4B } // usdot_v
+};
+
+const SimdFcadd simdFcadd[1] = {
+ { 0b0010111000000000111001 } // fcadd_v
+};
+
+const SimdFccmpFccmpe simdFccmpFccmpe[2] = {
+ { 0b00011110001000000000010000000000 }, // fccmp_v
+ { 0b00011110001000000000010000010000 } // fccmpe_v
+};
+
+const SimdFcm simdFcm[5] = {
+ { 0b0000111000100000111001, kHF_C, 0b0000111010100000110110 }, // fcmeq_v
+ { 0b0010111000100000111001, kHF_C, 0b0010111010100000110010 }, // fcmge_v
+ { 0b0010111010100000111001, kHF_C, 0b0000111010100000110010 }, // fcmgt_v
+ { 0b0000000000000000000000, kHF_C, 0b0010111010100000110110 }, // fcmle_v
+ { 0b0000000000000000000000, kHF_C, 0b0000111010100000111010 } // fcmlt_v
+};
+
+const SimdFcmla simdFcmla[1] = {
+ { 0b0010111000000000110001, 0b0010111100000000000100 } // fcmla_v
+};
+
+const SimdFcmpFcmpe simdFcmpFcmpe[2] = {
+ { 0b00011110001000000010000000000000 }, // fcmp_v
+ { 0b00011110001000000010000000010000 } // fcmpe_v
+};
+
+const SimdFcvtLN simdFcvtLN[6] = {
+ { 0b0000111000100001011110, 0, 0 }, // fcvtl_v
+ { 0b0100111000100001011110, 0, 0 }, // fcvtl2_v
+ { 0b0000111000100001011010, 0, 0 }, // fcvtn_v
+ { 0b0100111000100001011010, 0, 0 }, // fcvtn2_v
+ { 0b0010111000100001011010, 1, 1 }, // fcvtxn_v
+ { 0b0110111000100001011010, 1, 0 } // fcvtxn2_v
+};
+
+const SimdFcvtSV simdFcvtSV[12] = {
+ { 0b0000111000100001110010, 0b0000000000000000000000, 0b0001111000100100000000, 1 }, // fcvtas_v
+ { 0b0010111000100001110010, 0b0000000000000000000000, 0b0001111000100101000000, 1 }, // fcvtau_v
+ { 0b0000111000100001101110, 0b0000000000000000000000, 0b0001111000110000000000, 1 }, // fcvtms_v
+ { 0b0010111000100001101110, 0b0000000000000000000000, 0b0001111000110001000000, 1 }, // fcvtmu_v
+ { 0b0000111000100001101010, 0b0000000000000000000000, 0b0001111000100000000000, 1 }, // fcvtns_v
+ { 0b0010111000100001101010, 0b0000000000000000000000, 0b0001111000100001000000, 1 }, // fcvtnu_v
+ { 0b0000111010100001101010, 0b0000000000000000000000, 0b0001111000101000000000, 1 }, // fcvtps_v
+ { 0b0010111010100001101010, 0b0000000000000000000000, 0b0001111000101001000000, 1 }, // fcvtpu_v
+ { 0b0000111010100001101110, 0b0000111100000000111111, 0b0001111000111000000000, 1 }, // fcvtzs_v
+ { 0b0010111010100001101110, 0b0010111100000000111111, 0b0001111000111001000000, 1 }, // fcvtzu_v
+ { 0b0000111000100001110110, 0b0000111100000000111001, 0b0001111000100010000000, 0 }, // scvtf_v
+ { 0b0010111000100001110110, 0b0010111100000000111001, 0b0001111000100011000000, 0 } // ucvtf_v
+};
+
+const SimdFmlal simdFmlal[6] = {
+ { 0b0010111011000000111111, 0b0000111111000000111100, 0, kET_S, kET_H, kET_H }, // bfmlalb_v
+ { 0b0110111011000000111111, 0b0100111111000000111100, 0, kET_S, kET_H, kET_H }, // bfmlalt_v
+ { 0b0000111000100000111011, 0b0000111110000000000000, 1, kET_S, kET_H, kET_H }, // fmlal_v
+ { 0b0010111000100000110011, 0b0010111110000000100000, 1, kET_S, kET_H, kET_H }, // fmlal2_v
+ { 0b0000111010100000111011, 0b0000111110000000010000, 1, kET_S, kET_H, kET_H }, // fmlsl_v
+ { 0b0010111010100000110011, 0b0010111110000000110000, 1, kET_S, kET_H, kET_H } // fmlsl2_v
+};
+
+const SimdLdNStN simdLdNStN[12] = {
+ { 0b0000110101000000000000, 0b0000110001000000001000, 1, 0 }, // ld1_v
+ { 0b0000110101000000110000, 0b0000000000000000000000, 1, 1 }, // ld1r_v
+ { 0b0000110101100000000000, 0b0000110001000000100000, 2, 0 }, // ld2_v
+ { 0b0000110101100000110000, 0b0000000000000000000000, 2, 1 }, // ld2r_v
+ { 0b0000110101000000001000, 0b0000110001000000010000, 3, 0 }, // ld3_v
+ { 0b0000110101000000111000, 0b0000000000000000000000, 3, 1 }, // ld3r_v
+ { 0b0000110101100000001000, 0b0000110001000000000000, 4, 0 }, // ld4_v
+ { 0b0000110101100000111000, 0b0000000000000000000000, 4, 1 }, // ld4r_v
+ { 0b0000110100000000000000, 0b0000110000000000001000, 1, 0 }, // st1_v
+ { 0b0000110100100000000000, 0b0000110000000000100000, 2, 0 }, // st2_v
+ { 0b0000110100000000001000, 0b0000110000000000010000, 3, 0 }, // st3_v
+ { 0b0000110100100000001000, 0b0000110000000000000000, 4, 0 } // st4_v
+};
+
+const SimdLdSt simdLdSt[2] = {
+ { 0b0011110101, 0b00111100010, 0b00111100011, 0b00011100, Inst::kIdLdur_v }, // ldr_v
+ { 0b0011110100, 0b00111100000, 0b00111100001, 0b00000000, Inst::kIdStur_v } // str_v
+};
+
+const SimdLdpStp simdLdpStp[4] = {
+ { 0b0010110001, 0b0000000000 }, // ldnp_v
+ { 0b0010110101, 0b0010110011 }, // ldp_v
+ { 0b0010110000, 0b0000000000 }, // stnp_v
+ { 0b0010110100, 0b0010110010 } // stp_v
+};
+
+const SimdLdurStur simdLdurStur[2] = {
+ { 0b0011110001000000000000 }, // ldur_v
+ { 0b0011110000000000000000 } // stur_v
+};
+
+const SimdMoviMvni simdMoviMvni[2] = {
+ { 0b0000111100000000000001, 0 }, // movi_v
+ { 0b0000111100000000000001, 1 } // mvni_v
+};
+
+const SimdShift simdShift[40] = {
+ { 0b0000000000000000000000, 0b0000111100000000100011, 1, kVO_V_B8H4S2 }, // rshrn_v
+ { 0b0000000000000000000000, 0b0100111100000000100011, 1, kVO_V_B16H8S4 }, // rshrn2_v
+ { 0b0000000000000000000000, 0b0000111100000000010101, 0, kVO_V_Any }, // shl_v
+ { 0b0000000000000000000000, 0b0000111100000000100001, 1, kVO_V_B8H4S2 }, // shrn_v
+ { 0b0000000000000000000000, 0b0100111100000000100001, 1, kVO_V_B16H8S4 }, // shrn2_v
+ { 0b0000000000000000000000, 0b0010111100000000010101, 0, kVO_V_Any }, // sli_v
+ { 0b0000111000100000010111, 0b0000000000000000000000, 1, kVO_SV_Any }, // sqrshl_v
+ { 0b0000000000000000000000, 0b0000111100000000100111, 1, kVO_SV_B8H4S2 }, // sqrshrn_v
+ { 0b0000000000000000000000, 0b0100111100000000100111, 1, kVO_V_B16H8S4 }, // sqrshrn2_v
+ { 0b0000000000000000000000, 0b0010111100000000100011, 1, kVO_SV_B8H4S2 }, // sqrshrun_v
+ { 0b0000000000000000000000, 0b0110111100000000100011, 1, kVO_V_B16H8S4 }, // sqrshrun2_v
+ { 0b0000111000100000010011, 0b0000111100000000011101, 0, kVO_SV_Any }, // sqshl_v
+ { 0b0000000000000000000000, 0b0010111100000000011001, 0, kVO_SV_Any }, // sqshlu_v
+ { 0b0000000000000000000000, 0b0000111100000000100101, 1, kVO_SV_B8H4S2 }, // sqshrn_v
+ { 0b0000000000000000000000, 0b0100111100000000100101, 1, kVO_V_B16H8S4 }, // sqshrn2_v
+ { 0b0000000000000000000000, 0b0010111100000000100001, 1, kVO_SV_B8H4S2 }, // sqshrun_v
+ { 0b0000000000000000000000, 0b0110111100000000100001, 1, kVO_V_B16H8S4 }, // sqshrun2_v
+ { 0b0000000000000000000000, 0b0010111100000000010001, 1, kVO_V_Any }, // sri_v
+ { 0b0000111000100000010101, 0b0000000000000000000000, 0, kVO_V_Any }, // srshl_v
+ { 0b0000000000000000000000, 0b0000111100000000001001, 1, kVO_V_Any }, // srshr_v
+ { 0b0000000000000000000000, 0b0000111100000000001101, 1, kVO_V_Any }, // srsra_v
+ { 0b0000111000100000010001, 0b0000000000000000000000, 0, kVO_V_Any }, // sshl_v
+ { 0b0000000000000000000000, 0b0000111100000000101001, 0, kVO_V_B8H4S2 }, // sshll_v
+ { 0b0000000000000000000000, 0b0100111100000000101001, 0, kVO_V_B16H8S4 }, // sshll2_v
+ { 0b0000000000000000000000, 0b0000111100000000000001, 1, kVO_V_Any }, // sshr_v
+ { 0b0000000000000000000000, 0b0000111100000000000101, 1, kVO_V_Any }, // ssra_v
+ { 0b0010111000100000010111, 0b0000000000000000000000, 0, kVO_SV_Any }, // uqrshl_v
+ { 0b0000000000000000000000, 0b0010111100000000100111, 1, kVO_SV_B8H4S2 }, // uqrshrn_v
+ { 0b0000000000000000000000, 0b0110111100000000100111, 1, kVO_V_B16H8S4 }, // uqrshrn2_v
+ { 0b0010111000100000010011, 0b0010111100000000011101, 0, kVO_SV_Any }, // uqshl_v
+ { 0b0000000000000000000000, 0b0010111100000000100101, 1, kVO_SV_B8H4S2 }, // uqshrn_v
+ { 0b0000000000000000000000, 0b0110111100000000100101, 1, kVO_V_B16H8S4 }, // uqshrn2_v
+ { 0b0010111000100000010101, 0b0000000000000000000000, 0, kVO_V_Any }, // urshl_v
+ { 0b0000000000000000000000, 0b0010111100000000001001, 1, kVO_V_Any }, // urshr_v
+ { 0b0000000000000000000000, 0b0010111100000000001101, 1, kVO_V_Any }, // ursra_v
+ { 0b0010111000100000010001, 0b0000000000000000000000, 0, kVO_V_Any }, // ushl_v
+ { 0b0000000000000000000000, 0b0010111100000000101001, 0, kVO_V_B8H4S2 }, // ushll_v
+ { 0b0000000000000000000000, 0b0110111100000000101001, 0, kVO_V_B16H8S4 }, // ushll2_v
+ { 0b0000000000000000000000, 0b0010111100000000000001, 1, kVO_V_Any }, // ushr_v
+ { 0b0000000000000000000000, 0b0010111100000000000101, 1, kVO_V_Any } // usra_v
+};
+
+const SimdShiftES simdShiftES[2] = {
+ { 0b0010111000100001001110, kVO_V_B8H4S2 }, // shll_v
+ { 0b0110111000100001001110, kVO_V_B16H8S4 } // shll2_v
+};
+
+const SimdSm3tt simdSm3tt[4] = {
+ { 0b1100111001000000100000 }, // sm3tt1a_v
+ { 0b1100111001000000100001 }, // sm3tt1b_v
+ { 0b1100111001000000100010 }, // sm3tt2a_v
+ { 0b1100111001000000100011 } // sm3tt2b_v
+};
+
+const SimdSmovUmov simdSmovUmov[2] = {
+ { 0b0000111000000000001011, kVO_V_BHS, 1 }, // smov_v
+ { 0b0000111000000000001111, kVO_V_Any, 0 } // umov_v
+};
+
+const SimdSxtlUxtl simdSxtlUxtl[4] = {
+ { 0b0000111100000000101001, kVO_V_B8H4S2 }, // sxtl_v
+ { 0b0100111100000000101001, kVO_V_B16H8S4 }, // sxtl2_v
+ { 0b0010111100000000101001, kVO_V_B8H4S2 }, // uxtl_v
+ { 0b0110111100000000101001, kVO_V_B16H8S4 } // uxtl2_v
+};
+
+const SimdTblTbx simdTblTbx[2] = {
+ { 0b0000111000000000000000 }, // tbl_v
+ { 0b0000111000000000000100 } // tbx_v
+};
+// ----------------------------------------------------------------------------
+// ${EncodingData:End}
+
+} // {EncodingData}
+} // {InstDB}
+
+/*
+// ${CommonData:Begin}
+// ------------------- Automatically generated, do not edit -------------------
+const InstDB::CommonInfo InstDB::commonData[] = {
+ { 0} // #0 [ref=440x]
+};
+// ----------------------------------------------------------------------------
+// ${CommonData:End}
+*/
+
+// ArmUtil - Id <-> Name
+// =====================
+
+#ifndef ASMJIT_DISABLE_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] = {
+ { Inst::kIdAdc , Inst::kIdAnd_v + 1 },
+ { Inst::kIdB , Inst::kIdBsl_v + 1 },
+ { Inst::kIdCas , Inst::kIdCnt_v + 1 },
+ { Inst::kIdDc , Inst::kIdDup_v + 1 },
+ { Inst::kIdEon , Inst::kIdExt_v + 1 },
+ { Inst::kIdFabd_v , Inst::kIdFsub_v + 1 },
+ { Inst::kIdGmi , Inst::kIdGmi + 1 },
+ { Inst::kIdHint , Inst::kIdHvc + 1 },
+ { Inst::kIdIc , Inst::kIdIns_v + 1 },
+ { Inst::kIdNone , Inst::kIdNone + 1 },
+ { Inst::kIdNone , Inst::kIdNone + 1 },
+ { Inst::kIdLdadd , Inst::kIdLdur_v + 1 },
+ { Inst::kIdMadd , Inst::kIdMvni_v + 1 },
+ { Inst::kIdNeg , Inst::kIdNot_v + 1 },
+ { Inst::kIdOrn , Inst::kIdOrr_v + 1 },
+ { Inst::kIdPacda , Inst::kIdPmull2_v + 1 },
+ { Inst::kIdNone , Inst::kIdNone + 1 },
+ { Inst::kIdRbit , Inst::kIdRsubhn2_v + 1 },
+ { Inst::kIdSbc , Inst::kIdSxtl2_v + 1 },
+ { Inst::kIdTlbi , Inst::kIdTrn2_v + 1 },
+ { Inst::kIdUbfiz , Inst::kIdUzp2_v + 1 },
+ { Inst::kIdNone , Inst::kIdNone + 1 },
+ { Inst::kIdWfe , Inst::kIdWfi + 1 },
+ { Inst::kIdXaflag , Inst::kIdXtn2_v + 1 },
+ { Inst::kIdYield , Inst::kIdYield + 1 },
+ { Inst::kIdZip1_v , Inst::kIdZip2_v + 1 }
+};
+// ----------------------------------------------------------------------------
+// ${NameData:End}
+#endif
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // !ASMJIT_NO_AARCH64
diff --git a/src/asmjit/arm/a64instdb.h b/src/asmjit/arm/a64instdb.h
new file mode 100644
index 0000000..0575d1a
--- /dev/null
+++ b/src/asmjit/arm/a64instdb.h
@@ -0,0 +1,74 @@
+// 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_ARM_A64INSTDB_H_INCLUDED
+#define ASMJIT_ARM_A64INSTDB_H_INCLUDED
+
+#include "../arm/a64globals.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+
+//! \addtogroup asmjit_a64
+//! \{
+
+//! Instruction database (AArch64).
+namespace InstDB {
+
+//! Instruction flags.
+enum InstFlags : uint32_t {
+ //! The instruction provides conditional execution.
+ kInstFlagCond = 0x00000001u,
+ //! SIMD instruction that processes elements in pairs.
+ kInstFlagPair = 0x00000002u,
+ //! SIMD instruction that does widening (Long).
+ kInstFlagLong = 0x00000004u,
+ //! SIMD instruction that does narrowing (Narrow).
+ kInstFlagNarrow = 0x00000008u,
+ //! 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.
+ kInstFlagConsecutive = 0x00000080u
+};
+
+//! Instruction information (AArch64).
+struct InstInfo {
+ //! Instruction encoding type.
+ 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;
+
+ uint16_t _rwInfoIndex;
+ uint16_t _flags;
+
+ //! \name Accessors
+ //! \{
+
+ inline uint32_t rwInfoIndex() const noexcept { return _rwInfoIndex; }
+ inline uint32_t flags() const noexcept { return _flags; }
+
+ inline bool hasFlag(uint32_t flag) const { return (_flags & flag) != 0; }
+
+ //! \}
+};
+
+ASMJIT_VARAPI const InstInfo _instInfoTable[];
+
+static inline const InstInfo& infoById(InstId instId) noexcept {
+ instId &= uint32_t(InstIdParts::kRealId);
+ ASMJIT_ASSERT(Inst::isDefinedId(instId));
+ return _instInfoTable[instId];
+}
+
+} // {InstDB}
+
+//! \}
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // ASMJIT_ARM_A64INSTDB_H_INCLUDED
diff --git a/src/asmjit/arm/a64instdb_p.h b/src/asmjit/arm/a64instdb_p.h
new file mode 100644
index 0000000..eb4f3f8
--- /dev/null
+++ b/src/asmjit/arm/a64instdb_p.h
@@ -0,0 +1,876 @@
+// 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_ARM_A64INSTDB_H_P_INCLUDED
+#define ASMJIT_ARM_A64INSTDB_H_P_INCLUDED
+
+#include "../core/codeholder.h"
+#include "../arm/a64instdb.h"
+#include "../arm/a64operand.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+
+//! \cond INTERNAL
+//! \addtogroup asmjit_a64
+//! \{
+
+namespace InstDB {
+
+// a64::InstDB - Constants Used by Instructions
+// ============================================
+
+// GP register types supported by base instructions.
+static constexpr uint32_t kW = 0x1;
+static constexpr uint32_t kX = 0x2;
+static constexpr uint32_t kWX = 0x3;
+
+// GP high register IDs supported by the instruction.
+static constexpr uint32_t kZR = Gp::kIdZr;
+static constexpr uint32_t kSP = Gp::kIdSp;
+
+// a64::InstDB - RWInfo
+// ====================
+
+enum RWInfoType : uint32_t {
+ kRWI_R,
+ kRWI_RW,
+ kRWI_RX,
+ kRWI_RRW,
+ kRWI_RWX,
+ kRWI_W,
+ kRWI_WRW,
+ kRWI_WRX,
+ kRWI_WRRW,
+ kRWI_WRRX,
+ kRWI_WW,
+ kRWI_X,
+ kRWI_XRX,
+ kRWI_XXRRX,
+
+ kRWI_LDn,
+ kRWI_STn,
+
+ kRWI_SpecialStart = kRWI_LDn
+};
+
+// 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
+};
+
+// a64::InstDB - GpType
+// ====================
+
+enum GpType : uint8_t {
+ kGp_W,
+ kGp_X,
+ kGp_X_SP
+};
+
+// a64::InstDB - OPSig
+// ===================
+
+enum kOpSignature : uint32_t {
+ kOp_GpW = GpW::kSignature,
+ kOp_GpX = GpX::kSignature,
+
+ kOp_B = VecB::kSignature,
+ kOp_H = VecH::kSignature,
+ kOp_S = VecS::kSignature,
+ kOp_D = VecD::kSignature,
+ kOp_Q = VecV::kSignature,
+
+ kOp_V8B = VecD::kSignature | Vec::kSignatureElementB,
+ kOp_V4H = VecD::kSignature | Vec::kSignatureElementH,
+ kOp_V2S = VecD::kSignature | Vec::kSignatureElementS,
+
+ kOp_V16B = VecV::kSignature | Vec::kSignatureElementB,
+ kOp_V8H = VecV::kSignature | Vec::kSignatureElementH,
+ kOp_V4S = VecV::kSignature | Vec::kSignatureElementS,
+ kOp_V2D = VecV::kSignature | Vec::kSignatureElementD
+};
+
+// a64::InstDB - HFConv
+// ====================
+
+enum kHFConv : uint32_t {
+ //! FP16 version of the instruction is not available.
+ kHF_N,
+
+ //! Doesn't do any change to the opcode.
+ kHF_0,
+
+ kHF_A,
+ kHF_B,
+ kHF_C,
+ kHF_D,
+
+ kHF_Count
+};
+
+// a64::InstDB - VOType
+// ====================
+
+//! Vector operand type combinations used by FP&SIMD instructions.
+enum VOType : uint32_t {
+ kVO_V_B,
+ kVO_V_BH,
+ kVO_V_BH_4S,
+ kVO_V_BHS,
+ kVO_V_BHS_D2,
+ kVO_V_HS,
+ kVO_V_S,
+
+ kVO_V_B8H4,
+ kVO_V_B8H4S2,
+ kVO_V_B8D1,
+ kVO_V_H4S2,
+
+ kVO_V_B16,
+ kVO_V_B16H8,
+ kVO_V_B16H8S4,
+ kVO_V_B16D2,
+ kVO_V_H8S4,
+ kVO_V_S4,
+ kVO_V_D2,
+
+ kVO_SV_BHS,
+ kVO_SV_B8H4S2,
+ kVO_SV_HS,
+ kVO_V_Any,
+ kVO_SV_Any,
+
+ kVO_Count
+};
+
+// a64::InstDB - EncodingId
+// ========================
+
+// ${EncodingId:Begin}
+// ------------------- Automatically generated, do not edit -------------------
+enum EncodingId : uint32_t {
+ kEncodingNone = 0,
+ kEncodingBaseAddSub,
+ kEncodingBaseAdr,
+ kEncodingBaseAtDcIcTlbi,
+ kEncodingBaseAtomicCasp,
+ kEncodingBaseAtomicOp,
+ kEncodingBaseAtomicSt,
+ kEncodingBaseBfc,
+ kEncodingBaseBfi,
+ kEncodingBaseBfm,
+ kEncodingBaseBfx,
+ kEncodingBaseBranchCmp,
+ kEncodingBaseBranchReg,
+ kEncodingBaseBranchRel,
+ kEncodingBaseBranchTst,
+ kEncodingBaseCCmp,
+ kEncodingBaseCInc,
+ kEncodingBaseCSel,
+ kEncodingBaseCSet,
+ kEncodingBaseCmpCmn,
+ kEncodingBaseExtend,
+ kEncodingBaseExtract,
+ kEncodingBaseLdSt,
+ kEncodingBaseLdpStp,
+ kEncodingBaseLdxp,
+ kEncodingBaseLogical,
+ kEncodingBaseMov,
+ kEncodingBaseMovKNZ,
+ kEncodingBaseMrs,
+ kEncodingBaseMsr,
+ kEncodingBaseMvnNeg,
+ kEncodingBaseOp,
+ kEncodingBaseOpImm,
+ kEncodingBaseR,
+ kEncodingBaseRM_NoImm,
+ kEncodingBaseRM_SImm10,
+ kEncodingBaseRM_SImm9,
+ kEncodingBaseRR,
+ kEncodingBaseRRII,
+ kEncodingBaseRRR,
+ kEncodingBaseRRRR,
+ kEncodingBaseRev,
+ kEncodingBaseShift,
+ kEncodingBaseStx,
+ kEncodingBaseStxp,
+ kEncodingBaseSys,
+ kEncodingBaseTst,
+ kEncodingFSimdPair,
+ kEncodingFSimdSV,
+ kEncodingFSimdVV,
+ kEncodingFSimdVVV,
+ kEncodingFSimdVVVV,
+ kEncodingFSimdVVVe,
+ kEncodingISimdPair,
+ kEncodingISimdSV,
+ kEncodingISimdVV,
+ kEncodingISimdVVV,
+ kEncodingISimdVVVI,
+ kEncodingISimdVVVV,
+ kEncodingISimdVVVVx,
+ kEncodingISimdVVVe,
+ kEncodingISimdVVVx,
+ kEncodingISimdVVx,
+ kEncodingISimdWWV,
+ kEncodingSimdBicOrr,
+ kEncodingSimdCmp,
+ kEncodingSimdDot,
+ kEncodingSimdDup,
+ kEncodingSimdFcadd,
+ kEncodingSimdFccmpFccmpe,
+ kEncodingSimdFcm,
+ kEncodingSimdFcmla,
+ kEncodingSimdFcmpFcmpe,
+ kEncodingSimdFcsel,
+ kEncodingSimdFcvt,
+ kEncodingSimdFcvtLN,
+ kEncodingSimdFcvtSV,
+ kEncodingSimdFmlal,
+ kEncodingSimdFmov,
+ kEncodingSimdIns,
+ kEncodingSimdLdNStN,
+ kEncodingSimdLdSt,
+ kEncodingSimdLdpStp,
+ kEncodingSimdLdurStur,
+ kEncodingSimdMov,
+ kEncodingSimdMoviMvni,
+ kEncodingSimdShift,
+ kEncodingSimdShiftES,
+ kEncodingSimdSm3tt,
+ kEncodingSimdSmovUmov,
+ kEncodingSimdSxtlUxtl,
+ kEncodingSimdTblTbx
+};
+// ----------------------------------------------------------------------------
+// ${EncodingId:End}
+
+// a64::InstDB::EncodingData
+// =========================
+
+namespace EncodingData {
+
+#define M_OPCODE(field, bits) \
+ uint32_t _##field : bits; \
+ inline constexpr uint32_t field() const noexcept { return uint32_t(_##field) << (32 - bits); }
+
+struct BaseOp {
+ uint32_t opcode;
+};
+
+struct BaseOpImm {
+ uint32_t opcode;
+ uint16_t immBits;
+ uint16_t immOffset;
+};
+
+struct BaseR {
+ uint32_t opcode;
+ uint32_t rType : 8;
+ uint32_t rHiId : 8;
+ uint32_t rShift : 8;
+};
+
+struct BaseRR {
+ uint32_t opcode;
+ uint32_t aType : 2;
+ uint32_t aHiId : 6;
+ uint32_t aShift : 5;
+ uint32_t bType : 2;
+ uint32_t bHiId : 6;
+ uint32_t bShift : 5;
+ uint32_t uniform : 1;
+};
+
+struct BaseRRR {
+ M_OPCODE(opcode, 22)
+ uint32_t aType : 2;
+ uint32_t aHiId : 6;
+ uint32_t bType : 2;
+ uint32_t bHiId : 6;
+ uint32_t cType : 2;
+ uint32_t cHiId : 6;
+ uint32_t uniform : 1;
+};
+
+struct BaseRRRR {
+ M_OPCODE(opcode, 22)
+ uint32_t aType : 2;
+ uint32_t aHiId : 6;
+ uint32_t bType : 2;
+ uint32_t bHiId : 6;
+ uint32_t cType : 2;
+ uint32_t cHiId : 6;
+ uint32_t dType : 2;
+ uint32_t dHiId : 6;
+ uint32_t uniform : 1;
+};
+
+struct BaseRRII {
+ M_OPCODE(opcode, 22)
+ uint32_t aType : 2;
+ uint32_t aHiId : 6;
+ uint32_t bType : 2;
+ uint32_t bHiId : 6;
+ uint32_t aImmSize : 6;
+ uint32_t aImmDiscardLsb : 5;
+ uint32_t aImmOffset : 5;
+ uint32_t bImmSize : 6;
+ uint32_t bImmDiscardLsb : 5;
+ uint32_t bImmOffset : 5;
+};
+
+struct BaseAtDcIcTlbi {
+ uint32_t immVerifyMask : 14;
+ uint32_t immVerifyData : 14;
+ uint32_t mandatoryReg : 1;
+};
+
+struct BaseAdcSbc {
+ uint32_t opcode;
+};
+
+struct BaseAddSub {
+ uint32_t shiftedOp : 10; // sf|.......|Sh|.|Rm| Imm:6 |Rn|Rd|
+ uint32_t extendedOp : 10; // sf|.......|..|.|Rm|Opt|Imm3|Rn|Rd|
+ uint32_t immediateOp: 10; // sf|.......|Sh| Imm:12 |Rn|Rd|
+};
+
+struct BaseAdr {
+ M_OPCODE(opcode, 22)
+ OffsetType offsetType : 8;
+};
+
+struct BaseBfm {
+ uint32_t opcode; // sf|........|N|ImmR:6|ImmS:6|Rn|Rd|
+};
+
+struct BaseCmpCmn {
+ uint32_t shiftedOp : 10; // sf|.......|Sh|.|Rm| Imm:6 |Rn|11111|
+ uint32_t extendedOp : 10; // sf|.......|..|.|Rm|Opt|Imm3|Rn|11111|
+ uint32_t immediateOp: 10; // sf|.......|Sh| Imm:12 |Rn|11111|
+};
+
+struct BaseExtend {
+ M_OPCODE(opcode, 22) // sf|........|N|......|......|Rn|Rd|
+ uint32_t rType : 2;
+ uint32_t u : 1;
+};
+
+struct BaseLogical {
+ uint32_t shiftedOp : 10; // sf|.......|Sh|.|Rm| Imm:6 |Rn|Rd|
+ uint32_t immediateOp: 10; // sf|........|N|ImmR:6|ImmS:6|Rn|Rd|
+ uint32_t negateImm : 1 ; // True if this is an operation that must negate IMM.
+};
+
+struct BaseMvnNeg {
+ uint32_t opcode;
+};
+
+struct BaseShift {
+ M_OPCODE(registerOp, 22)
+ M_OPCODE(immediateOp, 22)
+ uint32_t ror : 2;
+};
+
+struct BaseTst {
+ uint32_t shiftedOp : 10; // sf|.......|Sh|.|Rm| Imm:6 |Rn|11111|
+ uint32_t immediateOp: 10; // sf|........|N|ImmR:6|ImmS:6|Rn|11111|
+};
+
+struct BaseRM_NoImm {
+ M_OPCODE(opcode, 22)
+ uint32_t rType : 2;
+ uint32_t rHiId : 6;
+ uint32_t xOffset : 5;
+};
+
+struct BaseRM_SImm9 {
+ M_OPCODE(offsetOp, 22)
+ M_OPCODE(prePostOp, 22)
+ uint32_t rType : 2;
+ uint32_t rHiId : 6;
+ uint32_t xOffset : 5;
+ uint32_t immShift : 4;
+};
+
+struct BaseRM_SImm10 {
+ M_OPCODE(opcode, 22)
+ uint32_t rType : 2;
+ uint32_t rHiId : 6;
+ uint32_t xOffset : 5;
+ uint32_t immShift : 4;
+};
+
+struct BaseLdSt {
+ uint32_t uOffsetOp : 10;
+ uint32_t prePostOp : 11;
+ uint32_t registerOp : 11;
+ uint32_t literalOp : 8;
+ uint32_t rType : 2;
+ uint32_t xOffset : 5;
+ uint32_t uOffsetShift : 3;
+ uint32_t uAltInstId : 14;
+};
+
+struct BaseLdpStp {
+ uint32_t offsetOp : 10;
+ uint32_t prePostOp : 10;
+ uint32_t rType : 2;
+ uint32_t xOffset : 5;
+ uint32_t offsetShift : 3;
+};
+
+struct BaseStx {
+ M_OPCODE(opcode, 22)
+ uint32_t rType : 2;
+ uint32_t xOffset : 5;
+};
+
+struct BaseLdxp {
+ M_OPCODE(opcode, 22)
+ uint32_t rType : 2;
+ uint32_t xOffset : 5;
+};
+
+struct BaseStxp {
+ M_OPCODE(opcode, 22)
+ uint32_t rType : 2;
+ uint32_t xOffset : 5;
+};
+
+struct BaseAtomicOp {
+ M_OPCODE(opcode, 22)
+ uint32_t rType : 2;
+ uint32_t xOffset : 5;
+ uint32_t zr : 1;
+};
+
+struct BaseAtomicSt {
+ M_OPCODE(opcode, 22)
+ uint32_t rType : 2;
+ uint32_t xOffset : 5;
+};
+
+struct BaseAtomicCasp {
+ M_OPCODE(opcode, 22)
+ uint32_t rType : 2;
+ uint32_t xOffset : 5;
+};
+
+typedef BaseOp BaseBranchReg;
+typedef BaseOp BaseBranchRel;
+typedef BaseOp BaseBranchCmp;
+typedef BaseOp BaseBranchTst;
+typedef BaseOp BaseExtract;
+typedef BaseOp BaseBfc;
+typedef BaseOp BaseBfi;
+typedef BaseOp BaseBfx;
+typedef BaseOp BaseCCmp;
+typedef BaseOp BaseCInc;
+typedef BaseOp BaseCSet;
+typedef BaseOp BaseCSel;
+typedef BaseOp BaseMovKNZ;
+typedef BaseOp BaseMull;
+
+struct FSimdGeneric {
+ uint32_t _scalarOp : 28;
+ uint32_t _scalarHf : 4;
+ uint32_t _vectorOp : 28;
+ uint32_t _vectorHf : 4;
+
+ constexpr uint32_t scalarOp() const noexcept { return uint32_t(_scalarOp) << 10; }
+ constexpr uint32_t vectorOp() const noexcept { return uint32_t(_vectorOp) << 10; }
+ constexpr uint32_t scalarHf() const noexcept { return uint32_t(_scalarHf); }
+ constexpr uint32_t vectorHf() const noexcept { return uint32_t(_vectorHf); }
+};
+
+typedef FSimdGeneric FSimdVV;
+typedef FSimdGeneric FSimdVVV;
+typedef FSimdGeneric FSimdVVVV;
+
+struct FSimdSV {
+ uint32_t opcode;
+};
+
+struct FSimdVVVe {
+ uint32_t _scalarOp : 28;
+ uint32_t _scalarHf : 4;
+ uint32_t _vectorOp;
+ uint32_t _elementOp;
+
+ constexpr uint32_t scalarOp() const noexcept { return uint32_t(_scalarOp) << 10; }
+ constexpr uint32_t scalarHf() const noexcept { return uint32_t(_scalarHf); };
+ constexpr uint32_t vectorOp() const noexcept { return uint32_t(_vectorOp) << 10; }
+ constexpr uint32_t vectorHf() const noexcept { return kHF_C; }
+ constexpr uint32_t elementScalarOp() const noexcept { return (uint32_t(_elementOp) << 10) | (0x5u << 28); }
+ constexpr uint32_t elementVectorOp() const noexcept { return (uint32_t(_elementOp) << 10); }
+};
+
+struct SimdFcadd {
+ uint32_t _opcode;
+
+ constexpr uint32_t opcode() const noexcept { return _opcode << 10; }
+};
+
+struct SimdFcmla {
+ uint32_t _regularOp;
+ uint32_t _elementOp;
+
+ constexpr uint32_t regularOp() const noexcept { return uint32_t(_regularOp) << 10; }
+ constexpr uint32_t elementOp() const noexcept { return (uint32_t(_elementOp) << 10); }
+};
+
+struct SimdFccmpFccmpe {
+ uint32_t _opcode;
+ constexpr uint32_t opcode() const noexcept { return _opcode; }
+};
+
+struct SimdFcm {
+ uint32_t _registerOp : 28;
+ uint32_t _registerHf : 4;
+
+ uint32_t _zeroOp : 28;
+
+ constexpr bool hasRegisterOp() const noexcept { return _registerOp != 0; }
+ constexpr bool hasZeroOp() const noexcept { return _zeroOp != 0; }
+
+ constexpr uint32_t registerScalarOp() const noexcept { return (uint32_t(_registerOp) << 10) | (0x5u << 28); }
+ constexpr uint32_t registerVectorOp() const noexcept { return uint32_t(_registerOp) << 10; }
+ constexpr uint32_t registerScalarHf() const noexcept { return uint32_t(_registerHf); }
+ constexpr uint32_t registerVectorHf() const noexcept { return uint32_t(_registerHf); }
+
+ constexpr uint32_t zeroScalarOp() const noexcept { return (uint32_t(_zeroOp) << 10) | (0x5u << 28); }
+ constexpr uint32_t zeroVectorOp() const noexcept { return (uint32_t(_zeroOp) << 10); }
+};
+
+struct SimdFcmpFcmpe {
+ uint32_t _opcode;
+ constexpr uint32_t opcode() const noexcept { return _opcode; }
+};
+
+struct SimdFcvtLN {
+ uint32_t _opcode : 22;
+ uint32_t _isCvtxn : 1;
+ uint32_t _hasScalar : 1;
+
+ constexpr uint32_t scalarOp() const noexcept { return (uint32_t(_opcode) << 10) | (0x5u << 28); }
+ constexpr uint32_t vectorOp() const noexcept { return (uint32_t(_opcode) << 10); }
+
+ constexpr uint32_t isCvtxn() const noexcept { return _isCvtxn; }
+ constexpr uint32_t hasScalar() const noexcept { return _hasScalar; }
+};
+
+struct SimdFcvtSV {
+ uint32_t _vectorIntOp;
+ uint32_t _vectorFpOp;
+ uint32_t _generalOp : 31;
+ uint32_t _isFloatToInt : 1;
+
+ constexpr uint32_t scalarIntOp() const noexcept { return (uint32_t(_vectorIntOp) << 10) | (0x5u << 28); }
+ constexpr uint32_t vectorIntOp() const noexcept { return uint32_t(_vectorIntOp) << 10; }
+ constexpr uint32_t scalarFpOp() const noexcept { return (uint32_t(_vectorFpOp) << 10) | (0x5u << 28); }
+ constexpr uint32_t vectorFpOp() const noexcept { return uint32_t(_vectorFpOp) << 10; }
+ constexpr uint32_t generalOp() const noexcept { return (uint32_t(_generalOp) << 10); }
+
+ constexpr uint32_t isFloatToInt() const noexcept { return _isFloatToInt; }
+ constexpr uint32_t isFixedPoint() const noexcept { return _vectorFpOp != 0; }
+};
+
+struct SimdFmlal {
+ uint32_t _vectorOp;
+ uint32_t _elementOp;
+ uint8_t _optionalQ;
+ uint8_t tA;
+ uint8_t tB;
+ uint8_t tElement;
+
+ constexpr uint32_t vectorOp() const noexcept { return uint32_t(_vectorOp) << 10; }
+ constexpr uint32_t elementOp() const noexcept { return uint32_t(_elementOp) << 10; }
+ constexpr uint32_t optionalQ() const noexcept { return _optionalQ; }
+};
+
+struct FSimdPair {
+ uint32_t _scalarOp;
+ uint32_t _vectorOp;
+
+ constexpr uint32_t scalarOp() const noexcept { return uint32_t(_scalarOp) << 10; }
+ constexpr uint32_t vectorOp() const noexcept { return uint32_t(_vectorOp) << 10; }
+};
+
+struct ISimdVV {
+ M_OPCODE(opcode, 22)
+ uint32_t vecOpType : 6;
+};
+
+struct ISimdVVx {
+ M_OPCODE(opcode, 22)
+ uint32_t op0Signature;
+ uint32_t op1Signature;
+};
+
+struct ISimdSV {
+ M_OPCODE(opcode, 22)
+ uint32_t vecOpType : 6;
+};
+
+struct ISimdVVV {
+ M_OPCODE(opcode, 22)
+ uint32_t vecOpType : 6;
+};
+
+struct ISimdVVVx {
+ M_OPCODE(opcode, 22)
+ uint32_t op0Signature;
+ uint32_t op1Signature;
+ uint32_t op2Signature;
+};
+
+struct ISimdWWV {
+ M_OPCODE(opcode, 22)
+ uint32_t vecOpType : 6;
+};
+
+struct ISimdVVVe {
+ uint32_t regularOp : 26; // 22 bits used.
+ uint32_t regularVecType : 6;
+ uint32_t elementOp : 26; // 22 bits used.
+ uint32_t elementVecType : 6;
+};
+
+struct ISimdVVVI {
+ M_OPCODE(opcode, 22)
+ uint32_t vecOpType : 6;
+ uint32_t immSize : 4;
+ uint32_t immShift : 4;
+ uint32_t imm64HasOneBitLess : 1;
+};
+
+struct ISimdVVVV {
+ uint32_t opcode : 22;
+ uint32_t vecOpType : 6;
+};
+
+struct ISimdVVVVx {
+ uint32_t opcode;
+ uint32_t op0Signature;
+ uint32_t op1Signature;
+ uint32_t op2Signature;
+ uint32_t op3Signature;
+};
+
+struct SimdBicOrr {
+ uint32_t registerOp; // 22 bits used.
+ uint32_t immediateOp; // 22 bits used.
+};
+
+struct SimdCmp {
+ uint32_t regOp;
+ uint32_t zeroOp : 22;
+ uint32_t vecOpType : 6;
+};
+
+struct SimdDot {
+ uint32_t vectorOp; // 22 bits used.
+ uint32_t elementOp; // 22 bits used.
+ uint8_t tA; // Element-type of the first operand.
+ uint8_t tB; // Element-type of the second and third operands.
+ uint8_t tElement; // Element-type of the element index[] operand.
+};
+
+struct SimdMoviMvni {
+ uint32_t opcode : 31;
+ uint32_t inverted : 1;
+};
+
+struct SimdLdSt {
+ uint32_t uOffsetOp : 10;
+ uint32_t prePostOp : 11;
+ uint32_t registerOp : 11;
+ uint32_t literalOp : 8;
+ uint32_t uAltInstId : 16;
+};
+
+struct SimdLdNStN {
+ uint32_t singleOp;
+ uint32_t multipleOp : 22;
+ uint32_t n : 3;
+ uint32_t replicate : 1;
+};
+
+struct SimdLdpStp {
+ uint32_t offsetOp : 10;
+ uint32_t prePostOp : 10;
+};
+
+struct SimdLdurStur {
+ uint32_t opcode;
+};
+
+struct ISimdPair {
+ uint32_t opcode2; // 22 bits used.
+ uint32_t opcode3 : 26; // 22 bits used.
+ uint32_t opType3 : 6;
+};
+
+struct SimdShift {
+ uint32_t registerOp; // 22 bits used.
+ uint32_t immediateOp : 22; // 22 bits used.
+ uint32_t invertedImm : 1;
+ uint32_t vecOpType : 6;
+};
+
+struct SimdShiftES {
+ uint32_t opcode : 22;
+ uint32_t vecOpType : 6;
+};
+
+struct SimdSm3tt {
+ uint32_t opcode;
+};
+
+struct SimdSmovUmov {
+ uint32_t opcode : 22;
+ uint32_t vecOpType : 6;
+ uint32_t isSigned : 1;
+};
+
+struct SimdSxtlUxtl {
+ uint32_t opcode : 22;
+ uint32_t vecOpType : 6;
+};
+
+struct SimdTblTbx {
+ uint32_t opcode;
+};
+
+#undef M_OPCODE
+
+// ${EncodingDataForward:Begin}
+// ------------------- Automatically generated, do not edit -------------------
+extern const BaseAddSub baseAddSub[4];
+extern const BaseAdr baseAdr[2];
+extern const BaseAtDcIcTlbi baseAtDcIcTlbi[4];
+extern const BaseAtomicCasp baseAtomicCasp[4];
+extern const BaseAtomicOp baseAtomicOp[123];
+extern const BaseAtomicSt baseAtomicSt[48];
+extern const BaseBfc baseBfc[1];
+extern const BaseBfi baseBfi[3];
+extern const BaseBfm baseBfm[3];
+extern const BaseBfx baseBfx[3];
+extern const BaseBranchCmp baseBranchCmp[2];
+extern const BaseBranchReg baseBranchReg[3];
+extern const BaseBranchRel baseBranchRel[2];
+extern const BaseBranchTst baseBranchTst[2];
+extern const BaseCCmp baseCCmp[2];
+extern const BaseCInc baseCInc[3];
+extern const BaseCSel baseCSel[4];
+extern const BaseCSet baseCSet[2];
+extern const BaseCmpCmn baseCmpCmn[2];
+extern const BaseExtend baseExtend[5];
+extern const BaseExtract baseExtract[1];
+extern const BaseLdSt baseLdSt[9];
+extern const BaseLdpStp baseLdpStp[6];
+extern const BaseLdxp baseLdxp[2];
+extern const BaseLogical baseLogical[8];
+extern const BaseMovKNZ baseMovKNZ[3];
+extern const BaseMvnNeg baseMvnNeg[3];
+extern const BaseOp baseOp[23];
+extern const BaseOpImm baseOpImm[14];
+extern const BaseR baseR[10];
+extern const BaseRM_NoImm baseRM_NoImm[21];
+extern const BaseRM_SImm10 baseRM_SImm10[2];
+extern const BaseRM_SImm9 baseRM_SImm9[23];
+extern const BaseRR baseRR[15];
+extern const BaseRRII baseRRII[2];
+extern const BaseRRR baseRRR[26];
+extern const BaseRRRR baseRRRR[6];
+extern const BaseShift baseShift[8];
+extern const BaseStx baseStx[3];
+extern const BaseStxp baseStxp[2];
+extern const BaseTst baseTst[1];
+extern const FSimdPair fSimdPair[5];
+extern const FSimdSV fSimdSV[4];
+extern const FSimdVV fSimdVV[17];
+extern const FSimdVVV fSimdVVV[13];
+extern const FSimdVVVV fSimdVVVV[4];
+extern const FSimdVVVe fSimdVVVe[4];
+extern const ISimdPair iSimdPair[1];
+extern const ISimdSV iSimdSV[7];
+extern const ISimdVV iSimdVV[29];
+extern const ISimdVVV iSimdVVV[65];
+extern const ISimdVVVI iSimdVVVI[2];
+extern const ISimdVVVV iSimdVVVV[2];
+extern const ISimdVVVVx iSimdVVVVx[1];
+extern const ISimdVVVe iSimdVVVe[25];
+extern const ISimdVVVx iSimdVVVx[17];
+extern const ISimdVVx iSimdVVx[13];
+extern const ISimdWWV iSimdWWV[8];
+extern const SimdBicOrr simdBicOrr[2];
+extern const SimdCmp simdCmp[7];
+extern const SimdDot simdDot[5];
+extern const SimdFcadd simdFcadd[1];
+extern const SimdFccmpFccmpe simdFccmpFccmpe[2];
+extern const SimdFcm simdFcm[5];
+extern const SimdFcmla simdFcmla[1];
+extern const SimdFcmpFcmpe simdFcmpFcmpe[2];
+extern const SimdFcvtLN simdFcvtLN[6];
+extern const SimdFcvtSV simdFcvtSV[12];
+extern const SimdFmlal simdFmlal[6];
+extern const SimdLdNStN simdLdNStN[12];
+extern const SimdLdSt simdLdSt[2];
+extern const SimdLdpStp simdLdpStp[4];
+extern const SimdLdurStur simdLdurStur[2];
+extern const SimdMoviMvni simdMoviMvni[2];
+extern const SimdShift simdShift[40];
+extern const SimdShiftES simdShiftES[2];
+extern const SimdSm3tt simdSm3tt[4];
+extern const SimdSmovUmov simdSmovUmov[2];
+extern const SimdSxtlUxtl simdSxtlUxtl[4];
+extern const SimdTblTbx simdTblTbx[2];
+// ----------------------------------------------------------------------------
+// ${EncodingDataForward:End}
+
+} // {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];
+#endif // !ASMJIT_NO_TEXT
+
+} // {InstDB}
+
+//! \}
+//! \endcond
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // ASMJIT_A64_ARMINSTDB_H_P_INCLUDED
+
diff --git a/src/asmjit/arm/a64operand.cpp b/src/asmjit/arm/a64operand.cpp
new file mode 100644
index 0000000..40a4a79
--- /dev/null
+++ b/src/asmjit/arm/a64operand.cpp
@@ -0,0 +1,85 @@
+// 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"
+#if !defined(ASMJIT_NO_AARCH64)
+
+#include "../core/misc_p.h"
+#include "../arm/a64operand.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+
+// a64::Operand - Tests
+// ====================
+
+#if defined(ASMJIT_TEST)
+UNIT(a64_operand) {
+ INFO("Checking if a64::reg(...) matches built-in IDs");
+ EXPECT(w(5) == w5);
+ EXPECT(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);
+
+ 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(v0.group() == RegGroup::kVec);
+ EXPECT(d0.group() == RegGroup::kVec);
+ EXPECT(s0.group() == RegGroup::kVec);
+ EXPECT(h0.group() == RegGroup::kVec);
+ EXPECT(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);
+
+ 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);
+
+ 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);
+}
+#endif
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // !ASMJIT_NO_AARCH64
diff --git a/src/asmjit/arm/a64operand.h b/src/asmjit/arm/a64operand.h
new file mode 100644
index 0000000..c2d3c17
--- /dev/null
+++ b/src/asmjit/arm/a64operand.h
@@ -0,0 +1,312 @@
+// 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_ARM_A64OPERAND_H_INCLUDED
+#define ASMJIT_ARM_A64OPERAND_H_INCLUDED
+
+#include "../arm/armoperand.h"
+
+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;
+
+#ifndef _DOXYGEN
+namespace regs {
+#endif
+
+using namespace ::asmjit::arm::regs;
+
+static constexpr GpW w0 = GpW(0);
+static constexpr GpW w1 = GpW(1);
+static constexpr GpW w2 = GpW(2);
+static constexpr GpW w3 = GpW(3);
+static constexpr GpW w4 = GpW(4);
+static constexpr GpW w5 = GpW(5);
+static constexpr GpW w6 = GpW(6);
+static constexpr GpW w7 = GpW(7);
+static constexpr GpW w8 = GpW(8);
+static constexpr GpW w9 = GpW(9);
+static constexpr GpW w10 = GpW(10);
+static constexpr GpW w11 = GpW(11);
+static constexpr GpW w12 = GpW(12);
+static constexpr GpW w13 = GpW(13);
+static constexpr GpW w14 = GpW(14);
+static constexpr GpW w15 = GpW(15);
+static constexpr GpW w16 = GpW(16);
+static constexpr GpW w17 = GpW(17);
+static constexpr GpW w18 = GpW(18);
+static constexpr GpW w19 = GpW(19);
+static constexpr GpW w20 = GpW(20);
+static constexpr GpW w21 = GpW(21);
+static constexpr GpW w22 = GpW(22);
+static constexpr GpW w23 = GpW(23);
+static constexpr GpW w24 = GpW(24);
+static constexpr GpW w25 = GpW(25);
+static constexpr GpW w26 = GpW(26);
+static constexpr GpW w27 = GpW(27);
+static constexpr GpW w28 = GpW(28);
+static constexpr GpW w29 = GpW(29);
+static constexpr GpW w30 = GpW(30);
+static constexpr GpW wzr = GpW(Gp::kIdZr);
+static constexpr GpW wsp = GpW(Gp::kIdSp);
+
+static constexpr GpX x0 = GpX(0);
+static constexpr GpX x1 = GpX(1);
+static constexpr GpX x2 = GpX(2);
+static constexpr GpX x3 = GpX(3);
+static constexpr GpX x4 = GpX(4);
+static constexpr GpX x5 = GpX(5);
+static constexpr GpX x6 = GpX(6);
+static constexpr GpX x7 = GpX(7);
+static constexpr GpX x8 = GpX(8);
+static constexpr GpX x9 = GpX(9);
+static constexpr GpX x10 = GpX(10);
+static constexpr GpX x11 = GpX(11);
+static constexpr GpX x12 = GpX(12);
+static constexpr GpX x13 = GpX(13);
+static constexpr GpX x14 = GpX(14);
+static constexpr GpX x15 = GpX(15);
+static constexpr GpX x16 = GpX(16);
+static constexpr GpX x17 = GpX(17);
+static constexpr GpX x18 = GpX(18);
+static constexpr GpX x19 = GpX(19);
+static constexpr GpX x20 = GpX(20);
+static constexpr GpX x21 = GpX(21);
+static constexpr GpX x22 = GpX(22);
+static constexpr GpX x23 = GpX(23);
+static constexpr GpX x24 = GpX(24);
+static constexpr GpX x25 = GpX(25);
+static constexpr GpX x26 = GpX(26);
+static constexpr GpX x27 = GpX(27);
+static constexpr GpX x28 = GpX(28);
+static constexpr GpX x29 = GpX(29);
+static constexpr GpX x30 = GpX(30);
+static constexpr GpX xzr = GpX(Gp::kIdZr);
+static constexpr GpX sp = GpX(Gp::kIdSp);
+
+static constexpr VecB b0 = VecB(0);
+static constexpr VecB b1 = VecB(1);
+static constexpr VecB b2 = VecB(2);
+static constexpr VecB b3 = VecB(3);
+static constexpr VecB b4 = VecB(4);
+static constexpr VecB b5 = VecB(5);
+static constexpr VecB b6 = VecB(6);
+static constexpr VecB b7 = VecB(7);
+static constexpr VecB b8 = VecB(8);
+static constexpr VecB b9 = VecB(9);
+static constexpr VecB b10 = VecB(10);
+static constexpr VecB b11 = VecB(11);
+static constexpr VecB b12 = VecB(12);
+static constexpr VecB b13 = VecB(13);
+static constexpr VecB b14 = VecB(14);
+static constexpr VecB b15 = VecB(15);
+static constexpr VecB b16 = VecB(16);
+static constexpr VecB b17 = VecB(17);
+static constexpr VecB b18 = VecB(18);
+static constexpr VecB b19 = VecB(19);
+static constexpr VecB b20 = VecB(20);
+static constexpr VecB b21 = VecB(21);
+static constexpr VecB b22 = VecB(22);
+static constexpr VecB b23 = VecB(23);
+static constexpr VecB b24 = VecB(24);
+static constexpr VecB b25 = VecB(25);
+static constexpr VecB b26 = VecB(26);
+static constexpr VecB b27 = VecB(27);
+static constexpr VecB b28 = VecB(28);
+static constexpr VecB b29 = VecB(29);
+static constexpr VecB b30 = VecB(30);
+static constexpr VecB b31 = VecB(31);
+
+static constexpr VecH h0 = VecH(0);
+static constexpr VecH h1 = VecH(1);
+static constexpr VecH h2 = VecH(2);
+static constexpr VecH h3 = VecH(3);
+static constexpr VecH h4 = VecH(4);
+static constexpr VecH h5 = VecH(5);
+static constexpr VecH h6 = VecH(6);
+static constexpr VecH h7 = VecH(7);
+static constexpr VecH h8 = VecH(8);
+static constexpr VecH h9 = VecH(9);
+static constexpr VecH h10 = VecH(10);
+static constexpr VecH h11 = VecH(11);
+static constexpr VecH h12 = VecH(12);
+static constexpr VecH h13 = VecH(13);
+static constexpr VecH h14 = VecH(14);
+static constexpr VecH h15 = VecH(15);
+static constexpr VecH h16 = VecH(16);
+static constexpr VecH h17 = VecH(17);
+static constexpr VecH h18 = VecH(18);
+static constexpr VecH h19 = VecH(19);
+static constexpr VecH h20 = VecH(20);
+static constexpr VecH h21 = VecH(21);
+static constexpr VecH h22 = VecH(22);
+static constexpr VecH h23 = VecH(23);
+static constexpr VecH h24 = VecH(24);
+static constexpr VecH h25 = VecH(25);
+static constexpr VecH h26 = VecH(26);
+static constexpr VecH h27 = VecH(27);
+static constexpr VecH h28 = VecH(28);
+static constexpr VecH h29 = VecH(29);
+static constexpr VecH h30 = VecH(30);
+static constexpr VecH h31 = VecH(31);
+
+static constexpr VecS s0 = VecS(0);
+static constexpr VecS s1 = VecS(1);
+static constexpr VecS s2 = VecS(2);
+static constexpr VecS s3 = VecS(3);
+static constexpr VecS s4 = VecS(4);
+static constexpr VecS s5 = VecS(5);
+static constexpr VecS s6 = VecS(6);
+static constexpr VecS s7 = VecS(7);
+static constexpr VecS s8 = VecS(8);
+static constexpr VecS s9 = VecS(9);
+static constexpr VecS s10 = VecS(10);
+static constexpr VecS s11 = VecS(11);
+static constexpr VecS s12 = VecS(12);
+static constexpr VecS s13 = VecS(13);
+static constexpr VecS s14 = VecS(14);
+static constexpr VecS s15 = VecS(15);
+static constexpr VecS s16 = VecS(16);
+static constexpr VecS s17 = VecS(17);
+static constexpr VecS s18 = VecS(18);
+static constexpr VecS s19 = VecS(19);
+static constexpr VecS s20 = VecS(20);
+static constexpr VecS s21 = VecS(21);
+static constexpr VecS s22 = VecS(22);
+static constexpr VecS s23 = VecS(23);
+static constexpr VecS s24 = VecS(24);
+static constexpr VecS s25 = VecS(25);
+static constexpr VecS s26 = VecS(26);
+static constexpr VecS s27 = VecS(27);
+static constexpr VecS s28 = VecS(28);
+static constexpr VecS s29 = VecS(29);
+static constexpr VecS s30 = VecS(30);
+static constexpr VecS s31 = VecS(31);
+
+static constexpr VecD d0 = VecD(0);
+static constexpr VecD d1 = VecD(1);
+static constexpr VecD d2 = VecD(2);
+static constexpr VecD d3 = VecD(3);
+static constexpr VecD d4 = VecD(4);
+static constexpr VecD d5 = VecD(5);
+static constexpr VecD d6 = VecD(6);
+static constexpr VecD d7 = VecD(7);
+static constexpr VecD d8 = VecD(8);
+static constexpr VecD d9 = VecD(9);
+static constexpr VecD d10 = VecD(10);
+static constexpr VecD d11 = VecD(11);
+static constexpr VecD d12 = VecD(12);
+static constexpr VecD d13 = VecD(13);
+static constexpr VecD d14 = VecD(14);
+static constexpr VecD d15 = VecD(15);
+static constexpr VecD d16 = VecD(16);
+static constexpr VecD d17 = VecD(17);
+static constexpr VecD d18 = VecD(18);
+static constexpr VecD d19 = VecD(19);
+static constexpr VecD d20 = VecD(20);
+static constexpr VecD d21 = VecD(21);
+static constexpr VecD d22 = VecD(22);
+static constexpr VecD d23 = VecD(23);
+static constexpr VecD d24 = VecD(24);
+static constexpr VecD d25 = VecD(25);
+static constexpr VecD d26 = VecD(26);
+static constexpr VecD d27 = VecD(27);
+static constexpr VecD d28 = VecD(28);
+static constexpr VecD d29 = VecD(29);
+static constexpr VecD d30 = VecD(30);
+static constexpr VecD d31 = VecD(31);
+
+static constexpr VecV q0 = VecV(0);
+static constexpr VecV q1 = VecV(1);
+static constexpr VecV q2 = VecV(2);
+static constexpr VecV q3 = VecV(3);
+static constexpr VecV q4 = VecV(4);
+static constexpr VecV q5 = VecV(5);
+static constexpr VecV q6 = VecV(6);
+static constexpr VecV q7 = VecV(7);
+static constexpr VecV q8 = VecV(8);
+static constexpr VecV q9 = VecV(9);
+static constexpr VecV q10 = VecV(10);
+static constexpr VecV q11 = VecV(11);
+static constexpr VecV q12 = VecV(12);
+static constexpr VecV q13 = VecV(13);
+static constexpr VecV q14 = VecV(14);
+static constexpr VecV q15 = VecV(15);
+static constexpr VecV q16 = VecV(16);
+static constexpr VecV q17 = VecV(17);
+static constexpr VecV q18 = VecV(18);
+static constexpr VecV q19 = VecV(19);
+static constexpr VecV q20 = VecV(20);
+static constexpr VecV q21 = VecV(21);
+static constexpr VecV q22 = VecV(22);
+static constexpr VecV q23 = VecV(23);
+static constexpr VecV q24 = VecV(24);
+static constexpr VecV q25 = VecV(25);
+static constexpr VecV q26 = VecV(26);
+static constexpr VecV q27 = VecV(27);
+static constexpr VecV q28 = VecV(28);
+static constexpr VecV q29 = VecV(29);
+static constexpr VecV q30 = VecV(30);
+static constexpr VecV q31 = VecV(31);
+
+static constexpr VecV v0 = VecV(0);
+static constexpr VecV v1 = VecV(1);
+static constexpr VecV v2 = VecV(2);
+static constexpr VecV v3 = VecV(3);
+static constexpr VecV v4 = VecV(4);
+static constexpr VecV v5 = VecV(5);
+static constexpr VecV v6 = VecV(6);
+static constexpr VecV v7 = VecV(7);
+static constexpr VecV v8 = VecV(8);
+static constexpr VecV v9 = VecV(9);
+static constexpr VecV v10 = VecV(10);
+static constexpr VecV v11 = VecV(11);
+static constexpr VecV v12 = VecV(12);
+static constexpr VecV v13 = VecV(13);
+static constexpr VecV v14 = VecV(14);
+static constexpr VecV v15 = VecV(15);
+static constexpr VecV v16 = VecV(16);
+static constexpr VecV v17 = VecV(17);
+static constexpr VecV v18 = VecV(18);
+static constexpr VecV v19 = VecV(19);
+static constexpr VecV v20 = VecV(20);
+static constexpr VecV v21 = VecV(21);
+static constexpr VecV v22 = VecV(22);
+static constexpr VecV v23 = VecV(23);
+static constexpr VecV v24 = VecV(24);
+static constexpr VecV v25 = VecV(25);
+static constexpr VecV v26 = VecV(26);
+static constexpr VecV v27 = VecV(27);
+static constexpr VecV v28 = VecV(28);
+static constexpr VecV v29 = VecV(29);
+static constexpr VecV v30 = VecV(30);
+static constexpr VecV v31 = VecV(31);
+
+#ifndef _DOXYGEN
+} // {regs}
+
+// Make `a64::regs` accessible through `a64` namespace as well.
+using namespace regs;
+#endif
+
+//! \}
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // ASMJIT_ARM_A64OPERAND_H_INCLUDED
diff --git a/src/asmjit/arm/a64rapass.cpp b/src/asmjit/arm/a64rapass.cpp
new file mode 100644
index 0000000..ad78369
--- /dev/null
+++ b/src/asmjit/arm/a64rapass.cpp
@@ -0,0 +1,806 @@
+// 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"
+#if !defined(ASMJIT_NO_AARCH64) && !defined(ASMJIT_NO_COMPILER)
+
+#include "../core/cpuinfo.h"
+#include "../core/support.h"
+#include "../core/type.h"
+#include "../arm/a64assembler.h"
+#include "../arm/a64compiler.h"
+#include "../arm/a64emithelper_p.h"
+#include "../arm/a64instapi_p.h"
+#include "../arm/a64instdb_p.h"
+#include "../arm/a64rapass_p.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+
+// a64::ARMRAPass - Helpers
+// ========================
+
+// TODO: [ARM] These should be shared with all backends.
+ASMJIT_MAYBE_UNUSED
+static inline uint64_t raImmMaskFromSize(uint32_t size) noexcept {
+ ASMJIT_ASSERT(size > 0 && size < 256);
+ static const uint64_t masks[] = {
+ 0x00000000000000FFu, // 1
+ 0x000000000000FFFFu, // 2
+ 0x00000000FFFFFFFFu, // 4
+ 0xFFFFFFFFFFFFFFFFu, // 8
+ 0x0000000000000000u, // 16
+ 0x0000000000000000u, // 32
+ 0x0000000000000000u, // 64
+ 0x0000000000000000u, // 128
+ 0x0000000000000000u // 256
+ };
+ return masks[Support::ctz(size)];
+}
+
+static const RegMask raConsecutiveLeadCountToRegMaskFilter[5] = {
+ 0xFFFFFFFFu, // [0] No consecutive.
+ 0x00000000u, // [1] Invalid, never used.
+ 0x7FFFFFFFu, // [2] 2 consecutive registers.
+ 0x3FFFFFFFu, // [3] 3 consecutive registers.
+ 0x1FFFFFFFu // [4] 4 consecutive registers.
+};
+
+static inline RATiedFlags raUseOutFlagsFromRWFlags(OpRWFlags rwFlags) noexcept {
+ static constexpr RATiedFlags map[] = {
+ RATiedFlags::kNone,
+ RATiedFlags::kRead | RATiedFlags::kUse, // kRead
+ RATiedFlags::kWrite | RATiedFlags::kOut, // kWrite
+ RATiedFlags::kRW | RATiedFlags::kUse, // kRW
+ };
+
+ return map[uint32_t(rwFlags & OpRWFlags::kRW)];
+}
+
+static inline RATiedFlags raRegRwFlags(OpRWFlags flags) noexcept {
+ return raUseOutFlagsFromRWFlags(flags);
+}
+
+static inline RATiedFlags raMemBaseRwFlags(OpRWFlags flags) noexcept {
+ constexpr uint32_t shift = Support::ConstCTZ<uint32_t(OpRWFlags::kMemBaseRW)>::value;
+ return raUseOutFlagsFromRWFlags(OpRWFlags(uint32_t(flags) >> shift) & OpRWFlags::kRW);
+}
+
+static inline RATiedFlags raMemIndexRwFlags(OpRWFlags flags) noexcept {
+ constexpr uint32_t shift = Support::ConstCTZ<uint32_t(OpRWFlags::kMemIndexRW)>::value;
+ return raUseOutFlagsFromRWFlags(OpRWFlags(uint32_t(flags) >> shift) & OpRWFlags::kRW);
+}
+// a64::RACFGBuilder
+// =================
+
+class RACFGBuilder : public RACFGBuilderT<RACFGBuilder> {
+public:
+ Arch _arch;
+
+ inline RACFGBuilder(ARMRAPass* pass) noexcept
+ : RACFGBuilderT<RACFGBuilder>(pass),
+ _arch(pass->cc()->arch()) {}
+
+ inline Compiler* cc() const noexcept { return static_cast<Compiler*>(_cc); }
+
+ Error onInst(InstNode* inst, InstControlFlow& controlType, RAInstBuilder& ib) noexcept;
+
+ Error onBeforeInvoke(InvokeNode* invokeNode) noexcept;
+ Error onInvoke(InvokeNode* invokeNode, RAInstBuilder& ib) noexcept;
+
+ Error moveImmToRegArg(InvokeNode* invokeNode, const FuncValue& arg, const Imm& imm_, BaseReg* out) noexcept;
+ Error moveImmToStackArg(InvokeNode* invokeNode, const FuncValue& arg, const Imm& imm_) noexcept;
+ Error moveRegToStackArg(InvokeNode* invokeNode, const FuncValue& arg, const BaseReg& reg) noexcept;
+
+ Error onBeforeRet(FuncRetNode* funcRet) noexcept;
+ Error onRet(FuncRetNode* funcRet, RAInstBuilder& ib) noexcept;
+};
+
+// a64::RACFGBuilder - OnInst
+// ==========================
+
+// TODO: [ARM] This is just a workaround...
+static InstControlFlow getControlFlowType(InstId instId) noexcept {
+ switch (instId) {
+ case Inst::kIdB:
+ case Inst::kIdBr:
+ if (BaseInst::extractARMCondCode(instId) == CondCode::kAL)
+ return InstControlFlow::kJump;
+ else
+ return InstControlFlow::kBranch;
+ case Inst::kIdBl:
+ case Inst::kIdBlr:
+ return InstControlFlow::kCall;
+ case Inst::kIdCbz:
+ case Inst::kIdCbnz:
+ case Inst::kIdTbz:
+ case Inst::kIdTbnz:
+ return InstControlFlow::kBranch;
+ case Inst::kIdRet:
+ return InstControlFlow::kReturn;
+ default:
+ return InstControlFlow::kRegular;
+ }
+}
+
+Error RACFGBuilder::onInst(InstNode* inst, InstControlFlow& controlType, RAInstBuilder& ib) noexcept {
+ InstRWInfo rwInfo;
+
+ InstId instId = inst->id();
+ if (Inst::isDefinedId(instId)) {
+ uint32_t opCount = inst->opCount();
+ const Operand* opArray = inst->operands();
+ ASMJIT_PROPAGATE(InstInternal::queryRWInfo(_arch, inst->baseInst(), opArray, opCount, &rwInfo));
+
+ const InstDB::InstInfo& instInfo = InstDB::infoById(instId);
+ uint32_t singleRegOps = 0;
+
+ if (opCount) {
+ uint32_t consecutiveOffset = 0xFFFFFFFFu;
+ uint32_t consecutiveParent = Globals::kInvalidId;
+
+ for (uint32_t i = 0; i < opCount; i++) {
+ const Operand& op = opArray[i];
+ const OpRWInfo& opRwInfo = rwInfo.operand(i);
+
+ if (op.isReg()) {
+ // Register Operand
+ // ----------------
+ const Reg& reg = op.as<Reg>();
+
+ RATiedFlags flags = raRegRwFlags(opRwInfo.opFlags());
+ uint32_t vIndex = Operand::virtIdToIndex(reg.id());
+
+ if (vIndex < Operand::kVirtIdCount) {
+ RAWorkReg* workReg;
+ ASMJIT_PROPAGATE(_pass->virtIndexAsWorkReg(vIndex, &workReg));
+
+ // Use RW instead of Write in case that not the whole register is overwritten. This is important for
+ // liveness as we cannot kill a register that will be used.
+ if ((flags & RATiedFlags::kRW) == RATiedFlags::kWrite) {
+ if (workReg->regByteMask() & ~(opRwInfo.writeByteMask() | opRwInfo.extendByteMask())) {
+ // Not write-only operation.
+ flags = (flags & ~RATiedFlags::kOut) | (RATiedFlags::kRead | RATiedFlags::kUse);
+ }
+ }
+
+ RegGroup group = workReg->group();
+
+ RegMask useRegs = _pass->_availableRegs[group];
+ RegMask outRegs = useRegs;
+
+ uint32_t useId = BaseReg::kIdBad;
+ uint32_t outId = BaseReg::kIdBad;
+
+ uint32_t useRewriteMask = 0;
+ uint32_t outRewriteMask = 0;
+
+ if (opRwInfo.consecutiveLeadCount()) {
+ // There must be a single consecutive register lead, otherwise the RW data is invalid.
+ if (consecutiveOffset != 0xFFFFFFFFu)
+ return DebugUtils::errored(kErrorInvalidState);
+
+ // A consecutive lead register cannot be used as a consecutive +1/+2/+3 register, the registers must be distinct.
+ if (RATiedReg::consecutiveDataFromFlags(flags) != 0)
+ return DebugUtils::errored(kErrorNotConsecutiveRegs);
+
+ flags |= RATiedFlags::kLeadConsecutive | RATiedReg::consecutiveDataToFlags(opRwInfo.consecutiveLeadCount() - 1);
+ consecutiveOffset = 0;
+
+ RegMask filter = raConsecutiveLeadCountToRegMaskFilter[opRwInfo.consecutiveLeadCount()];
+ if (Support::test(flags, RATiedFlags::kUse)) {
+ flags |= RATiedFlags::kUseConsecutive;
+ useRegs &= filter;
+ }
+ else {
+ flags |= RATiedFlags::kOutConsecutive;
+ outRegs &= filter;
+ }
+ }
+
+ if (Support::test(flags, RATiedFlags::kUse)) {
+ useRewriteMask = Support::bitMask(inst->getRewriteIndex(&reg._baseId));
+ if (opRwInfo.hasOpFlag(OpRWFlags::kRegPhysId)) {
+ useId = opRwInfo.physId();
+ flags |= RATiedFlags::kUseFixed;
+ }
+ else if (opRwInfo.hasOpFlag(OpRWFlags::kConsecutive)) {
+ if (consecutiveOffset == 0xFFFFFFFFu)
+ return DebugUtils::errored(kErrorInvalidState);
+ flags |= RATiedFlags::kUseConsecutive | RATiedReg::consecutiveDataToFlags(++consecutiveOffset);
+ }
+ }
+ else {
+ outRewriteMask = Support::bitMask(inst->getRewriteIndex(&reg._baseId));
+ if (opRwInfo.hasOpFlag(OpRWFlags::kRegPhysId)) {
+ outId = opRwInfo.physId();
+ flags |= RATiedFlags::kOutFixed;
+ }
+ else if (opRwInfo.hasOpFlag(OpRWFlags::kConsecutive)) {
+ if (consecutiveOffset == 0xFFFFFFFFu)
+ return DebugUtils::errored(kErrorInvalidState);
+ flags |= RATiedFlags::kOutConsecutive | RATiedReg::consecutiveDataToFlags(++consecutiveOffset);
+ }
+ }
+
+ // Special cases regarding element access.
+ 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 (Support::test(flags, RATiedFlags::kUse))
+ useId &= 0x0000FFFFu;
+ else
+ outId &= 0x0000FFFFu;
+ }
+ }
+
+ ASMJIT_PROPAGATE(ib.add(workReg, flags, useRegs, useId, useRewriteMask, outRegs, outId, outRewriteMask, opRwInfo.rmSize(), consecutiveParent));
+ if (singleRegOps == i)
+ singleRegOps++;
+
+ if (Support::test(flags, RATiedFlags::kLeadConsecutive | RATiedFlags::kUseConsecutive | RATiedFlags::kOutConsecutive))
+ consecutiveParent = workReg->workId();
+ }
+ }
+ else if (op.isMem()) {
+ // Memory Operand
+ // --------------
+ const Mem& mem = op.as<Mem>();
+
+ if (mem.isRegHome()) {
+ RAWorkReg* workReg;
+ ASMJIT_PROPAGATE(_pass->virtIndexAsWorkReg(Operand::virtIdToIndex(mem.baseId()), &workReg));
+ _pass->getOrCreateStackSlot(workReg);
+ }
+ else if (mem.hasBaseReg()) {
+ uint32_t vIndex = Operand::virtIdToIndex(mem.baseId());
+ if (vIndex < Operand::kVirtIdCount) {
+ RAWorkReg* workReg;
+ ASMJIT_PROPAGATE(_pass->virtIndexAsWorkReg(vIndex, &workReg));
+
+ RATiedFlags flags = raMemBaseRwFlags(opRwInfo.opFlags());
+ RegGroup group = workReg->group();
+ RegMask allocable = _pass->_availableRegs[group];
+
+ // Base registers have never fixed id on ARM.
+ const uint32_t useId = BaseReg::kIdBad;
+ const uint32_t outId = BaseReg::kIdBad;
+
+ uint32_t useRewriteMask = 0;
+ uint32_t outRewriteMask = 0;
+
+ if (Support::test(flags, RATiedFlags::kUse))
+ useRewriteMask = Support::bitMask(inst->getRewriteIndex(&mem._baseId));
+ else
+ outRewriteMask = Support::bitMask(inst->getRewriteIndex(&mem._baseId));
+
+ ASMJIT_PROPAGATE(ib.add(workReg, flags, allocable, useId, useRewriteMask, allocable, outId, outRewriteMask));
+ }
+ }
+
+ if (mem.hasIndexReg()) {
+ uint32_t vIndex = Operand::virtIdToIndex(mem.indexId());
+ if (vIndex < Operand::kVirtIdCount) {
+ RAWorkReg* workReg;
+ ASMJIT_PROPAGATE(_pass->virtIndexAsWorkReg(vIndex, &workReg));
+
+ RATiedFlags flags = raMemIndexRwFlags(opRwInfo.opFlags());
+ RegGroup group = workReg->group();
+ RegMask allocable = _pass->_availableRegs[group];
+
+ // Index registers have never fixed id on ARM.
+ const uint32_t useId = BaseReg::kIdBad;
+ const uint32_t outId = BaseReg::kIdBad;
+
+ uint32_t useRewriteMask = 0;
+ uint32_t outRewriteMask = 0;
+
+ if (Support::test(flags, RATiedFlags::kUse))
+ useRewriteMask = Support::bitMask(inst->getRewriteIndex(&mem._data[Operand::kDataMemIndexId]));
+ else
+ outRewriteMask = Support::bitMask(inst->getRewriteIndex(&mem._data[Operand::kDataMemIndexId]));
+
+ ASMJIT_PROPAGATE(ib.add(workReg, RATiedFlags::kUse | RATiedFlags::kRead, allocable, useId, useRewriteMask, allocable, outId, outRewriteMask));
+ }
+ }
+ }
+ }
+ }
+
+ controlType = getControlFlowType(instId);
+ }
+
+ return kErrorOk;
+}
+
+// a64::RACFGBuilder - OnInvoke
+// ============================
+
+Error RACFGBuilder::onBeforeInvoke(InvokeNode* invokeNode) noexcept {
+ const FuncDetail& fd = invokeNode->detail();
+ uint32_t argCount = invokeNode->argCount();
+
+ cc()->_setCursor(invokeNode->prev());
+
+ for (uint32_t argIndex = 0; argIndex < argCount; argIndex++) {
+ const FuncValuePack& argPack = fd.argPack(argIndex);
+ for (uint32_t valueIndex = 0; valueIndex < Globals::kMaxValuePack; valueIndex++) {
+ if (!argPack[valueIndex])
+ break;
+
+ const FuncValue& arg = argPack[valueIndex];
+ const Operand& op = invokeNode->arg(argIndex, valueIndex);
+
+ if (op.isNone())
+ continue;
+
+ if (op.isReg()) {
+ const Reg& reg = op.as<Reg>();
+ RAWorkReg* workReg;
+ ASMJIT_PROPAGATE(_pass->virtIndexAsWorkReg(Operand::virtIdToIndex(reg.id()), &workReg));
+
+ if (arg.isReg()) {
+ RegGroup regGroup = workReg->group();
+ RegGroup argGroup = Reg::groupOf(arg.regType());
+
+ if (regGroup != argGroup) {
+ // TODO: [ARM] Conversion is not supported.
+ return DebugUtils::errored(kErrorInvalidAssignment);
+ }
+ }
+ else {
+ ASMJIT_PROPAGATE(moveRegToStackArg(invokeNode, arg, reg));
+ }
+ }
+ else if (op.isImm()) {
+ if (arg.isReg()) {
+ BaseReg reg;
+ ASMJIT_PROPAGATE(moveImmToRegArg(invokeNode, arg, op.as<Imm>(), &reg));
+ invokeNode->_args[argIndex][valueIndex] = reg;
+ }
+ else {
+ ASMJIT_PROPAGATE(moveImmToStackArg(invokeNode, arg, op.as<Imm>()));
+ }
+ }
+ }
+ }
+
+ cc()->_setCursor(invokeNode);
+
+ if (fd.hasRet()) {
+ for (uint32_t valueIndex = 0; valueIndex < Globals::kMaxValuePack; valueIndex++) {
+ const FuncValue& ret = fd.ret(valueIndex);
+ if (!ret)
+ break;
+
+ const Operand& op = invokeNode->ret(valueIndex);
+ if (op.isReg()) {
+ const Reg& reg = op.as<Reg>();
+ RAWorkReg* workReg;
+ ASMJIT_PROPAGATE(_pass->virtIndexAsWorkReg(Operand::virtIdToIndex(reg.id()), &workReg));
+
+ if (ret.isReg()) {
+ RegGroup regGroup = workReg->group();
+ RegGroup retGroup = Reg::groupOf(ret.regType());
+
+ if (regGroup != retGroup) {
+ // TODO: [ARM] Conversion is not supported.
+ return DebugUtils::errored(kErrorInvalidAssignment);
+ }
+ }
+ }
+ }
+ }
+
+ // This block has function call(s).
+ _curBlock->addFlags(RABlockFlags::kHasFuncCalls);
+ _pass->func()->frame().addAttributes(FuncAttributes::kHasFuncCalls);
+ _pass->func()->frame().updateCallStackSize(fd.argStackSize());
+
+ return kErrorOk;
+}
+
+Error RACFGBuilder::onInvoke(InvokeNode* invokeNode, RAInstBuilder& ib) noexcept {
+ uint32_t argCount = invokeNode->argCount();
+ const FuncDetail& fd = invokeNode->detail();
+
+ for (uint32_t argIndex = 0; argIndex < argCount; argIndex++) {
+ const FuncValuePack& argPack = fd.argPack(argIndex);
+ for (uint32_t valueIndex = 0; valueIndex < Globals::kMaxValuePack; valueIndex++) {
+ if (!argPack[valueIndex])
+ continue;
+
+ const FuncValue& arg = argPack[valueIndex];
+ const Operand& op = invokeNode->arg(argIndex, valueIndex);
+
+ if (op.isNone())
+ continue;
+
+ if (op.isReg()) {
+ const Reg& reg = op.as<Reg>();
+ RAWorkReg* workReg;
+ ASMJIT_PROPAGATE(_pass->virtIndexAsWorkReg(Operand::virtIdToIndex(reg.id()), &workReg));
+
+ if (arg.isIndirect()) {
+ RegGroup regGroup = workReg->group();
+ if (regGroup != RegGroup::kGp)
+ return DebugUtils::errored(kErrorInvalidState);
+ ASMJIT_PROPAGATE(ib.addCallArg(workReg, arg.regId()));
+ }
+ else if (arg.isReg()) {
+ RegGroup regGroup = workReg->group();
+ RegGroup argGroup = Reg::groupOf(arg.regType());
+
+ if (regGroup == argGroup) {
+ ASMJIT_PROPAGATE(ib.addCallArg(workReg, arg.regId()));
+ }
+ }
+ }
+ }
+ }
+
+ for (uint32_t retIndex = 0; retIndex < Globals::kMaxValuePack; retIndex++) {
+ const FuncValue& ret = fd.ret(retIndex);
+ if (!ret)
+ break;
+
+ const Operand& op = invokeNode->ret(retIndex);
+ if (op.isReg()) {
+ const Reg& reg = op.as<Reg>();
+ RAWorkReg* workReg;
+ ASMJIT_PROPAGATE(_pass->virtIndexAsWorkReg(Operand::virtIdToIndex(reg.id()), &workReg));
+
+ if (ret.isReg()) {
+ RegGroup regGroup = workReg->group();
+ RegGroup retGroup = Reg::groupOf(ret.regType());
+
+ if (regGroup == retGroup) {
+ ASMJIT_PROPAGATE(ib.addCallRet(workReg, ret.regId()));
+ }
+ }
+ else {
+ return DebugUtils::errored(kErrorInvalidAssignment);
+ }
+ }
+ }
+
+ // Setup clobbered registers.
+ ib._clobbered[0] = Support::lsbMask<RegMask>(_pass->_physRegCount[RegGroup(0)]) & ~fd.preservedRegs(RegGroup(0));
+ ib._clobbered[1] = Support::lsbMask<RegMask>(_pass->_physRegCount[RegGroup(1)]) & ~fd.preservedRegs(RegGroup(1));
+ ib._clobbered[2] = Support::lsbMask<RegMask>(_pass->_physRegCount[RegGroup(2)]) & ~fd.preservedRegs(RegGroup(2));
+ ib._clobbered[3] = Support::lsbMask<RegMask>(_pass->_physRegCount[RegGroup(3)]) & ~fd.preservedRegs(RegGroup(3));
+
+ return kErrorOk;
+}
+
+// a64::RACFGBuilder - MoveImmToRegArg
+// ===================================
+
+Error RACFGBuilder::moveImmToRegArg(InvokeNode* invokeNode, const FuncValue& arg, const Imm& imm_, BaseReg* out) noexcept {
+ DebugUtils::unused(invokeNode);
+ ASMJIT_ASSERT(arg.isReg());
+
+ Imm imm(imm_);
+ TypeId typeId = TypeId::kVoid;
+
+ switch (arg.typeId()) {
+ case TypeId::kInt8 : typeId = TypeId::kUInt64; imm.signExtend8Bits(); break;
+ case TypeId::kUInt8 : typeId = TypeId::kUInt64; imm.zeroExtend8Bits(); break;
+ case TypeId::kInt16 : typeId = TypeId::kUInt64; imm.signExtend16Bits(); break;
+ case TypeId::kUInt16: typeId = TypeId::kUInt64; imm.zeroExtend16Bits(); break;
+ case TypeId::kInt32 : typeId = TypeId::kUInt64; imm.signExtend32Bits(); break;
+ case TypeId::kUInt32: typeId = TypeId::kUInt64; imm.zeroExtend32Bits(); break;
+ case TypeId::kInt64 : typeId = TypeId::kUInt64; break;
+ case TypeId::kUInt64: typeId = TypeId::kUInt64; break;
+
+ default:
+ return DebugUtils::errored(kErrorInvalidAssignment);
+ }
+
+ ASMJIT_PROPAGATE(cc()->_newReg(out, typeId, nullptr));
+ cc()->virtRegById(out->id())->setWeight(BaseRAPass::kCallArgWeight);
+ return cc()->mov(out->as<Gp>(), imm);
+}
+
+// a64::RACFGBuilder - MoveImmToStackArg
+// =====================================
+
+Error RACFGBuilder::moveImmToStackArg(InvokeNode* invokeNode, const FuncValue& arg, const Imm& imm_) noexcept {
+ BaseReg reg;
+
+ ASMJIT_PROPAGATE(moveImmToRegArg(invokeNode, arg, imm_, &reg));
+ ASMJIT_PROPAGATE(moveRegToStackArg(invokeNode, arg, reg));
+
+ return kErrorOk;
+}
+
+// a64::RACFGBuilder - MoveRegToStackArg
+// =====================================
+
+Error RACFGBuilder::moveRegToStackArg(InvokeNode* invokeNode, const FuncValue& arg, const BaseReg& reg) noexcept {
+ DebugUtils::unused(invokeNode);
+ Mem stackPtr = ptr(_pass->_sp.as<Gp>(), arg.stackOffset());
+
+ if (reg.isGp())
+ return cc()->str(reg.as<Gp>(), stackPtr);
+
+ if (reg.isVec())
+ return cc()->str(reg.as<Vec>(), stackPtr);
+
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
+// a64::RACFGBuilder - OnReg
+// =========================
+
+Error RACFGBuilder::onBeforeRet(FuncRetNode* funcRet) noexcept {
+ DebugUtils::unused(funcRet);
+ return kErrorOk;
+}
+
+Error RACFGBuilder::onRet(FuncRetNode* funcRet, RAInstBuilder& ib) noexcept {
+ const FuncDetail& funcDetail = _pass->func()->detail();
+ const Operand* opArray = funcRet->operands();
+ uint32_t opCount = funcRet->opCount();
+
+ for (uint32_t i = 0; i < opCount; i++) {
+ const Operand& op = opArray[i];
+ if (op.isNone()) continue;
+
+ const FuncValue& ret = funcDetail.ret(i);
+ if (ASMJIT_UNLIKELY(!ret.isReg()))
+ return DebugUtils::errored(kErrorInvalidAssignment);
+
+ if (op.isReg()) {
+ // Register return value.
+ const Reg& reg = op.as<Reg>();
+ uint32_t vIndex = Operand::virtIdToIndex(reg.id());
+
+ if (vIndex < Operand::kVirtIdCount) {
+ RAWorkReg* workReg;
+ ASMJIT_PROPAGATE(_pass->virtIndexAsWorkReg(vIndex, &workReg));
+
+ RegGroup group = workReg->group();
+ RegMask allocable = _pass->_availableRegs[group];
+ ASMJIT_PROPAGATE(ib.add(workReg, RATiedFlags::kUse | RATiedFlags::kRead, allocable, ret.regId(), 0, 0, BaseReg::kIdBad, 0));
+ }
+ }
+ else {
+ return DebugUtils::errored(kErrorInvalidAssignment);
+ }
+ }
+
+ return kErrorOk;
+}
+
+// a64::ARMRAPass - Construction & Destruction
+// ===========================================
+
+ARMRAPass::ARMRAPass() noexcept
+ : BaseRAPass() { _iEmitHelper = &_emitHelper; }
+ARMRAPass::~ARMRAPass() noexcept {}
+
+// a64::ARMRAPass - OnInit / OnDone
+// ================================
+
+void ARMRAPass::onInit() noexcept {
+ Arch arch = cc()->arch();
+
+ _emitHelper._emitter = _cb;
+
+ _archTraits = &ArchTraits::byArch(arch);
+ _physRegCount.set(RegGroup::kGp, 32);
+ _physRegCount.set(RegGroup::kVec, 32);
+ _physRegCount.set(RegGroup::kExtraVirt2, 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::kExtraVirt3] = Support::lsbMask<uint32_t>(_physRegCount.get(RegGroup::kExtraVirt3));
+
+ _scratchRegIndexes[0] = uint8_t(27);
+ _scratchRegIndexes[1] = uint8_t(28);
+
+ // The architecture specific setup makes implicitly all registers available. So
+ // make unavailable all registers that are special and cannot be used in general.
+ bool hasFP = _func->frame().hasPreservedFP();
+
+ if (hasFP)
+ makeUnavailable(RegGroup::kGp, Gp::kIdFp);
+
+ makeUnavailable(RegGroup::kGp, Gp::kIdSp);
+ makeUnavailable(RegGroup::kGp, Gp::kIdOs); // OS-specific use, usually TLS.
+
+ _sp = sp;
+ _fp = x29;
+}
+
+void ARMRAPass::onDone() noexcept {}
+
+// a64::ARMRAPass - BuildCFG
+// =========================
+
+Error ARMRAPass::buildCFG() noexcept {
+ return RACFGBuilder(this).run();
+}
+
+// a64::ARMRAPass - Rewrite
+// ========================
+
+ASMJIT_FAVOR_SPEED Error ARMRAPass::_rewrite(BaseNode* first, BaseNode* stop) noexcept {
+ uint32_t virtCount = cc()->_vRegArray.size();
+
+ BaseNode* node = first;
+ while (node != stop) {
+ BaseNode* next = node->next();
+ if (node->isInst()) {
+ InstNode* inst = node->as<InstNode>();
+ RAInst* raInst = node->passData<RAInst>();
+
+ Operand* operands = inst->operands();
+ uint32_t opCount = inst->opCount();
+
+ uint32_t i;
+
+ // Rewrite virtual registers into physical registers.
+ if (raInst) {
+ // If the instruction contains pass data (raInst) then it was a subject
+ // for register allocation and must be rewritten to use physical regs.
+ RATiedReg* tiedRegs = raInst->tiedRegs();
+ uint32_t tiedCount = raInst->tiedCount();
+
+ for (i = 0; i < tiedCount; i++) {
+ RATiedReg* tiedReg = &tiedRegs[i];
+
+ Support::BitWordIterator<uint32_t> useIt(tiedReg->useRewriteMask());
+ uint32_t useId = tiedReg->useId();
+ while (useIt.hasNext())
+ inst->rewriteIdAtIndex(useIt.next(), useId);
+
+ Support::BitWordIterator<uint32_t> outIt(tiedReg->outRewriteMask());
+ uint32_t outId = tiedReg->outId();
+ while (outIt.hasNext())
+ inst->rewriteIdAtIndex(outIt.next(), outId);
+ }
+
+ // This data is allocated by Zone passed to `runOnFunction()`, which
+ // will be reset after the RA pass finishes. So reset this data to
+ // prevent having a dead pointer after the RA pass is complete.
+ node->resetPassData();
+
+ if (ASMJIT_UNLIKELY(node->type() != NodeType::kInst)) {
+ // FuncRet terminates the flow, it must either be removed if the exit
+ // label is next to it (optimization) or patched to an architecture
+ // dependent jump instruction that jumps to the function's exit before
+ // the epilog.
+ if (node->type() == NodeType::kFuncRet) {
+ RABlock* block = raInst->block();
+ if (!isNextTo(node, _func->exitNode())) {
+ cc()->_setCursor(node->prev());
+ ASMJIT_PROPAGATE(emitJump(_func->exitNode()->label()));
+ }
+
+ BaseNode* prev = node->prev();
+ cc()->removeNode(node);
+ block->setLast(prev);
+ }
+ }
+ }
+
+ // Rewrite stack slot addresses.
+ for (i = 0; i < opCount; i++) {
+ Operand& op = operands[i];
+ if (op.isMem()) {
+ BaseMem& mem = op.as<BaseMem>();
+ if (mem.isRegHome()) {
+ uint32_t virtIndex = Operand::virtIdToIndex(mem.baseId());
+ if (ASMJIT_UNLIKELY(virtIndex >= virtCount))
+ return DebugUtils::errored(kErrorInvalidVirtId);
+
+ VirtReg* virtReg = cc()->virtRegByIndex(virtIndex);
+ RAWorkReg* workReg = virtReg->workReg();
+ ASMJIT_ASSERT(workReg != nullptr);
+
+ RAStackSlot* slot = workReg->stackSlot();
+ int32_t offset = slot->offset();
+
+ mem._setBase(_sp.type(), slot->baseRegId());
+ mem.clearRegHome();
+ mem.addOffsetLo32(offset);
+ }
+ }
+ }
+ }
+
+ node = next;
+ }
+
+ return kErrorOk;
+}
+
+// a64::ARMRAPass - Prolog & Epilog
+// ================================
+
+Error ARMRAPass::updateStackFrame() noexcept {
+ if (_func->frame().hasFuncCalls())
+ _func->frame().addDirtyRegs(RegGroup::kGp, Support::bitMask(Gp::kIdLr));
+
+ return BaseRAPass::updateStackFrame();
+}
+
+// a64::ARMRAPass - OnEmit
+// =======================
+
+Error ARMRAPass::emitMove(uint32_t workId, uint32_t dstPhysId, uint32_t srcPhysId) noexcept {
+ RAWorkReg* wReg = workRegById(workId);
+ BaseReg dst(wReg->signature(), dstPhysId);
+ BaseReg src(wReg->signature(), srcPhysId);
+
+ const char* comment = nullptr;
+
+#ifndef ASMJIT_NO_LOGGING
+ if (hasDiagnosticOption(DiagnosticOptions::kRAAnnotate)) {
+ _tmpString.assignFormat("<MOVE> %s", workRegById(workId)->name());
+ comment = _tmpString.data();
+ }
+#endif
+
+ return _emitHelper.emitRegMove(dst, src, wReg->typeId(), comment);
+}
+
+Error ARMRAPass::emitSwap(uint32_t aWorkId, uint32_t aPhysId, uint32_t bWorkId, uint32_t bPhysId) noexcept {
+ DebugUtils::unused(aWorkId, aPhysId, bWorkId, bPhysId);
+ return DebugUtils::errored(kErrorInvalidState);
+}
+
+Error ARMRAPass::emitLoad(uint32_t workId, uint32_t dstPhysId) noexcept {
+ RAWorkReg* wReg = workRegById(workId);
+ BaseReg dstReg(wReg->signature(), dstPhysId);
+ BaseMem srcMem(workRegAsMem(wReg));
+
+ const char* comment = nullptr;
+
+#ifndef ASMJIT_NO_LOGGING
+ if (hasDiagnosticOption(DiagnosticOptions::kRAAnnotate)) {
+ _tmpString.assignFormat("<LOAD> %s", workRegById(workId)->name());
+ comment = _tmpString.data();
+ }
+#endif
+
+ return _emitHelper.emitRegMove(dstReg, srcMem, wReg->typeId(), comment);
+}
+
+Error ARMRAPass::emitSave(uint32_t workId, uint32_t srcPhysId) noexcept {
+ RAWorkReg* wReg = workRegById(workId);
+ BaseMem dstMem(workRegAsMem(wReg));
+ BaseReg srcReg(wReg->signature(), srcPhysId);
+
+ const char* comment = nullptr;
+
+#ifndef ASMJIT_NO_LOGGING
+ if (hasDiagnosticOption(DiagnosticOptions::kRAAnnotate)) {
+ _tmpString.assignFormat("<SAVE> %s", workRegById(workId)->name());
+ comment = _tmpString.data();
+ }
+#endif
+
+ return _emitHelper.emitRegMove(dstMem, srcReg, wReg->typeId(), comment);
+}
+
+Error ARMRAPass::emitJump(const Label& label) noexcept {
+ return cc()->b(label);
+}
+
+Error ARMRAPass::emitPreCall(InvokeNode* invokeNode) noexcept {
+ DebugUtils::unused(invokeNode);
+ return kErrorOk;
+}
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // !ASMJIT_NO_AARCH64 && !ASMJIT_NO_COMPILER
diff --git a/src/asmjit/arm/a64rapass_p.h b/src/asmjit/arm/a64rapass_p.h
new file mode 100644
index 0000000..e1a90ab
--- /dev/null
+++ b/src/asmjit/arm/a64rapass_p.h
@@ -0,0 +1,105 @@
+// 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_ARM_A64RAPASS_P_H_INCLUDED
+#define ASMJIT_ARM_A64RAPASS_P_H_INCLUDED
+
+#include "../core/api-config.h"
+#ifndef ASMJIT_NO_COMPILER
+
+#include "../core/compiler.h"
+#include "../core/rabuilders_p.h"
+#include "../core/rapass_p.h"
+#include "../arm/a64assembler.h"
+#include "../arm/a64compiler.h"
+#include "../arm/a64emithelper_p.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+
+//! \cond INTERNAL
+//! \addtogroup asmjit_a64
+//! \{
+
+//! ARM register allocation pass.
+//!
+//! Takes care of generating function prologs and epilogs, and also performs
+//! register allocation.
+class ARMRAPass : public BaseRAPass {
+public:
+ ASMJIT_NONCOPYABLE(ARMRAPass)
+ typedef BaseRAPass Base;
+
+ EmitHelper _emitHelper;
+
+ //! \name Construction & Destruction
+ //! \{
+
+ ARMRAPass() noexcept;
+ virtual ~ARMRAPass() noexcept;
+
+ //! \}
+
+ //! \name Accessors
+ //! \{
+
+ //! Returns the compiler casted to `arm::Compiler`.
+ inline Compiler* cc() const noexcept { return static_cast<Compiler*>(_cb); }
+
+ //! Returns emit helper.
+ inline EmitHelper* emitHelper() noexcept { return &_emitHelper; }
+
+ //! \}
+
+ //! \name Events
+ //! \{
+
+ void onInit() noexcept override;
+ void onDone() noexcept override;
+
+ //! \}
+
+ //! \name CFG
+ //! \{
+
+ Error buildCFG() noexcept override;
+
+ //! \}
+
+ //! \name Rewrite
+ //! \{
+
+ Error _rewrite(BaseNode* first, BaseNode* stop) noexcept override;
+
+ //! \}
+
+ //! \name Prolog & Epilog
+ //! \{
+
+ Error updateStackFrame() noexcept override;
+
+ //! \}
+
+ //! \name Emit Helpers
+ //! \{
+
+ Error emitMove(uint32_t workId, uint32_t dstPhysId, uint32_t srcPhysId) noexcept override;
+ Error emitSwap(uint32_t aWorkId, uint32_t aPhysId, uint32_t bWorkId, uint32_t bPhysId) noexcept override;
+
+ Error emitLoad(uint32_t workId, uint32_t dstPhysId) noexcept override;
+ Error emitSave(uint32_t workId, uint32_t srcPhysId) noexcept override;
+
+ Error emitJump(const Label& label) noexcept override;
+ Error emitPreCall(InvokeNode* invokeNode) noexcept override;
+
+ //! \}
+};
+
+//! \}
+//! \endcond
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // !ASMJIT_NO_COMPILER
+#endif // ASMJIT_ARM_A64RAPASS_P_H_INCLUDED
diff --git a/src/asmjit/arm/a64utils.h b/src/asmjit/arm/a64utils.h
new file mode 100644
index 0000000..4a88ca5
--- /dev/null
+++ b/src/asmjit/arm/a64utils.h
@@ -0,0 +1,179 @@
+// 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_ARM_A64UTILS_H_INCLUDED
+#define ASMJIT_ARM_A64UTILS_H_INCLUDED
+
+#include "../arm/a64globals.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(a64)
+
+//! \addtogroup asmjit_a64
+//! \{
+
+//! Public utilities and helpers for targeting AArch64 architecture.
+namespace Utils {
+
+//! Decomposed fields of a logical immediate value (AArch64).
+struct LogicalImm {
+ uint32_t n;
+ uint32_t s;
+ uint32_t r;
+};
+
+//! Encodes the given `imm` value of the given `width` to a logical immediate value represented as N, S, and R fields
+//! and writes these fields to `out`.
+//!
+//! Encoding Table:
+//!
+//! ```
+//! +---+--------+--------+------+
+//! | N | ImmS | ImmR | Size |
+//! +---+--------+--------+------+
+//! | 1 | ssssss | rrrrrr | 64 |
+//! | 0 | 0sssss | .rrrrr | 32 |
+//! | 0 | 10ssss | ..rrrr | 16 |
+//! | 0 | 110sss | ...rrr | 8 |
+//! | 0 | 1110ss | ....rr | 4 |
+//! | 0 | 11110s | .....r | 2 |
+//! +---+--------+--------+------+
+//! ```
+ASMJIT_MAYBE_UNUSED
+static bool encodeLogicalImm(uint64_t imm, uint32_t width, a64::Utils::LogicalImm* out) noexcept {
+ // Determine the element width, which must be 2, 4, 8, 16, 32, or 64 bits.
+ do {
+ width /= 2;
+ uint64_t mask = (uint64_t(1) << width) - 1u;
+ if ((imm & mask) != ((imm >> width) & mask)) {
+ width *= 2;
+ break;
+ }
+ } while (width > 2);
+
+ // Patterns of all zeros and all ones are not encodable.
+ uint64_t lsbMask = Support::lsbMask<uint64_t>(width);
+ imm &= lsbMask;
+
+ if (imm == 0 || imm == lsbMask)
+ return false;
+
+ // Inspect the pattern and get the most important bit indexes.
+ //
+ // oIndex <-+ +-> zIndex
+ // | |
+ // |..zeros..|oCount|zCount|..ones..|
+ // |000000000|111111|000000|11111111|
+
+ uint32_t zIndex = Support::ctz(~imm);
+ uint64_t zImm = imm ^ ((uint64_t(1) << zIndex) - 1);
+ uint32_t zCount = (zImm ? Support::ctz(zImm) : width) - zIndex;
+
+ uint32_t oIndex = zIndex + zCount;
+ uint64_t oImm = ~(zImm ^ Support::lsbMask<uint64_t>(oIndex));
+ uint32_t oCount = (oImm ? Support::ctz(oImm) : width) - (oIndex);
+
+ // Verify whether the bit-pattern is encodable.
+ uint64_t mustBeZero = oImm ^ ~Support::lsbMask<uint64_t>(oIndex + oCount);
+ if (mustBeZero != 0 || (zIndex > 0 && width - (oIndex + oCount) != 0))
+ return false;
+
+ out->n = width == 64;
+ out->s = (oCount + zIndex - 1) | (Support::neg(width * 2) & 0x3F);
+ out->r = width - oIndex;
+ return true;
+}
+
+//! Returns true if the given `imm` value is encodable as a logical immediate. The `width` argument describes the
+//! 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 {
+ LogicalImm dummy;
+ return encodeLogicalImm(imm, width, &dummy);
+}
+
+//! 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 {
+ constexpr T kMask = T(0x0101010101010101 & Support::allOnes<T>());
+ return imm == (imm & kMask) * T(255);
+}
+
+//! \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 {
+ constexpr uint32_t kAllBsMask = Support::lsbMask<uint32_t>(kNumBBits);
+ constexpr uint32_t kB0Pattern = Support::bitMask(kNumBBits - 1);
+ constexpr uint32_t kB1Pattern = kAllBsMask ^ kB0Pattern;
+
+ T immZ = val & Support::lsbMask<T>(kNumZeroBits);
+ uint32_t immB = uint32_t(val >> (kNumZeroBits + kNumCDEFGHBits)) & kAllBsMask;
+
+ // ImmZ must be all zeros and ImmB must either be B0 or B1 pattern.
+ return immZ == 0 && (immB == kB0Pattern || immB == kB1Pattern);
+}
+//! \endcond
+
+//! Returns true if the given half 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.
+//!
+//! The floating point must have bits distributed in the following way:
+//!
+//! ```
+//! [aBbbcdef|gh000000]
+//! ```
+static inline 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.
+//!
+//! The floating point must have bits distributed in the following way:
+//!
+//! ```
+//! [aBbbbbbc|defgh000|00000000|00000000]
+//! ```
+static inline 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)); }
+
+//! 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.
+//!
+//! The floating point must have bits distributed in the following way:
+//!
+//! ```
+//! [aBbbbbbb|bbcdefgh|00000000|00000000|00000000|00000000|00000000|00000000]
+//! ```
+static inline 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)); }
+
+//! \cond
+template<typename T, uint32_t kNumBBits, uint32_t kNumCDEFGHBits, uint32_t kNumZeroBits>
+static inline uint32_t encodeFPToImm8Generic(T val) noexcept {
+ uint32_t bits = uint32_t(val >> kNumZeroBits);
+ return ((bits >> (kNumBBits + kNumCDEFGHBits - 7)) & 0x80u) | (bits & 0x7F);
+}
+//! \endcond
+
+//! Encodes a double precision floating point value into IMM8 format.
+//!
+//! \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); }
+//! \overload
+static inline uint32_t encodeFP64ToImm8(double val) noexcept { return encodeFP64ToImm8(Support::bitCast<uint64_t>(val)); }
+
+} // {Utils}
+
+//! \}
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // ASMJIT_ARM_A64UTILS_H_INCLUDED
+
diff --git a/src/asmjit/arm/armformatter.cpp b/src/asmjit/arm/armformatter.cpp
new file mode 100644
index 0000000..0432043
--- /dev/null
+++ b/src/asmjit/arm/armformatter.cpp
@@ -0,0 +1,143 @@
+// 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"
+#ifndef ASMJIT_NO_LOGGING
+
+#include "../core/misc_p.h"
+#include "../core/support.h"
+#include "../arm/armformatter_p.h"
+#include "../arm/armoperand.h"
+#include "../arm/a64instapi_p.h"
+#include "../arm/a64instdb_p.h"
+
+#ifndef ASMJIT_NO_COMPILER
+ #include "../core/compiler.h"
+#endif
+
+ASMJIT_BEGIN_SUB_NAMESPACE(arm)
+
+// arm::FormatterInternal - Format Feature
+// =======================================
+
+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"
+ "AES\0"
+ "ALTNZCV\0"
+ "ASIMD\0"
+ "BF16\0"
+ "BTI\0"
+ "CPUID\0"
+ "CRC32\0"
+ "DGH\0"
+ "DIT\0"
+ "DOTPROD\0"
+ "EDSP\0"
+ "FCMA\0"
+ "FJCVTZS\0"
+ "FLAGM\0"
+ "FP16CONV\0"
+ "FP16FML\0"
+ "FP16FULL\0"
+ "FRINT\0"
+ "I8MM\0"
+ "IDIVA\0"
+ "IDIVT\0"
+ "LSE\0"
+ "MTE\0"
+ "RCPC_IMMO\0"
+ "RDM\0"
+ "PMU\0"
+ "PMULL\0"
+ "RNG\0"
+ "SB\0"
+ "SHA1\0"
+ "SHA2\0"
+ "SHA3\0"
+ "SHA512\0"
+ "SM3\0"
+ "SM4\0"
+ "SSBS\0"
+ "SVE\0"
+ "SVE_BF16\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"
+ "TME\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
+ };
+ // @EnumStringEnd@
+
+ return sb.append(sFeatureString + sFeatureIndex[Support::min<uint32_t>(featureId, uint32_t(CpuFeatures::ARM::kMaxValue) + 1)]);
+}
+
+// arm::FormatterInternal - Format Constants
+// =========================================
+
+ASMJIT_FAVOR_SIZE Error FormatterInternal::formatCondCode(String& sb, CondCode cc) noexcept {
+ static const char condCodeData[] =
+ "al\0" "na\0"
+ "eq\0" "ne\0"
+ "cs\0" "cc\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>";
+ switch (shiftOp) {
+ case ShiftOp::kLSL: str = "lsl"; break;
+ case ShiftOp::kLSR: str = "lsr"; break;
+ case ShiftOp::kASR: str = "asr"; break;
+ case ShiftOp::kROR: str = "ror"; break;
+ case ShiftOp::kRRX: str = "rrx"; break;
+ case ShiftOp::kMSL: str = "msl"; break;
+ case ShiftOp::kUXTB: str = "uxtb"; break;
+ case ShiftOp::kUXTH: str = "uxth"; break;
+ case ShiftOp::kUXTW: str = "uxtw"; break;
+ case ShiftOp::kUXTX: str = "uxtx"; break;
+ case ShiftOp::kSXTB: str = "sxtb"; break;
+ case ShiftOp::kSXTH: str = "sxth"; break;
+ case ShiftOp::kSXTW: str = "sxtw"; break;
+ case ShiftOp::kSXTX: str = "sxtx"; break;
+ }
+ return sb.append(str);
+}
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // !ASMJIT_NO_LOGGING
diff --git a/src/asmjit/arm/armformatter_p.h b/src/asmjit/arm/armformatter_p.h
new file mode 100644
index 0000000..5821730
--- /dev/null
+++ b/src/asmjit/arm/armformatter_p.h
@@ -0,0 +1,44 @@
+// 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_ARM_ARMFORMATTER_P_H_INCLUDED
+#define ASMJIT_ARM_ARMFORMATTER_P_H_INCLUDED
+
+#include "../core/api-config.h"
+#ifndef ASMJIT_NO_LOGGING
+
+#include "../core/formatter.h"
+#include "../core/string.h"
+#include "../arm/armglobals.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(arm)
+
+//! \cond INTERNAL
+//! \addtogroup asmjit_arm
+//! \{
+
+namespace FormatterInternal {
+
+Error ASMJIT_CDECL formatFeature(
+ String& sb,
+ uint32_t featureId) noexcept;
+
+Error ASMJIT_CDECL formatCondCode(
+ String& sb,
+ CondCode cc) noexcept;
+
+Error ASMJIT_CDECL formatShiftOp(
+ String& sb,
+ ShiftOp shiftOp) noexcept;
+
+} // {FormatterInternal}
+
+//! \}
+//! \endcond
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // !ASMJIT_NO_LOGGING
+#endif // ASMJIT_ARM_ARMFORMATTER_P_H_INCLUDED
diff --git a/src/asmjit/arm/armglobals.h b/src/asmjit/arm/armglobals.h
new file mode 100644
index 0000000..506646f
--- /dev/null
+++ b/src/asmjit/arm/armglobals.h
@@ -0,0 +1,21 @@
+// 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_ARM_ARMGLOBALS_H_INCLUDED
+#define ASMJIT_ARM_ARMGLOBALS_H_INCLUDED
+
+#include "../core/archcommons.h"
+#include "../core/inst.h"
+
+//! \namespace asmjit::arm
+//! \ingroup asmjit_arm
+//!
+//! API shared between AArch32 & AArch64 backends.
+
+ASMJIT_BEGIN_SUB_NAMESPACE(arm)
+
+ASMJIT_END_SUB_NAMESPACE
+
+#endif // ASMJIT_ARM_ARMGLOBALS_H_INCLUDED
diff --git a/src/asmjit/arm/armoperand.h b/src/asmjit/arm/armoperand.h
new file mode 100644
index 0000000..e7803e9
--- /dev/null
+++ b/src/asmjit/arm/armoperand.h
@@ -0,0 +1,596 @@
+// 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_ARM_ARMOPERAND_H_INCLUDED
+#define ASMJIT_ARM_ARMOPERAND_H_INCLUDED
+
+#include "../core/archtraits.h"
+#include "../core/operand.h"
+#include "../core/type.h"
+#include "../arm/armglobals.h"
+
+ASMJIT_BEGIN_SUB_NAMESPACE(arm)
+
+//! \addtogroup asmjit_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 contains information about a particular register type. It's used by asmjit to setup register
+//! information on-the-fly and to populate tables that contain register information (this way it's possible to
+//! change register types and groups without having to reorder these tables).
+template<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 );
+//! \endcond
+
+//! Register (ARM).
+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 an `X` register (64-bit).
+ inline 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; }
+ //! Gets whether the register is a VEC-H register (16-bit).
+ inline 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; }
+ //! Gets whether the register is a VEC-D register (64-bit).
+ inline 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; }
+
+ //! 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; }
+
+ //! Gets whether the register is a VEC-V register (128-bit).
+ inline constexpr bool isVecV() const noexcept { return baseSignature() == RegTraits<RegType::kARM_VecV>::kSignature; }
+
+ template<RegType kRegType>
+ inline void setRegT(uint32_t id) noexcept {
+ setSignature(RegTraits<kRegType>::kSignature);
+ setId(id);
+ }
+
+ inline 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); }
+
+ template<RegType kRegType>
+ static inline RegGroup groupOfT() noexcept { return RegTraits<kRegType>::kGroup; }
+
+ template<RegType kRegType>
+ static inline 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;
+};
+
+//! Vector register (ARM).
+class Vec : public Reg {
+public:
+ ASMJIT_DEFINE_ABSTRACT_REG(Vec, Reg)
+
+ //! Additional signature bits used by arm::Vec.
+ enum AdditionalBits : uint32_t {
+ // Register element type (3 bits).
+ // |........|........|.XXX....|........|
+ kSignatureRegElementTypeShift = 12,
+ kSignatureRegElementTypeMask = 0x07 << kSignatureRegElementTypeShift,
+
+ // Register has element index (1 bit).
+ // |........|........|X.......|........|
+ kSignatureRegElementFlagShift = 15,
+ kSignatureRegElementFlagMask = 0x01 << kSignatureRegElementFlagShift,
+
+ // Register element index (4 bits).
+ // |........|....XXXX|........|........|
+ kSignatureRegElementIndexShift = 16,
+ 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); }
+
+ //! Returns element index of the register.
+ inline 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 {
+ _signature |= kSignatureRegElementFlagMask;
+ _signature.setField<kSignatureRegElementIndexMask>(elementIndex);
+ }
+ //! Resets element index of the register.
+ inline 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:
+ //! \cond INTERNAL
+ //! Additional bits of operand's signature used by `arm::Mem`.
+ enum AdditionalBits : uint32_t {
+ // Index shift value (5 bits).
+ // |........|.....XXX|XX......|........|
+ kSignatureMemShiftValueShift = 14,
+ kSignatureMemShiftValueMask = 0x1Fu << kSignatureMemShiftValueShift,
+
+ // Shift operation type (4 bits).
+ // |........|XXXX....|........|........|
+ kSignatureMemPredicateShift = 20,
+ kSignatureMemPredicateMask = 0x0Fu << kSignatureMemPredicateShift
+ };
+ //! \endcond
+
+ //! 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
+ };
+
+ //! \name Construction & Destruction
+ //! \{
+
+ //! Construct a default `Mem` operand, that points to [0].
+ inline constexpr Mem() noexcept
+ : BaseMem() {}
+
+ inline constexpr Mem(const Mem& other) noexcept
+ : BaseMem(other) {}
+
+ inline explicit Mem(Globals::NoInit_) noexcept
+ : BaseMem(Globals::NoInit) {}
+
+ inline 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
+ : 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
+ : 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
+ : 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
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
+ Signature::fromMemBaseType(base.type()) |
+ Signature::fromMemIndexType(index.type()) |
+ Signature::fromValue<kSignatureMemPredicateMask>(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
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
+ signature, uint32_t(base >> 32), 0, int32_t(uint32_t(base & 0xFFFFFFFFu))) {}
+
+ //! \}
+
+ //! \name Overloaded Operators
+ //! \{
+
+ inline Mem& operator=(const Mem& other) noexcept = default;
+
+ //! \}
+
+ //! \name ARM Specific Features
+ //! \{
+
+ //! Clones the memory operand.
+ inline constexpr Mem clone() const noexcept { return Mem(*this); }
+ //! Gets new memory operand adjusted by `off`.
+ inline Mem cloneAdjusted(int64_t off) const noexcept {
+ Mem result(*this);
+ result.addOffset(off);
+ return result;
+ }
+
+ using BaseMem::setIndex;
+
+ inline void setIndex(const BaseReg& index, uint32_t shift) noexcept {
+ setIndex(index);
+ setShift(shift);
+ }
+
+ //! Gets whether the memory operand has shift (aka scale) constant.
+ inline 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>(); }
+ //! 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); }
+
+ 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; }
+
+ inline void resetToFixedOffset() noexcept { resetPredicate(); }
+ inline void makePreIndex() noexcept { setPredicate(kOffsetPreIndex); }
+ inline void makePostIndex() noexcept { setPredicate(kOffsetPostIndex); }
+
+ inline Mem pre() const noexcept {
+ Mem result(*this);
+ result.setPredicate(kOffsetPreIndex);
+ return result;
+ }
+
+ inline Mem pre(int64_t off) const noexcept {
+ Mem result(*this);
+ result.setPredicate(kOffsetPreIndex);
+ result.addOffset(off);
+ return result;
+ }
+
+ inline Mem post() const noexcept {
+ Mem result(*this);
+ result.setPredicate(kOffsetPreIndex);
+ return result;
+ }
+
+ inline Mem post(int64_t off) const noexcept {
+ Mem result(*this);
+ result.setPredicate(kOffsetPostIndex);
+ result.addOffset(off);
+ return result;
+ }
+
+ //! \}
+};
+
+//! 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.
+//!
+//! \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); }
+
+//! \}
+
+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
+
+#endif // ASMJIT_ARM_ARMOPERAND_H_INCLUDED
diff --git a/src/asmjit/core.h b/src/asmjit/core.h
index 32f208f..4406ed8 100644
--- a/src/asmjit/core.h
+++ b/src/asmjit/core.h
@@ -26,9 +26,9 @@ namespace asmjit {
//!
//! \note It's important to understand that in order to learn AsmJit all groups are important. Some groups can be
//! omitted if a particular tool is out of interest - for example \ref asmjit_assembler users don't need to know
-//! about \ref asmjit_builder, but it's not the opposite. \ref asmjit_builder users must know about \ref
+//! about \ref asmjit_builder, but it's not the opposite. \ref asmjit_builder users should know about \ref
//! asmjit_assembler as it also uses operands, labels, and other concepts. Similarly \ref asmjit_compiler users
-//! must know how both \ref asmjit_assembler and \ref asmjit_builder tools work.
+//! should know how both \ref asmjit_assembler and \ref asmjit_builder tools work.
//!
//! \section where_to_start Where To Start
//!
@@ -70,13 +70,13 @@ namespace asmjit {
//!
//! - Make sure you put a breakpoint into \ref DebugUtils::errored() function if you have a problem with AsmJit
//! returning errors during instruction encoding or register allocation. Having an active breakpoint there can
-//! help to reveal the origin of the error, to inspect variables and other conditions that caused to it.
+//! help to reveal the origin of the error, to inspect variables and other conditions that caused it.
//!
//! The reason for using \ref Logger and \ref ErrorHandler is that they provide a very useful information about what's
-//! happening inside emitters. In many cases the information provided by these two is crucial to quickly fix issues
-//! that happen during development (for example wrong instruction, address, or register used). In addition, output from
-//! \ref Logger is always necessary when filling bug reports. In other words, using logging and proper error handling
-//! can save a lot of time during the development.
+//! happening inside emitters. In many cases the information provided by these two is crucial to quickly identify and
+//! fix issues that happen during development (for example wrong instruction, address, or register used). In addition,
+//! output from \ref Logger is always necessary when filling bug reports. In other words, using logging and proper error
+//! handling can save a lot of time during the development and can also save users from submitting issues.
//!
//! \section main_other Other Pages
//!
@@ -147,7 +147,9 @@ namespace asmjit {
//!
//! ### Supported Backends / Architectures
//!
-//! - **X86** - Both 32-bit and 64-bit backends tested on our CI.
+//! - **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)
//!
//! ### Static Builds and Embedding
//!
@@ -1807,6 +1809,14 @@ namespace asmjit {
//! \brief X86/X64 backend.
+//! \defgroup asmjit_arm ARM Commons
+//! \brief ARM commons shared between AArch32 and AArch64.
+
+
+//! \defgroup asmjit_a64 AArch64 Backend
+//! \brief AArch64 backend.
+
+
//! \cond INTERNAL
//! \defgroup asmjit_ra RA
//! \brief Register allocator internals.
diff --git a/src/asmjit/core/api-config.h b/src/asmjit/core/api-config.h
index 3c4f8b2..a0fb979 100644
--- a/src/asmjit/core/api-config.h
+++ b/src/asmjit/core/api-config.h
@@ -13,7 +13,7 @@
//! \{
//! AsmJit library version in `(Major << 16) | (Minor << 8) | (Patch)` format.
-#define ASMJIT_LIBRARY_VERSION 0x010800 /* 1.8.0 */
+#define ASMJIT_LIBRARY_VERSION 0x010900 /* 1.9.0 */
//! \def ASMJIT_ABI_NAMESPACE
//!
@@ -24,7 +24,7 @@
//! default, which makes it possible to use use multiple AsmJit libraries within a single project, totally controlled
//! by the users. This is useful especially in cases in which some of such library comes from a third party.
#ifndef ASMJIT_ABI_NAMESPACE
- #define ASMJIT_ABI_NAMESPACE _abi_1_8
+ #define ASMJIT_ABI_NAMESPACE _abi_1_9
#endif
//! \}
@@ -79,6 +79,12 @@ namespace asmjit {
//! 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
+
//! Disables non-host backends entirely (useful for JIT compilers to minimize the library size).
#define ASMJIT_NO_FOREIGN
@@ -206,6 +212,10 @@ namespace asmjit {
#if !ASMJIT_ARCH_X86 && !defined(ASMJIT_NO_X86)
#define ASMJIT_NO_X86
#endif
+
+ #if !ASMJIT_ARCH_ARM && !defined(ASMJIT_NO_AARCH64)
+ #define ASMJIT_NO_AARCH64
+ #endif
#endif
@@ -344,7 +354,6 @@ namespace asmjit {
#define ASMJIT_VECTORCALL
#endif
-
// Type alignment (not allowed by C++11 'alignas' keyword).
#if defined(__GNUC__)
#define ASMJIT_ALIGN_TYPE(TYPE, N) __attribute__((__aligned__(N))) TYPE
@@ -383,6 +392,15 @@ namespace asmjit {
#define ASMJIT_NONNULL(FUNCTION_ARGUMENT) FUNCTION_ARGUMENT
#endif
+//! \def ASMJIT_NOEXCEPT_TYPE
+//!
+//! Defined to `noexcept` in C++17 mode or nothing otherwise. Used by function typedefs.
+#if __cplusplus >= 201703L
+ #define ASMJIT_NOEXCEPT_TYPE noexcept
+#else
+ #define ASMJIT_NOEXCEPT_TYPE
+#endif
+
//! \def ASMJIT_ASSUME(...)
//!
//! Macro that tells the C/C++ compiler that the expression `...` evaluates to true.
diff --git a/src/asmjit/core/archcommons.h b/src/asmjit/core/archcommons.h
index 88b6069..e9d2c84 100644
--- a/src/asmjit/core/archcommons.h
+++ b/src/asmjit/core/archcommons.h
@@ -17,12 +17,105 @@ ASMJIT_BEGIN_SUB_NAMESPACE(arm)
//! \addtogroup asmjit_arm
//! \{
+//! Condition code (both AArch32 & AArch64).
+//!
+//! \note This enumeration doesn't match condition code that is used in AArch32/AArch64 opcodes. In general this
+//! condition code is encoded as `(cc - 2) & 0xF` so that `kAL` condition code is zero and encoded as 0xE in opcode.
+//! This makes it easier to use a condition code as an instruction modifier that defaults to 'al'.
+enum class CondCode : uint8_t {
+ kAL = 0x00u, //!< (no condition code) (always)
+ kNA = 0x01u, //!< (not available) (special)
+ kEQ = 0x02u, //!< Z==1 (any_sign ==)
+ 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 < )
+ kMI = 0x06u, //!< N==1 (is negative)
+ kPL = 0x07u, //!< N==0 (is positive or zero)
+ kVS = 0x08u, //!< V==1 (is overflow)
+ kVC = 0x09u, //!< V==0 (no overflow)
+ kHI = 0x0Au, //!< C==1 & Z==0 (unsigned > )
+ kLS = 0x0Bu, //!< C==0 | Z==1 (unsigned <=)
+ kGE = 0x0Cu, //!< N==V (signed >=)
+ kLT = 0x0Du, //!< N!=V (signed < )
+ 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.
+
+ 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).
+
+ kNegative = kMI, //!< Negative.
+ kPositive = kPL, //!< Positive or zero.
+
+ kSignedLT = kLT, //!< Signed `a < b`.
+ kSignedLE = kLE, //!< Signed `a <= b`.
+ kSignedGT = kGT, //!< Signed `a > b`.
+ kSignedGE = kGE, //!< Signed `a >= b`.
+
+ kUnsignedLT = kLO, //!< Unsigned `a < b`.
+ kUnsignedLE = kLS, //!< Unsigned `a <= b`.
+ kUnsignedGT = kHI, //!< Unsigned `a > b`.
+ kUnsignedGE = kHS, //!< Unsigned `a >= b`.
+
+ 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,
+
+ //! Maximum value of `DataType`.
+ kMaxValue = 15
+};
+
//! Shift operation predicate (ARM) describes either SHIFT or EXTEND operation.
//!
//! \note The constants are AsmJit specific. The first 5 values describe real constants on ARM32 and AArch64 hardware,
//! however, the addition constants that describe extend modes are specific to AsmJit and would be translated to the
//! AArch64 specific constants by the assembler.
-enum class ShiftOp {
+enum class ShiftOp : uint32_t {
//! Shift left logical operation (default).
//!
//! Available to all ARM architectures.
@@ -38,14 +131,10 @@ enum class ShiftOp {
//! Available to all ARM architectures.
kASR = 0x02u,
- //! Rotate right operation.
- //!
- //! \note Not available in AArch64 mode.
+ //! Rotate right operation (AArch32 only).
kROR = 0x03u,
- //! Rotate right with carry operation (encoded as `kShiftROR` with zero).
- //!
- //! \note Not available in AArch64 mode.
+ //! Rotate right with carry operation (encoded as `ShiftOp::kROR` with zero) (AArch32 only).
kRRX = 0x04u,
//! Shift left by filling low order bits with ones.
diff --git a/src/asmjit/core/archtraits.cpp b/src/asmjit/core/archtraits.cpp
index b83d930..fc825df 100644
--- a/src/asmjit/core/archtraits.cpp
+++ b/src/asmjit/core/archtraits.cpp
@@ -11,8 +11,8 @@
#include "../x86/x86archtraits_p.h"
#endif
-#ifdef ASMJIT_BUILD_ARM
- #include "../arm/armarchtraits_p.h"
+#if !defined(ASMJIT_NO_AARCH64)
+ #include "../arm/a64archtraits_p.h"
#endif
ASMJIT_BEGIN_NAMESPACE
@@ -83,8 +83,8 @@ ASMJIT_VARAPI const ArchTraits _archTraits[uint32_t(Arch::kMaxValue) + 1] = {
noArchTraits,
// AArch64 architecture.
-#ifdef ASMJIT_BUILD_ARM
- arm::a64ArchTraits,
+#if !defined(ASMJIT_NO_AARCH64)
+ a64::a64ArchTraits,
#else
noArchTraits,
#endif
diff --git a/src/asmjit/core/assembler.cpp b/src/asmjit/core/assembler.cpp
index ea223a3..d6c8762 100644
--- a/src/asmjit/core/assembler.cpp
+++ b/src/asmjit/core/assembler.cpp
@@ -271,7 +271,7 @@ Error BaseAssembler::embedLabel(const Label& label, size_t dataSize) {
re->_sourceSectionId = _section->id();
re->_sourceOffset = offset();
- re->_format.resetToDataValue(uint32_t(dataSize));
+ re->_format.resetToSimpleValue(OffsetType::kUnsignedOffset, dataSize);
if (le->isBound()) {
re->_targetSectionId = le->section()->id();
@@ -279,7 +279,7 @@ Error BaseAssembler::embedLabel(const Label& label, size_t dataSize) {
}
else {
OffsetFormat of;
- of.resetToDataValue(uint32_t(dataSize));
+ of.resetToSimpleValue(OffsetType::kUnsignedOffset, dataSize);
LabelLink* link = _code->newLabelLink(le, _section->id(), offset(), 0, of);
if (ASMJIT_UNLIKELY(!link))
@@ -348,7 +348,7 @@ Error BaseAssembler::embedLabelDelta(const Label& label, const Label& base, size
exp->setValueAsLabel(0, labelEntry);
exp->setValueAsLabel(1, baseEntry);
- re->_format.resetToDataValue(dataSize);
+ re->_format.resetToSimpleValue(OffsetType::kSignedOffset, dataSize);
re->_sourceSectionId = _section->id();
re->_sourceOffset = offset();
re->_payload = (uint64_t)(uintptr_t)exp;
diff --git a/src/asmjit/core/builder.cpp b/src/asmjit/core/builder.cpp
index e3767a1..5df243e 100644
--- a/src/asmjit/core/builder.cpp
+++ b/src/asmjit/core/builder.cpp
@@ -590,7 +590,9 @@ Error BaseBuilder::_emit(InstId instId, const Operand_& o0, const Operand_& o1,
Operand_ opArray[Globals::kMaxOpCount];
EmitterUtils::opArrayFromEmitArgs(opArray, o0, o1, o2, opExt);
- Error err = InstAPI::validate(arch(), BaseInst(instId, options, _extraReg), opArray, opCount);
+ ValidationFlags validationFlags = isCompiler() ? ValidationFlags::kEnableVirtRegs : ValidationFlags::kNone;
+ Error err = _funcs.validate(arch(), BaseInst(instId, options, _extraReg), opArray, opCount, validationFlags);
+
if (ASMJIT_UNLIKELY(err)) {
resetInstOptions();
resetExtraReg();
diff --git a/src/asmjit/core/builder.h b/src/asmjit/core/builder.h
index 8376986..3575de2 100644
--- a/src/asmjit/core/builder.h
+++ b/src/asmjit/core/builder.h
@@ -746,6 +746,9 @@ public:
//! Returns the instruction id, see `BaseInst::Id`.
inline InstId id() const noexcept { return _baseInst.id(); }
+ //! Returns the instruction real id, see `BaseInst::Id`.
+ inline 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); }
diff --git a/src/asmjit/core/codeholder.cpp b/src/asmjit/core/codeholder.cpp
index 25d8f90..cf763cf 100644
--- a/src/asmjit/core/codeholder.cpp
+++ b/src/asmjit/core/codeholder.cpp
@@ -194,6 +194,10 @@ Error CodeHolder::attach(BaseEmitter* emitter) noexcept {
if (ASMJIT_UNLIKELY(type == EmitterType::kNone || uint32_t(type) > uint32_t(EmitterType::kMaxValue)))
return DebugUtils::errored(kErrorInvalidState);
+ uint64_t archMask = emitter->_archMask;
+ if (ASMJIT_UNLIKELY(!(archMask & (uint64_t(1) << uint32_t(arch())))))
+ return DebugUtils::errored(kErrorInvalidArch);
+
// This is suspicious, but don't fail if `emitter` is already attached
// to this code holder. This is not error, but it's not recommended.
if (emitter->_code != nullptr) {
@@ -944,7 +948,6 @@ Error CodeHolder::relocateToBase(uint64_t baseAddress) noexcept {
return DebugUtils::errored(kErrorInvalidRelocEntry);
uint8_t* buffer = sourceSection->data();
- size_t valueOffset = size_t(re->sourceOffset()) + re->format().valueOffset();
switch (re->relocType()) {
case RelocType::kExpression: {
@@ -970,12 +973,18 @@ Error CodeHolder::relocateToBase(uint64_t baseAddress) noexcept {
case RelocType::kAbsToRel: {
value -= baseAddress + sectionOffset + sourceOffset + regionSize;
- if (addressSize > 4 && !Support::isInt32(int64_t(value)))
+
+ // Sign extend as we are not interested in the high 32-bit word in a 32-bit address space.
+ if (addressSize <= 4)
+ value = uint64_t(int64_t(int32_t(value & 0xFFFFFFFFu)));
+ else if (!Support::isInt32(int64_t(value)))
return DebugUtils::errored(kErrorRelocOffsetOutOfRange);
+
break;
}
case RelocType::kX64AddressEntry: {
+ size_t valueOffset = size_t(re->sourceOffset()) + re->format().valueOffset();
if (re->format().valueSize() != 4 || valueOffset < 2)
return DebugUtils::errored(kErrorInvalidRelocEntry);
@@ -1030,25 +1039,8 @@ Error CodeHolder::relocateToBase(uint64_t baseAddress) noexcept {
return DebugUtils::errored(kErrorInvalidRelocEntry);
}
- switch (re->format().valueSize()) {
- case 1:
- Support::writeU8(buffer + valueOffset, uint8_t(value & 0xFFu));
- break;
-
- case 2:
- Support::writeU16uLE(buffer + valueOffset, uint16_t(value & 0xFFFFu));
- break;
-
- case 4:
- Support::writeU32uLE(buffer + valueOffset, uint32_t(value & 0xFFFFFFFFu));
- break;
-
- case 8:
- Support::writeU64uLE(buffer + valueOffset, value);
- break;
-
- default:
- return DebugUtils::errored(kErrorInvalidRelocEntry);
+ if (!CodeWriterUtils::writeOffset(buffer + re->sourceOffset(), int64_t(value), re->format())) {
+ return DebugUtils::errored(kErrorInvalidRelocEntry);
}
}
diff --git a/src/asmjit/core/codeholder.h b/src/asmjit/core/codeholder.h
index b6257f2..e3bd0d5 100644
--- a/src/asmjit/core/codeholder.h
+++ b/src/asmjit/core/codeholder.h
@@ -276,7 +276,10 @@ enum class OffsetType : uint8_t {
//!
//! This offset type is sufficient for many targets that store offset as a continuous set bits within an
//! instruction word / sequence of bytes.
- kCommon = 0,
+ kSignedOffset,
+
+ //! An unsigned value having `_immBitCount` bits and shifted by `_immBitShift`.
+ kUnsignedOffset,
// AArch64 Specific Offset Formats
// -------------------------------
@@ -370,15 +373,15 @@ struct OffsetFormat {
//!
//! The region will be the same size as data and immediate bits would correspond to `dataSize * 8`. There will be
//! no immediate bit shift or discarded bits.
- inline void resetToDataValue(size_t dataSize) noexcept {
- ASMJIT_ASSERT(dataSize <= 8u);
+ inline void resetToSimpleValue(OffsetType type, size_t valueSize) noexcept {
+ ASMJIT_ASSERT(valueSize <= 8u);
- _type = OffsetType::kCommon;
+ _type = type;
_flags = uint8_t(0);
- _regionSize = uint8_t(dataSize);
- _valueSize = uint8_t(dataSize);
+ _regionSize = uint8_t(valueSize);
+ _valueSize = uint8_t(valueSize);
_valueOffset = uint8_t(0);
- _immBitCount = uint8_t(dataSize * 8u);
+ _immBitCount = uint8_t(valueSize * 8u);
_immBitShift = uint8_t(0);
_immDiscardLsb = uint8_t(0);
}
diff --git a/src/asmjit/core/codewriter.cpp b/src/asmjit/core/codewriter.cpp
index b416dec..1babc5f 100644
--- a/src/asmjit/core/codewriter.cpp
+++ b/src/asmjit/core/codewriter.cpp
@@ -14,26 +14,46 @@ bool CodeWriterUtils::encodeOffset32(uint32_t* dst, int64_t offset64, const Offs
uint32_t bitShift = format.immBitShift();
uint32_t discardLsb = format.immDiscardLsb();
+ // Invalid offset (should not happen).
if (!bitCount || bitCount > format.valueSize() * 8u)
return false;
- if (discardLsb) {
- ASMJIT_ASSERT(discardLsb <= 32);
- if ((offset64 & Support::lsbMask<uint32_t>(discardLsb)) != 0)
+ uint32_t value;
+
+ // First handle all unsigned offset types.
+ if (format.type() == OffsetType::kUnsignedOffset) {
+ if (discardLsb) {
+ ASMJIT_ASSERT(discardLsb <= 32);
+ if ((offset64 & Support::lsbMask<uint32_t>(discardLsb)) != 0)
+ return false;
+ offset64 = int64_t(uint64_t(offset64) >> discardLsb);
+ }
+
+ value = uint32_t(offset64 & Support::lsbMask<uint32_t>(bitCount));
+ if (value != offset64)
return false;
- offset64 >>= discardLsb;
}
+ else {
+ // The rest of OffsetType options are all signed.
+ if (discardLsb) {
+ ASMJIT_ASSERT(discardLsb <= 32);
+ if ((offset64 & Support::lsbMask<uint32_t>(discardLsb)) != 0)
+ return false;
+ offset64 >>= discardLsb;
+ }
- if (!Support::isInt32(offset64))
- return false;
+ if (!Support::isInt32(offset64))
+ return false;
- int32_t offset32 = int32_t(offset64);
- if (!Support::isEncodableOffset32(offset32, bitCount))
- return false;
+ value = uint32_t(int32_t(offset64));
+ if (!Support::isEncodableOffset32(int32_t(value), bitCount))
+ return false;
+ }
switch (format.type()) {
- case OffsetType::kCommon: {
- *dst = (uint32_t(offset32) & Support::lsbMask<uint32_t>(bitCount)) << bitShift;
+ case OffsetType::kSignedOffset:
+ case OffsetType::kUnsignedOffset: {
+ *dst = (value & Support::lsbMask<uint32_t>(bitCount)) << bitShift;
return true;
}
@@ -43,8 +63,8 @@ bool CodeWriterUtils::encodeOffset32(uint32_t* dst, int64_t offset64, const Offs
if (format.valueSize() != 4 || bitCount != 21 || bitShift != 5)
return false;
- uint32_t immLo = uint32_t(offset32) & 0x3u;
- uint32_t immHi = uint32_t(offset32 >> 2) & Support::lsbMask<uint32_t>(19);
+ uint32_t immLo = value & 0x3u;
+ uint32_t immHi = (value >> 2) & Support::lsbMask<uint32_t>(19);
*dst = (immLo << 29) | (immHi << 5);
return true;
@@ -62,19 +82,40 @@ bool CodeWriterUtils::encodeOffset64(uint64_t* dst, int64_t offset64, const Offs
if (!bitCount || bitCount > format.valueSize() * 8u)
return false;
- if (discardLsb) {
- ASMJIT_ASSERT(discardLsb <= 32);
- if ((offset64 & Support::lsbMask<uint32_t>(discardLsb)) != 0)
+ uint64_t value;
+
+ // First handle all unsigned offset types.
+ if (format.type() == OffsetType::kUnsignedOffset) {
+ if (discardLsb) {
+ ASMJIT_ASSERT(discardLsb <= 32);
+ if ((offset64 & Support::lsbMask<uint32_t>(discardLsb)) != 0)
+ return false;
+ offset64 = int64_t(uint64_t(offset64) >> discardLsb);
+ }
+
+ value = uint64_t(offset64) & Support::lsbMask<uint64_t>(bitCount);
+ if (value != uint64_t(offset64))
return false;
- offset64 >>= discardLsb;
}
+ else {
+ // The rest of OffsetType options are all signed.
+ if (discardLsb) {
+ ASMJIT_ASSERT(discardLsb <= 32);
+ if ((offset64 & Support::lsbMask<uint32_t>(discardLsb)) != 0)
+ return false;
+ offset64 >>= discardLsb;
+ }
- if (!Support::isEncodableOffset64(offset64, bitCount))
- return false;
+ if (!Support::isEncodableOffset64(offset64, bitCount))
+ return false;
+
+ value = uint64_t(offset64);
+ }
switch (format.type()) {
- case OffsetType::kCommon: {
- *dst = (uint64_t(offset64) & Support::lsbMask<uint64_t>(bitCount)) << format.immBitShift();
+ case OffsetType::kSignedOffset:
+ case OffsetType::kUnsignedOffset: {
+ *dst = (value & Support::lsbMask<uint64_t>(bitCount)) << format.immBitShift();
return true;
}
@@ -109,8 +150,9 @@ bool CodeWriterUtils::writeOffset(void* dst, int64_t offset64, const OffsetForma
case 4: {
uint32_t mask;
- if (!encodeOffset32(&mask, offset64, format))
+ if (!encodeOffset32(&mask, offset64, format)) {
return false;
+ }
Support::writeU32uLE(dst, Support::readU32uLE(dst) | mask);
return true;
diff --git a/src/asmjit/core/cpuinfo.cpp b/src/asmjit/core/cpuinfo.cpp
index ef152cd..7bf7407 100644
--- a/src/asmjit/core/cpuinfo.cpp
+++ b/src/asmjit/core/cpuinfo.cpp
@@ -980,7 +980,7 @@ namespace AppleHWId {
static ASMJIT_FAVOR_SIZE uint32_t queryARMCpuFamilyId() noexcept {
uint32_t result = 0;
- size_t size = sizeof(cpuFamily);
+ size_t size = sizeof(result);
int res = sysctlbyname("hw.cpufamily", &result, &size, nullptr, 0);
if (res != 0)
diff --git a/src/asmjit/core/cpuinfo.h b/src/asmjit/core/cpuinfo.h
index 974fb3e..4af5c3a 100644
--- a/src/asmjit/core/cpuinfo.h
+++ b/src/asmjit/core/cpuinfo.h
@@ -429,7 +429,7 @@ public:
kARMv8_4a, //!< ARMv8.4-A ISA.
kARMv8_5a, //!< ARMv8.5-A ISA.
kARMv8_6a, //!< ARMv8.6-A ISA.
- kARMv8_7a, //!< ARMv8.6-A ISA.
+ kARMv8_7a, //!< ARMv8.7-A ISA.
kVFPv2, //!< CPU has VFPv2 instruction set.
kVFPv3, //!< CPU has VFPv3 instruction set.
diff --git a/src/asmjit/core/emitter.cpp b/src/asmjit/core/emitter.cpp
index 38061b5..92d67a7 100644
--- a/src/asmjit/core/emitter.cpp
+++ b/src/asmjit/core/emitter.cpp
@@ -9,16 +9,6 @@
#include "../core/logger.h"
#include "../core/support.h"
-#if !defined(ASMJIT_NO_X86)
- #include "../x86/x86emithelper_p.h"
- #include "../x86/x86instdb_p.h"
-#endif // !ASMJIT_NO_X86
-
-#ifdef ASMJIT_BUILD_ARM
- #include "../arm/a64emithelper_p.h"
- #include "../arm/a64instdb.h"
-#endif // ASMJIT_BUILD_ARM
-
ASMJIT_BEGIN_NAMESPACE
// BaseEmitter - Construction & Destruction
@@ -219,70 +209,28 @@ Error BaseEmitter::_emitOpArray(InstId instId, const Operand_* operands, size_t
}
}
-// BaseEmitter - Emit (High-Level)
-// ===============================
+// BaseEmitter - Emit Utilities
+// ============================
-ASMJIT_FAVOR_SIZE Error BaseEmitter::emitProlog(const FuncFrame& frame) {
+Error BaseEmitter::emitProlog(const FuncFrame& frame) {
if (ASMJIT_UNLIKELY(!_code))
return DebugUtils::errored(kErrorNotInitialized);
-#if !defined(ASMJIT_NO_X86)
- if (environment().isFamilyX86()) {
- x86::EmitHelper emitHelper(this, frame.isAvxEnabled(), frame.isAvx512Enabled());
- return emitHelper.emitProlog(frame);
- }
-#endif
-
-#ifdef ASMJIT_BUILD_ARM
- if (environment().isArchAArch64()) {
- a64::EmitHelper emitHelper(this);
- return emitHelper.emitProlog(frame);
- }
-#endif
-
- return DebugUtils::errored(kErrorInvalidArch);
+ return _funcs.emitProlog(this, frame);
}
-ASMJIT_FAVOR_SIZE Error BaseEmitter::emitEpilog(const FuncFrame& frame) {
+Error BaseEmitter::emitEpilog(const FuncFrame& frame) {
if (ASMJIT_UNLIKELY(!_code))
return DebugUtils::errored(kErrorNotInitialized);
-#if !defined(ASMJIT_NO_X86)
- if (environment().isFamilyX86()) {
- x86::EmitHelper emitHelper(this, frame.isAvxEnabled(), frame.isAvx512Enabled());
- return emitHelper.emitEpilog(frame);
- }
-#endif
-
-#ifdef ASMJIT_BUILD_ARM
- if (environment().isArchAArch64()) {
- a64::EmitHelper emitHelper(this);
- return emitHelper.emitEpilog(frame);
- }
-#endif
-
- return DebugUtils::errored(kErrorInvalidArch);
+ return _funcs.emitEpilog(this, frame);
}
-ASMJIT_FAVOR_SIZE Error BaseEmitter::emitArgsAssignment(const FuncFrame& frame, const FuncArgsAssignment& args) {
+Error BaseEmitter::emitArgsAssignment(const FuncFrame& frame, const FuncArgsAssignment& args) {
if (ASMJIT_UNLIKELY(!_code))
return DebugUtils::errored(kErrorNotInitialized);
-#if !defined(ASMJIT_NO_X86)
- if (environment().isFamilyX86()) {
- x86::EmitHelper emitHelper(this, frame.isAvxEnabled(), frame.isAvx512Enabled());
- return emitHelper.emitArgsAssignment(frame, args);
- }
-#endif
-
-#ifdef ASMJIT_BUILD_ARM
- if (environment().isArchAArch64()) {
- a64::EmitHelper emitHelper(this);
- return emitHelper.emitArgsAssignment(frame, args);
- }
-#endif
-
- return DebugUtils::errored(kErrorInvalidArch);
+ return _funcs.emitArgsAssignment(this, frame, args);
}
// BaseEmitter - Comment
diff --git a/src/asmjit/core/emitter.h b/src/asmjit/core/emitter.h
index 2aca695..b8afd6b 100644
--- a/src/asmjit/core/emitter.h
+++ b/src/asmjit/core/emitter.h
@@ -8,6 +8,7 @@
#include "../core/archtraits.h"
#include "../core/codeholder.h"
+#include "../core/formatter.h"
#include "../core/inst.h"
#include "../core/operand.h"
#include "../core/type.h"
@@ -209,6 +210,9 @@ public:
//! Validation options.
DiagnosticOptions _diagnosticOptions = DiagnosticOptions::kNone;
+ //! All supported architectures in a bit-mask, where LSB is the bit with a zero index.
+ uint64_t _archMask = 0;
+
//! Encoding options.
EncodingOptions _encodingOptions = EncodingOptions::kNone;
@@ -236,6 +240,45 @@ public:
//! Inline comment of the next instruction (affects the next instruction).
const char* _inlineComment = nullptr;
+ //! Function callbacks used by emitter implementation.
+ //!
+ //! These are typically shared between Assembler/Builder/Compiler of a single backend.
+ struct Funcs {
+ typedef Error (ASMJIT_CDECL* EmitProlog)(BaseEmitter* emitter, const FuncFrame& frame);
+ typedef Error (ASMJIT_CDECL* EmitEpilog)(BaseEmitter* emitter, const FuncFrame& frame);
+ typedef Error (ASMJIT_CDECL* EmitArgsAssignment)(BaseEmitter* emitter, const FuncFrame& frame, const FuncArgsAssignment& args);
+
+ typedef Error (ASMJIT_CDECL* FormatInstruction)(
+ String& sb,
+ FormatFlags formatFlags,
+ const BaseEmitter* emitter,
+ 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;
+
+ //! Emit prolog implementation.
+ EmitProlog emitProlog;
+ //! Emit epilog implementation.
+ EmitEpilog emitEpilog;
+ //! Emit arguments assignment implementation.
+ EmitArgsAssignment emitArgsAssignment;
+ //! Instruction formatter implementation.
+ FormatInstruction formatInstruction;
+ //! Instruction validation implementation.
+ ValidateFunc validate;
+
+ //! Resets all functions to nullptr.
+ inline void reset() noexcept {
+ emitProlog = nullptr;
+ emitEpilog = nullptr;
+ emitArgsAssignment = nullptr;
+ validate = nullptr;
+ }
+ };
+
+ Funcs _funcs {};
+
//! \}
//! \name Construction & Destruction
diff --git a/src/asmjit/core/emitterutils.cpp b/src/asmjit/core/emitterutils.cpp
index ba79787..f36a1b3 100644
--- a/src/asmjit/core/emitterutils.cpp
+++ b/src/asmjit/core/emitterutils.cpp
@@ -86,7 +86,7 @@ void logInstructionEmitted(
opArrayFromEmitArgs(opArray, o0, o1, o2, opExt);
sb.appendChars(' ', logger->indentation(FormatIndentationGroup::kCode));
- Formatter::formatInstruction(sb, formatFlags, self, self->arch(), BaseInst(instId, options, self->extraReg()), opArray, Globals::kMaxOpCount);
+ self->_funcs.formatInstruction(sb, formatFlags, self, self->arch(), BaseInst(instId, options, self->extraReg()), opArray, Globals::kMaxOpCount);
if (Support::test(formatFlags, FormatFlags::kMachineCode))
finishFormattedLine(sb, logger->options(), self->bufferPtr(), size_t(emittedSize), relSize, immSize, self->inlineComment());
@@ -109,7 +109,7 @@ Error logInstructionFailed(
Operand_ opArray[Globals::kMaxOpCount];
opArrayFromEmitArgs(opArray, o0, o1, o2, opExt);
- Formatter::formatInstruction(sb, FormatFlags::kNone, self, self->arch(), BaseInst(instId, options, self->extraReg()), opArray, Globals::kMaxOpCount);
+ self->_funcs.formatInstruction(sb, FormatFlags::kNone, self, self->arch(), BaseInst(instId, options, self->extraReg()), opArray, Globals::kMaxOpCount);
if (self->inlineComment()) {
sb.append(" ; ");
diff --git a/src/asmjit/core/environment.h b/src/asmjit/core/environment.h
index 8225ef2..7e328a9 100644
--- a/src/asmjit/core/environment.h
+++ b/src/asmjit/core/environment.h
@@ -339,8 +339,12 @@ public:
//! Tests whether this architecture is of X86 family.
inline bool isFamilyX86() const noexcept { return isFamilyX86(_arch); }
- //! Tests whether this architecture family is ARM, Thumb, or AArch64.
+ //! Tests whether this architecture family is ARM, THUMB, or AArch64.
inline 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); }
+ //! Tests whether this architecture family is AArch64.
+ inline bool isFamilyAArch64() const noexcept { return isFamilyAArch64(_arch); }
//! Tests whether this architecture family is MISP or MIPS64.
inline bool isFamilyMIPS() const noexcept { return isFamilyMIPS(_arch); }
//! Tests whether this architecture family is RISC-V (both 32-bit and 64-bit).
@@ -431,16 +435,16 @@ public:
return uint32_t(arch) >= uint32_t(Arch::kBigEndian);
}
- //! Tests whether the given architecture is ARM or ARM_BE.
- static inline bool isArchARM(Arch arch) noexcept {
- return arch == Arch::kARM || arch == Arch::kARM_BE;
- }
-
//! Tests whether the given architecture is Thumb or Thumb_BE.
static inline bool isArchThumb(Arch arch) noexcept {
return arch == Arch::kThumb || arch == Arch::kThumb_BE;
}
+ //! Tests whether the given architecture is ARM or ARM_BE.
+ static inline bool isArchARM(Arch arch) noexcept {
+ return arch == Arch::kARM || arch == Arch::kARM_BE;
+ }
+
//! Tests whether the given architecture is AArch64 or AArch64_BE.
static inline bool isArchAArch64(Arch arch) noexcept {
return arch == Arch::kAArch64 || arch == Arch::kAArch64_BE;
@@ -461,11 +465,21 @@ public:
return arch == Arch::kX86 || arch == Arch::kX64;
}
- //! Tests whether the given architecture family is ARM, Thumb, or AArch64.
+ //! 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 {
+ return isArchARM(arch) || isArchThumb(arch);
+ }
+
+ //! Tests whether the given architecture family is AArch64.
+ static inline 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 {
return isArchMIPS32(arch) || isArchMIPS64(arch);
diff --git a/src/asmjit/core/formatter.cpp b/src/asmjit/core/formatter.cpp
index efa0c47..1c4b7b6 100644
--- a/src/asmjit/core/formatter.cpp
+++ b/src/asmjit/core/formatter.cpp
@@ -20,8 +20,8 @@
#include "../x86/x86formatter_p.h"
#endif
-#ifdef ASMJIT_BUILD_ARM
- #include "../arm/armformatter_p.h"
+#if !defined(ASMJIT_NO_AARCH64)
+ #include "../arm/a64formatter_p.h"
#endif
ASMJIT_BEGIN_NAMESPACE
@@ -107,7 +107,7 @@ Error formatFeature(
return x86::FormatterInternal::formatFeature(sb, featureId);
#endif
-#ifdef ASMJIT_BUILD_ARM
+#if !defined(ASMJIT_NO_AARCH32) && !defined(ASMJIT_NO_AARCH64)
if (Environment::isFamilyARM(arch))
return arm::FormatterInternal::formatFeature(sb, featureId);
#endif
@@ -164,9 +164,9 @@ Error formatRegister(
return x86::FormatterInternal::formatRegister(sb, formatFlags, emitter, arch, regType, regId);
#endif
-#ifdef ASMJIT_BUILD_ARM
- if (Environment::isFamilyARM(arch))
- return arm::FormatterInternal::formatRegister(sb, formatFlags, emitter, arch, regType, regId);
+#if !defined(ASMJIT_NO_AARCH64)
+ if (Environment::isFamilyAArch64(arch))
+ return a64::FormatterInternal::formatRegister(sb, formatFlags, emitter, arch, regType, regId);
#endif
return kErrorInvalidArch;
@@ -184,9 +184,9 @@ Error formatOperand(
return x86::FormatterInternal::formatOperand(sb, formatFlags, emitter, arch, op);
#endif
-#ifdef ASMJIT_BUILD_ARM
- if (Environment::isFamilyARM(arch))
- return arm::FormatterInternal::formatOperand(sb, formatFlags, emitter, arch, op);
+#if !defined(ASMJIT_NO_AARCH64)
+ if (Environment::isFamilyAArch64(arch))
+ return a64::FormatterInternal::formatOperand(sb, formatFlags, emitter, arch, op);
#endif
return kErrorInvalidArch;
@@ -282,9 +282,9 @@ Error formatInstruction(
return x86::FormatterInternal::formatInstruction(sb, formatFlags, emitter, arch, inst, operands, opCount);
#endif
-#ifdef ASMJIT_BUILD_ARM
+#if !defined(ASMJIT_NO_AARCH64)
if (Environment::isFamilyARM(arch))
- return arm::FormatterInternal::formatInstruction(sb, formatFlags, emitter, arch, inst, operands, opCount);
+ return a64::FormatterInternal::formatInstruction(sb, formatFlags, emitter, arch, inst, operands, opCount);
#endif
return kErrorInvalidArch;
@@ -408,7 +408,7 @@ Error formatNode(
case NodeType::kInst:
case NodeType::kJump: {
const InstNode* instNode = node->as<InstNode>();
- ASMJIT_PROPAGATE(formatInstruction(sb, formatOptions.flags(), builder,
+ ASMJIT_PROPAGATE(builder->_funcs.formatInstruction(sb, formatOptions.flags(), builder,
builder->arch(),
instNode->baseInst(), instNode->operands(), instNode->opCount()));
break;
@@ -525,7 +525,7 @@ Error formatNode(
case NodeType::kInvoke: {
const InvokeNode* invokeNode = node->as<InvokeNode>();
- ASMJIT_PROPAGATE(formatInstruction(sb, formatOptions.flags(), builder,
+ ASMJIT_PROPAGATE(builder->_funcs.formatInstruction(sb, formatOptions.flags(), builder,
builder->arch(),
invokeNode->baseInst(), invokeNode->operands(), invokeNode->opCount()));
break;
diff --git a/src/asmjit/core/func.cpp b/src/asmjit/core/func.cpp
index fcc962c..04dc2aa 100644
--- a/src/asmjit/core/func.cpp
+++ b/src/asmjit/core/func.cpp
@@ -14,8 +14,8 @@
#include "../x86/x86func_p.h"
#endif
-#ifdef ASMJIT_BUILD_ARM
- #include "../arm/armfunc_p.h"
+#if !defined(ASMJIT_NO_AARCH64)
+ #include "../arm/a64func_p.h"
#endif
ASMJIT_BEGIN_NAMESPACE
@@ -31,9 +31,9 @@ ASMJIT_FAVOR_SIZE Error CallConv::init(CallConvId ccId, const Environment& envir
return x86::FuncInternal::initCallConv(*this, ccId, environment);
#endif
-#ifdef ASMJIT_BUILD_ARM
- if (environment.isFamilyARM())
- return arm::FuncInternal::initCallConv(*this, ccId, environment);
+#if !defined(ASMJIT_NO_AARCH64)
+ if (environment.isFamilyAArch64())
+ return a64::FuncInternal::initCallConv(*this, ccId, environment);
#endif
return DebugUtils::errored(kErrorInvalidArgument);
@@ -73,9 +73,9 @@ ASMJIT_FAVOR_SIZE Error FuncDetail::init(const FuncSignature& signature, const E
return x86::FuncInternal::initFuncDetail(*this, signature, registerSize);
#endif
-#ifdef ASMJIT_BUILD_ARM
- if (environment.isFamilyARM())
- return arm::FuncInternal::initFuncDetail(*this, signature, registerSize);
+#if !defined(ASMJIT_NO_AARCH64)
+ if (environment.isFamilyAArch64())
+ return a64::FuncInternal::initFuncDetail(*this, signature, registerSize);
#endif
// We should never bubble here as if `cc.init()` succeeded then there has to be an implementation for the current
diff --git a/src/asmjit/core/inst.cpp b/src/asmjit/core/inst.cpp
index 26f1df9..8f29d8b 100644
--- a/src/asmjit/core/inst.cpp
+++ b/src/asmjit/core/inst.cpp
@@ -11,7 +11,7 @@
#include "../x86/x86instapi_p.h"
#endif
-#ifdef ASMJIT_BUILD_ARM
+#if !defined(ASMJIT_NO_AARCH64)
#include "../arm/a64instapi_p.h"
#endif
@@ -27,8 +27,8 @@ Error InstAPI::instIdToString(Arch arch, InstId instId, String& output) noexcept
return x86::InstInternal::instIdToString(arch, instId, output);
#endif
-#ifdef ASMJIT_BUILD_ARM
- if (Environment::isArchAArch64(arch))
+#if !defined(ASMJIT_NO_AARCH64)
+ if (Environment::isFamilyAArch64(arch))
return a64::InstInternal::instIdToString(arch, instId, output);
#endif
@@ -41,8 +41,8 @@ InstId InstAPI::stringToInstId(Arch arch, const char* s, size_t len) noexcept {
return x86::InstInternal::stringToInstId(arch, s, len);
#endif
-#ifdef ASMJIT_BUILD_ARM
- if (Environment::isArchAArch64(arch))
+#if !defined(ASMJIT_NO_AARCH64)
+ if (Environment::isFamilyAArch64(arch))
return a64::InstInternal::stringToInstId(arch, s, len);
#endif
@@ -60,8 +60,8 @@ Error InstAPI::validate(Arch arch, const BaseInst& inst, const Operand_* operand
return x86::InstInternal::validate(arch, inst, operands, opCount, validationFlags);
#endif
-#ifdef ASMJIT_BUILD_ARM
- if (Environment::isArchAArch64(arch))
+#if !defined(ASMJIT_NO_AARCH64)
+ if (Environment::isFamilyAArch64(arch))
return a64::InstInternal::validate(arch, inst, operands, opCount, validationFlags);
#endif
@@ -82,8 +82,8 @@ Error InstAPI::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_* oper
return x86::InstInternal::queryRWInfo(arch, inst, operands, opCount, out);
#endif
-#ifdef ASMJIT_BUILD_ARM
- if (Environment::isArchAArch64(arch))
+#if !defined(ASMJIT_NO_AARCH64)
+ if (Environment::isFamilyAArch64(arch))
return a64::InstInternal::queryRWInfo(arch, inst, operands, opCount, out);
#endif
@@ -101,8 +101,8 @@ Error InstAPI::queryFeatures(Arch arch, const BaseInst& inst, const Operand_* op
return x86::InstInternal::queryFeatures(arch, inst, operands, opCount, out);
#endif
-#ifdef ASMJIT_BUILD_ARM
- if (Environment::isArchAArch64(arch))
+#if !defined(ASMJIT_NO_AARCH64)
+ if (Environment::isFamilyAArch64(arch))
return a64::InstInternal::queryFeatures(arch, inst, operands, opCount, out);
#endif
diff --git a/src/asmjit/core/inst.h b/src/asmjit/core/inst.h
index 0b890d8..2310631 100644
--- a/src/asmjit/core/inst.h
+++ b/src/asmjit/core/inst.h
@@ -16,17 +16,41 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_instruction_db
//! \{
-//! Describes an instruction.
+//! Describes an instruction id and modifiers used together with the id.
//!
//! Each architecture has a set of valid instructions indexed from 0. Instruction with 0 id is, however, a special
-//! instruction that describes an invalid instruction. Different architectures can share the same instruction id,
-//! which would describe a different instruction per architecture.
+//! instruction 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.
//!
//! Instruction identifiers listed by architecture:
//!
//! - \ref x86::Inst (X86 and X86_64)
+//! - \ref a64::Inst (AArch64)
typedef uint32_t InstId;
+//! Instruction id parts.
+//!
+//! A mask that specifies a bit-layout of \ref InstId.
+enum class InstIdParts : uint32_t {
+ // Common Masks
+ // ------------
+
+ //! Real id without any modifiers (always 16 least significant bits).
+ kRealId = 0x0000FFFFu,
+ //! Instruction is abstract (or virtual, IR, etc...).
+ kAbstract = 0x80000000u,
+
+ // ARM Specific
+ // ------------
+
+ //! AArch32 first data type, used by ASIMD instructions (`inst.dt.dt2`).
+ kA32_DT = 0x000F0000u,
+ //! AArch32 second data type, used by ASIMD instructions (`inst.dt.dt2`).
+ kA32_DT2 = 0x00F00000u,
+ //! AArch32/AArch64 condition code.
+ kARM_Cond = 0x78000000u
+};
+
//! Instruction options.
//!
//! Instruction options complement instruction identifier and attributes.
@@ -184,7 +208,7 @@ public:
//! \name Members
//! \{
- //! Instruction id.
+ //! Instruction id with modifiers.
InstId _id;
//! Instruction options.
InstOptions _options;
@@ -224,16 +248,29 @@ public:
//! \}
- //! \name Instruction Id
+ //! \name Instruction id and modifiers
//! \{
- //! Returns the instruction id.
+ //! Returns the instruction id with modifiers.
inline InstId id() const noexcept { return _id; }
- //! Sets the instruction id to the given `id`.
+ //! Sets the instruction id and modiiers from `id`.
inline void setId(InstId id) noexcept { _id = id; }
- //! Resets the instruction id to zero, see \ref kIdNone.
+ //! Resets the instruction id and modifiers to zero, see \ref kIdNone.
inline 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); }
+
+ template<InstIdParts kPart>
+ inline 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 {
+ _id = (_id & ~uint32_t(kPart)) | (value << Support::ConstCTZ<uint32_t(kPart)>::value);
+ }
+
//! \}
//! \name Instruction Options
@@ -259,6 +296,27 @@ public:
inline 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)); }
+
+ //! \}
+
+ //! \name Statics
+ //! \{
+
+ static inline 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 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);
+ }
+
+ //! \}
};
//! CPU read/write flags used by \ref InstRWInfo.
diff --git a/src/asmjit/core/jitruntime.cpp b/src/asmjit/core/jitruntime.cpp
index 85fbdc4..491c204 100644
--- a/src/asmjit/core/jitruntime.cpp
+++ b/src/asmjit/core/jitruntime.cpp
@@ -43,6 +43,8 @@ Error JitRuntime::_add(void** dst, CodeHolder* code) noexcept {
// 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);
if (codeSize < estimatedCodeSize)
_allocator.shrink(rx, codeSize);
diff --git a/src/asmjit/core/operand.h b/src/asmjit/core/operand.h
index 0bf098a..2f81a21 100644
--- a/src/asmjit/core/operand.h
+++ b/src/asmjit/core/operand.h
@@ -98,6 +98,9 @@ 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, ...).
@@ -133,6 +136,26 @@ enum class RegType : uint8_t {
//! TMM register (AMX_TILE)
kX86_Tmm = kExtra + 6,
+ // ARM Specific Register Types
+ // ===========================
+
+ //! Program pointer (PC) register (AArch64).
+ kARM_PC = kPC,
+ //! 32-bit general purpose register (R or W).
+ kARM_GpW = kGp32,
+ //! 64-bit general purpose register (X).
+ kARM_GpX = kGp64,
+ //! 8-bit view of VFP/ASIMD register (B).
+ kARM_VecB = kVec8,
+ //! 16-bit view of VFP/ASIMD register (H).
+ kARM_VecH = kVec16,
+ //! 32-bit view of VFP/ASIMD register (S).
+ kARM_VecS = kVec32,
+ //! 64-bit view of VFP/ASIMD register (D).
+ kARM_VecD = kVec64,
+ //! 128-bit view of VFP/ASIMD register (Q|V).
+ kARM_VecV = kVec128,
+
//! Maximum value of `RegType`.
kMaxValue = 31
};
diff --git a/src/asmjit/core/support.h b/src/asmjit/core/support.h
index a9091c3..e55b808 100644
--- a/src/asmjit/core/support.h
+++ b/src/asmjit/core/support.h
@@ -176,6 +176,12 @@ static constexpr X sar(const X& x, const Y& y) noexcept {
return X(S(x) >> y);
}
+template<typename X, typename Y>
+static 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)));
+}
+
//! 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)); }
@@ -187,7 +193,33 @@ static constexpr T blsi(T x) noexcept {
return T(U(x) & neg(U(x)));
}
-//! Generate a trailing bit-mask that has `n` least significant (trailing) bits set.
+//! 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 {
+ typedef typename std::make_unsigned<T>::type U;
+ return (U(x) & (U(1) << asStdInt(n))) != 0;
+}
+
+// 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) {
+ typedef typename std::make_unsigned<T>::type U;
+ return value && ((U(value) + 1u) & U(value)) == 0;
+}
+
+// Tests whether the given value contains at least one bit or whether it's a
+// bit-mask of consecutive bits.
+//
+// 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) {
+ 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 {
typedef typename std::make_unsigned<T>::type U;
@@ -198,11 +230,15 @@ static constexpr T lsbMask(const CountT& n) noexcept {
: n ? T(shr(allOnes<T>(), bitSizeOf<T>() - size_t(n))) : T(0);
}
-//! 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 {
+//! Generats 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 {
typedef typename std::make_unsigned<T>::type U;
- return (U(x) & (U(1) << asUInt(n))) != 0;
+ return (sizeof(U) < sizeof(uintptr_t))
+ // Prevent undefined behavior by using a larger type than T.
+ ? T(allOnes<uintptr_t>() >> (bitSizeOf<uintptr_t>() - n))
+ // Prevent undefined behavior by performing `n & (nBits - 1)` so it's always within the range.
+ : T(sar(U(n != 0) << (bitSizeOf<U>() - 1), n ? uint32_t(n - 1) : uint32_t(0)));
}
//! Returns a bit-mask that has `x` bit set.
diff --git a/src/asmjit/core/virtmem.cpp b/src/asmjit/core/virtmem.cpp
index 8259f9c..43766ef 100644
--- a/src/asmjit/core/virtmem.cpp
+++ b/src/asmjit/core/virtmem.cpp
@@ -211,6 +211,7 @@ Error releaseDualMapping(DualMapping* dm, size_t size) noexcept {
dm->rw = nullptr;
return kErrorOk;
}
+
#endif
// Virtual Memory [Posix]
diff --git a/src/asmjit/core/zonetree.h b/src/asmjit/core/zonetree.h
index e1bfdc5..c5dbc78 100644
--- a/src/asmjit/core/zonetree.h
+++ b/src/asmjit/core/zonetree.h
@@ -364,6 +364,7 @@ public:
static inline ZoneTreeNode* _doubleRotate(ZoneTreeNode* ASMJIT_NONNULL(root), size_t dir) noexcept {
ZoneTreeNode* child = root->_getChild(!dir);
ASMJIT_ASSUME(child != nullptr);
+
root->_setChild(!dir, _singleRotate(child, !dir));
return _singleRotate(root, dir);
}
diff --git a/src/asmjit/x86/x86assembler.cpp b/src/asmjit/x86/x86assembler.cpp
index 4da28f1..f11fea0 100644
--- a/src/asmjit/x86/x86assembler.cpp
+++ b/src/asmjit/x86/x86assembler.cpp
@@ -15,6 +15,8 @@
#include "../core/misc_p.h"
#include "../core/support.h"
#include "../x86/x86assembler.h"
+#include "../x86/x86emithelper_p.h"
+#include "../x86/x86instapi_p.h"
#include "../x86/x86instdb_p.h"
#include "../x86/x86formatter_p.h"
#include "../x86/x86opcode_p.h"
@@ -525,6 +527,10 @@ 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);
}
@@ -604,7 +610,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 = InstAPI::validate(arch(), BaseInst(instId, options, _extraReg), opArray, Globals::kMaxOpCount);
+ err = _funcs.validate(arch(), BaseInst(instId, options, _extraReg), opArray, Globals::kMaxOpCount, ValidationFlags::kNone);
if (ASMJIT_UNLIKELY(err))
goto Failed;
}
@@ -4159,7 +4165,7 @@ EmitModSib:
re->_sourceSectionId = _section->id();
re->_sourceOffset = offset();
- re->_format.resetToDataValue(4);
+ re->_format.resetToSimpleValue(OffsetType::kSignedOffset, 4);
re->_format.setLeadingAndTrailingSize(writer.offsetFrom(_bufferPtr), immSize);
re->_payload = uint64_t(rmRel->as<Mem>().offset());
@@ -4256,7 +4262,7 @@ EmitModSib_LabelRip_X86:
re->_sourceSectionId = _section->id();
re->_sourceOffset = offset();
- re->_format.resetToDataValue(4);
+ re->_format.resetToSimpleValue(OffsetType::kUnsignedOffset, 4);
re->_format.setLeadingAndTrailingSize(writer.offsetFrom(_bufferPtr), immSize);
re->_payload = uint64_t(int64_t(relOffset));
@@ -4281,7 +4287,7 @@ EmitModSib_LabelRip_X86:
re->_sourceSectionId = _section->id();
re->_targetSectionId = _section->id();
- re->_format.resetToDataValue(4);
+ re->_format.resetToSimpleValue(OffsetType::kUnsignedOffset, 4);
re->_format.setLeadingAndTrailingSize(writer.offsetFrom(_bufferPtr), immSize);
re->_sourceOffset = offset();
re->_payload = re->_sourceOffset + re->_format.regionSize() + uint64_t(int64_t(relOffset));
@@ -4871,13 +4877,13 @@ EmitJmpCall:
writer.emit8If(0x0F, (opcode & Opcode::kMM_Mask) != 0); // Emit 0F prefix.
writer.emit8(opcode.v); // Emit opcode.
writer.emit8If(x86EncodeMod(3, opReg, 0), opReg != 0); // Emit MOD.
- re->_format.resetToDataValue(4);
+ re->_format.resetToSimpleValue(OffsetType::kSignedOffset, 4);
re->_format.setLeadingAndTrailingSize(writer.offsetFrom(_bufferPtr), immSize);
writer.emit32uLE(0); // Emit DISP32.
}
else {
writer.emit8(opCode8); // Emit opcode.
- re->_format.resetToDataValue(4);
+ re->_format.resetToSimpleValue(OffsetType::kSignedOffset, 1);
re->_format.setLeadingAndTrailingSize(writer.offsetFrom(_bufferPtr), immSize);
writer.emit8(0); // Emit DISP8 (zero).
}
@@ -4919,7 +4925,7 @@ EmitRel:
// Chain with label.
size_t offset = size_t(writer.offsetFrom(_bufferData));
OffsetFormat of;
- of.resetToDataValue(relSize);
+ of.resetToSimpleValue(OffsetType::kSignedOffset, relSize);
LabelLink* link = _code->newLabelLink(label, _section->id(), offset, relOffset, of);
if (ASMJIT_UNLIKELY(!link))
@@ -5077,9 +5083,6 @@ Error Assembler::align(AlignMode alignMode, uint32_t alignment) {
Error Assembler::onAttach(CodeHolder* code) noexcept {
Arch arch = code->arch();
- if (!Environment::isFamilyX86(arch))
- return DebugUtils::errored(kErrorInvalidArch);
-
ASMJIT_PROPAGATE(Base::onAttach(code));
if (Environment::is32Bit(arch)) {
@@ -5099,7 +5102,6 @@ Error Assembler::onAttach(CodeHolder* code) noexcept {
Error Assembler::onDetach(CodeHolder* code) noexcept {
_forcedInstOptions &= ~InstOptions::kX86_InvalidRex;
_setAddressOverrideMask(0);
-
return Base::onDetach(code);
}
diff --git a/src/asmjit/x86/x86builder.cpp b/src/asmjit/x86/x86builder.cpp
index a1b848d..a27948b 100644
--- a/src/asmjit/x86/x86builder.cpp
+++ b/src/asmjit/x86/x86builder.cpp
@@ -8,15 +8,37 @@
#include "../x86/x86assembler.h"
#include "../x86/x86builder.h"
+#include "../x86/x86emithelper_p.h"
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
+// x86::Builder - Construction & Destruction
+// =========================================
+
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);
}
Builder::~Builder() noexcept {}
+// x86::Builder - Events
+// =====================
+
+Error Builder::onAttach(CodeHolder* code) noexcept {
+ return Base::onAttach(code);
+}
+
+Error Builder::onDetach(CodeHolder* code) noexcept {
+ return Base::onDetach(code);
+}
+
+// x86::Builder - Finalize
+// =======================
+
Error Builder::finalize() {
ASMJIT_PROPAGATE(runPasses());
Assembler a(_code);
@@ -25,14 +47,6 @@ Error Builder::finalize() {
return serializeTo(&a);
}
-Error Builder::onAttach(CodeHolder* code) noexcept {
- Arch arch = code->arch();
- if (!Environment::isFamilyX86(arch))
- return DebugUtils::errored(kErrorInvalidArch);
-
- return Base::onAttach(code);
-}
-
ASMJIT_END_SUB_NAMESPACE
#endif // !ASMJIT_NO_X86 && !ASMJIT_NO_BUILDER
diff --git a/src/asmjit/x86/x86builder.h b/src/asmjit/x86/x86builder.h
index 31c9783..f3bb11a 100644
--- a/src/asmjit/x86/x86builder.h
+++ b/src/asmjit/x86/x86builder.h
@@ -327,17 +327,18 @@ public:
//! \}
- //! \name Finalize
+ //! \name Events
//! \{
- ASMJIT_API Error finalize() override;
+ ASMJIT_API Error onAttach(CodeHolder* code) noexcept override;
+ ASMJIT_API Error onDetach(CodeHolder* code) noexcept override;
//! \}
- //! \name Events
+ //! \name Finalize
//! \{
- ASMJIT_API Error onAttach(CodeHolder* code) noexcept override;
+ ASMJIT_API Error finalize() override;
//! \}
};
diff --git a/src/asmjit/x86/x86compiler.cpp b/src/asmjit/x86/x86compiler.cpp
index 014ba19..04d0980 100644
--- a/src/asmjit/x86/x86compiler.cpp
+++ b/src/asmjit/x86/x86compiler.cpp
@@ -8,29 +8,28 @@
#include "../x86/x86assembler.h"
#include "../x86/x86compiler.h"
+#include "../x86/x86instapi_p.h"
#include "../x86/x86rapass_p.h"
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
+// x86::Compiler - Construction & Destruction
+// ==========================================
+
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);
}
Compiler::~Compiler() noexcept {}
-Error Compiler::finalize() {
- ASMJIT_PROPAGATE(runPasses());
- Assembler a(_code);
- a.addEncodingOptions(encodingOptions());
- a.addDiagnosticOptions(diagnosticOptions());
- return serializeTo(&a);
-}
+// x86::Compiler - Events
+// ======================
Error Compiler::onAttach(CodeHolder* code) noexcept {
- Arch arch = code->arch();
- if (!Environment::isFamilyX86(arch))
- return DebugUtils::errored(kErrorInvalidArch);
-
ASMJIT_PROPAGATE(Base::onAttach(code));
Error err = addPassT<X86RAPass>();
@@ -42,6 +41,21 @@ Error Compiler::onAttach(CodeHolder* code) noexcept {
return kErrorOk;
}
+Error Compiler::onDetach(CodeHolder* code) noexcept {
+ return Base::onDetach(code);
+}
+
+// x86::Compiler - Finalize
+// ========================
+
+Error Compiler::finalize() {
+ ASMJIT_PROPAGATE(runPasses());
+ Assembler a(_code);
+ a.addEncodingOptions(encodingOptions());
+ a.addDiagnosticOptions(diagnosticOptions());
+ return serializeTo(&a);
+}
+
ASMJIT_END_SUB_NAMESPACE
#endif // !ASMJIT_NO_X86 && !ASMJIT_NO_COMPILER
diff --git a/src/asmjit/x86/x86compiler.h b/src/asmjit/x86/x86compiler.h
index 466ffa2..d89aea0 100644
--- a/src/asmjit/x86/x86compiler.h
+++ b/src/asmjit/x86/x86compiler.h
@@ -697,17 +697,18 @@ public:
//! \}
- //! \name Finalize
+ //! \name Events
//! \{
- ASMJIT_API Error finalize() override;
+ ASMJIT_API Error onAttach(CodeHolder* code) noexcept override;
+ ASMJIT_API Error onDetach(CodeHolder* code) noexcept override;
//! \}
- //! \name Events
+ //! \name Finalize
//! \{
- ASMJIT_API Error onAttach(CodeHolder* code) noexcept override;
+ ASMJIT_API Error finalize() override;
//! \}
};
diff --git a/src/asmjit/x86/x86emithelper.cpp b/src/asmjit/x86/x86emithelper.cpp
index d2d90c7..cc558e0 100644
--- a/src/asmjit/x86/x86emithelper.cpp
+++ b/src/asmjit/x86/x86emithelper.cpp
@@ -14,6 +14,8 @@
#include "../core/radefs_p.h"
#include "../x86/x86emithelper_p.h"
#include "../x86/x86emitter.h"
+#include "../x86/x86formatter_p.h"
+#include "../x86/x86instapi_p.h"
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
@@ -583,6 +585,35 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitEpilog(const FuncFrame& frame) {
return kErrorOk;
}
+static Error ASMJIT_CDECL Emitter_emitProlog(BaseEmitter* emitter, const FuncFrame& frame) {
+ EmitHelper emitHelper(emitter, frame.isAvxEnabled(), frame.isAvx512Enabled());
+ return emitHelper.emitProlog(frame);
+}
+
+static Error ASMJIT_CDECL Emitter_emitEpilog(BaseEmitter* emitter, const FuncFrame& frame) {
+ EmitHelper emitHelper(emitter, frame.isAvxEnabled(), frame.isAvx512Enabled());
+ return emitHelper.emitEpilog(frame);
+}
+
+static Error ASMJIT_CDECL Emitter_emitArgsAssignment(BaseEmitter* emitter, const FuncFrame& frame, const FuncArgsAssignment& args) {
+ EmitHelper emitHelper(emitter, frame.isAvxEnabled(), frame.isAvx512Enabled());
+ return emitHelper.emitArgsAssignment(frame, args);
+}
+
+void assignEmitterFuncs(BaseEmitter* emitter) {
+ emitter->_funcs.emitProlog = Emitter_emitProlog;
+ emitter->_funcs.emitEpilog = Emitter_emitEpilog;
+ emitter->_funcs.emitArgsAssignment = Emitter_emitArgsAssignment;
+
+#ifndef ASMJIT_NO_LOGGING
+ emitter->_funcs.formatInstruction = FormatterInternal::formatInstruction;
+#endif
+
+#ifndef ASMJIT_NO_VALIDATION
+ emitter->_funcs.validate = InstInternal::validate;
+#endif
+}
+
ASMJIT_END_SUB_NAMESPACE
#endif // !ASMJIT_NO_X86
diff --git a/src/asmjit/x86/x86emithelper_p.h b/src/asmjit/x86/x86emithelper_p.h
index 98d16da..e71d9af 100644
--- a/src/asmjit/x86/x86emithelper_p.h
+++ b/src/asmjit/x86/x86emithelper_p.h
@@ -50,6 +50,8 @@ public:
Error emitEpilog(const FuncFrame& frame);
};
+void assignEmitterFuncs(BaseEmitter* emitter);
+
//! \}
//! \endcond
diff --git a/src/asmjit/x86/x86formatter.cpp b/src/asmjit/x86/x86formatter.cpp
index b667019..d62dd18 100644
--- a/src/asmjit/x86/x86formatter.cpp
+++ b/src/asmjit/x86/x86formatter.cpp
@@ -10,6 +10,7 @@
#include "../core/misc_p.h"
#include "../core/support.h"
#include "../x86/x86formatter_p.h"
+#include "../x86/x86instapi_p.h"
#include "../x86/x86instdb_p.h"
#include "../x86/x86operand.h"
@@ -880,7 +881,7 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatInstruction(
}
}
- ASMJIT_PROPAGATE(InstAPI::instIdToString(arch, instId, sb));
+ ASMJIT_PROPAGATE(InstInternal::instIdToString(arch, instId, sb));
}
else {
ASMJIT_PROPAGATE(sb.appendFormat("[InstId=#%u]", unsigned(instId)));
diff --git a/src/asmjit/x86/x86formatter_p.h b/src/asmjit/x86/x86formatter_p.h
index 1dbdb68..f37a8f6 100644
--- a/src/asmjit/x86/x86formatter_p.h
+++ b/src/asmjit/x86/x86formatter_p.h
@@ -21,11 +21,11 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
namespace FormatterInternal {
-Error formatFeature(
+Error ASMJIT_CDECL formatFeature(
String& sb,
uint32_t featureId) noexcept;
-Error formatRegister(
+Error ASMJIT_CDECL formatRegister(
String& sb,
FormatFlags flags,
const BaseEmitter* emitter,
@@ -33,14 +33,14 @@ Error formatRegister(
RegType regType,
uint32_t regId) noexcept;
-Error formatOperand(
+Error ASMJIT_CDECL formatOperand(
String& sb,
FormatFlags flags,
const BaseEmitter* emitter,
Arch arch,
const Operand_& op) noexcept;
-Error formatInstruction(
+Error ASMJIT_CDECL formatInstruction(
String& sb,
FormatFlags flags,
const BaseEmitter* emitter,
diff --git a/src/asmjit/x86/x86instapi_p.h b/src/asmjit/x86/x86instapi_p.h
index 0a4b10a..56f7fb9 100644
--- a/src/asmjit/x86/x86instapi_p.h
+++ b/src/asmjit/x86/x86instapi_p.h
@@ -18,17 +18,17 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
namespace InstInternal {
#ifndef ASMJIT_NO_TEXT
-Error instIdToString(Arch arch, InstId instId, String& output) noexcept;
-InstId stringToInstId(Arch arch, const char* s, size_t len) noexcept;
+Error ASMJIT_CDECL instIdToString(Arch arch, InstId instId, String& output) noexcept;
+InstId ASMJIT_CDECL stringToInstId(Arch arch, const char* s, size_t len) noexcept;
#endif // !ASMJIT_NO_TEXT
#ifndef ASMJIT_NO_VALIDATION
-Error validate(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, ValidationFlags validationFlags) noexcept;
+Error ASMJIT_CDECL validate(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, ValidationFlags validationFlags) noexcept;
#endif // !ASMJIT_NO_VALIDATION
#ifndef ASMJIT_NO_INTROSPECTION
-Error queryRWInfo(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, InstRWInfo* out) noexcept;
-Error queryFeatures(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, CpuFeatures* out) noexcept;
+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;
#endif // !ASMJIT_NO_INTROSPECTION
} // {InstInternal}
diff --git a/test/asmjit_test_assembler.cpp b/test/asmjit_test_assembler.cpp
index bcb16ad..4b40a75 100644
--- a/test/asmjit_test_assembler.cpp
+++ b/test/asmjit_test_assembler.cpp
@@ -18,6 +18,10 @@ bool testX86Assembler(const TestSettings& settings) noexcept;
bool testX64Assembler(const TestSettings& settings) noexcept;
#endif
+#if !defined(ASMJIT_NO_AARCH64)
+bool testA64Assembler(const TestSettings& settings) noexcept;
+#endif
+
int main(int argc, char* argv[]) {
CmdLine cmdLine(argc, argv);
@@ -43,6 +47,7 @@ int main(int argc, char* argv[]) {
const char* arch = cmdLine.valueOf("--arch", "all");
bool x86Failed = false;
bool x64Failed = false;
+ bool aarch64Failed = false;
#if !defined(ASMJIT_NO_X86)
if ((strcmp(arch, "all") == 0 || strcmp(arch, "x86") == 0))
@@ -52,11 +57,23 @@ int main(int argc, char* argv[]) {
x64Failed = !testX64Assembler(settings);
#endif
- bool failed = x86Failed || x64Failed;
+#if !defined(ASMJIT_NO_AARCH64)
+ if ((strcmp(arch, "all") == 0 || strcmp(arch, "aarch64") == 0))
+ aarch64Failed = !testA64Assembler(settings);
+#endif
+
+ bool failed = x86Failed || x64Failed || aarch64Failed;
if (failed) {
- if (x86Failed) printf("** X86 test suite failed **\n");
- if (x64Failed) printf("** X64 test suite failed **\n");
+ if (x86Failed)
+ printf("** X86 test suite failed **\n");
+
+ if (x64Failed)
+ printf("** X64 test suite failed **\n");
+
+ if (aarch64Failed)
+ printf("** AArch64 test suite failed **\n");
+
printf("** FAILURE **\n");
}
else {
diff --git a/test/asmjit_test_assembler.h b/test/asmjit_test_assembler.h
index 0e98c26..61d774b 100644
--- a/test/asmjit_test_assembler.h
+++ b/test/asmjit_test_assembler.h
@@ -20,6 +20,7 @@ public:
asmjit::Environment env {};
asmjit::CodeHolder code {};
AssemblerType assembler {};
+ asmjit::Label L0 {};
const TestSettings& settings;
size_t passed {};
@@ -45,6 +46,7 @@ public:
code.reset();
code.init(env, 0);
code.attach(&assembler);
+ L0 = assembler.newLabel();
if (settings.validate)
assembler.addDiagnosticOptions(asmjit::DiagnosticOptions::kValidateAssembler);
diff --git a/test/asmjit_test_assembler_a64.cpp b/test/asmjit_test_assembler_a64.cpp
new file mode 100644
index 0000000..a1d1178
--- /dev/null
+++ b/test/asmjit_test_assembler_a64.cpp
@@ -0,0 +1,4006 @@
+// 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 <asmjit/core.h>
+#if !defined(ASMJIT_NO_AARCH64)
+
+#include <asmjit/a64.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "asmjit_test_assembler.h"
+#include "cmdline.h"
+
+using namespace asmjit;
+
+#define TEST_INSTRUCTION(OPCODE, ...) \
+ tester.testInstruction(OPCODE, #__VA_ARGS__, tester.assembler.__VA_ARGS__)
+
+static void ASMJIT_NOINLINE testA64AssemblerBase(AssemblerTester<a64::Assembler>& tester) noexcept {
+ using namespace a64;
+
+ TEST_INSTRUCTION("4100031A", adc(w1, w2, w3));
+ TEST_INSTRUCTION("4100039A", adc(x1, x2, x3));
+ TEST_INSTRUCTION("E103031A", adc(w1, wzr, w3));
+ TEST_INSTRUCTION("E103039A", adc(x1, xzr, x3));
+ TEST_INSTRUCTION("5F00031A", adc(wzr, w2, w3));
+ TEST_INSTRUCTION("5F00039A", adc(xzr, x2, x3));
+ TEST_INSTRUCTION("4100033A", adcs(w1, w2, w3));
+ TEST_INSTRUCTION("410003BA", adcs(x1, x2, x3));
+ TEST_INSTRUCTION("4100030B", add(w1, w2, w3));
+ TEST_INSTRUCTION("4100038B", add(x1, x2, x3));
+ TEST_INSTRUCTION("410C030B", add(w1, w2, w3, lsl(3)));
+ TEST_INSTRUCTION("410C038B", add(x1, x2, x3, lsl(3)));
+ TEST_INSTRUCTION("FF030411", add(wsp, wsp, 256));
+ TEST_INSTRUCTION("FFFF3F11", add(wsp, wsp, 0xFFF));
+ TEST_INSTRUCTION("FF030491", add(sp, sp, 256));
+ TEST_INSTRUCTION("FFFF3F91", add(sp, sp, 0xFFF));
+ TEST_INSTRUCTION("E103030B", add(w1, wzr, w3));
+ TEST_INSTRUCTION("E103038B", add(x1, xzr, x3));
+ TEST_INSTRUCTION("5F00030B", add(wzr, w2, w3));
+ TEST_INSTRUCTION("5F00038B", add(xzr, x2, x3));
+ TEST_INSTRUCTION("83004011", add(w3, w4, 0, lsl(12)));
+ TEST_INSTRUCTION("83004091", add(x3, x4, 0, lsl(12)));
+ TEST_INSTRUCTION("83005011", add(w3, w4, 1024, lsl(12)));
+ TEST_INSTRUCTION("83005091", add(x3, x4, 1024, lsl(12)));
+ TEST_INSTRUCTION("83005011", add(w3, w4, 1024, lsl(12)));
+ TEST_INSTRUCTION("83005091", add(x3, x4, 1024, lsl(12)));
+ TEST_INSTRUCTION("FF830091", add(sp, sp, 32));
+ TEST_INSTRUCTION("412C8291", addg(x1, x2, 32, 11));
+ TEST_INSTRUCTION("5F2C8291", addg(sp, x2, 32, 11));
+ TEST_INSTRUCTION("E12F8291", addg(x1, sp, 32, 11));
+ TEST_INSTRUCTION("4100032B", adds(w1, w2, w3));
+ TEST_INSTRUCTION("410003AB", adds(x1, x2, x3));
+ TEST_INSTRUCTION("01000010", adr(x1, 0));
+ TEST_INSTRUCTION("01080010", adr(x1, 256));
+ TEST_INSTRUCTION("010000B0", adrp(x1, 4096));
+ TEST_INSTRUCTION("4100030A", and_(w1, w2, w3));
+ TEST_INSTRUCTION("4100038A", and_(x1, x2, x3));
+ TEST_INSTRUCTION("41000012", and_(w1, w2, 1));
+ TEST_INSTRUCTION("41004092", and_(x1, x2, 1));
+ TEST_INSTRUCTION("410C0012", and_(w1, w2, 15));
+ TEST_INSTRUCTION("410C4092", and_(x1, x2, 15));
+ TEST_INSTRUCTION("3F1C0012", and_(wsp, w1, 0xFF));
+ TEST_INSTRUCTION("3F1C4092", and_(sp, x1, 0xFF));
+ TEST_INSTRUCTION("E103030A", and_(w1, wzr, w3));
+ TEST_INSTRUCTION("E103038A", and_(x1, xzr, x3));
+ TEST_INSTRUCTION("5F00030A", and_(wzr, w2, w3));
+ TEST_INSTRUCTION("5F00038A", and_(xzr, x2, x3));
+ TEST_INSTRUCTION("00000012", and_(w0, w0, 0x1));
+ TEST_INSTRUCTION("00004092", and_(x0, x0, 0x1));
+ TEST_INSTRUCTION("410C0012", and_(w1, w2, 0xf));
+ TEST_INSTRUCTION("410C4092", and_(x1, x2, 0xf));
+ TEST_INSTRUCTION("BFEC7C92", and_(sp, x5, 0xfffffffffffffff0));
+ TEST_INSTRUCTION("4100036A", ands(w1, w2, w3));
+ TEST_INSTRUCTION("410003EA", ands(x1, x2, x3));
+ TEST_INSTRUCTION("E103036A", ands(w1, wzr, w3));
+ TEST_INSTRUCTION("E10303EA", ands(x1, xzr, x3));
+ TEST_INSTRUCTION("5F00036A", ands(wzr, w2, w3));
+ TEST_INSTRUCTION("5F0003EA", ands(xzr, x2, x3));
+ TEST_INSTRUCTION("00000072", ands(w0, w0, 0x1));
+ TEST_INSTRUCTION("000040F2", ands(x0, x0, 0x1));
+ TEST_INSTRUCTION("410C0072", ands(w1, w2, 0xf));
+ TEST_INSTRUCTION("410C40F2", ands(x1, x2, 0xf));
+ TEST_INSTRUCTION("417C0F13", asr(w1, w2, 15));
+ TEST_INSTRUCTION("41FC4F93", asr(x1, x2, 15));
+ TEST_INSTRUCTION("4128C31A", asrv(w1, w2, w3));
+ TEST_INSTRUCTION("4128C39A", asrv(x1, x2, x3));
+ TEST_INSTRUCTION("4F7808D5", at(Predicate::AT::kS1E0R, x15));
+ TEST_INSTRUCTION("4118C1DA", autda(x1, x2));
+ TEST_INSTRUCTION("E11BC1DA", autda(x1, sp));
+ TEST_INSTRUCTION("411CC1DA", autdb(x1, x2));
+ TEST_INSTRUCTION("E11FC1DA", autdb(x1, sp));
+ TEST_INSTRUCTION("E13BC1DA", autdza(x1));
+ TEST_INSTRUCTION("F43BC1DA", autdza(x20));
+ TEST_INSTRUCTION("E13FC1DA", autdzb(x1));
+ TEST_INSTRUCTION("F43FC1DA", autdzb(x20));
+ TEST_INSTRUCTION("4110C1DA", autia(x1, x2));
+ TEST_INSTRUCTION("E113C1DA", autia(x1, sp));
+ TEST_INSTRUCTION("9F2103D5", autia1716());
+ TEST_INSTRUCTION("BF2303D5", autiasp());
+ TEST_INSTRUCTION("9F2303D5", autiaz());
+ TEST_INSTRUCTION("4114C1DA", autib(x1, x2));
+ TEST_INSTRUCTION("E117C1DA", autib(x1, sp));
+ TEST_INSTRUCTION("DF2103D5", autib1716());
+ TEST_INSTRUCTION("FF2303D5", autibsp());
+ TEST_INSTRUCTION("DF2303D5", autibz());
+ TEST_INSTRUCTION("E133C1DA", autiza(x1));
+ TEST_INSTRUCTION("F433C1DA", autiza(x20));
+ TEST_INSTRUCTION("E137C1DA", autizb(x1));
+ TEST_INSTRUCTION("F437C1DA", autizb(x20));
+ TEST_INSTRUCTION("5F4000D5", axflag());
+ TEST_INSTRUCTION("E13F1833", bfc(w1, 8, 16));
+ TEST_INSTRUCTION("E13F78B3", bfc(x1, 8, 16));
+ TEST_INSTRUCTION("413C1833", bfi(w1, w2, 8, 16));
+ TEST_INSTRUCTION("413C78B3", bfi(x1, x2, 8, 16));
+ TEST_INSTRUCTION("41400833", bfm(w1, w2, 8, 16));
+ TEST_INSTRUCTION("414048B3", bfm(x1, x2, 8, 16));
+ TEST_INSTRUCTION("415C0833", bfxil(w1, w2, 8, 16));
+ TEST_INSTRUCTION("415C48B3", bfxil(x1, x2, 8, 16));
+ TEST_INSTRUCTION("41781F12", bic(w1, w2, 1));
+ TEST_INSTRUCTION("41F87F92", bic(x1, x2, 1));
+ TEST_INSTRUCTION("416C1C12", bic(w1, w2, 15));
+ TEST_INSTRUCTION("41EC7C92", bic(x1, x2, 15));
+ TEST_INSTRUCTION("4110230A", bic(w1, w2, w3, lsl(4)));
+ TEST_INSTRUCTION("4110238A", bic(x1, x2, x3, lsl(4)));
+ TEST_INSTRUCTION("E103230A", bic(w1, wzr, w3));
+ TEST_INSTRUCTION("E103238A", bic(x1, xzr, x3));
+ TEST_INSTRUCTION("41781F72", bics(w1, w2, 1));
+ TEST_INSTRUCTION("41F87FF2", bics(x1, x2, 1));
+ TEST_INSTRUCTION("416C1C72", bics(w1, w2, 15));
+ TEST_INSTRUCTION("41EC7CF2", bics(x1, x2, 15));
+ TEST_INSTRUCTION("4110236A", bics(w1, w2, w3, lsl(4)));
+ TEST_INSTRUCTION("411023EA", bics(x1, x2, x3, lsl(4)));
+ TEST_INSTRUCTION("E103236A", bics(w1, wzr, w3));
+ TEST_INSTRUCTION("E10323EA", bics(x1, xzr, x3));
+ TEST_INSTRUCTION("60031FD6", br(x27));
+ TEST_INSTRUCTION("E0031FD6", br(xzr));
+ TEST_INSTRUCTION("200020D4", brk(1));
+ TEST_INSTRUCTION("627CA188", cas(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("627CA1C8", cas(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("627CE188", casa(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("627CE1C8", casa(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("627CE108", casab(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("627CE148", casah(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("62FCE188", casal(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("62FCE1C8", casal(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("62FCE108", casalb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("62FCE148", casalh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("627CA108", casb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("627CA148", cash(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("62FCA188", casl(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("62FCA1C8", casl(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("62FCA108", caslb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("62FCA148", caslh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("687C2208", casp(w2, w3, w8, w9, ptr(x3)));
+ TEST_INSTRUCTION("687C2248", casp(x2, x3, x8, x9, ptr(x3)));
+ TEST_INSTRUCTION("687C6208", caspa(w2, w3, w8, w9, ptr(x3)));
+ TEST_INSTRUCTION("687C6248", caspa(x2, x3, x8, x9, ptr(x3)));
+ TEST_INSTRUCTION("68FC6208", caspal(w2, w3, w8, w9, ptr(x3)));
+ TEST_INSTRUCTION("68FC6248", caspal(x2, x3, x8, x9, ptr(x3)));
+ TEST_INSTRUCTION("68FC2208", caspl(w2, w3, w8, w9, ptr(x3)));
+ TEST_INSTRUCTION("68FC2248", caspl(x2, x3, x8, x9, ptr(x3)));
+ TEST_INSTRUCTION("2300423A", ccmn(w1, w2, 3, CondCode::kEQ));
+ TEST_INSTRUCTION("230042BA", ccmn(x1, x2, 3, CondCode::kEQ));
+ TEST_INSTRUCTION("2308423A", ccmn(w1, 2, 3, CondCode::kEQ));
+ TEST_INSTRUCTION("230842BA", ccmn(x1, 2, 3, CondCode::kEQ));
+ TEST_INSTRUCTION("23005F3A", ccmn(w1, wzr, 3, CondCode::kEQ));
+ TEST_INSTRUCTION("23005FBA", ccmn(x1, xzr, 3, CondCode::kEQ));
+ TEST_INSTRUCTION("2300427A", ccmp(w1, w2, 3, CondCode::kEQ));
+ TEST_INSTRUCTION("230042FA", ccmp(x1, x2, 3, CondCode::kEQ));
+ TEST_INSTRUCTION("2308427A", ccmp(w1, 2, 3, CondCode::kEQ));
+ TEST_INSTRUCTION("230842FA", ccmp(x1, 2, 3, CondCode::kEQ));
+ TEST_INSTRUCTION("23005F7A", ccmp(w1, wzr, 3, CondCode::kEQ));
+ TEST_INSTRUCTION("23005FFA", ccmp(x1, xzr, 3, CondCode::kEQ));
+ TEST_INSTRUCTION("1F4000D5", cfinv());
+ TEST_INSTRUCTION("4114821A", cinc(w1, w2, CondCode::kEQ));
+ TEST_INSTRUCTION("4114829A", cinc(x1, x2, CondCode::kEQ));
+ TEST_INSTRUCTION("5F14821A", cinc(wzr, w2, CondCode::kEQ));
+ TEST_INSTRUCTION("E1179F1A", cinc(w1, wzr, CondCode::kEQ));
+ TEST_INSTRUCTION("5F14829A", cinc(xzr, x2, CondCode::kEQ));
+ TEST_INSTRUCTION("E1179F9A", cinc(x1, xzr, CondCode::kEQ));
+ TEST_INSTRUCTION("4110825A", cinv(w1, w2, CondCode::kEQ));
+ TEST_INSTRUCTION("411082DA", cinv(x1, x2, CondCode::kEQ));
+ TEST_INSTRUCTION("5F10825A", cinv(wzr, w2, CondCode::kEQ));
+ TEST_INSTRUCTION("E1139F5A", cinv(w1, wzr, CondCode::kEQ));
+ TEST_INSTRUCTION("5F1082DA", cinv(xzr, x2, CondCode::kEQ));
+ TEST_INSTRUCTION("E1139FDA", cinv(x1, xzr, CondCode::kEQ));
+ TEST_INSTRUCTION("5F3B03D5", clrex(11));
+ TEST_INSTRUCTION("4114C05A", cls(w1, w2));
+ TEST_INSTRUCTION("4114C0DA", cls(x1, x2));
+ TEST_INSTRUCTION("E117C05A", cls(w1, wzr));
+ TEST_INSTRUCTION("E117C0DA", cls(x1, xzr));
+ TEST_INSTRUCTION("5F14C05A", cls(wzr, w2));
+ TEST_INSTRUCTION("5F14C0DA", cls(xzr, x2));
+ TEST_INSTRUCTION("4110C05A", clz(w1, w2));
+ TEST_INSTRUCTION("4110C0DA", clz(x1, x2));
+ TEST_INSTRUCTION("E113C05A", clz(w1, wzr));
+ TEST_INSTRUCTION("E113C0DA", clz(x1, xzr));
+ TEST_INSTRUCTION("5F10C05A", clz(wzr, w2));
+ TEST_INSTRUCTION("5F10C0DA", clz(xzr, x2));
+ TEST_INSTRUCTION("3F840031", cmn(w1, 33));
+ TEST_INSTRUCTION("3FFC4331", cmn(w1, 0xFF000));
+ TEST_INSTRUCTION("FF030231", cmn(wsp, 128));
+ TEST_INSTRUCTION("3F8400B1", cmn(x1, 33));
+ TEST_INSTRUCTION("3FFC43B1", cmn(x1, 0xFF000));
+ TEST_INSTRUCTION("FF0302B1", cmn(sp, 128));
+ TEST_INSTRUCTION("3F00022B", cmn(w1, w2));
+ TEST_INSTRUCTION("3F0002AB", cmn(x1, x2));
+ TEST_INSTRUCTION("3F08222B", cmn(w1, w2, uxtb(2)));
+ TEST_INSTRUCTION("3F0822AB", cmn(x1, x2, uxtb(2)));
+ TEST_INSTRUCTION("FF43212B", cmn(wsp, w1));
+ TEST_INSTRUCTION("FF07212B", cmn(wsp, w1, uxtb(1)));
+ TEST_INSTRUCTION("FF6321AB", cmn(sp, x1));
+ TEST_INSTRUCTION("FF6721AB", cmn(sp, x1, uxtx(1)));
+ TEST_INSTRUCTION("3F840071", cmp(w1, 33));
+ TEST_INSTRUCTION("3FFC4371", cmp(w1, 0xFF000));
+ TEST_INSTRUCTION("FF030271", cmp(wsp, 128));
+ TEST_INSTRUCTION("3F8400F1", cmp(x1, 33));
+ TEST_INSTRUCTION("3FFC43F1", cmp(x1, 0xFF000));
+ TEST_INSTRUCTION("FF0302F1", cmp(sp, 128));
+ TEST_INSTRUCTION("3F00026B", cmp(w1, w2));
+ TEST_INSTRUCTION("3F0002EB", cmp(x1, x2));
+ TEST_INSTRUCTION("3F08226B", cmp(w1, w2, uxtb(2)));
+ TEST_INSTRUCTION("3F0822EB", cmp(x1, x2, uxtb(2)));
+ TEST_INSTRUCTION("FF43216B", cmp(wsp, w1));
+ TEST_INSTRUCTION("FF07216B", cmp(wsp, w1, uxtb(1)));
+ TEST_INSTRUCTION("FF6321EB", cmp(sp, x1));
+ TEST_INSTRUCTION("FF6721EB", cmp(sp, x1, uxtx(1)));
+ TEST_INSTRUCTION("3F00C2BA", cmpp(x1, x2));
+ TEST_INSTRUCTION("3F00DFBA", cmpp(x1, sp));
+ TEST_INSTRUCTION("FF03C2BA", cmpp(sp, x2));
+ TEST_INSTRUCTION("FF03DFBA", cmpp(sp, sp));
+ TEST_INSTRUCTION("4140C31A", crc32b(w1, w2, w3));
+ TEST_INSTRUCTION("5F40C31A", crc32b(wzr, w2, w3));
+ TEST_INSTRUCTION("E143C31A", crc32b(w1, wzr, w3));
+ TEST_INSTRUCTION("4140DF1A", crc32b(w1, w2, wzr));
+ TEST_INSTRUCTION("4150C31A", crc32cb(w1, w2, w3));
+ TEST_INSTRUCTION("5F50C31A", crc32cb(wzr, w2, w3));
+ TEST_INSTRUCTION("E153C31A", crc32cb(w1, wzr, w3));
+ TEST_INSTRUCTION("4150DF1A", crc32cb(w1, w2, wzr));
+ TEST_INSTRUCTION("4154C31A", crc32ch(w1, w2, w3));
+ TEST_INSTRUCTION("5F54C31A", crc32ch(wzr, w2, w3));
+ TEST_INSTRUCTION("E157C31A", crc32ch(w1, wzr, w3));
+ TEST_INSTRUCTION("4154DF1A", crc32ch(w1, w2, wzr));
+ TEST_INSTRUCTION("4158C31A", crc32cw(w1, w2, w3));
+ TEST_INSTRUCTION("5F58C31A", crc32cw(wzr, w2, w3));
+ TEST_INSTRUCTION("E15BC31A", crc32cw(w1, wzr, w3));
+ TEST_INSTRUCTION("4158DF1A", crc32cw(w1, w2, wzr));
+ TEST_INSTRUCTION("415CC39A", crc32cx(w1, w2, x3));
+ TEST_INSTRUCTION("5F5CC39A", crc32cx(wzr, w2, x3));
+ TEST_INSTRUCTION("E15FC39A", crc32cx(w1, wzr, x3));
+ TEST_INSTRUCTION("415CDF9A", crc32cx(w1, w2, xzr));
+ TEST_INSTRUCTION("4144C31A", crc32h(w1, w2, w3));
+ TEST_INSTRUCTION("5F44C31A", crc32h(wzr, w2, w3));
+ TEST_INSTRUCTION("E147C31A", crc32h(w1, wzr, w3));
+ TEST_INSTRUCTION("4144DF1A", crc32h(w1, w2, wzr));
+ TEST_INSTRUCTION("4148C31A", crc32w(w1, w2, w3));
+ TEST_INSTRUCTION("5F48C31A", crc32w(wzr, w2, w3));
+ TEST_INSTRUCTION("E14BC31A", crc32w(w1, wzr, w3));
+ TEST_INSTRUCTION("4148DF1A", crc32w(w1, w2, wzr));
+ TEST_INSTRUCTION("414CC39A", crc32x(w1, w2, x3));
+ TEST_INSTRUCTION("5F4CC39A", crc32x(wzr, w2, x3));
+ TEST_INSTRUCTION("E14FC39A", crc32x(w1, wzr, x3));
+ TEST_INSTRUCTION("414CDF9A", crc32x(w1, w2, xzr));
+ TEST_INSTRUCTION("9F2203D5", csdb());
+ TEST_INSTRUCTION("4100831A", csel(w1, w2, w3, CondCode::kEQ));
+ TEST_INSTRUCTION("4100839A", csel(x1, x2, x3, CondCode::kEQ));
+ TEST_INSTRUCTION("E1179F1A", cset(w1, CondCode::kEQ));
+ TEST_INSTRUCTION("E1179F9A", cset(x1, CondCode::kEQ));
+ TEST_INSTRUCTION("E1179F1A", cset(w1, CondCode::kEQ));
+ TEST_INSTRUCTION("E1179F9A", cset(x1, CondCode::kEQ));
+ TEST_INSTRUCTION("E1139F5A", csetm(w1, CondCode::kEQ));
+ TEST_INSTRUCTION("E1139FDA", csetm(x1, CondCode::kEQ));
+ TEST_INSTRUCTION("4104831A", csinc(w1, w2, w3, CondCode::kEQ));
+ TEST_INSTRUCTION("4104839A", csinc(x1, x2, x3, CondCode::kEQ));
+ TEST_INSTRUCTION("4100835A", csinv(w1, w2, w3, CondCode::kEQ));
+ TEST_INSTRUCTION("410083DA", csinv(x1, x2, x3, CondCode::kEQ));
+ TEST_INSTRUCTION("4104835A", csneg(w1, w2, w3, CondCode::kEQ));
+ TEST_INSTRUCTION("410483DA", csneg(x1, x2, x3, CondCode::kEQ));
+ TEST_INSTRUCTION("2F740BD5", dc(Predicate::DC::kZVA, x15));
+ TEST_INSTRUCTION("2100B0D4", dcps1(0x8001));
+ TEST_INSTRUCTION("2200B0D4", dcps2(0x8001));
+ TEST_INSTRUCTION("2300B0D4", dcps3(0x8001));
+ TEST_INSTRUCTION("DF2003D5", dgh());
+ TEST_INSTRUCTION("BF3103D5", dmb(1));
+ TEST_INSTRUCTION("E003BFD6", drps());
+ TEST_INSTRUCTION("9F3103D5", dsb(1));
+ TEST_INSTRUCTION("4100234A", eon(w1, w2, w3));
+ TEST_INSTRUCTION("5F00234A", eon(wzr, w2, w3));
+ TEST_INSTRUCTION("E103234A", eon(w1, wzr, w3));
+ TEST_INSTRUCTION("41003F4A", eon(w1, w2, wzr));
+ TEST_INSTRUCTION("4110234A", eon(w1, w2, w3, lsl(4)));
+ TEST_INSTRUCTION("410023CA", eon(x1, x2, x3));
+ TEST_INSTRUCTION("5F0023CA", eon(xzr, x2, x3));
+ TEST_INSTRUCTION("E10323CA", eon(x1, xzr, x3));
+ TEST_INSTRUCTION("41003FCA", eon(x1, x2, xzr));
+ TEST_INSTRUCTION("411023CA", eon(x1, x2, x3, lsl(4)));
+ TEST_INSTRUCTION("4100034A", eor(w1, w2, w3));
+ TEST_INSTRUCTION("5F00034A", eor(wzr, w2, w3));
+ TEST_INSTRUCTION("E103034A", eor(w1, wzr, w3));
+ TEST_INSTRUCTION("41001F4A", eor(w1, w2, wzr));
+ TEST_INSTRUCTION("410003CA", eor(x1, x2, x3));
+ TEST_INSTRUCTION("5F0003CA", eor(xzr, x2, x3));
+ TEST_INSTRUCTION("E10303CA", eor(x1, xzr, x3));
+ TEST_INSTRUCTION("41001FCA", eor(x1, x2, xzr));
+ TEST_INSTRUCTION("4110034A", eor(w1, w2, w3, lsl(4)));
+ TEST_INSTRUCTION("411003CA", eor(x1, x2, x3, lsl(4)));
+ TEST_INSTRUCTION("3F1C0052", eor(wsp, w1, 0xFF));
+ TEST_INSTRUCTION("FF1F0052", eor(wsp, wzr, 0xFF));
+ TEST_INSTRUCTION("3F1C40D2", eor(sp, x1, 0xFF));
+ TEST_INSTRUCTION("FF1F40D2", eor(sp, xzr, 0xFF));
+ TEST_INSTRUCTION("41001252", eor(w1, w2, 0x4000));
+ TEST_INSTRUCTION("410071D2", eor(x1, x2, 0x8000));
+ TEST_INSTRUCTION("E0039FD6", eret());
+ TEST_INSTRUCTION("1F2203D5", esb());
+ TEST_INSTRUCTION("413C8313", extr(w1, w2, w3, 15));
+ TEST_INSTRUCTION("5F3C8313", extr(wzr, w2, w3, 15));
+ TEST_INSTRUCTION("E13F8313", extr(w1, wzr, w3, 15));
+ TEST_INSTRUCTION("413C9F13", extr(w1, w2, wzr, 15));
+ TEST_INSTRUCTION("413CC393", extr(x1, x2, x3, 15));
+ TEST_INSTRUCTION("5F3CC393", extr(xzr, x2, x3, 15));
+ TEST_INSTRUCTION("E13FC393", extr(x1, xzr, x3, 15));
+ TEST_INSTRUCTION("413CDF93", extr(x1, x2, xzr, 15));
+ TEST_INSTRUCTION("4114C39A", gmi(x1, x2, x3));
+ TEST_INSTRUCTION("E117C39A", gmi(x1, sp, x3));
+ TEST_INSTRUCTION("200040D4", hlt(1));
+ TEST_INSTRUCTION("220000D4", hvc(1));
+ TEST_INSTRUCTION("2F750BD5", ic(Predicate::IC::kIVAU, x15));
+ TEST_INSTRUCTION("DF3103D5", isb(1));
+ TEST_INSTRUCTION("620021B8", ldadd(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E20321B8", ldadd(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("620021F8", ldadd(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E20321F8", ldadd(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("6200A1B8", ldadda(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E203A1B8", ldadda(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6200A1F8", ldadda(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E203A1F8", ldadda(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("6200A138", ldaddab(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E203A138", ldaddab(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6200A178", ldaddah(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E203A178", ldaddah(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6200E1B8", ldaddal(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E203E1B8", ldaddal(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6200E1F8", ldaddal(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E203E1F8", ldaddal(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("6200E138", ldaddalb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E203E138", ldaddalb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6200E178", ldaddalh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E203E178", ldaddalh(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("62002138", ldaddb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2032138", ldaddb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("62002178", ldaddh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2032178", ldaddh(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("620061B8", ldaddl(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E20361B8", ldaddl(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("620061F8", ldaddl(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E20361F8", ldaddl(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("62006138", ldaddlb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2036138", ldaddlb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("62006178", ldaddlh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2036178", ldaddlh(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("621021B8", ldclr(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E21321B8", ldclr(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("621021F8", ldclr(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E21321F8", ldclr(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("6210A1B8", ldclra(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E213A1B8", ldclra(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6210A1F8", ldclra(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E213A1F8", ldclra(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("6210A138", ldclrab(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E213A138", ldclrab(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6210A178", ldclrah(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E213A178", ldclrah(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6210E1B8", ldclral(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E213E1B8", ldclral(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6210E1F8", ldclral(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E213E1F8", ldclral(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("6210E138", ldclralb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E213E138", ldclralb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6210E178", ldclralh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E213E178", ldclralh(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("62102138", ldclrb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2132138", ldclrb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("62102178", ldclrh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2132178", ldclrh(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("621061B8", ldclrl(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E21361B8", ldclrl(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("621061F8", ldclrl(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E21361F8", ldclrl(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("62106138", ldclrlb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2136138", ldclrlb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("62106178", ldclrlh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2136178", ldclrlh(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("622021B8", ldeor(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E22321B8", ldeor(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("622021F8", ldeor(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E22321F8", ldeor(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("6220A1B8", ldeora(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E223A1B8", ldeora(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6220A1F8", ldeora(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E223A1F8", ldeora(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("6220A138", ldeorab(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E223A138", ldeorab(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6220A178", ldeorah(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E223A178", ldeorah(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6220E1B8", ldeoral(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E223E1B8", ldeoral(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6220E1F8", ldeoral(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E223E1F8", ldeoral(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("6220E138", ldeoralb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E223E138", ldeoralb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6220E178", ldeoralh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E223E178", ldeoralh(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("62202138", ldeorb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2232138", ldeorb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("62202178", ldeorh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2232178", ldeorh(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("622061B8", ldeorl(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E22361B8", ldeorl(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("622061F8", ldeorl(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E22361F8", ldeorl(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("62206138", ldeorlb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2236138", ldeorlb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("62206178", ldeorlh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2236178", ldeorlh(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("410060D9", ldg(x1, ptr(x2)));
+ TEST_INSTRUCTION("418060D9", ldg(x1, ptr(x2, 128)));
+ TEST_INSTRUCTION("E10360D9", ldg(x1, ptr(sp)));
+ TEST_INSTRUCTION("E18360D9", ldg(x1, ptr(sp, 128)));
+ TEST_INSTRUCTION("4100E0D9", ldgm(x1, ptr(x2)));
+ TEST_INSTRUCTION("E103E0D9", ldgm(x1, ptr(sp)));
+ TEST_INSTRUCTION("417CDF88", ldlar(w1, ptr(x2)));
+ TEST_INSTRUCTION("E17FDF88", ldlar(w1, ptr(sp)));
+ TEST_INSTRUCTION("417CDFC8", ldlar(x1, ptr(x2)));
+ TEST_INSTRUCTION("E17FDFC8", ldlar(x1, ptr(sp)));
+ TEST_INSTRUCTION("417CDF08", ldlarb(w1, ptr(x2)));
+ TEST_INSTRUCTION("E17FDF08", ldlarb(w1, ptr(sp)));
+ TEST_INSTRUCTION("417CDF48", ldlarh(w1, ptr(x2)));
+ TEST_INSTRUCTION("E17FDF48", ldlarh(w1, ptr(sp)));
+ TEST_INSTRUCTION("41084028", ldnp(w1, w2, ptr(x2)));
+ TEST_INSTRUCTION("41086028", ldnp(w1, w2, ptr(x2, -256)));
+ TEST_INSTRUCTION("41885F28", ldnp(w1, w2, ptr(x2, 252)));
+ TEST_INSTRUCTION("410840A8", ldnp(x1, x2, ptr(x2)));
+ TEST_INSTRUCTION("410860A8", ldnp(x1, x2, ptr(x2, -512)));
+ TEST_INSTRUCTION("41885FA8", ldnp(x1, x2, ptr(x2, 504)));
+ TEST_INSTRUCTION("41084029", ldp(w1, w2, ptr(x2)));
+ TEST_INSTRUCTION("41086029", ldp(w1, w2, ptr(x2, -256)));
+ TEST_INSTRUCTION("41885F29", ldp(w1, w2, ptr(x2, 252)));
+ TEST_INSTRUCTION("410840A9", ldp(x1, x2, ptr(x2)));
+ TEST_INSTRUCTION("410860A9", ldp(x1, x2, ptr(x2, -512)));
+ TEST_INSTRUCTION("41885FA9", ldp(x1, x2, ptr(x2, 504)));
+ TEST_INSTRUCTION("41084069", ldpsw(x1, x2, ptr(x2)));
+ TEST_INSTRUCTION("41086069", ldpsw(x1, x2, ptr(x2, -256)));
+ TEST_INSTRUCTION("41885F69", ldpsw(x1, x2, ptr(x2, 252)));
+ TEST_INSTRUCTION("410040B9", ldr(w1, ptr(x2)));
+ TEST_INSTRUCTION("413040B9", ldr(w1, ptr(x2, 48)));
+ TEST_INSTRUCTION("410C43B8", ldr(w1, ptr_pre(x2, 48)));
+ TEST_INSTRUCTION("416863B8", ldr(w1, ptr(x2, x3)));
+ TEST_INSTRUCTION("410040F9", ldr(x1, ptr(x2)));
+ TEST_INSTRUCTION("411840F9", ldr(x1, ptr(x2, 48)));
+ TEST_INSTRUCTION("410C43F8", ldr(x1, ptr_pre(x2, 48)));
+ TEST_INSTRUCTION("416863F8", ldr(x1, ptr(x2, x3)));
+ TEST_INSTRUCTION("FB0F5FF8", ldr(x27, ptr_pre(sp, -16)));
+ TEST_INSTRUCTION("FB0741F8", ldr(x27, ptr_post(sp, 16)));
+ TEST_INSTRUCTION("411040B8", ldr(w1, ptr(x2, 1))); // LDUR
+ TEST_INSTRUCTION("41D05FB8", ldr(w1, ptr(x2, -3))); // LDUR
+ TEST_INSTRUCTION("41705FB8", ldr(w1, ptr(x2, -9))); // LDUR
+ TEST_INSTRUCTION("411040F8", ldr(x1, ptr(x2, 1))); // LDUR
+ TEST_INSTRUCTION("413040F8", ldr(x1, ptr(x2, 3))); // LDUR
+ TEST_INSTRUCTION("41705FF8", ldr(x1, ptr(x2, -9))); // LDUR
+ TEST_INSTRUCTION("41004039", ldrb(w1, ptr(x2)));
+ TEST_INSTRUCTION("41C04039", ldrb(w1, ptr(x2, 48)));
+ TEST_INSTRUCTION("410C4338", ldrb(w1, ptr_pre(x2, 48)));
+ TEST_INSTRUCTION("41686338", ldrb(w1, ptr(x2, x3)));
+ TEST_INSTRUCTION("41044039", ldrb(w1, ptr(x2, 1)));
+ TEST_INSTRUCTION("41D05F38", ldrb(w1, ptr(x2, -3))); // LDURB
+ TEST_INSTRUCTION("41705F38", ldrb(w1, ptr(x2, -9))); // LDURB
+ TEST_INSTRUCTION("41004079", ldrh(w1, ptr(x2)));
+ TEST_INSTRUCTION("41604079", ldrh(w1, ptr(x2, 48)));
+ TEST_INSTRUCTION("410C4378", ldrh(w1, ptr_pre(x2, 48)));
+ TEST_INSTRUCTION("41686378", ldrh(w1, ptr(x2, x3)));
+ TEST_INSTRUCTION("41104078", ldrh(w1, ptr(x2, 1))); // LDURH
+ TEST_INSTRUCTION("41D05F78", ldrh(w1, ptr(x2, -3))); // LDURH
+ TEST_INSTRUCTION("41705F78", ldrh(w1, ptr(x2, -9))); // LDURH
+ TEST_INSTRUCTION("4104C039", ldrsb(w1, ptr(x2, 1)));
+ TEST_INSTRUCTION("41D0DF38", ldrsb(w1, ptr(x2, -3))); // LDURSB
+ TEST_INSTRUCTION("4170DF38", ldrsb(w1, ptr(x2, -9))); // LDURSB
+ TEST_INSTRUCTION("41048039", ldrsb(x1, ptr(x2, 1)));
+ TEST_INSTRUCTION("41D09F38", ldrsb(x1, ptr(x2, -3))); // LDURSB
+ TEST_INSTRUCTION("41709F38", ldrsb(x1, ptr(x2, -9))); // LDURSB
+ TEST_INSTRUCTION("4110C078", ldrsh(w1, ptr(x2, 1))); // LDURSH
+ TEST_INSTRUCTION("41D0DF78", ldrsh(w1, ptr(x2, -3))); // LDURSH
+ TEST_INSTRUCTION("4170DF78", ldrsh(w1, ptr(x2, -9))); // LDURSH
+ TEST_INSTRUCTION("41108078", ldrsh(x1, ptr(x2, 1))); // LDURSH
+ TEST_INSTRUCTION("41D09F78", ldrsh(x1, ptr(x2, -3))); // LDURSH
+ TEST_INSTRUCTION("41709F78", ldrsh(x1, ptr(x2, -9))); // LDURSH
+ TEST_INSTRUCTION("410080B9", ldrsw(x1, ptr(x2)));
+ TEST_INSTRUCTION("413080B9", ldrsw(x1, ptr(x2, 48)));
+ TEST_INSTRUCTION("410C83B8", ldrsw(x1, ptr_pre(x2, 48)));
+ TEST_INSTRUCTION("410483B8", ldrsw(x1, ptr_post(x2, 48)));
+ TEST_INSTRUCTION("4168A3B8", ldrsw(x1, ptr(x2, x3)));
+ TEST_INSTRUCTION("411080B8", ldrsw(x1, ptr(x2, 1))); // LDURSW
+ TEST_INSTRUCTION("413080B8", ldrsw(x1, ptr(x2, 3))); // LDURSW
+ TEST_INSTRUCTION("41709FB8", ldrsw(x1, ptr(x2, -9))); // LDURSW
+ TEST_INSTRUCTION("410420F8", ldraa(x1, ptr(x2)));
+ TEST_INSTRUCTION("410460F8", ldraa(x1, ptr(x2, -4096)));
+ TEST_INSTRUCTION("410C60F8", ldraa(x1, ptr_pre(x2, -4096)));
+ TEST_INSTRUCTION("41FC3FF8", ldraa(x1, ptr_pre(x2, 4088)));
+ TEST_INSTRUCTION("E10720F8", ldraa(x1, ptr(sp)));
+ TEST_INSTRUCTION("E10760F8", ldraa(x1, ptr(sp, -4096)));
+ TEST_INSTRUCTION("E10F60F8", ldraa(x1, ptr_pre(sp, -4096)));
+ TEST_INSTRUCTION("E1FF3FF8", ldraa(x1, ptr_pre(sp, 4088)));
+ TEST_INSTRUCTION("4104A0F8", ldrab(x1, ptr(x2)));
+ TEST_INSTRUCTION("4104E0F8", ldrab(x1, ptr(x2, -4096)));
+ TEST_INSTRUCTION("410CE0F8", ldrab(x1, ptr_pre(x2, -4096)));
+ TEST_INSTRUCTION("41FCBFF8", ldrab(x1, ptr_pre(x2, 4088)));
+ TEST_INSTRUCTION("E107A0F8", ldrab(x1, ptr(sp)));
+ TEST_INSTRUCTION("E107E0F8", ldrab(x1, ptr(sp, -4096)));
+ TEST_INSTRUCTION("E10FE0F8", ldrab(x1, ptr_pre(sp, -4096)));
+ TEST_INSTRUCTION("E1FFBFF8", ldrab(x1, ptr_pre(sp, 4088)));
+ TEST_INSTRUCTION("60DBA0B8", ldrsw(x0, ptr(x27, w0, sxtw(2))));
+ TEST_INSTRUCTION("623021B8", ldset(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E23321B8", ldset(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("623021F8", ldset(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E23321F8", ldset(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("6230A1B8", ldseta(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E233A1B8", ldseta(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6230A1F8", ldseta(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E233A1F8", ldseta(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("6230A138", ldsetab(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E233A138", ldsetab(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6230A178", ldsetah(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E233A178", ldsetah(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6230E1B8", ldsetal(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E233E1B8", ldsetal(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6230E1F8", ldsetal(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E233E1F8", ldsetal(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("6230E178", ldsetalh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E233E178", ldsetalh(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6230E138", ldsetalb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E233E138", ldsetalb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("62302138", ldsetb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2332138", ldsetb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("62302178", ldseth(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2332178", ldseth(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("623061B8", ldsetl(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E23361B8", ldsetl(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("623061F8", ldsetl(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E23361F8", ldsetl(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("62306138", ldsetlb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2336138", ldsetlb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("62306178", ldsetlh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2336178", ldsetlh(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("624021B8", ldsmax(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E24321B8", ldsmax(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("624021F8", ldsmax(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E24321F8", ldsmax(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("6240A1B8", ldsmaxa(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E243A1B8", ldsmaxa(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6240A1F8", ldsmaxa(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E243A1F8", ldsmaxa(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("6240A138", ldsmaxab(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E243A138", ldsmaxab(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6240A178", ldsmaxah(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E243A178", ldsmaxah(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6240E1B8", ldsmaxal(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E243E1B8", ldsmaxal(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6240E1F8", ldsmaxal(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E243E1F8", ldsmaxal(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("6240E138", ldsmaxalb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E243E138", ldsmaxalb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6240E178", ldsmaxalh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E243E178", ldsmaxalh(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("62402138", ldsmaxb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2432138", ldsmaxb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("62402178", ldsmaxh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2432178", ldsmaxh(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("624061B8", ldsmaxl(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E24361B8", ldsmaxl(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("624061F8", ldsmaxl(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E24361F8", ldsmaxl(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("62406138", ldsmaxlb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2436138", ldsmaxlb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("62406178", ldsmaxlh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2436178", ldsmaxlh(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("625021B8", ldsmin(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E25321B8", ldsmin(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("625021F8", ldsmin(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E25321F8", ldsmin(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("6250A1B8", ldsmina(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E253A1B8", ldsmina(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6250A1F8", ldsmina(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E253A1F8", ldsmina(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("6250A138", ldsminab(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E253A138", ldsminab(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6250A178", ldsminah(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E253A178", ldsminah(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6250E1B8", ldsminal(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E253E1B8", ldsminal(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6250E1F8", ldsminal(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E253E1F8", ldsminal(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("6250E138", ldsminalb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E253E138", ldsminalb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6250E178", ldsminalh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E253E178", ldsminalh(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("62502138", ldsminb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2532138", ldsminb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("62502178", ldsminh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2532178", ldsminh(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("625061B8", ldsminl(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E25361B8", ldsminl(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("625061F8", ldsminl(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E25361F8", ldsminl(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("62506138", ldsminlb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2536138", ldsminlb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("62506178", ldsminlh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2536178", ldsminlh(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("410840B8", ldtr(w1, ptr(x2)));
+ TEST_INSTRUCTION("411848B8", ldtr(w1, ptr(x2, 129)));
+ TEST_INSTRUCTION("E10B40B8", ldtr(w1, ptr(sp)));
+ TEST_INSTRUCTION("E11B48B8", ldtr(w1, ptr(sp, 129)));
+ TEST_INSTRUCTION("410840F8", ldtr(x1, ptr(x2)));
+ TEST_INSTRUCTION("411848F8", ldtr(x1, ptr(x2, 129)));
+ TEST_INSTRUCTION("E10B40F8", ldtr(x1, ptr(sp)));
+ TEST_INSTRUCTION("E11B48F8", ldtr(x1, ptr(sp, 129)));
+ TEST_INSTRUCTION("41084038", ldtrb(w1, ptr(x2)));
+ TEST_INSTRUCTION("41184838", ldtrb(w1, ptr(x2, 129)));
+ TEST_INSTRUCTION("E10B4038", ldtrb(w1, ptr(sp)));
+ TEST_INSTRUCTION("E11B4838", ldtrb(w1, ptr(sp, 129)));
+ TEST_INSTRUCTION("41084078", ldtrh(w1, ptr(x2)));
+ TEST_INSTRUCTION("41184878", ldtrh(w1, ptr(x2, 129)));
+ TEST_INSTRUCTION("E10B4078", ldtrh(w1, ptr(sp)));
+ TEST_INSTRUCTION("E11B4878", ldtrh(w1, ptr(sp, 129)));
+ TEST_INSTRUCTION("4108C038", ldtrsb(w1, ptr(x2)));
+ TEST_INSTRUCTION("4118C838", ldtrsb(w1, ptr(x2, 129)));
+ TEST_INSTRUCTION("E10BC038", ldtrsb(w1, ptr(sp)));
+ TEST_INSTRUCTION("E11BC838", ldtrsb(w1, ptr(sp, 129)));
+ TEST_INSTRUCTION("4108C078", ldtrsh(w1, ptr(x2)));
+ TEST_INSTRUCTION("4118C878", ldtrsh(w1, ptr(x2, 129)));
+ TEST_INSTRUCTION("E10BC078", ldtrsh(w1, ptr(sp)));
+ TEST_INSTRUCTION("E11BC878", ldtrsh(w1, ptr(sp, 129)));
+ TEST_INSTRUCTION("410880B8", ldtrsw(x1, ptr(x2)));
+ TEST_INSTRUCTION("411888B8", ldtrsw(x1, ptr(x2, 129)));
+ TEST_INSTRUCTION("E10B80B8", ldtrsw(x1, ptr(sp)));
+ TEST_INSTRUCTION("E11B88B8", ldtrsw(x1, ptr(sp, 129)));
+ TEST_INSTRUCTION("626021B8", ldumax(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E26321B8", ldumax(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("626021F8", ldumax(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E26321F8", ldumax(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("6260A1B8", ldumaxa(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E263A1B8", ldumaxa(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6260A1F8", ldumaxa(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E263A1F8", ldumaxa(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("6260A138", ldumaxab(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E263A138", ldumaxab(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6260A178", ldumaxah(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E263A178", ldumaxah(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6260E1B8", ldumaxal(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E263E1B8", ldumaxal(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6260E1F8", ldumaxal(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E263E1F8", ldumaxal(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("6260E138", ldumaxalb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E263E138", ldumaxalb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6260E178", ldumaxalh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E263E178", ldumaxalh(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("62602138", ldumaxb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2632138", ldumaxb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("62602178", ldumaxh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2632178", ldumaxh(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("626061B8", ldumaxl(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E26361B8", ldumaxl(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("626061F8", ldumaxl(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E26361F8", ldumaxl(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("62606138", ldumaxlb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2636138", ldumaxlb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("62606178", ldumaxlh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2636178", ldumaxlh(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("627021B8", ldumin(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E27321B8", ldumin(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("627021F8", ldumin(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E27321F8", ldumin(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("6270A1B8", ldumina(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E273A1B8", ldumina(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6270A1F8", ldumina(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E273A1F8", ldumina(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("6270A138", lduminab(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E273A138", lduminab(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6270A178", lduminah(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E273A178", lduminah(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6270E1B8", lduminal(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E273E1B8", lduminal(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6270E1F8", lduminal(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E273E1F8", lduminal(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("6270E138", lduminalb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E273E138", lduminalb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("6270E178", lduminalh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E273E178", lduminalh(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("62702138", lduminb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2732138", lduminb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("62702178", lduminh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2732178", lduminh(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("627061B8", lduminl(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E27361B8", lduminl(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("627061F8", lduminl(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E27361F8", lduminl(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("62706138", lduminlb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2736138", lduminlb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("62706178", lduminlh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E2736178", lduminlh(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("410040B8", ldur(w1, ptr(x2)));
+ TEST_INSTRUCTION("411048B8", ldur(w1, ptr(x2, 129)));
+ TEST_INSTRUCTION("E10340B8", ldur(w1, ptr(sp)));
+ TEST_INSTRUCTION("E11348B8", ldur(w1, ptr(sp, 129)));
+ TEST_INSTRUCTION("410040F8", ldur(x1, ptr(x2)));
+ TEST_INSTRUCTION("411048F8", ldur(x1, ptr(x2, 129)));
+ TEST_INSTRUCTION("E10340F8", ldur(x1, ptr(sp)));
+ TEST_INSTRUCTION("E11348F8", ldur(x1, ptr(sp, 129)));
+ TEST_INSTRUCTION("41004038", ldurb(w1, ptr(x2)));
+ TEST_INSTRUCTION("41104838", ldurb(w1, ptr(x2, 129)));
+ TEST_INSTRUCTION("E1034038", ldurb(w1, ptr(sp)));
+ TEST_INSTRUCTION("E1134838", ldurb(w1, ptr(sp, 129)));
+ TEST_INSTRUCTION("41004078", ldurh(w1, ptr(x2)));
+ TEST_INSTRUCTION("41104878", ldurh(w1, ptr(x2, 129)));
+ TEST_INSTRUCTION("E1034078", ldurh(w1, ptr(sp)));
+ TEST_INSTRUCTION("E1134878", ldurh(w1, ptr(sp, 129)));
+ TEST_INSTRUCTION("4100C038", ldursb(w1, ptr(x2)));
+ TEST_INSTRUCTION("4110C838", ldursb(w1, ptr(x2, 129)));
+ TEST_INSTRUCTION("E103C038", ldursb(w1, ptr(sp)));
+ TEST_INSTRUCTION("E113C838", ldursb(w1, ptr(sp, 129)));
+ TEST_INSTRUCTION("4100C078", ldursh(w1, ptr(x2)));
+ TEST_INSTRUCTION("4110C878", ldursh(w1, ptr(x2, 129)));
+ TEST_INSTRUCTION("E103C078", ldursh(w1, ptr(sp)));
+ TEST_INSTRUCTION("E113C878", ldursh(w1, ptr(sp, 129)));
+ TEST_INSTRUCTION("410080B8", ldursw(x1, ptr(x2)));
+ TEST_INSTRUCTION("411088B8", ldursw(x1, ptr(x2, 129)));
+ TEST_INSTRUCTION("E10380B8", ldursw(x1, ptr(sp)));
+ TEST_INSTRUCTION("E11388B8", ldursw(x1, ptr(sp, 129)));
+ TEST_INSTRUCTION("61087F88", ldxp(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E10B7F88", ldxp(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("61087FC8", ldxp(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E10B7FC8", ldxp(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("417C5F88", ldxr(w1, ptr(x2)));
+ TEST_INSTRUCTION("E17F5F88", ldxr(w1, ptr(sp)));
+ TEST_INSTRUCTION("417C5FC8", ldxr(x1, ptr(x2)));
+ TEST_INSTRUCTION("E17F5FC8", ldxr(x1, ptr(sp)));
+ TEST_INSTRUCTION("417C5F08", ldxrb(w1, ptr(x2)));
+ TEST_INSTRUCTION("E17F5F08", ldxrb(w1, ptr(sp)));
+ TEST_INSTRUCTION("417C5F48", ldxrh(w1, ptr(x2)));
+ TEST_INSTRUCTION("E17F5F48", ldxrh(w1, ptr(sp)));
+ TEST_INSTRUCTION("4120C31A", lsl(w1, w2, w3));
+ TEST_INSTRUCTION("4120C39A", lsl(x1, x2, x3));
+ TEST_INSTRUCTION("41401153", lsl(w1, w2, 15));
+ TEST_INSTRUCTION("41C071D3", lsl(x1, x2, 15));
+ TEST_INSTRUCTION("4120C31A", lslv(w1, w2, w3));
+ TEST_INSTRUCTION("4120C39A", lslv(x1, x2, x3));
+ TEST_INSTRUCTION("4124C31A", lsr(w1, w2, w3));
+ TEST_INSTRUCTION("4124C39A", lsr(x1, x2, x3));
+ TEST_INSTRUCTION("417C0F53", lsr(w1, w2, 15));
+ TEST_INSTRUCTION("41FC4FD3", lsr(x1, x2, 15));
+ TEST_INSTRUCTION("4124C31A", lsrv(w1, w2, w3));
+ TEST_INSTRUCTION("4124C39A", lsrv(x1, x2, x3));
+ TEST_INSTRUCTION("4110031B", madd(w1, w2, w3, w4));
+ TEST_INSTRUCTION("4110039B", madd(x1, x2, x3, x4));
+ TEST_INSTRUCTION("41FC031B", mneg(w1, w2, w3));
+ TEST_INSTRUCTION("41FC039B", mneg(x1, x2, x3));
+ TEST_INSTRUCTION("E103022A", mov(w1, w2));
+ TEST_INSTRUCTION("E10302AA", mov(x1, x2));
+ TEST_INSTRUCTION("01008052", mov(w1, 0));
+ TEST_INSTRUCTION("01008012", mov(w1, -1));
+ TEST_INSTRUCTION("21008052", mov(w1, 1));
+ TEST_INSTRUCTION("41008052", mov(w1, 2));
+ TEST_INSTRUCTION("61008052", mov(w1, 3));
+ TEST_INSTRUCTION("81008052", mov(w1, 4));
+ TEST_INSTRUCTION("A1008052", mov(w1, 5));
+ TEST_INSTRUCTION("C1008052", mov(w1, 6));
+ TEST_INSTRUCTION("E1008052", mov(w1, 7));
+ TEST_INSTRUCTION("01018052", mov(w1, 8));
+ TEST_INSTRUCTION("21018052", mov(w1, 9));
+ TEST_INSTRUCTION("41018052", mov(w1, 10));
+ TEST_INSTRUCTION("8146A252", mov(w1, 0x12340000));
+ TEST_INSTRUCTION("81468252", mov(w1, 0x00001234));
+ TEST_INSTRUCTION("61B9BD12", mov(w1, 0x1234FFFF));
+ TEST_INSTRUCTION("61B99D12", mov(w1, 0xFFFF1234));
+ TEST_INSTRUCTION("010080D2", mov(x1, 0));
+ TEST_INSTRUCTION("01008092", mov(x1, -1));
+ TEST_INSTRUCTION("8146E2D2", mov(x1, 0x1234000000000000));
+ TEST_INSTRUCTION("8146C2D2", mov(x1, 0x0000123400000000));
+ TEST_INSTRUCTION("8146A2D2", mov(x1, 0x0000000012340000));
+ TEST_INSTRUCTION("814682D2", mov(x1, 0x0000000000001234));
+ TEST_INSTRUCTION("61B9FD92", mov(x1, 0x1234FFFFFFFFFFFF));
+ TEST_INSTRUCTION("61B9DD92", mov(x1, 0xFFFF1234FFFFFFFF));
+ TEST_INSTRUCTION("61B9BD92", mov(x1, 0xFFFFFFFF1234FFFF));
+ TEST_INSTRUCTION("61B99D92", mov(x1, 0xFFFFFFFFFFFF1234));
+ TEST_INSTRUCTION("E1030011", mov(w1, wsp));
+ TEST_INSTRUCTION("E1030091", mov(x1, sp));
+ TEST_INSTRUCTION("3F000011", mov(wsp, w1));
+ TEST_INSTRUCTION("FF3F0032", mov(wsp, 0xFFFF));
+ TEST_INSTRUCTION("3F000091", mov(sp, x1));
+ TEST_INSTRUCTION("FF3F40B2", mov(sp, 0xFFFF));
+ TEST_INSTRUCTION("FF030011", mov(wsp, wsp));
+ TEST_INSTRUCTION("FF030091", mov(sp, sp));
+ TEST_INSTRUCTION("015138D5", mrs(x1, Predicate::SysReg::kAFSR0_EL1));
+ TEST_INSTRUCTION("01423BD5", mrs(x1, Predicate::SysReg::kNZCV));
+ TEST_INSTRUCTION("015118D5", msr(Predicate::SysReg::kAFSR0_EL1, x1));
+ TEST_INSTRUCTION("01421BD5", msr(Predicate::SysReg::kNZCV, x1));
+ TEST_INSTRUCTION("4190031B", msub(w1, w2, w3, w4));
+ TEST_INSTRUCTION("4190039B", msub(x1, x2, x3, x4));
+ TEST_INSTRUCTION("417C031B", mul(w1, w2, w3));
+ TEST_INSTRUCTION("417C039B", mul(x1, x2, x3));
+ TEST_INSTRUCTION("E103222A", mvn(w1, w2));
+ TEST_INSTRUCTION("E10322AA", mvn(x1, x2));
+ TEST_INSTRUCTION("E113222A", mvn(w1, w2, lsl(4)));
+ TEST_INSTRUCTION("E11322AA", mvn(x1, x2, lsl(4)));
+ TEST_INSTRUCTION("E103024B", neg(w1, w2));
+ TEST_INSTRUCTION("E10302CB", neg(x1, x2));
+ TEST_INSTRUCTION("E113024B", neg(w1, w2, lsl(4)));
+ TEST_INSTRUCTION("E11302CB", neg(x1, x2, lsl(4)));
+ TEST_INSTRUCTION("E103026B", negs(w1, w2));
+ TEST_INSTRUCTION("E10302EB", negs(x1, x2));
+ TEST_INSTRUCTION("E113026B", negs(w1, w2, lsl(4)));
+ TEST_INSTRUCTION("E11302EB", negs(x1, x2, lsl(4)));
+ TEST_INSTRUCTION("E103025A", ngc(w1, w2));
+ TEST_INSTRUCTION("E10302DA", ngc(x1, x2));
+ TEST_INSTRUCTION("E103027A", ngcs(w1, w2));
+ TEST_INSTRUCTION("E10302FA", ngcs(x1, x2));
+ TEST_INSTRUCTION("4100232A", orn(w1, w2, w3));
+ TEST_INSTRUCTION("410023AA", orn(x1, x2, x3));
+ TEST_INSTRUCTION("4110232A", orn(w1, w2, w3, lsl(4)));
+ TEST_INSTRUCTION("411023AA", orn(x1, x2, x3, lsl(4)));
+ TEST_INSTRUCTION("4100032A", orr(w1, w2, w3));
+ TEST_INSTRUCTION("410003AA", orr(x1, x2, x3));
+ TEST_INSTRUCTION("4110032A", orr(w1, w2, w3, lsl(4)));
+ TEST_INSTRUCTION("411003AA", orr(x1, x2, x3, lsl(4)));
+ TEST_INSTRUCTION("3F1C0032", orr(wsp, w1, 0xFF));
+ TEST_INSTRUCTION("3F1C40B2", orr(sp, x1, 0xFF));
+ TEST_INSTRUCTION("41001232", orr(w1, w2, 0x4000));
+ TEST_INSTRUCTION("410071B2", orr(x1, x2, 0x8000));
+ TEST_INSTRUCTION("E8030032", orr(w8, wzr, 0x1));
+ TEST_INSTRUCTION("E80340B2", orr(x8, xzr, 0x1));
+ TEST_INSTRUCTION("4108C1DA", pacda(x1, x2));
+ TEST_INSTRUCTION("E10BC1DA", pacda(x1, sp));
+ TEST_INSTRUCTION("410CC1DA", pacdb(x1, x2));
+ TEST_INSTRUCTION("E10FC1DA", pacdb(x1, sp));
+ TEST_INSTRUCTION("E12BC1DA", pacdza(x1));
+ TEST_INSTRUCTION("F42BC1DA", pacdza(x20));
+ TEST_INSTRUCTION("E12FC1DA", pacdzb(x1));
+ TEST_INSTRUCTION("F42FC1DA", pacdzb(x20));
+ TEST_INSTRUCTION("4130C39A", pacga(x1, x2, x3));
+ TEST_INSTRUCTION("4130DF9A", pacga(x1, x2, sp));
+ TEST_INSTRUCTION("9F3403D5", pssbb());
+ TEST_INSTRUCTION("4100C05A", rbit(w1, w2));
+ TEST_INSTRUCTION("4100C0DA", rbit(x1, x2));
+ TEST_INSTRUCTION("4108C05A", rev(w1, w2));
+ TEST_INSTRUCTION("410CC0DA", rev(x1, x2));
+ TEST_INSTRUCTION("4104C05A", rev16(w1, w2));
+ TEST_INSTRUCTION("4104C0DA", rev16(x1, x2));
+ TEST_INSTRUCTION("4108C0DA", rev32(x1, x2));
+ TEST_INSTRUCTION("410CC0DA", rev64(x1, x2));
+ TEST_INSTRUCTION("412CC31A", ror(w1, w2, w3));
+ TEST_INSTRUCTION("412CC39A", ror(x1, x2, x3));
+ TEST_INSTRUCTION("413C8213", ror(w1, w2, 15));
+ TEST_INSTRUCTION("413CC293", ror(x1, x2, 15));
+ TEST_INSTRUCTION("412CC31A", rorv(w1, w2, w3));
+ TEST_INSTRUCTION("412CC39A", rorv(x1, x2, x3));
+ TEST_INSTRUCTION("4100035A", sbc(w1, w2, w3));
+ TEST_INSTRUCTION("410003DA", sbc(x1, x2, x3));
+ TEST_INSTRUCTION("4100037A", sbcs(w1, w2, w3));
+ TEST_INSTRUCTION("410003FA", sbcs(x1, x2, x3));
+ TEST_INSTRUCTION("41241B13", sbfiz(w1, w2, 5, 10));
+ TEST_INSTRUCTION("41247B93", sbfiz(x1, x2, 5, 10));
+ TEST_INSTRUCTION("41280513", sbfm(w1, w2, 5, 10));
+ TEST_INSTRUCTION("41284593", sbfm(x1, x2, 5, 10));
+ TEST_INSTRUCTION("41380513", sbfx(w1, w2, 5, 10));
+ TEST_INSTRUCTION("41384593", sbfx(x1, x2, 5, 10));
+ TEST_INSTRUCTION("410CC31A", sdiv(w1, w2, w3));
+ TEST_INSTRUCTION("410CC39A", sdiv(x1, x2, x3));
+ TEST_INSTRUCTION("2D08003A", setf8(w1));
+ TEST_INSTRUCTION("2D48003A", setf16(w1));
+ TEST_INSTRUCTION("4110239B", smaddl(x1, w2, w3, x4));
+ TEST_INSTRUCTION("230000D4", smc(1));
+ TEST_INSTRUCTION("41FC239B", smnegl(x1, w2, w3));
+ TEST_INSTRUCTION("4190239B", smsubl(x1, w2, w3, x4));
+ TEST_INSTRUCTION("417C439B", smulh(x1, x2, x3));
+ TEST_INSTRUCTION("417C239B", smull(x1, w2, w3));
+ TEST_INSTRUCTION("9F3003D5", ssbb());
+ TEST_INSTRUCTION("4108A0D9", st2g(x1, ptr(x2)));
+ TEST_INSTRUCTION("4188A0D9", st2g(x1, ptr(x2, 128)));
+ TEST_INSTRUCTION("418CA0D9", st2g(x1, ptr_pre(x2, 128)));
+ TEST_INSTRUCTION("4184A0D9", st2g(x1, ptr_post(x2, 128)));
+ TEST_INSTRUCTION("E10BA0D9", st2g(x1, ptr(sp)));
+ TEST_INSTRUCTION("E18BA0D9", st2g(x1, ptr(sp, 128)));
+ TEST_INSTRUCTION("E18FA0D9", st2g(x1, ptr_pre(sp, 128)));
+ TEST_INSTRUCTION("E187A0D9", st2g(x1, ptr_post(sp, 128)));
+ TEST_INSTRUCTION("5F08A0D9", st2g(sp, ptr(x2)));
+ TEST_INSTRUCTION("5F88A0D9", st2g(sp, ptr(x2, 128)));
+ TEST_INSTRUCTION("5F8CA0D9", st2g(sp, ptr_pre(x2, 128)));
+ TEST_INSTRUCTION("5F84A0D9", st2g(sp, ptr_post(x2, 128)));
+ TEST_INSTRUCTION("FF0BA0D9", st2g(sp, ptr(sp)));
+ TEST_INSTRUCTION("FF8BA0D9", st2g(sp, ptr(sp, 128)));
+ TEST_INSTRUCTION("FF8FA0D9", st2g(sp, ptr_pre(sp, 128)));
+ TEST_INSTRUCTION("FF87A0D9", st2g(sp, ptr_post(sp, 128)));
+ TEST_INSTRUCTION("410820D9", stg(x1, ptr(x2)));
+ TEST_INSTRUCTION("418820D9", stg(x1, ptr(x2, 128)));
+ TEST_INSTRUCTION("418C20D9", stg(x1, ptr_pre(x2, 128)));
+ TEST_INSTRUCTION("418420D9", stg(x1, ptr_post(x2, 128)));
+ TEST_INSTRUCTION("E10B20D9", stg(x1, ptr(sp)));
+ TEST_INSTRUCTION("E18B20D9", stg(x1, ptr(sp, 128)));
+ TEST_INSTRUCTION("E18F20D9", stg(x1, ptr_pre(sp, 128)));
+ TEST_INSTRUCTION("E18720D9", stg(x1, ptr_post(sp, 128)));
+ TEST_INSTRUCTION("5F0820D9", stg(sp, ptr(x2)));
+ TEST_INSTRUCTION("5F8820D9", stg(sp, ptr(x2, 128)));
+ TEST_INSTRUCTION("5F8C20D9", stg(sp, ptr_pre(x2, 128)));
+ TEST_INSTRUCTION("5F8420D9", stg(sp, ptr_post(x2, 128)));
+ TEST_INSTRUCTION("FF0B20D9", stg(sp, ptr(sp)));
+ TEST_INSTRUCTION("FF8B20D9", stg(sp, ptr(sp, 128)));
+ TEST_INSTRUCTION("FF8F20D9", stg(sp, ptr_pre(sp, 128)));
+ TEST_INSTRUCTION("FF8720D9", stg(sp, ptr_post(sp, 128)));
+ TEST_INSTRUCTION("4100A0D9", stgm(x1, ptr(x2)));
+ TEST_INSTRUCTION("E103A0D9", stgm(x1, ptr(sp)));
+ TEST_INSTRUCTION("FF03A0D9", stgm(xzr, ptr(sp)));
+ TEST_INSTRUCTION("61080069", stgp(x1, x2, ptr(x3)));
+ TEST_INSTRUCTION("61082069", stgp(x1, x2, ptr(x3, -1024)));
+ TEST_INSTRUCTION("6108A069", stgp(x1, x2, ptr_pre(x3, -1024)));
+ TEST_INSTRUCTION("6108A068", stgp(x1, x2, ptr_post(x3, -1024)));
+ TEST_INSTRUCTION("61881F69", stgp(x1, x2, ptr(x3, 1008)));
+ TEST_INSTRUCTION("61889F69", stgp(x1, x2, ptr_pre(x3, 1008)));
+ TEST_INSTRUCTION("61889F68", stgp(x1, x2, ptr_post(x3, 1008)));
+ TEST_INSTRUCTION("E10B0069", stgp(x1, x2, ptr(sp)));
+ TEST_INSTRUCTION("E10B2069", stgp(x1, x2, ptr(sp, -1024)));
+ TEST_INSTRUCTION("E10BA069", stgp(x1, x2, ptr_pre(sp, -1024)));
+ TEST_INSTRUCTION("E10BA068", stgp(x1, x2, ptr_post(sp, -1024)));
+ TEST_INSTRUCTION("E18B1F69", stgp(x1, x2, ptr(sp, 1008)));
+ TEST_INSTRUCTION("E18B9F69", stgp(x1, x2, ptr_pre(sp, 1008)));
+ TEST_INSTRUCTION("E18B9F68", stgp(x1, x2, ptr_post(sp, 1008)));
+ TEST_INSTRUCTION("41080029", stp(w1, w2, ptr(x2)));
+ TEST_INSTRUCTION("41082029", stp(w1, w2, ptr(x2, -256)));
+ TEST_INSTRUCTION("41881F29", stp(w1, w2, ptr(x2, 252)));
+ TEST_INSTRUCTION("410800A9", stp(x1, x2, ptr(x2)));
+ TEST_INSTRUCTION("410820A9", stp(x1, x2, ptr(x2, -512)));
+ TEST_INSTRUCTION("41881FA9", stp(x1, x2, ptr(x2, 504)));
+ TEST_INSTRUCTION("FB0F1FF8", str(x27, ptr_pre(sp, -16)));
+ TEST_INSTRUCTION("411000B8", str(w1, ptr(x2, 1))); // STUR
+ TEST_INSTRUCTION("41D01FB8", str(w1, ptr(x2, -3))); // STUR
+ TEST_INSTRUCTION("41701FB8", str(w1, ptr(x2, -9))); // STUR
+ TEST_INSTRUCTION("411000F8", str(x1, ptr(x2, 1))); // STUR
+ TEST_INSTRUCTION("413000F8", str(x1, ptr(x2, 3))); // STUR
+ TEST_INSTRUCTION("41701FF8", str(x1, ptr(x2, -9))); // STUR
+ TEST_INSTRUCTION("41040039", strb(w1, ptr(x2, 1)));
+ TEST_INSTRUCTION("41D01F38", strb(w1, ptr(x2, -3))); // STURB
+ TEST_INSTRUCTION("41701F38", strb(w1, ptr(x2, -9))); // STURB
+ TEST_INSTRUCTION("41100078", strh(w1, ptr(x2, 1))); // STURH
+ TEST_INSTRUCTION("41D01F78", strh(w1, ptr(x2, -3))); // STURH
+ TEST_INSTRUCTION("41701F78", strh(w1, ptr(x2, -9))); // STURH
+ TEST_INSTRUCTION("410800B8", sttr(w1, ptr(x2)));
+ TEST_INSTRUCTION("411808B8", sttr(w1, ptr(x2, 129)));
+ TEST_INSTRUCTION("E10B00B8", sttr(w1, ptr(sp)));
+ TEST_INSTRUCTION("E11B08B8", sttr(w1, ptr(sp, 129)));
+ TEST_INSTRUCTION("410800F8", sttr(x1, ptr(x2)));
+ TEST_INSTRUCTION("411808F8", sttr(x1, ptr(x2, 129)));
+ TEST_INSTRUCTION("E10B00F8", sttr(x1, ptr(sp)));
+ TEST_INSTRUCTION("E11B08F8", sttr(x1, ptr(sp, 129)));
+ TEST_INSTRUCTION("41080038", sttrb(w1, ptr(x2)));
+ TEST_INSTRUCTION("41180838", sttrb(w1, ptr(x2, 129)));
+ TEST_INSTRUCTION("E10B0038", sttrb(w1, ptr(sp)));
+ TEST_INSTRUCTION("E11B0838", sttrb(w1, ptr(sp, 129)));
+ TEST_INSTRUCTION("41080078", sttrh(w1, ptr(x2)));
+ TEST_INSTRUCTION("41180878", sttrh(w1, ptr(x2, 129)));
+ TEST_INSTRUCTION("E10B0078", sttrh(w1, ptr(sp)));
+ TEST_INSTRUCTION("E11B0878", sttrh(w1, ptr(sp, 129)));
+ TEST_INSTRUCTION("410000B8", stur(w1, ptr(x2)));
+ TEST_INSTRUCTION("411008B8", stur(w1, ptr(x2, 129)));
+ TEST_INSTRUCTION("E10300B8", stur(w1, ptr(sp)));
+ TEST_INSTRUCTION("E11308B8", stur(w1, ptr(sp, 129)));
+ TEST_INSTRUCTION("410000F8", stur(x1, ptr(x2)));
+ TEST_INSTRUCTION("411008F8", stur(x1, ptr(x2, 129)));
+ TEST_INSTRUCTION("E10300F8", stur(x1, ptr(sp)));
+ TEST_INSTRUCTION("E11308F8", stur(x1, ptr(sp, 129)));
+ TEST_INSTRUCTION("41000038", sturb(w1, ptr(x2)));
+ TEST_INSTRUCTION("41100838", sturb(w1, ptr(x2, 129)));
+ TEST_INSTRUCTION("E1030038", sturb(w1, ptr(sp)));
+ TEST_INSTRUCTION("E1130838", sturb(w1, ptr(sp, 129)));
+ TEST_INSTRUCTION("41000078", sturh(w1, ptr(x2)));
+ TEST_INSTRUCTION("41100878", sturh(w1, ptr(x2, 129)));
+ TEST_INSTRUCTION("E1030078", sturh(w1, ptr(sp)));
+ TEST_INSTRUCTION("E1130878", sturh(w1, ptr(sp, 129)));
+ TEST_INSTRUCTION("820C2188", stxp(w1, w2, w3, ptr(x4)));
+ TEST_INSTRUCTION("E20F2188", stxp(w1, w2, w3, ptr(sp)));
+ TEST_INSTRUCTION("820C21C8", stxp(w1, x2, x3, ptr(x4)));
+ TEST_INSTRUCTION("E20F21C8", stxp(w1, x2, x3, ptr(sp)));
+ TEST_INSTRUCTION("627C0188", stxr(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E27F0188", stxr(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("627C01C8", stxr(w1, x2, ptr(x3)));
+ TEST_INSTRUCTION("E27F01C8", stxr(w1, x2, ptr(sp)));
+ TEST_INSTRUCTION("627C0108", stxrb(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E27F0108", stxrb(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("627C0148", stxrh(w1, w2, ptr(x3)));
+ TEST_INSTRUCTION("E27F0148", stxrh(w1, w2, ptr(sp)));
+ TEST_INSTRUCTION("4108E0D9", stz2g(x1, ptr(x2)));
+ TEST_INSTRUCTION("4108F0D9", stz2g(x1, ptr(x2, -4096)));
+ TEST_INSTRUCTION("410CF0D9", stz2g(x1, ptr_pre(x2, -4096)));
+ TEST_INSTRUCTION("4104F0D9", stz2g(x1, ptr_post(x2, -4096)));
+ TEST_INSTRUCTION("41F8EFD9", stz2g(x1, ptr(x2, 4080)));
+ TEST_INSTRUCTION("41FCEFD9", stz2g(x1, ptr_pre(x2, 4080)));
+ TEST_INSTRUCTION("41F4EFD9", stz2g(x1, ptr_post(x2, 4080)));
+ TEST_INSTRUCTION("E10BE0D9", stz2g(x1, ptr(sp)));
+ TEST_INSTRUCTION("E10BF0D9", stz2g(x1, ptr(sp, -4096)));
+ TEST_INSTRUCTION("E10FF0D9", stz2g(x1, ptr_pre(sp, -4096)));
+ TEST_INSTRUCTION("E107F0D9", stz2g(x1, ptr_post(sp, -4096)));
+ TEST_INSTRUCTION("E1FBEFD9", stz2g(x1, ptr(sp, 4080)));
+ TEST_INSTRUCTION("E1FFEFD9", stz2g(x1, ptr_pre(sp, 4080)));
+ TEST_INSTRUCTION("E1F7EFD9", stz2g(x1, ptr_post(sp, 4080)));
+ TEST_INSTRUCTION("410860D9", stzg(x1, ptr(x2)));
+ TEST_INSTRUCTION("418860D9", stzg(x1, ptr(x2, 128)));
+ TEST_INSTRUCTION("418C60D9", stzg(x1, ptr_pre(x2, 128)));
+ TEST_INSTRUCTION("418460D9", stzg(x1, ptr_post(x2, 128)));
+ TEST_INSTRUCTION("E10B60D9", stzg(x1, ptr(sp)));
+ TEST_INSTRUCTION("E18B60D9", stzg(x1, ptr(sp, 128)));
+ TEST_INSTRUCTION("E18F60D9", stzg(x1, ptr_pre(sp, 128)));
+ TEST_INSTRUCTION("E18760D9", stzg(x1, ptr_post(sp, 128)));
+ TEST_INSTRUCTION("5F0860D9", stzg(sp, ptr(x2)));
+ TEST_INSTRUCTION("5F8860D9", stzg(sp, ptr(x2, 128)));
+ TEST_INSTRUCTION("5F8C60D9", stzg(sp, ptr_pre(x2, 128)));
+ TEST_INSTRUCTION("5F8460D9", stzg(sp, ptr_post(x2, 128)));
+ TEST_INSTRUCTION("FF0B60D9", stzg(sp, ptr(sp)));
+ TEST_INSTRUCTION("FF8B60D9", stzg(sp, ptr(sp, 128)));
+ TEST_INSTRUCTION("FF8F60D9", stzg(sp, ptr_pre(sp, 128)));
+ TEST_INSTRUCTION("FF8760D9", stzg(sp, ptr_post(sp, 128)));
+ TEST_INSTRUCTION("410020D9", stzgm(x1, ptr(x2)));
+ TEST_INSTRUCTION("E10320D9", stzgm(x1, ptr(sp)));
+ TEST_INSTRUCTION("4100034B", sub(w1, w2, w3));
+ TEST_INSTRUCTION("410003CB", sub(x1, x2, x3));
+ TEST_INSTRUCTION("410C034B", sub(w1, w2, w3, lsl(3)));
+ TEST_INSTRUCTION("410C03CB", sub(x1, x2, x3, lsl(3)));
+ TEST_INSTRUCTION("FF030451", sub(wsp, wsp, 256));
+ TEST_INSTRUCTION("FFFF3F51", sub(wsp, wsp, 0xFFF));
+ TEST_INSTRUCTION("FF0304D1", sub(sp, sp, 256));
+ TEST_INSTRUCTION("FFFF3FD1", sub(sp, sp, 0xFFF));
+ TEST_INSTRUCTION("412C82D1", subg(x1, x2, 32, 11));
+ TEST_INSTRUCTION("5F2C82D1", subg(sp, x2, 32, 11));
+ TEST_INSTRUCTION("E12F82D1", subg(x1, sp, 32, 11));
+ TEST_INSTRUCTION("4100C39A", subp(x1, x2, x3));
+ TEST_INSTRUCTION("E103C39A", subp(x1, sp, x3));
+ TEST_INSTRUCTION("4100DF9A", subp(x1, x2, sp));
+ TEST_INSTRUCTION("4100C3BA", subps(x1, x2, x3));
+ TEST_INSTRUCTION("E103C3BA", subps(x1, sp, x3));
+ TEST_INSTRUCTION("4100DFBA", subps(x1, x2, sp));
+ TEST_INSTRUCTION("4100036B", subs(w1, w2, w3));
+ TEST_INSTRUCTION("410003EB", subs(x1, x2, x3));
+ TEST_INSTRUCTION("410C036B", subs(w1, w2, w3, lsl(3)));
+ TEST_INSTRUCTION("410C03EB", subs(x1, x2, x3, lsl(3)));
+ TEST_INSTRUCTION("210000D4", svc(1));
+ TEST_INSTRUCTION("411C0013", sxtb(w1, w2));
+ TEST_INSTRUCTION("411C4093", sxtb(x1, w2));
+ TEST_INSTRUCTION("413C0013", sxth(w1, w2));
+ TEST_INSTRUCTION("413C4093", sxth(x1, w2));
+ TEST_INSTRUCTION("417C4093", sxtw(x1, w2));
+ TEST_INSTRUCTION("932309D5", sys(1, 2, 3, 4, x19));
+ TEST_INSTRUCTION("AF8708D5", tlbi(Predicate::TLBI::kVALE1, x15));
+ TEST_INSTRUCTION("3F000072", tst(w1, 1));
+ TEST_INSTRUCTION("3F0040F2", tst(x1, 1));
+ TEST_INSTRUCTION("3F00026A", tst(w1, w2));
+ TEST_INSTRUCTION("3F0002EA", tst(x1, x2));
+ TEST_INSTRUCTION("3F10026A", tst(w1, w2, lsl(4)));
+ TEST_INSTRUCTION("3F1002EA", tst(x1, x2, lsl(4)));
+ TEST_INSTRUCTION("00000000", udf(0));
+ TEST_INSTRUCTION("01800000", udf(0x8001));
+ TEST_INSTRUCTION("4108C31A", udiv(w1, w2, w3));
+ TEST_INSTRUCTION("4108C39A", udiv(x1, x2, x3));
+ TEST_INSTRUCTION("41241B53", ubfiz(w1, w2, 5, 10));
+ TEST_INSTRUCTION("41247BD3", ubfiz(x1, x2, 5, 10));
+ TEST_INSTRUCTION("41280553", ubfm(w1, w2, 5, 10));
+ TEST_INSTRUCTION("412845D3", ubfm(x1, x2, 5, 10));
+ TEST_INSTRUCTION("41380553", ubfx(w1, w2, 5, 10));
+ TEST_INSTRUCTION("413845D3", ubfx(x1, x2, 5, 10));
+ TEST_INSTRUCTION("4110A39B", umaddl(x1, w2, w3, x4));
+ TEST_INSTRUCTION("41FCA39B", umnegl(x1, w2, w3));
+ TEST_INSTRUCTION("4190A39B", umsubl(x1, w2, w3, x4));
+ TEST_INSTRUCTION("417CC39B", umulh(x1, x2, x3));
+ TEST_INSTRUCTION("417CA39B", umull(x1, w2, w3));
+ TEST_INSTRUCTION("411C0053", uxtb(w1, w2));
+ TEST_INSTRUCTION("413C0053", uxth(w1, w2));
+ TEST_INSTRUCTION("3F4000D5", xaflag());
+ TEST_INSTRUCTION("E147C1DA", xpacd(x1));
+ TEST_INSTRUCTION("E143C1DA", xpaci(x1));
+ TEST_INSTRUCTION("FF2003D5", xpaclri());
+}
+
+static void ASMJIT_NOINLINE testA64AssemblerRel(AssemblerTester<a64::Assembler>& tester) noexcept {
+ using namespace a64;
+
+ // Must be a reference, because it's recreated after every `TEST_INSTRUCTION()`.
+ const Label& L0 = tester.L0;
+
+ TEST_INSTRUCTION("01000010", adr(x1, L0));
+ TEST_INSTRUCTION("00000014", b(L0));
+ TEST_INSTRUCTION("00000014", b_al(L0));
+ TEST_INSTRUCTION("00000054", b_eq(L0));
+ TEST_INSTRUCTION("01000054", b_ne(L0));
+ TEST_INSTRUCTION("02000054", b_hs(L0));
+ TEST_INSTRUCTION("03000054", b_lo(L0));
+ TEST_INSTRUCTION("04000054", b_mi(L0));
+ TEST_INSTRUCTION("05000054", b_pl(L0));
+ TEST_INSTRUCTION("06000054", b_vs(L0));
+ TEST_INSTRUCTION("07000054", b_vc(L0));
+ TEST_INSTRUCTION("08000054", b_hi(L0));
+ TEST_INSTRUCTION("09000054", b_ls(L0));
+ TEST_INSTRUCTION("0A000054", b_ge(L0));
+ TEST_INSTRUCTION("0B000054", b_lt(L0));
+ TEST_INSTRUCTION("0C000054", b_gt(L0));
+ TEST_INSTRUCTION("0D000054", b_le(L0));
+ TEST_INSTRUCTION("00000014", b(CondCode::kAL, L0));
+ TEST_INSTRUCTION("00000054", b(CondCode::kEQ, L0));
+ TEST_INSTRUCTION("01000054", b(CondCode::kNE, L0));
+ TEST_INSTRUCTION("02000054", b(CondCode::kHS, L0));
+ TEST_INSTRUCTION("03000054", b(CondCode::kLO, L0));
+ TEST_INSTRUCTION("04000054", b(CondCode::kMI, L0));
+ TEST_INSTRUCTION("05000054", b(CondCode::kPL, L0));
+ TEST_INSTRUCTION("06000054", b(CondCode::kVS, L0));
+ TEST_INSTRUCTION("07000054", b(CondCode::kVC, L0));
+ TEST_INSTRUCTION("08000054", b(CondCode::kHI, L0));
+ TEST_INSTRUCTION("09000054", b(CondCode::kLS, L0));
+ TEST_INSTRUCTION("0A000054", b(CondCode::kGE, L0));
+ TEST_INSTRUCTION("0B000054", b(CondCode::kLT, L0));
+ TEST_INSTRUCTION("0C000054", b(CondCode::kGT, L0));
+ TEST_INSTRUCTION("0D000054", b(CondCode::kLE, L0));
+
+ TEST_INSTRUCTION("00000094", bl(L0));
+ TEST_INSTRUCTION("01000034", cbz(w1, L0));
+ TEST_INSTRUCTION("010000B4", cbz(x1, L0));
+ TEST_INSTRUCTION("01000035", cbnz(w1, L0));
+ TEST_INSTRUCTION("010000B5", cbnz(x1, L0));
+ TEST_INSTRUCTION("01001837", tbnz(w1, 3, L0));
+ TEST_INSTRUCTION("010008B7", tbnz(x1, 33, L0));
+ TEST_INSTRUCTION("01001836", tbz(w1, 3, L0));
+ TEST_INSTRUCTION("010008B6", tbz(x1, 33, L0));
+}
+
+static void ASMJIT_NOINLINE testA64AssemblerSIMD(AssemblerTester<a64::Assembler>& tester) noexcept {
+ using namespace a64;
+
+ TEST_INSTRUCTION("41B8200E", abs(v1.b8(), v2.b8()));
+ TEST_INSTRUCTION("41B8600E", abs(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("41B8A00E", abs(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41B8E05E", abs(d1, d2));
+ TEST_INSTRUCTION("41B8204E", abs(v1.b16(), v2.b16()));
+ TEST_INSTRUCTION("41B8604E", abs(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("41B8A04E", abs(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("41B8E04E", abs(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("4184230E", add(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4184630E", add(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4184A30E", add(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4184E35E", add(d1, d2, d3));
+ TEST_INSTRUCTION("4184234E", add(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4184634E", add(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4184A34E", add(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4184E34E", add(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4140230E", addhn(v1.b8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4140630E", addhn(v1.h4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4140A30E", addhn(v1.s2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4140234E", addhn2(v1.b16(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4140634E", addhn2(v1.h8(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4140A34E", addhn2(v1.s4(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("41BC230E", addp(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("41BC630E", addp(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41BCA30E", addp(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("41B8F15E", addp(d1, v2.d2()));
+ TEST_INSTRUCTION("41BC234E", addp(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("41BC634E", addp(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41BCA34E", addp(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41BCE34E", addp(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("41B8310E", addv(b1, v2.b8()));
+ TEST_INSTRUCTION("41B8314E", addv(b1, v2.b16()));
+ TEST_INSTRUCTION("41B8710E", addv(h1, v2.h4()));
+ TEST_INSTRUCTION("41B8714E", addv(h1, v2.h8()));
+ TEST_INSTRUCTION("41B8B14E", addv(s1, v2.s4()));
+ TEST_INSTRUCTION("4158284E", aesd(v1.b16(), v2.b16()));
+ TEST_INSTRUCTION("4148284E", aese(v1.b16(), v2.b16()));
+ TEST_INSTRUCTION("4178284E", aesimc(v1.b16(), v2.b16()));
+ TEST_INSTRUCTION("4168284E", aesmc(v1.b16(), v2.b16()));
+ TEST_INSTRUCTION("411C230E", and_(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("411C234E", and_(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("411023CE", bcax(v1.b16(), v2.b16(), v3.b16(), v4.b16()));
+ TEST_INSTRUCTION("4140631E", bfcvt(h1, s2));
+ TEST_INSTRUCTION("4168A10E", bfcvtn(v1.h4(), v2.s4()));
+ TEST_INSTRUCTION("4168A14E", bfcvtn2(v1.h8(), v2.s4()));
+ TEST_INSTRUCTION("41FC432E", bfdot(v1.s2(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41FC436E", bfdot(v1.s4(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41F0430F", bfdot(v1.s2(), v2.h4(), v3.h2(0)));
+ TEST_INSTRUCTION("41F8634F", bfdot(v1.s4(), v2.h8(), v3.h2(3)));
+ TEST_INSTRUCTION("41FCC32E", bfmlalb(v1.s4(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41F0C30F", bfmlalb(v1.s4(), v2.h8(), v3.h(0)));
+ TEST_INSTRUCTION("41F8F30F", bfmlalb(v1.s4(), v2.h8(), v3.h(7)));
+ TEST_INSTRUCTION("41FCC36E", bfmlalt(v1.s4(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41F0C34F", bfmlalt(v1.s4(), v2.h8(), v3.h(0)));
+ TEST_INSTRUCTION("41F8F34F", bfmlalt(v1.s4(), v2.h8(), v3.h(7)));
+ TEST_INSTRUCTION("41EC436E", bfmmla(v1.s4(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("411C630E", bic(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("411C634E", bic(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("E197072F", bic(v1.h4(), 255));
+ TEST_INSTRUCTION("E1B7072F", bic(v1.h4(), 255, lsl(8)));
+ TEST_INSTRUCTION("E197076F", bic(v1.h8(), 255));
+ TEST_INSTRUCTION("E1B7076F", bic(v1.h8(), 255, lsl(8)));
+ TEST_INSTRUCTION("E117072F", bic(v1.s2(), 255));
+ TEST_INSTRUCTION("E137072F", bic(v1.s2(), 255, lsl(8)));
+ TEST_INSTRUCTION("E117076F", bic(v1.s4(), 255));
+ TEST_INSTRUCTION("E177076F", bic(v1.s4(), 255, lsl(24)));
+ TEST_INSTRUCTION("411CE32E", bif(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("411CE36E", bif(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("411CA32E", bit(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("411CA36E", bit(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("411C632E", bsl(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("411C636E", bsl(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4148200E", cls(v1.b8(), v2.b8()));
+ TEST_INSTRUCTION("4148600E", cls(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("4148A00E", cls(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("4148204E", cls(v1.b16(), v2.b16()));
+ TEST_INSTRUCTION("4148604E", cls(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("4148A04E", cls(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("4148202E", clz(v1.b8(), v2.b8()));
+ TEST_INSTRUCTION("4148602E", clz(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("4148A02E", clz(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("4148206E", clz(v1.b16(), v2.b16()));
+ TEST_INSTRUCTION("4148606E", clz(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("4148A06E", clz(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("418C232E", cmeq(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("418C632E", cmeq(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("418CA32E", cmeq(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("418CE37E", cmeq(d1, d2, d3));
+ TEST_INSTRUCTION("418C236E", cmeq(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("418C636E", cmeq(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("418CA36E", cmeq(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("418CE36E", cmeq(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4198200E", cmeq(v1.b8(), v2.b8(), 0));
+ TEST_INSTRUCTION("4198600E", cmeq(v1.h4(), v2.h4(), 0));
+ TEST_INSTRUCTION("4198A00E", cmeq(v1.s2(), v2.s2(), 0));
+ TEST_INSTRUCTION("4198E05E", cmeq(d1, d2, 0));
+ TEST_INSTRUCTION("4198204E", cmeq(v1.b16(), v2.b16(), 0));
+ TEST_INSTRUCTION("4198604E", cmeq(v1.h8(), v2.h8(), 0));
+ TEST_INSTRUCTION("4198A04E", cmeq(v1.s4(), v2.s4(), 0));
+ TEST_INSTRUCTION("4198E04E", cmeq(v1.d2(), v2.d2(), 0));
+ TEST_INSTRUCTION("413C230E", cmge(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("413C630E", cmge(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("413CA30E", cmge(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("413CE35E", cmge(d1, d2, d3));
+ TEST_INSTRUCTION("413C234E", cmge(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("413C634E", cmge(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("413CA34E", cmge(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("413CE34E", cmge(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4188202E", cmge(v1.b8(), v2.b8(), 0));
+ TEST_INSTRUCTION("4188602E", cmge(v1.h4(), v2.h4(), 0));
+ TEST_INSTRUCTION("4188A02E", cmge(v1.s2(), v2.s2(), 0));
+ TEST_INSTRUCTION("4188E07E", cmge(d1, d2, 0));
+ TEST_INSTRUCTION("4188206E", cmge(v1.b16(), v2.b16(), 0));
+ TEST_INSTRUCTION("4188606E", cmge(v1.h8(), v2.h8(), 0));
+ TEST_INSTRUCTION("4188A06E", cmge(v1.s4(), v2.s4(), 0));
+ TEST_INSTRUCTION("4188E06E", cmge(v1.d2(), v2.d2(), 0));
+ TEST_INSTRUCTION("4134230E", cmgt(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4134630E", cmgt(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4134A30E", cmgt(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4134E35E", cmgt(d1, d2, d3));
+ TEST_INSTRUCTION("4134234E", cmgt(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4134634E", cmgt(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4134A34E", cmgt(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4134E34E", cmgt(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4188200E", cmgt(v1.b8(), v2.b8(), 0));
+ TEST_INSTRUCTION("4188600E", cmgt(v1.h4(), v2.h4(), 0));
+ TEST_INSTRUCTION("4188A00E", cmgt(v1.s2(), v2.s2(), 0));
+ TEST_INSTRUCTION("4188E05E", cmgt(d1, d2, 0));
+ TEST_INSTRUCTION("4188204E", cmgt(v1.b16(), v2.b16(), 0));
+ TEST_INSTRUCTION("4188604E", cmgt(v1.h8(), v2.h8(), 0));
+ TEST_INSTRUCTION("4188A04E", cmgt(v1.s4(), v2.s4(), 0));
+ TEST_INSTRUCTION("4188E04E", cmgt(v1.d2(), v2.d2(), 0));
+ TEST_INSTRUCTION("4134232E", cmhi(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4134632E", cmhi(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4134A32E", cmhi(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4134E37E", cmhi(d1, d2, d3));
+ TEST_INSTRUCTION("4134236E", cmhi(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4134636E", cmhi(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4134A36E", cmhi(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4134E36E", cmhi(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("413C232E", cmhs(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("413C632E", cmhs(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("413CA32E", cmhs(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("413CE37E", cmhs(d1, d2, d3));
+ TEST_INSTRUCTION("413C236E", cmhs(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("413C636E", cmhs(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("413CA36E", cmhs(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("413CE36E", cmhs(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4198202E", cmle(v1.b8(), v2.b8(), 0));
+ TEST_INSTRUCTION("4198602E", cmle(v1.h4(), v2.h4(), 0));
+ TEST_INSTRUCTION("4198A02E", cmle(v1.s2(), v2.s2(), 0));
+ TEST_INSTRUCTION("4198E07E", cmle(d1, d2, 0));
+ TEST_INSTRUCTION("4198206E", cmle(v1.b16(), v2.b16(), 0));
+ TEST_INSTRUCTION("4198606E", cmle(v1.h8(), v2.h8(), 0));
+ TEST_INSTRUCTION("4198A06E", cmle(v1.s4(), v2.s4(), 0));
+ TEST_INSTRUCTION("4198E06E", cmle(v1.d2(), v2.d2(), 0));
+ TEST_INSTRUCTION("41A8200E", cmlt(v1.b8(), v2.b8(), 0));
+ TEST_INSTRUCTION("41A8600E", cmlt(v1.h4(), v2.h4(), 0));
+ TEST_INSTRUCTION("41A8A00E", cmlt(v1.s2(), v2.s2(), 0));
+ TEST_INSTRUCTION("41A8E05E", cmlt(d1, d2, 0));
+ TEST_INSTRUCTION("41A8204E", cmlt(v1.b16(), v2.b16(), 0));
+ TEST_INSTRUCTION("41A8604E", cmlt(v1.h8(), v2.h8(), 0));
+ TEST_INSTRUCTION("41A8A04E", cmlt(v1.s4(), v2.s4(), 0));
+ TEST_INSTRUCTION("41A8E04E", cmlt(v1.d2(), v2.d2(), 0));
+ TEST_INSTRUCTION("418C230E", cmtst(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("418C630E", cmtst(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("418CA30E", cmtst(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("418CE35E", cmtst(d1, d2, d3));
+ TEST_INSTRUCTION("418C234E", cmtst(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("418C634E", cmtst(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("418CA34E", cmtst(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("418CE34E", cmtst(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4158200E", cnt(v1.b8(), v2.b8()));
+ TEST_INSTRUCTION("4158204E", cnt(v1.b16(), v2.b16()));
+ TEST_INSTRUCTION("410C010E", dup(v1.b8(), w2));
+ TEST_INSTRUCTION("410C020E", dup(v1.h4(), w2));
+ TEST_INSTRUCTION("410C040E", dup(v1.s2(), w2));
+ TEST_INSTRUCTION("410C014E", dup(v1.b16(), w2));
+ TEST_INSTRUCTION("410C024E", dup(v1.h8(), w2));
+ TEST_INSTRUCTION("410C044E", dup(v1.s4(), w2));
+ TEST_INSTRUCTION("410C084E", dup(v1.d2(), x2));
+ TEST_INSTRUCTION("4F04035E", dup(b15, v2.b(1)));
+ TEST_INSTRUCTION("4F04065E", dup(h15, v2.h(1)));
+ TEST_INSTRUCTION("4F040C5E", dup(s15, v2.s(1)));
+ TEST_INSTRUCTION("4F04185E", dup(d15, v2.d(1)));
+ TEST_INSTRUCTION("4F04030E", dup(v15.b8(), v2.b(1)));
+ TEST_INSTRUCTION("4F04060E", dup(v15.h4(), v2.h(1)));
+ TEST_INSTRUCTION("4F040C0E", dup(v15.s2(), v2.s(1)));
+ TEST_INSTRUCTION("4F04034E", dup(v15.b16(), v2.b(1)));
+ TEST_INSTRUCTION("4F04064E", dup(v15.h8(), v2.h(1)));
+ TEST_INSTRUCTION("4F040C4E", dup(v15.s4(), v2.s(1)));
+ TEST_INSTRUCTION("4F04184E", dup(v15.d2(), v2.d(1)));
+ TEST_INSTRUCTION("411C232E", eor(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("411C236E", eor(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("411003CE", eor3(v1.b16(), v2.b16(), v3.b16(), v4.b16()));
+ TEST_INSTRUCTION("4128032E", ext(v1.b8(), v2.b8(), v3.b8(), 5));
+ TEST_INSTRUCTION("4128036E", ext(v1.b16(), v2.b16(), v3.b16(), 5));
+ TEST_INSTRUCTION("4114C37E", fabd(h1, h2, h3));
+ TEST_INSTRUCTION("41D4A37E", fabd(s1, s2, s3));
+ TEST_INSTRUCTION("41D4E37E", fabd(d1, d2, d3));
+ TEST_INSTRUCTION("4114C32E", fabd(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41D4A32E", fabd(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4114C36E", fabd(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41D4A36E", fabd(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41D4E36E", fabd(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("41C0E01E", fabs(h1, h2));
+ TEST_INSTRUCTION("41C0201E", fabs(s1, s2));
+ TEST_INSTRUCTION("41C0601E", fabs(d1, d2));
+ TEST_INSTRUCTION("41F8F80E", fabs(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("41F8A00E", fabs(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41F8F84E", fabs(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("41F8A04E", fabs(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("41F8E04E", fabs(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("412C437E", facge(h1, h2, h3));
+ TEST_INSTRUCTION("41EC237E", facge(s1, s2, s3));
+ TEST_INSTRUCTION("41EC637E", facge(d1, d2, d3));
+ TEST_INSTRUCTION("412C432E", facge(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41EC232E", facge(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("412C436E", facge(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41EC236E", facge(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41EC636E", facge(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("412CC37E", facgt(h1, h2, h3));
+ TEST_INSTRUCTION("41ECA37E", facgt(s1, s2, s3));
+ TEST_INSTRUCTION("41ECE37E", facgt(d1, d2, d3));
+ TEST_INSTRUCTION("412CC32E", facgt(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41ECA32E", facgt(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("412CC36E", facgt(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41ECA36E", facgt(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41ECE36E", facgt(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4128E31E", fadd(h1, h2, h3));
+ TEST_INSTRUCTION("4128231E", fadd(s1, s2, s3));
+ TEST_INSTRUCTION("4128631E", fadd(d1, d2, d3));
+ TEST_INSTRUCTION("4114430E", fadd(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41D4230E", fadd(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4114434E", fadd(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41D4234E", fadd(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41D4634E", fadd(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("41D8305E", faddp(h1, v2.h2()));
+ TEST_INSTRUCTION("41D8307E", faddp(s1, v2.s2()));
+ TEST_INSTRUCTION("41D8707E", faddp(d1, v2.d2()));
+ TEST_INSTRUCTION("4114432E", faddp(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41D4232E", faddp(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4114436E", faddp(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41D4236E", faddp(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41D4636E", faddp(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("41E4432E", fcadd(v1.h4(), v2.h4(), v3.h4(), 90));
+ TEST_INSTRUCTION("41E4832E", fcadd(v1.s2(), v2.s2(), v3.s2(), 90));
+ TEST_INSTRUCTION("41E4436E", fcadd(v1.h8(), v2.h8(), v3.h8(), 90));
+ TEST_INSTRUCTION("41E4836E", fcadd(v1.s4(), v2.s4(), v3.s4(), 90));
+ TEST_INSTRUCTION("41E4C36E", fcadd(v1.d2(), v2.d2(), v3.d2(), 90));
+ TEST_INSTRUCTION("41F4432E", fcadd(v1.h4(), v2.h4(), v3.h4(), 270));
+ TEST_INSTRUCTION("41F4832E", fcadd(v1.s2(), v2.s2(), v3.s2(), 270));
+ TEST_INSTRUCTION("41F4436E", fcadd(v1.h8(), v2.h8(), v3.h8(), 270));
+ TEST_INSTRUCTION("41F4836E", fcadd(v1.s4(), v2.s4(), v3.s4(), 270));
+ TEST_INSTRUCTION("41F4C36E", fcadd(v1.d2(), v2.d2(), v3.d2(), 270));
+ TEST_INSTRUCTION("2404E21E", fccmp(h1, h2, 4, CondCode::kEQ));
+ TEST_INSTRUCTION("2404221E", fccmp(s1, s2, 4, CondCode::kEQ));
+ TEST_INSTRUCTION("2404621E", fccmp(d1, d2, 4, CondCode::kEQ));
+ TEST_INSTRUCTION("3404E21E", fccmpe(h1, h2, 4, CondCode::kEQ));
+ TEST_INSTRUCTION("3404221E", fccmpe(s1, s2, 4, CondCode::kEQ));
+ TEST_INSTRUCTION("3404621E", fccmpe(d1, d2, 4, CondCode::kEQ));
+ TEST_INSTRUCTION("4124435E", fcmeq(h1, h2, h3));
+ TEST_INSTRUCTION("41E4235E", fcmeq(s1, s2, s3));
+ TEST_INSTRUCTION("41E4635E", fcmeq(d1, d2, d3));
+ TEST_INSTRUCTION("4124430E", fcmeq(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41E4230E", fcmeq(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4124434E", fcmeq(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41E4234E", fcmeq(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41E4634E", fcmeq(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("41D8F85E", fcmeq(h1, h2, 0));
+ TEST_INSTRUCTION("41D8A05E", fcmeq(s1, s2, 0));
+ TEST_INSTRUCTION("41D8E05E", fcmeq(d1, d2, 0));
+ TEST_INSTRUCTION("41D8F80E", fcmeq(v1.h4(), v2.h4(), 0));
+ TEST_INSTRUCTION("41D8A00E", fcmeq(v1.s2(), v2.s2(), 0));
+ TEST_INSTRUCTION("41D8F84E", fcmeq(v1.h8(), v2.h8(), 0));
+ TEST_INSTRUCTION("41D8A04E", fcmeq(v1.s4(), v2.s4(), 0));
+ TEST_INSTRUCTION("41D8E04E", fcmeq(v1.d2(), v2.d2(), 0));
+ TEST_INSTRUCTION("4124437E", fcmge(h1, h2, h3));
+ TEST_INSTRUCTION("41E4237E", fcmge(s1, s2, s3));
+ TEST_INSTRUCTION("41E4637E", fcmge(d1, d2, d3));
+ TEST_INSTRUCTION("4124432E", fcmge(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41E4232E", fcmge(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4124436E", fcmge(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41E4236E", fcmge(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41E4636E", fcmge(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("41C8F87E", fcmge(h1, h2, 0));
+ TEST_INSTRUCTION("41C8A07E", fcmge(s1, s2, 0));
+ TEST_INSTRUCTION("41C8E07E", fcmge(d1, d2, 0));
+ TEST_INSTRUCTION("41C8F82E", fcmge(v1.h4(), v2.h4(), 0));
+ TEST_INSTRUCTION("41C8A02E", fcmge(v1.s2(), v2.s2(), 0));
+ TEST_INSTRUCTION("41C8F86E", fcmge(v1.h8(), v2.h8(), 0));
+ TEST_INSTRUCTION("41C8A06E", fcmge(v1.s4(), v2.s4(), 0));
+ TEST_INSTRUCTION("41C8E06E", fcmge(v1.d2(), v2.d2(), 0));
+ TEST_INSTRUCTION("4124C37E", fcmgt(h1, h2, h3));
+ TEST_INSTRUCTION("41E4A37E", fcmgt(s1, s2, s3));
+ TEST_INSTRUCTION("41E4E37E", fcmgt(d1, d2, d3));
+ TEST_INSTRUCTION("4124C32E", fcmgt(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41E4A32E", fcmgt(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4124C36E", fcmgt(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41E4A36E", fcmgt(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41E4E36E", fcmgt(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("41C8F85E", fcmgt(h1, h2, 0));
+ TEST_INSTRUCTION("41C8A05E", fcmgt(s1, s2, 0));
+ TEST_INSTRUCTION("41C8E05E", fcmgt(d1, d2, 0));
+ TEST_INSTRUCTION("41C8F80E", fcmgt(v1.h4(), v2.h4(), 0));
+ TEST_INSTRUCTION("41C8A00E", fcmgt(v1.s2(), v2.s2(), 0));
+ TEST_INSTRUCTION("41C8F84E", fcmgt(v1.h8(), v2.h8(), 0));
+ TEST_INSTRUCTION("41C8A04E", fcmgt(v1.s4(), v2.s4(), 0));
+ TEST_INSTRUCTION("41C8E04E", fcmgt(v1.d2(), v2.d2(), 0));
+ TEST_INSTRUCTION("41CC432E", fcmla(v1.h4(), v2.h4(), v3.h4(), 90));
+ TEST_INSTRUCTION("41CC832E", fcmla(v1.s2(), v2.s2(), v3.s2(), 90));
+ TEST_INSTRUCTION("41CC436E", fcmla(v1.h8(), v2.h8(), v3.h8(), 90));
+ TEST_INSTRUCTION("41CC836E", fcmla(v1.s4(), v2.s4(), v3.s4(), 90));
+ TEST_INSTRUCTION("41CCC36E", fcmla(v1.d2(), v2.d2(), v3.d2(), 90));
+ TEST_INSTRUCTION("41DC432E", fcmla(v1.h4(), v2.h4(), v3.h4(), 270));
+ TEST_INSTRUCTION("41DC832E", fcmla(v1.s2(), v2.s2(), v3.s2(), 270));
+ TEST_INSTRUCTION("41DC436E", fcmla(v1.h8(), v2.h8(), v3.h8(), 270));
+ TEST_INSTRUCTION("41DC836E", fcmla(v1.s4(), v2.s4(), v3.s4(), 270));
+ TEST_INSTRUCTION("41DCC36E", fcmla(v1.d2(), v2.d2(), v3.d2(), 270));
+ TEST_INSTRUCTION("4130432F", fcmla(v1.h4(), v2.h4(), v3.h(0), 90));
+ TEST_INSTRUCTION("4130632F", fcmla(v1.h4(), v2.h4(), v3.h(1), 90));
+ TEST_INSTRUCTION("4130436F", fcmla(v1.h8(), v2.h8(), v3.h(0), 90));
+ TEST_INSTRUCTION("4138636F", fcmla(v1.h8(), v2.h8(), v3.h(3), 90));
+ TEST_INSTRUCTION("4130836F", fcmla(v1.s4(), v2.s4(), v3.s(0), 90));
+ TEST_INSTRUCTION("4138836F", fcmla(v1.s4(), v2.s4(), v3.s(1), 90));
+ TEST_INSTRUCTION("4170432F", fcmla(v1.h4(), v2.h4(), v3.h(0), 270));
+ TEST_INSTRUCTION("4170632F", fcmla(v1.h4(), v2.h4(), v3.h(1), 270));
+ TEST_INSTRUCTION("4170436F", fcmla(v1.h8(), v2.h8(), v3.h(0), 270));
+ TEST_INSTRUCTION("4178636F", fcmla(v1.h8(), v2.h8(), v3.h(3), 270));
+ TEST_INSTRUCTION("4170836F", fcmla(v1.s4(), v2.s4(), v3.s(0), 270));
+ TEST_INSTRUCTION("4178836F", fcmla(v1.s4(), v2.s4(), v3.s(1), 270));
+ TEST_INSTRUCTION("41D8F87E", fcmle(h1, h2, 0));
+ TEST_INSTRUCTION("41D8A07E", fcmle(s1, s2, 0));
+ TEST_INSTRUCTION("41D8E07E", fcmle(d1, d2, 0));
+ TEST_INSTRUCTION("41D8F82E", fcmle(v1.h4(), v2.h4(), 0));
+ TEST_INSTRUCTION("41D8A02E", fcmle(v1.s2(), v2.s2(), 0));
+ TEST_INSTRUCTION("41D8F86E", fcmle(v1.h8(), v2.h8(), 0));
+ TEST_INSTRUCTION("41D8A06E", fcmle(v1.s4(), v2.s4(), 0));
+ TEST_INSTRUCTION("41D8E06E", fcmle(v1.d2(), v2.d2(), 0));
+ TEST_INSTRUCTION("41E8F85E", fcmlt(h1, h2, 0));
+ TEST_INSTRUCTION("41E8A05E", fcmlt(s1, s2, 0));
+ TEST_INSTRUCTION("41E8E05E", fcmlt(d1, d2, 0));
+ TEST_INSTRUCTION("41E8F80E", fcmlt(v1.h4(), v2.h4(), 0));
+ TEST_INSTRUCTION("41E8A00E", fcmlt(v1.s2(), v2.s2(), 0));
+ TEST_INSTRUCTION("41E8F84E", fcmlt(v1.h8(), v2.h8(), 0));
+ TEST_INSTRUCTION("41E8A04E", fcmlt(v1.s4(), v2.s4(), 0));
+ TEST_INSTRUCTION("41E8E04E", fcmlt(v1.d2(), v2.d2(), 0));
+ TEST_INSTRUCTION("2020E21E", fcmp(h1, h2));
+ TEST_INSTRUCTION("2020221E", fcmp(s1, s2));
+ TEST_INSTRUCTION("2020621E", fcmp(d1, d2));
+ TEST_INSTRUCTION("2820E01E", fcmp(h1, 0));
+ TEST_INSTRUCTION("2820201E", fcmp(s1, 0));
+ TEST_INSTRUCTION("2820601E", fcmp(d1, 0));
+ TEST_INSTRUCTION("3020E21E", fcmpe(h1, h2));
+ TEST_INSTRUCTION("3020221E", fcmpe(s1, s2));
+ TEST_INSTRUCTION("3020621E", fcmpe(d1, d2));
+ TEST_INSTRUCTION("3820E01E", fcmpe(h1, 0));
+ TEST_INSTRUCTION("3820201E", fcmpe(s1, 0));
+ TEST_INSTRUCTION("3820601E", fcmpe(d1, 0));
+ TEST_INSTRUCTION("410CE31E", fcsel(h1, h2, h3, CondCode::kEQ));
+ TEST_INSTRUCTION("410C231E", fcsel(s1, s2, s3, CondCode::kEQ));
+ TEST_INSTRUCTION("410C631E", fcsel(d1, d2, d3, CondCode::kEQ));
+ TEST_INSTRUCTION("41C0231E", fcvt(h1, s2));
+ TEST_INSTRUCTION("41C0631E", fcvt(h1, d2));
+ TEST_INSTRUCTION("4140E21E", fcvt(s1, h2));
+ TEST_INSTRUCTION("4140621E", fcvt(s1, d2));
+ TEST_INSTRUCTION("41C0E21E", fcvt(d1, h2));
+ TEST_INSTRUCTION("41C0221E", fcvt(d1, s2));
+ TEST_INSTRUCTION("4100E41E", fcvtas(w1, h2));
+ TEST_INSTRUCTION("4100241E", fcvtas(w1, s2));
+ TEST_INSTRUCTION("4100641E", fcvtas(w1, d2));
+ TEST_INSTRUCTION("4100E49E", fcvtas(x1, h2));
+ TEST_INSTRUCTION("4100249E", fcvtas(x1, s2));
+ TEST_INSTRUCTION("4100649E", fcvtas(x1, d2));
+ TEST_INSTRUCTION("41C8795E", fcvtas(h1, h2));
+ TEST_INSTRUCTION("41C8215E", fcvtas(s1, s2));
+ TEST_INSTRUCTION("41C8615E", fcvtas(d1, d2));
+ TEST_INSTRUCTION("41C8790E", fcvtas(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("41C8210E", fcvtas(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41C8794E", fcvtas(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("41C8214E", fcvtas(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("41C8614E", fcvtas(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("4100E51E", fcvtau(w1, h2));
+ TEST_INSTRUCTION("4100251E", fcvtau(w1, s2));
+ TEST_INSTRUCTION("4100651E", fcvtau(w1, d2));
+ TEST_INSTRUCTION("4100E59E", fcvtau(x1, h2));
+ TEST_INSTRUCTION("4100259E", fcvtau(x1, s2));
+ TEST_INSTRUCTION("4100659E", fcvtau(x1, d2));
+ TEST_INSTRUCTION("41C8797E", fcvtau(h1, h2));
+ TEST_INSTRUCTION("41C8217E", fcvtau(s1, s2));
+ TEST_INSTRUCTION("41C8617E", fcvtau(d1, d2));
+ TEST_INSTRUCTION("41C8792E", fcvtau(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("41C8212E", fcvtau(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41C8796E", fcvtau(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("41C8216E", fcvtau(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("41C8616E", fcvtau(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("4178210E", fcvtl(v1.s4(), v2.h4()));
+ TEST_INSTRUCTION("4178214E", fcvtl2(v1.s4(), v2.h8()));
+ TEST_INSTRUCTION("4178610E", fcvtl(v1.d2(), v2.s2()));
+ TEST_INSTRUCTION("4178614E", fcvtl2(v1.d2(), v2.s4()));
+ TEST_INSTRUCTION("4100F01E", fcvtms(w1, h2));
+ TEST_INSTRUCTION("4100301E", fcvtms(w1, s2));
+ TEST_INSTRUCTION("4100701E", fcvtms(w1, d2));
+ TEST_INSTRUCTION("4100F09E", fcvtms(x1, h2));
+ TEST_INSTRUCTION("4100309E", fcvtms(x1, s2));
+ TEST_INSTRUCTION("4100709E", fcvtms(x1, d2));
+ TEST_INSTRUCTION("41B8795E", fcvtms(h1, h2));
+ TEST_INSTRUCTION("41B8215E", fcvtms(s1, s2));
+ TEST_INSTRUCTION("41B8615E", fcvtms(d1, d2));
+ TEST_INSTRUCTION("41B8790E", fcvtms(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("41B8210E", fcvtms(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41B8794E", fcvtms(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("41B8214E", fcvtms(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("41B8614E", fcvtms(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("4100F11E", fcvtmu(w1, h2));
+ TEST_INSTRUCTION("4100311E", fcvtmu(w1, s2));
+ TEST_INSTRUCTION("4100711E", fcvtmu(w1, d2));
+ TEST_INSTRUCTION("4100F19E", fcvtmu(x1, h2));
+ TEST_INSTRUCTION("4100319E", fcvtmu(x1, s2));
+ TEST_INSTRUCTION("4100719E", fcvtmu(x1, d2));
+ TEST_INSTRUCTION("41B8797E", fcvtmu(h1, h2));
+ TEST_INSTRUCTION("41B8217E", fcvtmu(s1, s2));
+ TEST_INSTRUCTION("41B8617E", fcvtmu(d1, d2));
+ TEST_INSTRUCTION("41B8792E", fcvtmu(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("41B8212E", fcvtmu(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41B8796E", fcvtmu(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("41B8216E", fcvtmu(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("41B8616E", fcvtmu(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("4168210E", fcvtn(v1.h4(), v2.s4()));
+ TEST_INSTRUCTION("4168214E", fcvtn2(v1.h8(), v2.s4()));
+ TEST_INSTRUCTION("4168610E", fcvtn(v1.s2(), v2.d2()));
+ TEST_INSTRUCTION("4168614E", fcvtn2(v1.s4(), v2.d2()));
+ TEST_INSTRUCTION("4100E01E", fcvtns(w1, h2));
+ TEST_INSTRUCTION("4100201E", fcvtns(w1, s2));
+ TEST_INSTRUCTION("4100601E", fcvtns(w1, d2));
+ TEST_INSTRUCTION("4100E09E", fcvtns(x1, h2));
+ TEST_INSTRUCTION("4100209E", fcvtns(x1, s2));
+ TEST_INSTRUCTION("4100609E", fcvtns(x1, d2));
+ TEST_INSTRUCTION("41A8795E", fcvtns(h1, h2));
+ TEST_INSTRUCTION("41A8215E", fcvtns(s1, s2));
+ TEST_INSTRUCTION("41A8615E", fcvtns(d1, d2));
+ TEST_INSTRUCTION("41A8790E", fcvtns(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("41A8210E", fcvtns(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41A8794E", fcvtns(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("41A8214E", fcvtns(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("41A8614E", fcvtns(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("4100E11E", fcvtnu(w1, h2));
+ TEST_INSTRUCTION("4100211E", fcvtnu(w1, s2));
+ TEST_INSTRUCTION("4100611E", fcvtnu(w1, d2));
+ TEST_INSTRUCTION("4100E19E", fcvtnu(x1, h2));
+ TEST_INSTRUCTION("4100219E", fcvtnu(x1, s2));
+ TEST_INSTRUCTION("4100619E", fcvtnu(x1, d2));
+ TEST_INSTRUCTION("41A8797E", fcvtnu(h1, h2));
+ TEST_INSTRUCTION("41A8217E", fcvtnu(s1, s2));
+ TEST_INSTRUCTION("41A8617E", fcvtnu(d1, d2));
+ TEST_INSTRUCTION("41A8792E", fcvtnu(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("41A8212E", fcvtnu(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41A8796E", fcvtnu(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("41A8216E", fcvtnu(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("41A8616E", fcvtnu(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("4100E81E", fcvtps(w1, h2));
+ TEST_INSTRUCTION("4100281E", fcvtps(w1, s2));
+ TEST_INSTRUCTION("4100681E", fcvtps(w1, d2));
+ TEST_INSTRUCTION("4100E89E", fcvtps(x1, h2));
+ TEST_INSTRUCTION("4100289E", fcvtps(x1, s2));
+ TEST_INSTRUCTION("4100689E", fcvtps(x1, d2));
+ TEST_INSTRUCTION("41A8F95E", fcvtps(h1, h2));
+ TEST_INSTRUCTION("41A8A15E", fcvtps(s1, s2));
+ TEST_INSTRUCTION("41A8E15E", fcvtps(d1, d2));
+ TEST_INSTRUCTION("41A8F90E", fcvtps(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("41A8A10E", fcvtps(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41A8F94E", fcvtps(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("41A8A14E", fcvtps(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("41A8E14E", fcvtps(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("4100E91E", fcvtpu(w1, h2));
+ TEST_INSTRUCTION("4100291E", fcvtpu(w1, s2));
+ TEST_INSTRUCTION("4100691E", fcvtpu(w1, d2));
+ TEST_INSTRUCTION("4100E99E", fcvtpu(x1, h2));
+ TEST_INSTRUCTION("4100299E", fcvtpu(x1, s2));
+ TEST_INSTRUCTION("4100699E", fcvtpu(x1, d2));
+ TEST_INSTRUCTION("41A8F97E", fcvtpu(h1, h2));
+ TEST_INSTRUCTION("41A8A17E", fcvtpu(s1, s2));
+ TEST_INSTRUCTION("41A8E17E", fcvtpu(d1, d2));
+ TEST_INSTRUCTION("41A8F92E", fcvtpu(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("41A8A12E", fcvtpu(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41A8F96E", fcvtpu(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("41A8A16E", fcvtpu(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("41A8E16E", fcvtpu(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("2168617E", fcvtxn(s1, d1));
+ TEST_INSTRUCTION("4168612E", fcvtxn(v1.s2(), v2.d2()));
+ TEST_INSTRUCTION("4168616E", fcvtxn2(v1.s4(), v2.d2()));
+ TEST_INSTRUCTION("4100F81E", fcvtzs(w1, h2));
+ TEST_INSTRUCTION("4100381E", fcvtzs(w1, s2));
+ TEST_INSTRUCTION("4100781E", fcvtzs(w1, d2));
+ TEST_INSTRUCTION("4100F89E", fcvtzs(x1, h2));
+ TEST_INSTRUCTION("4100389E", fcvtzs(x1, s2));
+ TEST_INSTRUCTION("4100789E", fcvtzs(x1, d2));
+ TEST_INSTRUCTION("41B8F95E", fcvtzs(h1, h2));
+ TEST_INSTRUCTION("41B8A15E", fcvtzs(s1, s2));
+ TEST_INSTRUCTION("41B8E15E", fcvtzs(d1, d2));
+ TEST_INSTRUCTION("41B8F90E", fcvtzs(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("41B8A10E", fcvtzs(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41B8F94E", fcvtzs(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("41B8A14E", fcvtzs(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("41B8E14E", fcvtzs(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("41E0D81E", fcvtzs(w1, h2, 8));
+ TEST_INSTRUCTION("41E0181E", fcvtzs(w1, s2, 8));
+ TEST_INSTRUCTION("41E0581E", fcvtzs(w1, d2, 8));
+ TEST_INSTRUCTION("41E0D89E", fcvtzs(x1, h2, 8));
+ TEST_INSTRUCTION("41E0189E", fcvtzs(x1, s2, 8));
+ TEST_INSTRUCTION("41E0589E", fcvtzs(x1, d2, 8));
+ TEST_INSTRUCTION("41FC185F", fcvtzs(h1, h2, 8));
+ TEST_INSTRUCTION("41FC385F", fcvtzs(s1, s2, 8));
+ TEST_INSTRUCTION("41FC785F", fcvtzs(d1, d2, 8));
+ TEST_INSTRUCTION("41FC180F", fcvtzs(v1.h4(), v2.h4(), 8));
+ TEST_INSTRUCTION("41FC380F", fcvtzs(v1.s2(), v2.s2(), 8));
+ TEST_INSTRUCTION("41FC184F", fcvtzs(v1.h8(), v2.h8(), 8));
+ TEST_INSTRUCTION("41FC384F", fcvtzs(v1.s4(), v2.s4(), 8));
+ TEST_INSTRUCTION("41FC784F", fcvtzs(v1.d2(), v2.d2(), 8));
+ TEST_INSTRUCTION("4100F91E", fcvtzu(w1, h2));
+ TEST_INSTRUCTION("4100391E", fcvtzu(w1, s2));
+ TEST_INSTRUCTION("4100791E", fcvtzu(w1, d2));
+ TEST_INSTRUCTION("4100F99E", fcvtzu(x1, h2));
+ TEST_INSTRUCTION("4100399E", fcvtzu(x1, s2));
+ TEST_INSTRUCTION("4100799E", fcvtzu(x1, d2));
+ TEST_INSTRUCTION("41B8F97E", fcvtzu(h1, h2));
+ TEST_INSTRUCTION("41B8A17E", fcvtzu(s1, s2));
+ TEST_INSTRUCTION("41B8E17E", fcvtzu(d1, d2));
+ TEST_INSTRUCTION("41B8F92E", fcvtzu(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("41B8A12E", fcvtzu(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41B8F96E", fcvtzu(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("41B8A16E", fcvtzu(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("41B8E16E", fcvtzu(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("41E0D91E", fcvtzu(w1, h2, 8));
+ TEST_INSTRUCTION("41E0191E", fcvtzu(w1, s2, 8));
+ TEST_INSTRUCTION("41E0591E", fcvtzu(w1, d2, 8));
+ TEST_INSTRUCTION("41E0D99E", fcvtzu(x1, h2, 8));
+ TEST_INSTRUCTION("41E0199E", fcvtzu(x1, s2, 8));
+ TEST_INSTRUCTION("41E0599E", fcvtzu(x1, d2, 8));
+ TEST_INSTRUCTION("41FC187F", fcvtzu(h1, h2, 8));
+ TEST_INSTRUCTION("41FC387F", fcvtzu(s1, s2, 8));
+ TEST_INSTRUCTION("41FC787F", fcvtzu(d1, d2, 8));
+ TEST_INSTRUCTION("41FC182F", fcvtzu(v1.h4(), v2.h4(), 8));
+ TEST_INSTRUCTION("41FC382F", fcvtzu(v1.s2(), v2.s2(), 8));
+ TEST_INSTRUCTION("41FC186F", fcvtzu(v1.h8(), v2.h8(), 8));
+ TEST_INSTRUCTION("41FC386F", fcvtzu(v1.s4(), v2.s4(), 8));
+ TEST_INSTRUCTION("41FC786F", fcvtzu(v1.d2(), v2.d2(), 8));
+ TEST_INSTRUCTION("4118E31E", fdiv(h1, h2, h3));
+ TEST_INSTRUCTION("4118231E", fdiv(s1, s2, s3));
+ TEST_INSTRUCTION("4118631E", fdiv(d1, d2, d3));
+ TEST_INSTRUCTION("413C432E", fdiv(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41FC232E", fdiv(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("413C436E", fdiv(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41FC236E", fdiv(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41FC636E", fdiv(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("41007E1E", fjcvtzs(w1, d2));
+ TEST_INSTRUCTION("4110C31F", fmadd(h1, h2, h3, h4));
+ TEST_INSTRUCTION("4110031F", fmadd(s1, s2, s3, s4));
+ TEST_INSTRUCTION("4110431F", fmadd(d1, d2, d3, d4));
+ TEST_INSTRUCTION("4148E31E", fmax(h1, h2, h3));
+ TEST_INSTRUCTION("4148231E", fmax(s1, s2, s3));
+ TEST_INSTRUCTION("4148631E", fmax(d1, d2, d3));
+ TEST_INSTRUCTION("4134430E", fmax(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41F4230E", fmax(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4134434E", fmax(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41F4234E", fmax(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41F4634E", fmax(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4168E31E", fmaxnm(h1, h2, h3));
+ TEST_INSTRUCTION("4168231E", fmaxnm(s1, s2, s3));
+ TEST_INSTRUCTION("4168631E", fmaxnm(d1, d2, d3));
+ TEST_INSTRUCTION("4104430E", fmaxnm(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41C4230E", fmaxnm(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4104434E", fmaxnm(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41C4234E", fmaxnm(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41C4634E", fmaxnm(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("41C8305E", fmaxnmp(h1, v2.h2()));
+ TEST_INSTRUCTION("41C8307E", fmaxnmp(s1, v2.s2()));
+ TEST_INSTRUCTION("41C8707E", fmaxnmp(d1, v2.d2()));
+ TEST_INSTRUCTION("4104432E", fmaxnmp(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41C4232E", fmaxnmp(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4104436E", fmaxnmp(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41C4236E", fmaxnmp(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41C4636E", fmaxnmp(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("41C8300E", fmaxnmv(h1, v2.h4()));
+ TEST_INSTRUCTION("41C8304E", fmaxnmv(h1, v2.h8()));
+ TEST_INSTRUCTION("41C8306E", fmaxnmv(s1, v2.s4()));
+ TEST_INSTRUCTION("41F8305E", fmaxp(h1, v2.h2()));
+ TEST_INSTRUCTION("41F8307E", fmaxp(s1, v2.s2()));
+ TEST_INSTRUCTION("41F8707E", fmaxp(d1, v2.d2()));
+ TEST_INSTRUCTION("4134432E", fmaxp(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41F4232E", fmaxp(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4134436E", fmaxp(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41F4236E", fmaxp(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41F4636E", fmaxp(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("41F8300E", fmaxv(h1, v2.h4()));
+ TEST_INSTRUCTION("41F8304E", fmaxv(h1, v2.h8()));
+ TEST_INSTRUCTION("41F8306E", fmaxv(s1, v2.s4()));
+ TEST_INSTRUCTION("4158E31E", fmin(h1, h2, h3));
+ TEST_INSTRUCTION("4158231E", fmin(s1, s2, s3));
+ TEST_INSTRUCTION("4158631E", fmin(d1, d2, d3));
+ TEST_INSTRUCTION("4134C30E", fmin(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41F4A30E", fmin(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4134C34E", fmin(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41F4A34E", fmin(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41F4E34E", fmin(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4178E31E", fminnm(h1, h2, h3));
+ TEST_INSTRUCTION("4178231E", fminnm(s1, s2, s3));
+ TEST_INSTRUCTION("4178631E", fminnm(d1, d2, d3));
+ TEST_INSTRUCTION("4104C30E", fminnm(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41C4A30E", fminnm(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4104C34E", fminnm(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41C4A34E", fminnm(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41C4E34E", fminnm(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("41C8B05E", fminnmp(h1, v2.h2()));
+ TEST_INSTRUCTION("41C8B07E", fminnmp(s1, v2.s2()));
+ TEST_INSTRUCTION("41C8F07E", fminnmp(d1, v2.d2()));
+ TEST_INSTRUCTION("4104C32E", fminnmp(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41C4A32E", fminnmp(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4104C36E", fminnmp(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41C4A36E", fminnmp(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41C4E36E", fminnmp(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("41C8B00E", fminnmv(h1, v2.h4()));
+ TEST_INSTRUCTION("41C8B04E", fminnmv(h1, v2.h8()));
+ TEST_INSTRUCTION("41C8B06E", fminnmv(s1, v2.s4()));
+ TEST_INSTRUCTION("41F8B05E", fminp(h1, v2.h2()));
+ TEST_INSTRUCTION("41F8B07E", fminp(s1, v2.s2()));
+ TEST_INSTRUCTION("41F8F07E", fminp(d1, v2.d2()));
+ TEST_INSTRUCTION("4134C32E", fminp(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41F4A32E", fminp(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4134C36E", fminp(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41F4A36E", fminp(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41F4E36E", fminp(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("41F8B00E", fminv(h1, v2.h4()));
+ TEST_INSTRUCTION("41F8B04E", fminv(h1, v2.h8()));
+ TEST_INSTRUCTION("41F8B06E", fminv(s1, v2.s4()));
+ TEST_INSTRUCTION("410C430E", fmla(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41CC230E", fmla(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("410C434E", fmla(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41CC234E", fmla(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41CC634E", fmla(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4118335F", fmla(h1, h2, v3.h(7)));
+ TEST_INSTRUCTION("4118A35F", fmla(s1, s2, v3.s(3)));
+ TEST_INSTRUCTION("4118C35F", fmla(d1, d2, v3.d(1)));
+ TEST_INSTRUCTION("4118330F", fmla(v1.h4(), v2.h4(), v3.h(7)));
+ TEST_INSTRUCTION("4118A30F", fmla(v1.s2(), v2.s2(), v3.s(3)));
+ TEST_INSTRUCTION("4118334F", fmla(v1.h8(), v2.h8(), v3.h(7)));
+ TEST_INSTRUCTION("4118A34F", fmla(v1.s4(), v2.s4(), v3.s(3)));
+ TEST_INSTRUCTION("4118C34F", fmla(v1.d2(), v2.d2(), v3.d(1)));
+ TEST_INSTRUCTION("41EC230E", fmlal(v1.s2(), v2.h2(), v3.h2()));
+ TEST_INSTRUCTION("41EC234E", fmlal(v1.s4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4100830F", fmlal(v1.s2(), v2.h2(), v3.h(0)));
+ TEST_INSTRUCTION("4108B30F", fmlal(v1.s2(), v2.h2(), v3.h(7)));
+ TEST_INSTRUCTION("4100834F", fmlal(v1.s4(), v2.h4(), v3.h(0)));
+ TEST_INSTRUCTION("4108B34F", fmlal(v1.s4(), v2.h4(), v3.h(7)));
+ TEST_INSTRUCTION("41CC232E", fmlal2(v1.s2(), v2.h2(), v3.h2()));
+ TEST_INSTRUCTION("41CC236E", fmlal2(v1.s4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4180832F", fmlal2(v1.s2(), v2.h2(), v3.h(0)));
+ TEST_INSTRUCTION("4188B32F", fmlal2(v1.s2(), v2.h2(), v3.h(7)));
+ TEST_INSTRUCTION("4180836F", fmlal2(v1.s4(), v2.h4(), v3.h(0)));
+ TEST_INSTRUCTION("4188B36F", fmlal2(v1.s4(), v2.h4(), v3.h(7)));
+ TEST_INSTRUCTION("410CC30E", fmls(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41CCA30E", fmls(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("410CC34E", fmls(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41CCA34E", fmls(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41CCE34E", fmls(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4158335F", fmls(h1, h2, v3.h(7)));
+ TEST_INSTRUCTION("4158A35F", fmls(s1, s2, v3.s(3)));
+ TEST_INSTRUCTION("4158C35F", fmls(d1, d2, v3.d(1)));
+ TEST_INSTRUCTION("4158330F", fmls(v1.h4(), v2.h4(), v3.h(7)));
+ TEST_INSTRUCTION("4158A30F", fmls(v1.s2(), v2.s2(), v3.s(3)));
+ TEST_INSTRUCTION("4158334F", fmls(v1.h8(), v2.h8(), v3.h(7)));
+ TEST_INSTRUCTION("4158A34F", fmls(v1.s4(), v2.s4(), v3.s(3)));
+ TEST_INSTRUCTION("4158C34F", fmls(v1.d2(), v2.d2(), v3.d(1)));
+ TEST_INSTRUCTION("41ECA30E", fmlsl(v1.s2(), v2.h2(), v3.h2()));
+ TEST_INSTRUCTION("41ECA34E", fmlsl(v1.s4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4140830F", fmlsl(v1.s2(), v2.h2(), v3.h(0)));
+ TEST_INSTRUCTION("4148B30F", fmlsl(v1.s2(), v2.h2(), v3.h(7)));
+ TEST_INSTRUCTION("4140834F", fmlsl(v1.s4(), v2.h4(), v3.h(0)));
+ TEST_INSTRUCTION("4148B34F", fmlsl(v1.s4(), v2.h4(), v3.h(7)));
+ TEST_INSTRUCTION("41CCA32E", fmlsl2(v1.s2(), v2.h2(), v3.h2()));
+ TEST_INSTRUCTION("41CCA36E", fmlsl2(v1.s4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41C0832F", fmlsl2(v1.s2(), v2.h2(), v3.h(0)));
+ TEST_INSTRUCTION("41C8B32F", fmlsl2(v1.s2(), v2.h2(), v3.h(7)));
+ TEST_INSTRUCTION("41C0836F", fmlsl2(v1.s4(), v2.h4(), v3.h(0)));
+ TEST_INSTRUCTION("41C8B36F", fmlsl2(v1.s4(), v2.h4(), v3.h(7)));
+ TEST_INSTRUCTION("4100E71E", fmov(h1, w2));
+ TEST_INSTRUCTION("4100E79E", fmov(h1, x2));
+ TEST_INSTRUCTION("4100271E", fmov(s1, w2));
+ TEST_INSTRUCTION("4100679E", fmov(d1, x2));
+ TEST_INSTRUCTION("4100AF9E", fmov(v1.d(1), x2));
+ TEST_INSTRUCTION("4100E61E", fmov(w1, h2));
+ TEST_INSTRUCTION("4100E69E", fmov(x1, h2));
+ TEST_INSTRUCTION("4100261E", fmov(w1, s2));
+ TEST_INSTRUCTION("4100669E", fmov(x1, d2));
+ TEST_INSTRUCTION("4100AE9E", fmov(x1, v2.d(1)));
+ TEST_INSTRUCTION("0110EA1E", fmov(h1, 0.25));
+ TEST_INSTRUCTION("0110EC1E", fmov(h1, 0.5));
+ TEST_INSTRUCTION("0110EF1E", fmov(h1, 1.5));
+ TEST_INSTRUCTION("0110E01E", fmov(h1, 2.0));
+ TEST_INSTRUCTION("01D0E51E", fmov(h1, 15.0));
+ TEST_INSTRUCTION("01102A1E", fmov(s1, 0.25));
+ TEST_INSTRUCTION("01102C1E", fmov(s1, 0.5));
+ TEST_INSTRUCTION("01102F1E", fmov(s1, 1.5));
+ TEST_INSTRUCTION("0110201E", fmov(s1, 2.0));
+ TEST_INSTRUCTION("01D0251E", fmov(s1, 15.0));
+ TEST_INSTRUCTION("01106A1E", fmov(d1, 0.25));
+ TEST_INSTRUCTION("01106C1E", fmov(d1, 0.5));
+ TEST_INSTRUCTION("01106F1E", fmov(d1, 1.5));
+ TEST_INSTRUCTION("0110601E", fmov(d1, 2.0));
+ TEST_INSTRUCTION("01D0651E", fmov(d1, 15.0));
+ TEST_INSTRUCTION("01FC030F", fmov(v1.h4(), 0.5));
+ TEST_INSTRUCTION("01FC000F", fmov(v1.h4(), 2.0));
+ TEST_INSTRUCTION("01FC034F", fmov(v1.h8(), 0.5));
+ TEST_INSTRUCTION("01FC004F", fmov(v1.h8(), 2.0));
+ TEST_INSTRUCTION("01F4030F", fmov(v1.s2(), 0.5));
+ TEST_INSTRUCTION("01F4000F", fmov(v1.s2(), 2.0));
+ TEST_INSTRUCTION("01F4034F", fmov(v1.s4(), 0.5));
+ TEST_INSTRUCTION("01F4004F", fmov(v1.s4(), 2.0));
+ TEST_INSTRUCTION("01F4036F", fmov(v1.d2(), 0.5));
+ TEST_INSTRUCTION("01F4006F", fmov(v1.d2(), 2.0));
+ TEST_INSTRUCTION("4190C31F", fmsub(h1, h2, h3, h4));
+ TEST_INSTRUCTION("4190031F", fmsub(s1, s2, s3, s4));
+ TEST_INSTRUCTION("4190431F", fmsub(d1, d2, d3, d4));
+ TEST_INSTRUCTION("4108E31E", fmul(h1, h2, h3));
+ TEST_INSTRUCTION("4108231E", fmul(s1, s2, s3));
+ TEST_INSTRUCTION("4108631E", fmul(d1, d2, d3));
+ TEST_INSTRUCTION("411C432E", fmul(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41DC232E", fmul(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("411C436E", fmul(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41DC236E", fmul(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41DC636E", fmul(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4198335F", fmul(h1, h2, v3.h(7)));
+ TEST_INSTRUCTION("4198A35F", fmul(s1, s2, v3.s(3)));
+ TEST_INSTRUCTION("4198C35F", fmul(d1, d2, v3.d(1)));
+ TEST_INSTRUCTION("4198330F", fmul(v1.h4(), v2.h4(), v3.h(7)));
+ TEST_INSTRUCTION("4198A30F", fmul(v1.s2(), v2.s2(), v3.s(3)));
+ TEST_INSTRUCTION("4198334F", fmul(v1.h8(), v2.h8(), v3.h(7)));
+ TEST_INSTRUCTION("4198A34F", fmul(v1.s4(), v2.s4(), v3.s(3)));
+ TEST_INSTRUCTION("4198C34F", fmul(v1.d2(), v2.d2(), v3.d(1)));
+ TEST_INSTRUCTION("411C435E", fmulx(h1, h2, h3));
+ TEST_INSTRUCTION("41DC235E", fmulx(s1, s2, s3));
+ TEST_INSTRUCTION("41DC635E", fmulx(d1, d2, d3));
+ TEST_INSTRUCTION("411C430E", fmulx(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41DC230E", fmulx(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("411C434E", fmulx(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41DC234E", fmulx(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41DC634E", fmulx(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4198337F", fmulx(h1, h2, v3.h(7)));
+ TEST_INSTRUCTION("4198A37F", fmulx(s1, s2, v3.s(3)));
+ TEST_INSTRUCTION("4198C37F", fmulx(d1, d2, v3.d(1)));
+ TEST_INSTRUCTION("4198332F", fmulx(v1.h4(), v2.h4(), v3.h(7)));
+ TEST_INSTRUCTION("4198A32F", fmulx(v1.s2(), v2.s2(), v3.s(3)));
+ TEST_INSTRUCTION("4198336F", fmulx(v1.h8(), v2.h8(), v3.h(7)));
+ TEST_INSTRUCTION("4198A36F", fmulx(v1.s4(), v2.s4(), v3.s(3)));
+ TEST_INSTRUCTION("4198C36F", fmulx(v1.d2(), v2.d2(), v3.d(1)));
+ TEST_INSTRUCTION("4140E11E", fneg(h1, h2));
+ TEST_INSTRUCTION("4140211E", fneg(s1, s2));
+ TEST_INSTRUCTION("4140611E", fneg(d1, d2));
+ TEST_INSTRUCTION("41F8F82E", fneg(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("41F8A02E", fneg(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41F8F86E", fneg(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("41F8A06E", fneg(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("41F8E06E", fneg(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("4110E31F", fnmadd(h1, h2, h3, h4));
+ TEST_INSTRUCTION("4110231F", fnmadd(s1, s2, s3, s4));
+ TEST_INSTRUCTION("4110631F", fnmadd(d1, d2, d3, d4));
+ TEST_INSTRUCTION("4190E31F", fnmsub(h1, h2, h3, h4));
+ TEST_INSTRUCTION("4190231F", fnmsub(s1, s2, s3, s4));
+ TEST_INSTRUCTION("4190631F", fnmsub(d1, d2, d3, d4));
+ TEST_INSTRUCTION("4188E31E", fnmul(h1, h2, h3));
+ TEST_INSTRUCTION("4188231E", fnmul(s1, s2, s3));
+ TEST_INSTRUCTION("4188631E", fnmul(d1, d2, d3));
+ TEST_INSTRUCTION("41D8F95E", frecpe(h1, h2));
+ TEST_INSTRUCTION("41D8A15E", frecpe(s1, s2));
+ TEST_INSTRUCTION("41D8E15E", frecpe(d1, d2));
+ TEST_INSTRUCTION("41D8F90E", frecpe(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("41D8A10E", frecpe(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41D8F94E", frecpe(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("41D8A14E", frecpe(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("41D8E14E", frecpe(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("413C435E", frecps(h1, h2, h3));
+ TEST_INSTRUCTION("41FC235E", frecps(s1, s2, s3));
+ TEST_INSTRUCTION("41FC635E", frecps(d1, d2, d3));
+ TEST_INSTRUCTION("413C430E", frecps(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41FC230E", frecps(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("413C434E", frecps(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41FC234E", frecps(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41FC634E", frecps(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("41F8F95E", frecpx(h1, h2));
+ TEST_INSTRUCTION("41F8A15E", frecpx(s1, s2));
+ TEST_INSTRUCTION("41F8E15E", frecpx(d1, d2));
+ TEST_INSTRUCTION("41C0281E", frint32x(s1, s2));
+ TEST_INSTRUCTION("41C0681E", frint32x(d1, d2));
+ TEST_INSTRUCTION("41E8212E", frint32x(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41E8216E", frint32x(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("41E8616E", frint32x(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("4140281E", frint32z(s1, s2));
+ TEST_INSTRUCTION("4140681E", frint32z(d1, d2));
+ TEST_INSTRUCTION("41E8210E", frint32z(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41E8214E", frint32z(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("41E8614E", frint32z(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("41C0291E", frint64x(s1, s2));
+ TEST_INSTRUCTION("41C0691E", frint64x(d1, d2));
+ TEST_INSTRUCTION("41F8212E", frint64x(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41F8216E", frint64x(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("41F8616E", frint64x(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("4140291E", frint64z(s1, s2));
+ TEST_INSTRUCTION("4140691E", frint64z(d1, d2));
+ TEST_INSTRUCTION("41F8210E", frint64z(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41F8214E", frint64z(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("41F8614E", frint64z(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("4140E61E", frinta(h1, h2));
+ TEST_INSTRUCTION("4140261E", frinta(s1, s2));
+ TEST_INSTRUCTION("4140661E", frinta(d1, d2));
+ TEST_INSTRUCTION("4188792E", frinta(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("4188212E", frinta(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("4188796E", frinta(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("4188216E", frinta(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("4188616E", frinta(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("41C0E71E", frinti(h1, h2));
+ TEST_INSTRUCTION("41C0271E", frinti(s1, s2));
+ TEST_INSTRUCTION("41C0671E", frinti(d1, d2));
+ TEST_INSTRUCTION("4198F92E", frinti(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("4198A12E", frinti(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("4198F96E", frinti(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("4198A16E", frinti(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("4198E16E", frinti(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("4140E51E", frintm(h1, h2));
+ TEST_INSTRUCTION("4140251E", frintm(s1, s2));
+ TEST_INSTRUCTION("4140651E", frintm(d1, d2));
+ TEST_INSTRUCTION("4198790E", frintm(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("4198210E", frintm(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("4198794E", frintm(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("4198214E", frintm(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("4198614E", frintm(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("4140E41E", frintn(h1, h2));
+ TEST_INSTRUCTION("4140241E", frintn(s1, s2));
+ TEST_INSTRUCTION("4140641E", frintn(d1, d2));
+ TEST_INSTRUCTION("4188790E", frintn(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("4188210E", frintn(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("4188794E", frintn(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("4188214E", frintn(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("4188614E", frintn(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("41C0E41E", frintp(h1, h2));
+ TEST_INSTRUCTION("41C0241E", frintp(s1, s2));
+ TEST_INSTRUCTION("41C0641E", frintp(d1, d2));
+ TEST_INSTRUCTION("4188F90E", frintp(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("4188A10E", frintp(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("4188F94E", frintp(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("4188A14E", frintp(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("4188E14E", frintp(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("4140E71E", frintx(h1, h2));
+ TEST_INSTRUCTION("4140271E", frintx(s1, s2));
+ TEST_INSTRUCTION("4140671E", frintx(d1, d2));
+ TEST_INSTRUCTION("4198792E", frintx(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("4198212E", frintx(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("4198796E", frintx(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("4198216E", frintx(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("4198616E", frintx(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("41C0E51E", frintz(h1, h2));
+ TEST_INSTRUCTION("41C0251E", frintz(s1, s2));
+ TEST_INSTRUCTION("41C0651E", frintz(d1, d2));
+ TEST_INSTRUCTION("4198F90E", frintz(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("4198A10E", frintz(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("4198F94E", frintz(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("4198A14E", frintz(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("4198E14E", frintz(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("41D8F97E", frsqrte(h1, h2));
+ TEST_INSTRUCTION("41D8A17E", frsqrte(s1, s2));
+ TEST_INSTRUCTION("41D8E17E", frsqrte(d1, d2));
+ TEST_INSTRUCTION("41D8F92E", frsqrte(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("41D8A12E", frsqrte(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41D8F96E", frsqrte(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("41D8A16E", frsqrte(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("41D8E16E", frsqrte(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("413CC35E", frsqrts(h1, h2, h3));
+ TEST_INSTRUCTION("41FCA35E", frsqrts(s1, s2, s3));
+ TEST_INSTRUCTION("41FCE35E", frsqrts(d1, d2, d3));
+ TEST_INSTRUCTION("413CC30E", frsqrts(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41FCA30E", frsqrts(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("413CC34E", frsqrts(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41FCA34E", frsqrts(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41FCE34E", frsqrts(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("41C0E11E", fsqrt(h1, h2));
+ TEST_INSTRUCTION("41C0211E", fsqrt(s1, s2));
+ TEST_INSTRUCTION("41C0611E", fsqrt(d1, d2));
+ TEST_INSTRUCTION("41F8F92E", fsqrt(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("41F8A12E", fsqrt(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41F8F96E", fsqrt(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("41F8A16E", fsqrt(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("41F8E16E", fsqrt(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("4138E31E", fsub(h1, h2, h3));
+ TEST_INSTRUCTION("4138231E", fsub(s1, s2, s3));
+ TEST_INSTRUCTION("4138631E", fsub(d1, d2, d3));
+ TEST_INSTRUCTION("4114C30E", fsub(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41D4A30E", fsub(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4114C34E", fsub(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41D4A34E", fsub(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41D4E34E", fsub(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("411C014E", ins(v1.b(0), w2));
+ TEST_INSTRUCTION("411C074E", ins(v1.b(3), w2));
+ TEST_INSTRUCTION("411C0D4E", ins(v1.b(6), w2));
+ TEST_INSTRUCTION("411C134E", ins(v1.b(9), w2));
+ TEST_INSTRUCTION("411C1F4E", ins(v1.b(15), w2));
+ TEST_INSTRUCTION("411C024E", ins(v1.h(0), w2));
+ TEST_INSTRUCTION("411C0E4E", ins(v1.h(3), w2));
+ TEST_INSTRUCTION("411C1E4E", ins(v1.h(7), w2));
+ TEST_INSTRUCTION("411C044E", ins(v1.s(0), w2));
+ TEST_INSTRUCTION("411C0C4E", ins(v1.s(1), w2));
+ TEST_INSTRUCTION("411C144E", ins(v1.s(2), w2));
+ TEST_INSTRUCTION("411C1C4E", ins(v1.s(3), w2));
+ TEST_INSTRUCTION("411C084E", ins(v1.d(0), x2));
+ TEST_INSTRUCTION("411C184E", ins(v1.d(1), x2));
+ TEST_INSTRUCTION("417C016E", ins(v1.b(0), v2.b(15)));
+ TEST_INSTRUCTION("4174036E", ins(v1.b(1), v2.b(14)));
+ TEST_INSTRUCTION("4174026E", ins(v1.h(0), v2.h(7)));
+ TEST_INSTRUCTION("4164066E", ins(v1.h(1), v2.h(6)));
+ TEST_INSTRUCTION("4164046E", ins(v1.s(0), v2.s(3)));
+ TEST_INSTRUCTION("41440C6E", ins(v1.s(1), v2.s(2)));
+ TEST_INSTRUCTION("4144086E", ins(v1.d(0), v2.d(1)));
+ TEST_INSTRUCTION("4104186E", ins(v1.d(1), v2.d(0)));
+ TEST_INSTRUCTION("4100400D", ld1(v1.b(0), ptr(x2)));
+ TEST_INSTRUCTION("4100DF0D", ld1(v1.b(0), ptr_post(x2, 1)));
+ TEST_INSTRUCTION("4100CB0D", ld1(v1.b(0), ptr_post(x2, x11)));
+ TEST_INSTRUCTION("4140400D", ld1(v1.h(0), ptr(x2)));
+ TEST_INSTRUCTION("4140DF0D", ld1(v1.h(0), ptr_post(x2, 2)));
+ TEST_INSTRUCTION("4140CB0D", ld1(v1.h(0), ptr_post(x2, x11)));
+ TEST_INSTRUCTION("4180400D", ld1(v1.s(0), ptr(x2)));
+ TEST_INSTRUCTION("4180DF0D", ld1(v1.s(0), ptr_post(x2, 4)));
+ TEST_INSTRUCTION("4180CB0D", ld1(v1.s(0), ptr_post(x2, x11)));
+ TEST_INSTRUCTION("4184400D", ld1(v1.d(0), ptr(x2)));
+ TEST_INSTRUCTION("4184DF0D", ld1(v1.d(0), ptr_post(x2, 8)));
+ TEST_INSTRUCTION("4184CB0D", ld1(v1.d(0), ptr_post(x2, x11)));
+ TEST_INSTRUCTION("411C404D", ld1(v1.b(15), ptr(x2)));
+ TEST_INSTRUCTION("411CDF4D", ld1(v1.b(15), ptr_post(x2, 1)));
+ TEST_INSTRUCTION("411CCB4D", ld1(v1.b(15), ptr_post(x2, x11)));
+ TEST_INSTRUCTION("4158404D", ld1(v1.h(7), ptr(x2)));
+ TEST_INSTRUCTION("4158DF4D", ld1(v1.h(7), ptr_post(x2, 2)));
+ TEST_INSTRUCTION("4158CB4D", ld1(v1.h(7), ptr_post(x2, x11)));
+ TEST_INSTRUCTION("4190404D", ld1(v1.s(3), ptr(x2)));
+ TEST_INSTRUCTION("4190DF4D", ld1(v1.s(3), ptr_post(x2, 4)));
+ TEST_INSTRUCTION("4190CB4D", ld1(v1.s(3), ptr_post(x2, x11)));
+ TEST_INSTRUCTION("4184404D", ld1(v1.d(1), ptr(x2)));
+ TEST_INSTRUCTION("4184DF4D", ld1(v1.d(1), ptr_post(x2, 8)));
+ TEST_INSTRUCTION("4184CB4D", ld1(v1.d(1), ptr_post(x2, x11)));
+ TEST_INSTRUCTION("4170400C", ld1(v1.b8(), ptr(x2)));
+ TEST_INSTRUCTION("4170DF0C", ld1(v1.b8(), ptr_post(x2, 8)));
+ TEST_INSTRUCTION("4170404C", ld1(v1.b16(), ptr(x2)));
+ TEST_INSTRUCTION("4170DF4C", ld1(v1.b16(), ptr_post(x2, 16)));
+ TEST_INSTRUCTION("61A0400C", ld1(v1.b8(), v2.b8(), ptr(x3)));
+ TEST_INSTRUCTION("61A0DF0C", ld1(v1.b8(), v2.b8(), ptr_post(x3, 16)));
+ TEST_INSTRUCTION("61A0404C", ld1(v1.b16(), v2.b16(), ptr(x3)));
+ TEST_INSTRUCTION("61A0DF4C", ld1(v1.b16(), v2.b16(), ptr_post(x3, 32)));
+ TEST_INSTRUCTION("8160400C", ld1(v1.b8(), v2.b8(), v3.b8(), ptr(x4)));
+ TEST_INSTRUCTION("8160DF0C", ld1(v1.b8(), v2.b8(), v3.b8(), ptr_post(x4, 24)));
+ TEST_INSTRUCTION("8160404C", ld1(v1.b16(), v2.b16(), v3.b16(), ptr(x4)));
+ TEST_INSTRUCTION("8160DF4C", ld1(v1.b16(), v2.b16(), v3.b16(), ptr_post(x4, 48)));
+ TEST_INSTRUCTION("A120400C", ld1(v1.b8(), v2.b8(), v3.b8(), v4.b8(), ptr(x5)));
+ TEST_INSTRUCTION("A120DF0C", ld1(v1.b8(), v2.b8(), v3.b8(), v4.b8(), ptr_post(x5, 32)));
+ TEST_INSTRUCTION("A120404C", ld1(v1.b16(), v2.b16(), v3.b16(), v4.b16(), ptr(x5)));
+ TEST_INSTRUCTION("A120DF4C", ld1(v1.b16(), v2.b16(), v3.b16(), v4.b16(), ptr_post(x5, 64)));
+ TEST_INSTRUCTION("4174400C", ld1(v1.h4(), ptr(x2)));
+ TEST_INSTRUCTION("4174DF0C", ld1(v1.h4(), ptr_post(x2, 8)));
+ TEST_INSTRUCTION("4174404C", ld1(v1.h8(), ptr(x2)));
+ TEST_INSTRUCTION("4174DF4C", ld1(v1.h8(), ptr_post(x2, 16)));
+ TEST_INSTRUCTION("61A4400C", ld1(v1.h4(), v2.h4(), ptr(x3)));
+ TEST_INSTRUCTION("61A4DF0C", ld1(v1.h4(), v2.h4(), ptr_post(x3, 16)));
+ TEST_INSTRUCTION("61A4404C", ld1(v1.h8(), v2.h8(), ptr(x3)));
+ TEST_INSTRUCTION("61A4DF4C", ld1(v1.h8(), v2.h8(), ptr_post(x3, 32)));
+ TEST_INSTRUCTION("8164400C", ld1(v1.h4(), v2.h4(), v3.h4(), ptr(x4)));
+ TEST_INSTRUCTION("8164DF0C", ld1(v1.h4(), v2.h4(), v3.h4(), ptr_post(x4, 24)));
+ TEST_INSTRUCTION("8164404C", ld1(v1.h8(), v2.h8(), v3.h8(), ptr(x4)));
+ TEST_INSTRUCTION("8164DF4C", ld1(v1.h8(), v2.h8(), v3.h8(), ptr_post(x4, 48)));
+ TEST_INSTRUCTION("A124400C", ld1(v1.h4(), v2.h4(), v3.h4(), v4.h4(), ptr(x5)));
+ TEST_INSTRUCTION("A124DF0C", ld1(v1.h4(), v2.h4(), v3.h4(), v4.h4(), ptr_post(x5, 32)));
+ TEST_INSTRUCTION("A124404C", ld1(v1.h8(), v2.h8(), v3.h8(), v4.h8(), ptr(x5)));
+ TEST_INSTRUCTION("A124DF4C", ld1(v1.h8(), v2.h8(), v3.h8(), v4.h8(), ptr_post(x5, 64)));
+ TEST_INSTRUCTION("4178400C", ld1(v1.s2(), ptr(x2)));
+ TEST_INSTRUCTION("4178DF0C", ld1(v1.s2(), ptr_post(x2, 8)));
+ TEST_INSTRUCTION("4178404C", ld1(v1.s4(), ptr(x2)));
+ TEST_INSTRUCTION("4178DF4C", ld1(v1.s4(), ptr_post(x2, 16)));
+ TEST_INSTRUCTION("61A8400C", ld1(v1.s2(), v2.s2(), ptr(x3)));
+ TEST_INSTRUCTION("61A8DF0C", ld1(v1.s2(), v2.s2(), ptr_post(x3, 16)));
+ TEST_INSTRUCTION("61A8404C", ld1(v1.s4(), v2.s4(), ptr(x3)));
+ TEST_INSTRUCTION("61A8DF4C", ld1(v1.s4(), v2.s4(), ptr_post(x3, 32)));
+ TEST_INSTRUCTION("8168400C", ld1(v1.s2(), v2.s2(), v3.s2(), ptr(x4)));
+ TEST_INSTRUCTION("8168DF0C", ld1(v1.s2(), v2.s2(), v3.s2(), ptr_post(x4, 24)));
+ TEST_INSTRUCTION("8168404C", ld1(v1.s4(), v2.s4(), v3.s4(), ptr(x4)));
+ TEST_INSTRUCTION("8168DF4C", ld1(v1.s4(), v2.s4(), v3.s4(), ptr_post(x4, 48)));
+ TEST_INSTRUCTION("A128400C", ld1(v1.s2(), v2.s2(), v3.s2(), v4.s2(), ptr(x5)));
+ TEST_INSTRUCTION("A128DF0C", ld1(v1.s2(), v2.s2(), v3.s2(), v4.s2(), ptr_post(x5, 32)));
+ TEST_INSTRUCTION("A128404C", ld1(v1.s4(), v2.s4(), v3.s4(), v4.s4(), ptr(x5)));
+ TEST_INSTRUCTION("A128DF4C", ld1(v1.s4(), v2.s4(), v3.s4(), v4.s4(), ptr_post(x5, 64)));
+ TEST_INSTRUCTION("417C404C", ld1(v1.d2(), ptr(x2)));
+ TEST_INSTRUCTION("417CDF4C", ld1(v1.d2(), ptr_post(x2, 16)));
+ TEST_INSTRUCTION("61AC404C", ld1(v1.d2(), v2.d2(), ptr(x3)));
+ TEST_INSTRUCTION("61ACDF4C", ld1(v1.d2(), v2.d2(), ptr_post(x3, 32)));
+ TEST_INSTRUCTION("816C404C", ld1(v1.d2(), v2.d2(), v3.d2(), ptr(x4)));
+ TEST_INSTRUCTION("816CDF4C", ld1(v1.d2(), v2.d2(), v3.d2(), ptr_post(x4, 48)));
+ TEST_INSTRUCTION("A12C404C", ld1(v1.d2(), v2.d2(), v3.d2(), v4.d2(), ptr(x5)));
+ TEST_INSTRUCTION("A12CDF4C", ld1(v1.d2(), v2.d2(), v3.d2(), v4.d2(), ptr_post(x5, 64)));
+ TEST_INSTRUCTION("41C0400D", ld1r(v1.b8(), ptr(x2)));
+ TEST_INSTRUCTION("41C0DF0D", ld1r(v1.b8(), ptr_post(x2, 1)));
+ TEST_INSTRUCTION("41C0CB0D", ld1r(v1.b8(), ptr_post(x2, x11)));
+ TEST_INSTRUCTION("41C0404D", ld1r(v1.b16(), ptr(x2)));
+ TEST_INSTRUCTION("41C0DF4D", ld1r(v1.b16(), ptr_post(x2, 1)));
+ TEST_INSTRUCTION("41C0CB4D", ld1r(v1.b16(), ptr_post(x2, x11)));
+ TEST_INSTRUCTION("41C4400D", ld1r(v1.h4(), ptr(x2)));
+ TEST_INSTRUCTION("41C4DF0D", ld1r(v1.h4(), ptr_post(x2, 2)));
+ TEST_INSTRUCTION("41C4CB0D", ld1r(v1.h4(), ptr_post(x2, x11)));
+ TEST_INSTRUCTION("41C4404D", ld1r(v1.h8(), ptr(x2)));
+ TEST_INSTRUCTION("41C4DF4D", ld1r(v1.h8(), ptr_post(x2, 2)));
+ TEST_INSTRUCTION("41C4CB4D", ld1r(v1.h8(), ptr_post(x2, x11)));
+ TEST_INSTRUCTION("41C8400D", ld1r(v1.s2(), ptr(x2)));
+ TEST_INSTRUCTION("41C8DF0D", ld1r(v1.s2(), ptr_post(x2, 4)));
+ TEST_INSTRUCTION("41C8CB0D", ld1r(v1.s2(), ptr_post(x2, x11)));
+ TEST_INSTRUCTION("41C8404D", ld1r(v1.s4(), ptr(x2)));
+ TEST_INSTRUCTION("41C8DF4D", ld1r(v1.s4(), ptr_post(x2, 4)));
+ TEST_INSTRUCTION("41C8CB4D", ld1r(v1.s4(), ptr_post(x2, x11)));
+ TEST_INSTRUCTION("41CC404D", ld1r(v1.d2(), ptr(x2)));
+ TEST_INSTRUCTION("41CCDF4D", ld1r(v1.d2(), ptr_post(x2, 8)));
+ TEST_INSTRUCTION("41CCCB4D", ld1r(v1.d2(), ptr_post(x2, x11)));
+ TEST_INSTRUCTION("6100600D", ld2(v1.b(0), v2.b(0), ptr(x3)));
+ TEST_INSTRUCTION("6100FF0D", ld2(v1.b(0), v2.b(0), ptr_post(x3, 2)));
+ TEST_INSTRUCTION("6100EB0D", ld2(v1.b(0), v2.b(0), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("6140600D", ld2(v1.h(0), v2.h(0), ptr(x3)));
+ TEST_INSTRUCTION("6140FF0D", ld2(v1.h(0), v2.h(0), ptr_post(x3, 4)));
+ TEST_INSTRUCTION("6140EB0D", ld2(v1.h(0), v2.h(0), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("6180600D", ld2(v1.s(0), v2.s(0), ptr(x3)));
+ TEST_INSTRUCTION("6180FF0D", ld2(v1.s(0), v2.s(0), ptr_post(x3, 8)));
+ TEST_INSTRUCTION("6180EB0D", ld2(v1.s(0), v2.s(0), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("6184600D", ld2(v1.d(0), v2.d(0), ptr(x3)));
+ TEST_INSTRUCTION("6184FF0D", ld2(v1.d(0), v2.d(0), ptr_post(x3, 16)));
+ TEST_INSTRUCTION("6184EB0D", ld2(v1.d(0), v2.d(0), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("611C604D", ld2(v1.b(15), v2.b(15), ptr(x3)));
+ TEST_INSTRUCTION("611CFF4D", ld2(v1.b(15), v2.b(15), ptr_post(x3, 2)));
+ TEST_INSTRUCTION("611CEB4D", ld2(v1.b(15), v2.b(15), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("6158604D", ld2(v1.h(7), v2.h(7), ptr(x3)));
+ TEST_INSTRUCTION("6158FF4D", ld2(v1.h(7), v2.h(7), ptr_post(x3, 4)));
+ TEST_INSTRUCTION("6158EB4D", ld2(v1.h(7), v2.h(7), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("6190604D", ld2(v1.s(3), v2.s(3), ptr(x3)));
+ TEST_INSTRUCTION("6190FF4D", ld2(v1.s(3), v2.s(3), ptr_post(x3, 8)));
+ TEST_INSTRUCTION("6190EB4D", ld2(v1.s(3), v2.s(3), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("6184604D", ld2(v1.d(1), v2.d(1), ptr(x3)));
+ TEST_INSTRUCTION("6184FF4D", ld2(v1.d(1), v2.d(1), ptr_post(x3, 16)));
+ TEST_INSTRUCTION("6184EB4D", ld2(v1.d(1), v2.d(1), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("6180400C", ld2(v1.b8(), v2.b8(), ptr(x3)));
+ TEST_INSTRUCTION("6180DF0C", ld2(v1.b8(), v2.b8(), ptr_post(x3, 16)));
+ TEST_INSTRUCTION("6180CB0C", ld2(v1.b8(), v2.b8(), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("6180404C", ld2(v1.b16(), v2.b16(), ptr(x3)));
+ TEST_INSTRUCTION("6180DF4C", ld2(v1.b16(), v2.b16(), ptr_post(x3, 32)));
+ TEST_INSTRUCTION("6180CB4C", ld2(v1.b16(), v2.b16(), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("6184400C", ld2(v1.h4(), v2.h4(), ptr(x3)));
+ TEST_INSTRUCTION("6184DF0C", ld2(v1.h4(), v2.h4(), ptr_post(x3, 16)));
+ TEST_INSTRUCTION("6184CB0C", ld2(v1.h4(), v2.h4(), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("6184404C", ld2(v1.h8(), v2.h8(), ptr(x3)));
+ TEST_INSTRUCTION("6184DF4C", ld2(v1.h8(), v2.h8(), ptr_post(x3, 32)));
+ TEST_INSTRUCTION("6184CB4C", ld2(v1.h8(), v2.h8(), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("6188400C", ld2(v1.s2(), v2.s2(), ptr(x3)));
+ TEST_INSTRUCTION("6188DF0C", ld2(v1.s2(), v2.s2(), ptr_post(x3, 16)));
+ TEST_INSTRUCTION("6188CB0C", ld2(v1.s2(), v2.s2(), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("6188404C", ld2(v1.s4(), v2.s4(), ptr(x3)));
+ TEST_INSTRUCTION("6188DF4C", ld2(v1.s4(), v2.s4(), ptr_post(x3, 32)));
+ TEST_INSTRUCTION("6188CB4C", ld2(v1.s4(), v2.s4(), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("618C404C", ld2(v1.d2(), v2.d2(), ptr(x3)));
+ TEST_INSTRUCTION("618CDF4C", ld2(v1.d2(), v2.d2(), ptr_post(x3, 32)));
+ TEST_INSTRUCTION("618CCB4C", ld2(v1.d2(), v2.d2(), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("61C0600D", ld2r(v1.b8(), v2.b8(), ptr(x3)));
+ TEST_INSTRUCTION("61C0FF0D", ld2r(v1.b8(), v2.b8(), ptr_post(x3, 2)));
+ TEST_INSTRUCTION("61C0EB0D", ld2r(v1.b8(), v2.b8(), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("61C0604D", ld2r(v1.b16(), v2.b16(), ptr(x3)));
+ TEST_INSTRUCTION("61C0FF4D", ld2r(v1.b16(), v2.b16(), ptr_post(x3, 2)));
+ TEST_INSTRUCTION("61C0EB4D", ld2r(v1.b16(), v2.b16(), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("61C4600D", ld2r(v1.h4(), v2.h4(), ptr(x3)));
+ TEST_INSTRUCTION("61C4FF0D", ld2r(v1.h4(), v2.h4(), ptr_post(x3, 4)));
+ TEST_INSTRUCTION("61C4EB0D", ld2r(v1.h4(), v2.h4(), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("61C4604D", ld2r(v1.h8(), v2.h8(), ptr(x3)));
+ TEST_INSTRUCTION("61C4FF4D", ld2r(v1.h8(), v2.h8(), ptr_post(x3, 4)));
+ TEST_INSTRUCTION("61C4EB4D", ld2r(v1.h8(), v2.h8(), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("61C8600D", ld2r(v1.s2(), v2.s2(), ptr(x3)));
+ TEST_INSTRUCTION("61C8FF0D", ld2r(v1.s2(), v2.s2(), ptr_post(x3, 8)));
+ TEST_INSTRUCTION("61C8EB0D", ld2r(v1.s2(), v2.s2(), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("61C8604D", ld2r(v1.s4(), v2.s4(), ptr(x3)));
+ TEST_INSTRUCTION("61C8FF4D", ld2r(v1.s4(), v2.s4(), ptr_post(x3, 8)));
+ TEST_INSTRUCTION("61C8EB4D", ld2r(v1.s4(), v2.s4(), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("61CC604D", ld2r(v1.d2(), v2.d2(), ptr(x3)));
+ TEST_INSTRUCTION("61CCFF4D", ld2r(v1.d2(), v2.d2(), ptr_post(x3, 16)));
+ TEST_INSTRUCTION("61CCEB4D", ld2r(v1.d2(), v2.d2(), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("8120400D", ld3(v1.b(0), v2.b(0), v3.b(0), ptr(x4)));
+ TEST_INSTRUCTION("8120DF0D", ld3(v1.b(0), v2.b(0), v3.b(0), ptr_post(x4, 3)));
+ TEST_INSTRUCTION("8120CB0D", ld3(v1.b(0), v2.b(0), v3.b(0), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("8160400D", ld3(v1.h(0), v2.h(0), v3.h(0), ptr(x4)));
+ TEST_INSTRUCTION("8160DF0D", ld3(v1.h(0), v2.h(0), v3.h(0), ptr_post(x4, 6)));
+ TEST_INSTRUCTION("8160CB0D", ld3(v1.h(0), v2.h(0), v3.h(0), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("81A0400D", ld3(v1.s(0), v2.s(0), v3.s(0), ptr(x4)));
+ TEST_INSTRUCTION("81A0DF0D", ld3(v1.s(0), v2.s(0), v3.s(0), ptr_post(x4, 12)));
+ TEST_INSTRUCTION("81A0CB0D", ld3(v1.s(0), v2.s(0), v3.s(0), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("81A4400D", ld3(v1.d(0), v2.d(0), v3.d(0), ptr(x4)));
+ TEST_INSTRUCTION("81A4DF0D", ld3(v1.d(0), v2.d(0), v3.d(0), ptr_post(x4, 24)));
+ TEST_INSTRUCTION("81A4CB0D", ld3(v1.d(0), v2.d(0), v3.d(0), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("813C404D", ld3(v1.b(15), v2.b(15), v3.b(15), ptr(x4)));
+ TEST_INSTRUCTION("813CDF4D", ld3(v1.b(15), v2.b(15), v3.b(15), ptr_post(x4, 3)));
+ TEST_INSTRUCTION("813CCB4D", ld3(v1.b(15), v2.b(15), v3.b(15), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("8178404D", ld3(v1.h(7), v2.h(7), v3.h(7), ptr(x4)));
+ TEST_INSTRUCTION("8178DF4D", ld3(v1.h(7), v2.h(7), v3.h(7), ptr_post(x4, 6)));
+ TEST_INSTRUCTION("8178CB4D", ld3(v1.h(7), v2.h(7), v3.h(7), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("81B0404D", ld3(v1.s(3), v2.s(3), v3.s(3), ptr(x4)));
+ TEST_INSTRUCTION("81B0DF4D", ld3(v1.s(3), v2.s(3), v3.s(3), ptr_post(x4, 12)));
+ TEST_INSTRUCTION("81B0CB4D", ld3(v1.s(3), v2.s(3), v3.s(3), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("81A4404D", ld3(v1.d(1), v2.d(1), v3.d(1), ptr(x4)));
+ TEST_INSTRUCTION("81A4DF4D", ld3(v1.d(1), v2.d(1), v3.d(1), ptr_post(x4, 24)));
+ TEST_INSTRUCTION("81A4CB4D", ld3(v1.d(1), v2.d(1), v3.d(1), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("8140400C", ld3(v1.b8(), v2.b8(), v3.b8(), ptr(x4)));
+ TEST_INSTRUCTION("8140DF0C", ld3(v1.b8(), v2.b8(), v3.b8(), ptr_post(x4, 24)));
+ TEST_INSTRUCTION("8140CB0C", ld3(v1.b8(), v2.b8(), v3.b8(), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("8140404C", ld3(v1.b16(), v2.b16(), v3.b16(), ptr(x4)));
+ TEST_INSTRUCTION("8140DF4C", ld3(v1.b16(), v2.b16(), v3.b16(), ptr_post(x4, 48)));
+ TEST_INSTRUCTION("8140CB4C", ld3(v1.b16(), v2.b16(), v3.b16(), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("8144400C", ld3(v1.h4(), v2.h4(), v3.h4(), ptr(x4)));
+ TEST_INSTRUCTION("8144DF0C", ld3(v1.h4(), v2.h4(), v3.h4(), ptr_post(x4, 24)));
+ TEST_INSTRUCTION("8144CB0C", ld3(v1.h4(), v2.h4(), v3.h4(), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("8144404C", ld3(v1.h8(), v2.h8(), v3.h8(), ptr(x4)));
+ TEST_INSTRUCTION("8144DF4C", ld3(v1.h8(), v2.h8(), v3.h8(), ptr_post(x4, 48)));
+ TEST_INSTRUCTION("8144CB4C", ld3(v1.h8(), v2.h8(), v3.h8(), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("8148400C", ld3(v1.s2(), v2.s2(), v3.s2(), ptr(x4)));
+ TEST_INSTRUCTION("8148DF0C", ld3(v1.s2(), v2.s2(), v3.s2(), ptr_post(x4, 24)));
+ TEST_INSTRUCTION("8148CB0C", ld3(v1.s2(), v2.s2(), v3.s2(), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("8148404C", ld3(v1.s4(), v2.s4(), v3.s4(), ptr(x4)));
+ TEST_INSTRUCTION("8148DF4C", ld3(v1.s4(), v2.s4(), v3.s4(), ptr_post(x4, 48)));
+ TEST_INSTRUCTION("8148CB4C", ld3(v1.s4(), v2.s4(), v3.s4(), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("814C404C", ld3(v1.d2(), v2.d2(), v3.d2(), ptr(x4)));
+ TEST_INSTRUCTION("814CDF4C", ld3(v1.d2(), v2.d2(), v3.d2(), ptr_post(x4, 48)));
+ TEST_INSTRUCTION("814CCB4C", ld3(v1.d2(), v2.d2(), v3.d2(), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("81E0400D", ld3r(v1.b8(), v2.b8(), v3.b8(), ptr(x4)));
+ TEST_INSTRUCTION("81E0DF0D", ld3r(v1.b8(), v2.b8(), v3.b8(), ptr_post(x4, 3)));
+ TEST_INSTRUCTION("81E0CB0D", ld3r(v1.b8(), v2.b8(), v3.b8(), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("81E0404D", ld3r(v1.b16(), v2.b16(), v3.b16(), ptr(x4)));
+ TEST_INSTRUCTION("81E0DF4D", ld3r(v1.b16(), v2.b16(), v3.b16(), ptr_post(x4, 3)));
+ TEST_INSTRUCTION("81E0CB4D", ld3r(v1.b16(), v2.b16(), v3.b16(), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("81E4400D", ld3r(v1.h4(), v2.h4(), v3.h4(), ptr(x4)));
+ TEST_INSTRUCTION("81E4DF0D", ld3r(v1.h4(), v2.h4(), v3.h4(), ptr_post(x4, 6)));
+ TEST_INSTRUCTION("81E4CB0D", ld3r(v1.h4(), v2.h4(), v3.h4(), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("81E4404D", ld3r(v1.h8(), v2.h8(), v3.h8(), ptr(x4)));
+ TEST_INSTRUCTION("81E4DF4D", ld3r(v1.h8(), v2.h8(), v3.h8(), ptr_post(x4, 6)));
+ TEST_INSTRUCTION("81E4CB4D", ld3r(v1.h8(), v2.h8(), v3.h8(), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("81E8400D", ld3r(v1.s2(), v2.s2(), v3.s2(), ptr(x4)));
+ TEST_INSTRUCTION("81E8DF0D", ld3r(v1.s2(), v2.s2(), v3.s2(), ptr_post(x4, 12)));
+ TEST_INSTRUCTION("81E8CB0D", ld3r(v1.s2(), v2.s2(), v3.s2(), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("81E8404D", ld3r(v1.s4(), v2.s4(), v3.s4(), ptr(x4)));
+ TEST_INSTRUCTION("81E8DF4D", ld3r(v1.s4(), v2.s4(), v3.s4(), ptr_post(x4, 12)));
+ TEST_INSTRUCTION("81E8CB4D", ld3r(v1.s4(), v2.s4(), v3.s4(), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("81EC404D", ld3r(v1.d2(), v2.d2(), v3.d2(), ptr(x4)));
+ TEST_INSTRUCTION("81ECDF4D", ld3r(v1.d2(), v2.d2(), v3.d2(), ptr_post(x4, 24)));
+ TEST_INSTRUCTION("81ECCB4D", ld3r(v1.d2(), v2.d2(), v3.d2(), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("A120600D", ld4(v1.b(0), v2.b(0), v3.b(0), v4.b(0), ptr(x5)));
+ TEST_INSTRUCTION("A120FF0D", ld4(v1.b(0), v2.b(0), v3.b(0), v4.b(0), ptr_post(x5, 4)));
+ TEST_INSTRUCTION("A120EB0D", ld4(v1.b(0), v2.b(0), v3.b(0), v4.b(0), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A160600D", ld4(v1.h(0), v2.h(0), v3.h(0), v4.h(0), ptr(x5)));
+ TEST_INSTRUCTION("A160FF0D", ld4(v1.h(0), v2.h(0), v3.h(0), v4.h(0), ptr_post(x5, 8)));
+ TEST_INSTRUCTION("A160EB0D", ld4(v1.h(0), v2.h(0), v3.h(0), v4.h(0), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A1A0600D", ld4(v1.s(0), v2.s(0), v3.s(0), v4.s(0), ptr(x5)));
+ TEST_INSTRUCTION("A1A0FF0D", ld4(v1.s(0), v2.s(0), v3.s(0), v4.s(0), ptr_post(x5, 16)));
+ TEST_INSTRUCTION("A1A0EB0D", ld4(v1.s(0), v2.s(0), v3.s(0), v4.s(0), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A1A4600D", ld4(v1.d(0), v2.d(0), v3.d(0), v4.d(0), ptr(x5)));
+ TEST_INSTRUCTION("A1A4FF0D", ld4(v1.d(0), v2.d(0), v3.d(0), v4.d(0), ptr_post(x5, 32)));
+ TEST_INSTRUCTION("A1A4EB0D", ld4(v1.d(0), v2.d(0), v3.d(0), v4.d(0), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A13C604D", ld4(v1.b(15), v2.b(15), v3.b(15), v4.b(15), ptr(x5)));
+ TEST_INSTRUCTION("A13CFF4D", ld4(v1.b(15), v2.b(15), v3.b(15), v4.b(15), ptr_post(x5, 4)));
+ TEST_INSTRUCTION("A13CEB4D", ld4(v1.b(15), v2.b(15), v3.b(15), v4.b(15), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A178604D", ld4(v1.h(7), v2.h(7), v3.h(7), v4.h(7), ptr(x5)));
+ TEST_INSTRUCTION("A178FF4D", ld4(v1.h(7), v2.h(7), v3.h(7), v4.h(7), ptr_post(x5, 8)));
+ TEST_INSTRUCTION("A178EB4D", ld4(v1.h(7), v2.h(7), v3.h(7), v4.h(7), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A1B0604D", ld4(v1.s(3), v2.s(3), v3.s(3), v4.s(3), ptr(x5)));
+ TEST_INSTRUCTION("A1B0FF4D", ld4(v1.s(3), v2.s(3), v3.s(3), v4.s(3), ptr_post(x5, 16)));
+ TEST_INSTRUCTION("A1B0EB4D", ld4(v1.s(3), v2.s(3), v3.s(3), v4.s(3), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A1A4604D", ld4(v1.d(1), v2.d(1), v3.d(1), v4.d(1), ptr(x5)));
+ TEST_INSTRUCTION("A1A4FF4D", ld4(v1.d(1), v2.d(1), v3.d(1), v4.d(1), ptr_post(x5, 32)));
+ TEST_INSTRUCTION("A1A4EB4D", ld4(v1.d(1), v2.d(1), v3.d(1), v4.d(1), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A100400C", ld4(v1.b8(), v2.b8(), v3.b8(), v4.b8(), ptr(x5)));
+ TEST_INSTRUCTION("A100DF0C", ld4(v1.b8(), v2.b8(), v3.b8(), v4.b8(), ptr_post(x5, 32)));
+ TEST_INSTRUCTION("A100CB0C", ld4(v1.b8(), v2.b8(), v3.b8(), v4.b8(), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A100404C", ld4(v1.b16(), v2.b16(), v3.b16(), v4.b16(), ptr(x5)));
+ TEST_INSTRUCTION("A100DF4C", ld4(v1.b16(), v2.b16(), v3.b16(), v4.b16(), ptr_post(x5, 64)));
+ TEST_INSTRUCTION("A100CB4C", ld4(v1.b16(), v2.b16(), v3.b16(), v4.b16(), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A104400C", ld4(v1.h4(), v2.h4(), v3.h4(), v4.h4(), ptr(x5)));
+ TEST_INSTRUCTION("A104DF0C", ld4(v1.h4(), v2.h4(), v3.h4(), v4.h4(), ptr_post(x5, 32)));
+ TEST_INSTRUCTION("A104CB0C", ld4(v1.h4(), v2.h4(), v3.h4(), v4.h4(), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A104404C", ld4(v1.h8(), v2.h8(), v3.h8(), v4.h8(), ptr(x5)));
+ TEST_INSTRUCTION("A104DF4C", ld4(v1.h8(), v2.h8(), v3.h8(), v4.h8(), ptr_post(x5, 64)));
+ TEST_INSTRUCTION("A104CB4C", ld4(v1.h8(), v2.h8(), v3.h8(), v4.h8(), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A108400C", ld4(v1.s2(), v2.s2(), v3.s2(), v4.s2(), ptr(x5)));
+ TEST_INSTRUCTION("A108DF0C", ld4(v1.s2(), v2.s2(), v3.s2(), v4.s2(), ptr_post(x5, 32)));
+ TEST_INSTRUCTION("A108CB0C", ld4(v1.s2(), v2.s2(), v3.s2(), v4.s2(), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A108404C", ld4(v1.s4(), v2.s4(), v3.s4(), v4.s4(), ptr(x5)));
+ TEST_INSTRUCTION("A108DF4C", ld4(v1.s4(), v2.s4(), v3.s4(), v4.s4(), ptr_post(x5, 64)));
+ TEST_INSTRUCTION("A108CB4C", ld4(v1.s4(), v2.s4(), v3.s4(), v4.s4(), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A10C404C", ld4(v1.d2(), v2.d2(), v3.d2(), v4.d2(), ptr(x5)));
+ TEST_INSTRUCTION("A10CDF4C", ld4(v1.d2(), v2.d2(), v3.d2(), v4.d2(), ptr_post(x5, 64)));
+ TEST_INSTRUCTION("A10CCB4C", ld4(v1.d2(), v2.d2(), v3.d2(), v4.d2(), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A1E0600D", ld4r(v1.b8(), v2.b8(), v3.b8(), v4.b8(), ptr(x5)));
+ TEST_INSTRUCTION("A1E0FF0D", ld4r(v1.b8(), v2.b8(), v3.b8(), v4.b8(), ptr_post(x5, 4)));
+ TEST_INSTRUCTION("A1E0EB0D", ld4r(v1.b8(), v2.b8(), v3.b8(), v4.b8(), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A1E0604D", ld4r(v1.b16(), v2.b16(), v3.b16(), v4.b16(), ptr(x5)));
+ TEST_INSTRUCTION("A1E0FF4D", ld4r(v1.b16(), v2.b16(), v3.b16(), v4.b16(), ptr_post(x5, 4)));
+ TEST_INSTRUCTION("A1E0EB4D", ld4r(v1.b16(), v2.b16(), v3.b16(), v4.b16(), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A1E4600D", ld4r(v1.h4(), v2.h4(), v3.h4(), v4.h4(), ptr(x5)));
+ TEST_INSTRUCTION("A1E4FF0D", ld4r(v1.h4(), v2.h4(), v3.h4(), v4.h4(), ptr_post(x5, 8)));
+ TEST_INSTRUCTION("A1E4EB0D", ld4r(v1.h4(), v2.h4(), v3.h4(), v4.h4(), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A1E4604D", ld4r(v1.h8(), v2.h8(), v3.h8(), v4.h8(), ptr(x5)));
+ TEST_INSTRUCTION("A1E4FF4D", ld4r(v1.h8(), v2.h8(), v3.h8(), v4.h8(), ptr_post(x5, 8)));
+ TEST_INSTRUCTION("A1E4EB4D", ld4r(v1.h8(), v2.h8(), v3.h8(), v4.h8(), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A1E8600D", ld4r(v1.s2(), v2.s2(), v3.s2(), v4.s2(), ptr(x5)));
+ TEST_INSTRUCTION("A1E8FF0D", ld4r(v1.s2(), v2.s2(), v3.s2(), v4.s2(), ptr_post(x5, 16)));
+ TEST_INSTRUCTION("A1E8EB0D", ld4r(v1.s2(), v2.s2(), v3.s2(), v4.s2(), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A1E8604D", ld4r(v1.s4(), v2.s4(), v3.s4(), v4.s4(), ptr(x5)));
+ TEST_INSTRUCTION("A1E8FF4D", ld4r(v1.s4(), v2.s4(), v3.s4(), v4.s4(), ptr_post(x5, 16)));
+ TEST_INSTRUCTION("A1E8EB4D", ld4r(v1.s4(), v2.s4(), v3.s4(), v4.s4(), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A1EC604D", ld4r(v1.d2(), v2.d2(), v3.d2(), v4.d2(), ptr(x5)));
+ TEST_INSTRUCTION("A1ECFF4D", ld4r(v1.d2(), v2.d2(), v3.d2(), v4.d2(), ptr_post(x5, 32)));
+ TEST_INSTRUCTION("A1ECEB4D", ld4r(v1.d2(), v2.d2(), v3.d2(), v4.d2(), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("8109402C", ldnp(s1, s2, ptr(x12)));
+ TEST_INSTRUCTION("8189402C", ldnp(s1, s2, ptr(x12, 4)));
+ TEST_INSTRUCTION("8109702C", ldnp(s1, s2, ptr(x12, -128)));
+ TEST_INSTRUCTION("E10B402C", ldnp(s1, s2, ptr(sp)));
+ TEST_INSTRUCTION("E18B402C", ldnp(s1, s2, ptr(sp, 4)));
+ TEST_INSTRUCTION("E10B502C", ldnp(s1, s2, ptr(sp, 128)));
+ TEST_INSTRUCTION("8109406C", ldnp(d1, d2, ptr(x12)));
+ TEST_INSTRUCTION("8189406C", ldnp(d1, d2, ptr(x12, 8)));
+ TEST_INSTRUCTION("8109786C", ldnp(d1, d2, ptr(x12, -128)));
+ TEST_INSTRUCTION("E10B406C", ldnp(d1, d2, ptr(sp)));
+ TEST_INSTRUCTION("E18B406C", ldnp(d1, d2, ptr(sp, 8)));
+ TEST_INSTRUCTION("E10B486C", ldnp(d1, d2, ptr(sp, 128)));
+ TEST_INSTRUCTION("810940AC", ldnp(q1, q2, ptr(x12)));
+ TEST_INSTRUCTION("818940AC", ldnp(q1, q2, ptr(x12, 16)));
+ TEST_INSTRUCTION("81097CAC", ldnp(q1, q2, ptr(x12, -128)));
+ TEST_INSTRUCTION("E10B40AC", ldnp(q1, q2, ptr(sp)));
+ TEST_INSTRUCTION("E18B40AC", ldnp(q1, q2, ptr(sp, 16)));
+ TEST_INSTRUCTION("E10B44AC", ldnp(q1, q2, ptr(sp, 128)));
+ TEST_INSTRUCTION("8109402D", ldp(s1, s2, ptr(x12)));
+ TEST_INSTRUCTION("8189402D", ldp(s1, s2, ptr(x12, 4)));
+ TEST_INSTRUCTION("8109702D", ldp(s1, s2, ptr(x12, -128)));
+ TEST_INSTRUCTION("8189C02D", ldp(s1, s2, ptr_pre(x12, 4)));
+ TEST_INSTRUCTION("8189C02C", ldp(s1, s2, ptr_post(x12, 4)));
+ TEST_INSTRUCTION("E10B402D", ldp(s1, s2, ptr(sp)));
+ TEST_INSTRUCTION("E18B402D", ldp(s1, s2, ptr(sp, 4)));
+ TEST_INSTRUCTION("E10B502D", ldp(s1, s2, ptr(sp, 128)));
+ TEST_INSTRUCTION("E18BC02C", ldp(s1, s2, ptr_post(sp, 4)));
+ TEST_INSTRUCTION("E18BC02D", ldp(s1, s2, ptr_pre(sp, 4)));
+ TEST_INSTRUCTION("8109406D", ldp(d1, d2, ptr(x12)));
+ TEST_INSTRUCTION("8189406D", ldp(d1, d2, ptr(x12, 8)));
+ TEST_INSTRUCTION("8109786D", ldp(d1, d2, ptr(x12, -128)));
+ TEST_INSTRUCTION("8189C06D", ldp(d1, d2, ptr_pre(x12, 8)));
+ TEST_INSTRUCTION("8189C06C", ldp(d1, d2, ptr_post(x12, 8)));
+ TEST_INSTRUCTION("E10B406D", ldp(d1, d2, ptr(sp)));
+ TEST_INSTRUCTION("E18B406D", ldp(d1, d2, ptr(sp, 8)));
+ TEST_INSTRUCTION("E10B486D", ldp(d1, d2, ptr(sp, 128)));
+ TEST_INSTRUCTION("E18BC06D", ldp(d1, d2, ptr_pre(sp, 8)));
+ TEST_INSTRUCTION("E18BC06C", ldp(d1, d2, ptr_post(sp, 8)));
+ TEST_INSTRUCTION("810940AD", ldp(q1, q2, ptr(x12)));
+ TEST_INSTRUCTION("818940AD", ldp(q1, q2, ptr(x12, 16)));
+ TEST_INSTRUCTION("81097CAD", ldp(q1, q2, ptr(x12, -128)));
+ TEST_INSTRUCTION("8189C0AD", ldp(q1, q2, ptr_pre(x12, 16)));
+ TEST_INSTRUCTION("8189C0AC", ldp(q1, q2, ptr_post(x12, 16)));
+ TEST_INSTRUCTION("E10B40AD", ldp(q1, q2, ptr(sp)));
+ TEST_INSTRUCTION("E18B40AD", ldp(q1, q2, ptr(sp, 16)));
+ TEST_INSTRUCTION("E10B44AD", ldp(q1, q2, ptr(sp, 128)));
+ TEST_INSTRUCTION("E18BC0AD", ldp(q1, q2, ptr_pre(sp, 16)));
+ TEST_INSTRUCTION("E18BC0AC", ldp(q1, q2, ptr_post(sp, 16)));
+ TEST_INSTRUCTION("4100403D", ldr(b1, ptr(x2)));
+ TEST_INSTRUCTION("4114403C", ldr(b1, ptr_post(x2, 1)));
+ TEST_INSTRUCTION("4104403D", ldr(b1, ptr(x2, 1)));
+ TEST_INSTRUCTION("411C403C", ldr(b1, ptr_pre(x2, 1)));
+ TEST_INSTRUCTION("4114483C", ldr(b1, ptr_post(x2, 129)));
+ TEST_INSTRUCTION("4100407D", ldr(h1, ptr(x2)));
+ TEST_INSTRUCTION("4124407C", ldr(h1, ptr_post(x2, 2)));
+ TEST_INSTRUCTION("4104407D", ldr(h1, ptr(x2, 2)));
+ TEST_INSTRUCTION("412C407C", ldr(h1, ptr_pre(x2, 2)));
+ TEST_INSTRUCTION("4124487C", ldr(h1, ptr_post(x2, 130)));
+ TEST_INSTRUCTION("410040BD", ldr(s1, ptr(x2)));
+ TEST_INSTRUCTION("414440BC", ldr(s1, ptr_post(x2, 4)));
+ TEST_INSTRUCTION("410440BD", ldr(s1, ptr(x2, 4)));
+ TEST_INSTRUCTION("414C40BC", ldr(s1, ptr_pre(x2, 4)));
+ TEST_INSTRUCTION("414448BC", ldr(s1, ptr_post(x2, 132)));
+ TEST_INSTRUCTION("410040FD", ldr(d1, ptr(x2)));
+ TEST_INSTRUCTION("418440FC", ldr(d1, ptr_post(x2, 8)));
+ TEST_INSTRUCTION("410440FD", ldr(d1, ptr(x2, 8)));
+ TEST_INSTRUCTION("418C40FC", ldr(d1, ptr_pre(x2, 8)));
+ TEST_INSTRUCTION("414448FC", ldr(d1, ptr_post(x2, 132)));
+ TEST_INSTRUCTION("4168633C", ldr(b1, ptr(x2, x3)));
+ TEST_INSTRUCTION("4148633C", ldr(b1, ptr(x2, w3, uxtw(0))));
+ TEST_INSTRUCTION("41C8633C", ldr(b1, ptr(x2, w3, sxtw(0))));
+ TEST_INSTRUCTION("4168637C", ldr(h1, ptr(x2, x3)));
+ TEST_INSTRUCTION("4178637C", ldr(h1, ptr(x2, x3, lsl(1))));
+ TEST_INSTRUCTION("4148637C", ldr(h1, ptr(x2, w3, uxtw(0))));
+ TEST_INSTRUCTION("4158637C", ldr(h1, ptr(x2, w3, uxtw(1))));
+ TEST_INSTRUCTION("41C8637C", ldr(h1, ptr(x2, w3, sxtw(0))));
+ TEST_INSTRUCTION("41D8637C", ldr(h1, ptr(x2, w3, sxtw(1))));
+ TEST_INSTRUCTION("416863BC", ldr(s1, ptr(x2, x3)));
+ TEST_INSTRUCTION("417863BC", ldr(s1, ptr(x2, x3, lsl(2))));
+ TEST_INSTRUCTION("414863BC", ldr(s1, ptr(x2, w3, uxtw(0))));
+ TEST_INSTRUCTION("415863BC", ldr(s1, ptr(x2, w3, uxtw(2))));
+ TEST_INSTRUCTION("41C863BC", ldr(s1, ptr(x2, w3, sxtw(0))));
+ TEST_INSTRUCTION("41D863BC", ldr(s1, ptr(x2, w3, sxtw(2))));
+ TEST_INSTRUCTION("416863FC", ldr(d1, ptr(x2, x3)));
+ TEST_INSTRUCTION("417863FC", ldr(d1, ptr(x2, x3, lsl(3))));
+ TEST_INSTRUCTION("414863FC", ldr(d1, ptr(x2, w3, uxtw(0))));
+ TEST_INSTRUCTION("415863FC", ldr(d1, ptr(x2, w3, uxtw(3))));
+ TEST_INSTRUCTION("41C863FC", ldr(d1, ptr(x2, w3, sxtw(0))));
+ TEST_INSTRUCTION("41D863FC", ldr(d1, ptr(x2, w3, sxtw(3))));
+ TEST_INSTRUCTION("4104403D", ldr(b1, ptr(x2, 1)));
+ TEST_INSTRUCTION("41F05F3C", ldr(b1, ptr(x2, -1))); // LDUR
+ TEST_INSTRUCTION("4110407C", ldr(h1, ptr(x2, 1))); // LDUR
+ TEST_INSTRUCTION("41F05F7C", ldr(h1, ptr(x2, -1))); // LDUR
+ TEST_INSTRUCTION("411040BC", ldr(s1, ptr(x2, 1))); // LDUR
+ TEST_INSTRUCTION("41F05FBC", ldr(s1, ptr(x2, -1))); // LDUR
+ TEST_INSTRUCTION("411040FC", ldr(d1, ptr(x2, 1))); // LDUR
+ TEST_INSTRUCTION("41F05FFC", ldr(d1, ptr(x2, -1))); // LDUR
+ TEST_INSTRUCTION("8101403C", ldur(b1, ptr(x12)));
+ TEST_INSTRUCTION("8131403C", ldur(b1, ptr(x12, 3)));
+ TEST_INSTRUCTION("8131463C", ldur(b1, ptr(x12, 99)));
+ TEST_INSTRUCTION("81F14F3C", ldur(b1, ptr(x12, 255)));
+ TEST_INSTRUCTION("8101503C", ldur(b1, ptr(x12, -256)));
+ TEST_INSTRUCTION("E103403C", ldur(b1, ptr(sp)));
+ TEST_INSTRUCTION("E153483C", ldur(b1, ptr(sp, 133)));
+ TEST_INSTRUCTION("8101407C", ldur(h1, ptr(x12)));
+ TEST_INSTRUCTION("8131407C", ldur(h1, ptr(x12, 3)));
+ TEST_INSTRUCTION("8131467C", ldur(h1, ptr(x12, 99)));
+ TEST_INSTRUCTION("81F14F7C", ldur(h1, ptr(x12, 255)));
+ TEST_INSTRUCTION("8101507C", ldur(h1, ptr(x12, -256)));
+ TEST_INSTRUCTION("E103407C", ldur(h1, ptr(sp)));
+ TEST_INSTRUCTION("E153487C", ldur(h1, ptr(sp, 133)));
+ TEST_INSTRUCTION("810140BC", ldur(s1, ptr(x12)));
+ TEST_INSTRUCTION("813140BC", ldur(s1, ptr(x12, 3)));
+ TEST_INSTRUCTION("813146BC", ldur(s1, ptr(x12, 99)));
+ TEST_INSTRUCTION("81F14FBC", ldur(s1, ptr(x12, 255)));
+ TEST_INSTRUCTION("810150BC", ldur(s1, ptr(x12, -256)));
+ TEST_INSTRUCTION("E10340BC", ldur(s1, ptr(sp)));
+ TEST_INSTRUCTION("E15348BC", ldur(s1, ptr(sp, 133)));
+ TEST_INSTRUCTION("810140FC", ldur(d1, ptr(x12)));
+ TEST_INSTRUCTION("813140FC", ldur(d1, ptr(x12, 3)));
+ TEST_INSTRUCTION("813146FC", ldur(d1, ptr(x12, 99)));
+ TEST_INSTRUCTION("81F14FFC", ldur(d1, ptr(x12, 255)));
+ TEST_INSTRUCTION("810150FC", ldur(d1, ptr(x12, -256)));
+ TEST_INSTRUCTION("E10340FC", ldur(d1, ptr(sp)));
+ TEST_INSTRUCTION("E15348FC", ldur(d1, ptr(sp, 133)));
+ TEST_INSTRUCTION("8101C03C", ldur(q1, ptr(x12)));
+ TEST_INSTRUCTION("8131C03C", ldur(q1, ptr(x12, 3)));
+ TEST_INSTRUCTION("8131C63C", ldur(q1, ptr(x12, 99)));
+ TEST_INSTRUCTION("81F1CF3C", ldur(q1, ptr(x12, 255)));
+ TEST_INSTRUCTION("8101D03C", ldur(q1, ptr(x12, -256)));
+ TEST_INSTRUCTION("E103C03C", ldur(q1, ptr(sp)));
+ TEST_INSTRUCTION("E153C83C", ldur(q1, ptr(sp, 133)));
+ TEST_INSTRUCTION("4194230E", mla(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4194630E", mla(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4194A30E", mla(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4194234E", mla(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4194634E", mla(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4194A34E", mla(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4100432F", mla(v1.h4(), v2.h4(), v3.h(0)));
+ TEST_INSTRUCTION("4100532F", mla(v1.h4(), v2.h4(), v3.h(1)));
+ TEST_INSTRUCTION("4100632F", mla(v1.h4(), v2.h4(), v3.h(2)));
+ TEST_INSTRUCTION("4100732F", mla(v1.h4(), v2.h4(), v3.h(3)));
+ TEST_INSTRUCTION("4108436F", mla(v1.h8(), v2.h8(), v3.h(4)));
+ TEST_INSTRUCTION("4108536F", mla(v1.h8(), v2.h8(), v3.h(5)));
+ TEST_INSTRUCTION("4108636F", mla(v1.h8(), v2.h8(), v3.h(6)));
+ TEST_INSTRUCTION("4108736F", mla(v1.h8(), v2.h8(), v3.h(7)));
+ TEST_INSTRUCTION("4100832F", mla(v1.s2(), v2.s2(), v3.s(0)));
+ TEST_INSTRUCTION("4100A32F", mla(v1.s2(), v2.s2(), v3.s(1)));
+ TEST_INSTRUCTION("4108836F", mla(v1.s4(), v2.s4(), v3.s(2)));
+ TEST_INSTRUCTION("4108A36F", mla(v1.s4(), v2.s4(), v3.s(3)));
+ TEST_INSTRUCTION("4194232E", mls(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4194632E", mls(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4194A32E", mls(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4194236E", mls(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4194636E", mls(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4194A36E", mls(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4140432F", mls(v1.h4(), v2.h4(), v3.h(0)));
+ TEST_INSTRUCTION("4140532F", mls(v1.h4(), v2.h4(), v3.h(1)));
+ TEST_INSTRUCTION("4140632F", mls(v1.h4(), v2.h4(), v3.h(2)));
+ TEST_INSTRUCTION("4140732F", mls(v1.h4(), v2.h4(), v3.h(3)));
+ TEST_INSTRUCTION("4148436F", mls(v1.h8(), v2.h8(), v3.h(4)));
+ TEST_INSTRUCTION("4148536F", mls(v1.h8(), v2.h8(), v3.h(5)));
+ TEST_INSTRUCTION("4148636F", mls(v1.h8(), v2.h8(), v3.h(6)));
+ TEST_INSTRUCTION("4148736F", mls(v1.h8(), v2.h8(), v3.h(7)));
+ TEST_INSTRUCTION("4140832F", mls(v1.s2(), v2.s2(), v3.s(0)));
+ TEST_INSTRUCTION("4140A32F", mls(v1.s2(), v2.s2(), v3.s(1)));
+ TEST_INSTRUCTION("4148836F", mls(v1.s4(), v2.s4(), v3.s(2)));
+ TEST_INSTRUCTION("4148A36F", mls(v1.s4(), v2.s4(), v3.s(3)));
+ TEST_INSTRUCTION("4F04035E", mov(b15, v2.b(1)));
+ TEST_INSTRUCTION("4F04065E", mov(h15, v2.h(1)));
+ TEST_INSTRUCTION("4F040C5E", mov(s15, v2.s(1)));
+ TEST_INSTRUCTION("4F04185E", mov(d15, v2.d(1)));
+ TEST_INSTRUCTION("411C014E", mov(v1.b(0), w2));
+ TEST_INSTRUCTION("411C074E", mov(v1.b(3), w2));
+ TEST_INSTRUCTION("411C0D4E", mov(v1.b(6), w2));
+ TEST_INSTRUCTION("411C134E", mov(v1.b(9), w2));
+ TEST_INSTRUCTION("411C1F4E", mov(v1.b(15), w2));
+ TEST_INSTRUCTION("411C024E", mov(v1.h(0), w2));
+ TEST_INSTRUCTION("411C0E4E", mov(v1.h(3), w2));
+ TEST_INSTRUCTION("411C1E4E", mov(v1.h(7), w2));
+ TEST_INSTRUCTION("411C044E", mov(v1.s(0), w2));
+ TEST_INSTRUCTION("411C0C4E", mov(v1.s(1), w2));
+ TEST_INSTRUCTION("411C144E", mov(v1.s(2), w2));
+ TEST_INSTRUCTION("411C1C4E", mov(v1.s(3), w2));
+ TEST_INSTRUCTION("411C084E", mov(v1.d(0), x2));
+ TEST_INSTRUCTION("411C184E", mov(v1.d(1), x2));
+ TEST_INSTRUCTION("417C016E", mov(v1.b(0), v2.b(15)));
+ TEST_INSTRUCTION("4174036E", mov(v1.b(1), v2.b(14)));
+ TEST_INSTRUCTION("4174026E", mov(v1.h(0), v2.h(7)));
+ TEST_INSTRUCTION("4164066E", mov(v1.h(1), v2.h(6)));
+ TEST_INSTRUCTION("4164046E", mov(v1.s(0), v2.s(3)));
+ TEST_INSTRUCTION("41440C6E", mov(v1.s(1), v2.s(2)));
+ TEST_INSTRUCTION("4144086E", mov(v1.d(0), v2.d(1)));
+ TEST_INSTRUCTION("4104186E", mov(v1.d(1), v2.d(0)));
+ TEST_INSTRUCTION("41E5010F", movi(v1.b8(), 42));
+ TEST_INSTRUCTION("4185010F", movi(v1.h4(), 42));
+ TEST_INSTRUCTION("4105010F", movi(v1.s2(), 42));
+ TEST_INSTRUCTION("C1E5022F", movi(d1, 0x00FF0000FFFFFF00u));
+ TEST_INSTRUCTION("41E5014F", movi(v1.b16(), 42));
+ TEST_INSTRUCTION("4185014F", movi(v1.h8(), 42));
+ TEST_INSTRUCTION("4105014F", movi(v1.s4(), 42));
+ TEST_INSTRUCTION("E167074F", movi(v1.s4(), 0xFF, lsl(24)));
+ TEST_INSTRUCTION("E1D7074F", movi(v1.s4(), 0xFF, msl(16)));
+ TEST_INSTRUCTION("C1E5026F", movi(v1.d2(), 0x00FF0000FFFFFF00u));
+ TEST_INSTRUCTION("419C230E", mul(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("419C630E", mul(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("419CA30E", mul(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("419C234E", mul(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("419C634E", mul(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("419CA34E", mul(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4158202E", mvn(v1.b8(), v2.b8()));
+ TEST_INSTRUCTION("4158206E", mvn(v1.b16(), v2.b16()));
+ TEST_INSTRUCTION("4185012F", mvni(v1.h4(), 42));
+ TEST_INSTRUCTION("4105012F", mvni(v1.s2(), 42));
+ TEST_INSTRUCTION("4185016F", mvni(v1.h8(), 42));
+ TEST_INSTRUCTION("4105016F", mvni(v1.s4(), 42));
+ TEST_INSTRUCTION("41B8202E", neg(v1.b8(), v2.b8()));
+ TEST_INSTRUCTION("41B8602E", neg(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("41B8A02E", neg(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41B8E07E", neg(d1, d2));
+ TEST_INSTRUCTION("41B8206E", neg(v1.b16(), v2.b16()));
+ TEST_INSTRUCTION("41B8606E", neg(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("41B8A06E", neg(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("41B8E06E", neg(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("4158202E", not_(v1.b8(), v2.b8()));
+ TEST_INSTRUCTION("4158206E", not_(v1.b16(), v2.b16()));
+ TEST_INSTRUCTION("411CE30E", orn(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("411CE34E", orn(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("411CA30E", orr(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("411CA34E", orr(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("E197070F", orr(v1.h4(), 255));
+ TEST_INSTRUCTION("E1B7070F", orr(v1.h4(), 255, lsl(8)));
+ TEST_INSTRUCTION("E197074F", orr(v1.h8(), 255));
+ TEST_INSTRUCTION("E1B7074F", orr(v1.h8(), 255, lsl(8)));
+ TEST_INSTRUCTION("E117070F", orr(v1.s2(), 255));
+ TEST_INSTRUCTION("E137070F", orr(v1.s2(), 255, lsl(8)));
+ TEST_INSTRUCTION("E117074F", orr(v1.s4(), 255));
+ TEST_INSTRUCTION("E177074F", orr(v1.s4(), 255, lsl(24)));
+ TEST_INSTRUCTION("419C232E", pmul(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("419C236E", pmul(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("41E0230E", pmull(v1.h8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("41E0E30E", pmull(q1, d2, d3));
+ TEST_INSTRUCTION("41E0234E", pmull2(v1.h8(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("41E0E34E", pmull2(q1, v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4140232E", raddhn(v1.b8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4140632E", raddhn(v1.h4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4140A32E", raddhn(v1.s2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4140236E", raddhn2(v1.b16(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4140636E", raddhn2(v1.h8(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4140A36E", raddhn2(v1.s4(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("418C63CE", rax1(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4158602E", rbit(v1.b8(), v2.b8()));
+ TEST_INSTRUCTION("4158606E", rbit(v1.b16(), v2.b16()));
+ TEST_INSTRUCTION("4118200E", rev16(v1.b8(), v2.b8()));
+ TEST_INSTRUCTION("4118204E", rev16(v1.b16(), v2.b16()));
+ TEST_INSTRUCTION("4108202E", rev32(v1.b8(), v2.b8()));
+ TEST_INSTRUCTION("4108206E", rev32(v1.b16(), v2.b16()));
+ TEST_INSTRUCTION("4108602E", rev32(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("4108606E", rev32(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("4108200E", rev64(v1.b8(), v2.b8()));
+ TEST_INSTRUCTION("4108204E", rev64(v1.b16(), v2.b16()));
+ TEST_INSTRUCTION("4108600E", rev64(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("4108604E", rev64(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("4108A00E", rev64(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("4108A04E", rev64(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("418C090F", rshrn(v1.b8(), v2.h8(), 7));
+ TEST_INSTRUCTION("418C110F", rshrn(v1.h4(), v2.s4(), 15));
+ TEST_INSTRUCTION("418C210F", rshrn(v1.s2(), v2.d2(), 31));
+ TEST_INSTRUCTION("418C094F", rshrn2(v1.b16(), v2.h8(), 7));
+ TEST_INSTRUCTION("418C114F", rshrn2(v1.h8(), v2.s4(), 15));
+ TEST_INSTRUCTION("418C214F", rshrn2(v1.s4(), v2.d2(), 31));
+ TEST_INSTRUCTION("4160232E", rsubhn(v1.b8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4160632E", rsubhn(v1.h4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4160A32E", rsubhn(v1.s2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4160236E", rsubhn2(v1.b16(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4160636E", rsubhn2(v1.h8(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4160A36E", rsubhn2(v1.s4(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("417C230E", saba(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("417C630E", saba(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("417CA30E", saba(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("417C234E", saba(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("417C634E", saba(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("417CA34E", saba(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4150230E", sabal(v1.h8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4150630E", sabal(v1.s4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4150A30E", sabal(v1.d2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4150234E", sabal2(v1.h8(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4150634E", sabal2(v1.s4(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4150A34E", sabal2(v1.d2(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4174230E", sabd(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4174630E", sabd(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4174A30E", sabd(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4174234E", sabd(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4174634E", sabd(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4174A34E", sabd(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4170230E", sabdl(v1.h8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4170630E", sabdl(v1.s4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4170A30E", sabdl(v1.d2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4170234E", sabdl2(v1.h8(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4170634E", sabdl2(v1.s4(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4170A34E", sabdl2(v1.d2(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4168200E", sadalp(v1.h4(), v2.b8()));
+ TEST_INSTRUCTION("4168600E", sadalp(v1.s2(), v2.h4()));
+ TEST_INSTRUCTION("4168A00E", sadalp(d1, v2.s2()));
+ TEST_INSTRUCTION("4168204E", sadalp(v1.h8(), v2.b16()));
+ TEST_INSTRUCTION("4168604E", sadalp(v1.s4(), v2.h8()));
+ TEST_INSTRUCTION("4168A04E", sadalp(v1.d2(), v2.s4()));
+ TEST_INSTRUCTION("4100230E", saddl(v1.h8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4100630E", saddl(v1.s4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4100A30E", saddl(v1.d2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4100234E", saddl2(v1.h8(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4100634E", saddl2(v1.s4(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4100A34E", saddl2(v1.d2(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4128200E", saddlp(v1.h4(), v2.b8()));
+ TEST_INSTRUCTION("4128600E", saddlp(v1.s2(), v2.h4()));
+ TEST_INSTRUCTION("4128A00E", saddlp(d1, v2.s2()));
+ TEST_INSTRUCTION("4128204E", saddlp(v1.h8(), v2.b16()));
+ TEST_INSTRUCTION("4128604E", saddlp(v1.s4(), v2.h8()));
+ TEST_INSTRUCTION("4128A04E", saddlp(v1.d2(), v2.s4()));
+ TEST_INSTRUCTION("4138300E", saddlv(h1, v2.b8()));
+ TEST_INSTRUCTION("4138304E", saddlv(h1, v2.b16()));
+ TEST_INSTRUCTION("4138700E", saddlv(s1, v2.h4()));
+ TEST_INSTRUCTION("4138704E", saddlv(s1, v2.h8()));
+ TEST_INSTRUCTION("4138B04E", saddlv(d1, v2.s4()));
+ TEST_INSTRUCTION("4110230E", saddw(v1.h8(), v2.h8(), v3.b8()));
+ TEST_INSTRUCTION("4110630E", saddw(v1.s4(), v2.s4(), v3.h4()));
+ TEST_INSTRUCTION("4110A30E", saddw(v1.d2(), v2.d2(), v3.s2()));
+ TEST_INSTRUCTION("4110234E", saddw2(v1.h8(), v2.h8(), v3.b16()));
+ TEST_INSTRUCTION("4110634E", saddw2(v1.s4(), v2.s4(), v3.h8()));
+ TEST_INSTRUCTION("4110A34E", saddw2(v1.d2(), v2.d2(), v3.s4()));
+ TEST_INSTRUCTION("4100E21E", scvtf(h1, w2));
+ TEST_INSTRUCTION("4100221E", scvtf(s1, w2));
+ TEST_INSTRUCTION("4100621E", scvtf(d1, w2));
+ TEST_INSTRUCTION("4100E29E", scvtf(h1, x2));
+ TEST_INSTRUCTION("4100229E", scvtf(s1, x2));
+ TEST_INSTRUCTION("4100629E", scvtf(d1, x2));
+ TEST_INSTRUCTION("41D8795E", scvtf(h1, h2));
+ TEST_INSTRUCTION("41D8215E", scvtf(s1, s2));
+ TEST_INSTRUCTION("41D8615E", scvtf(d1, d2));
+ TEST_INSTRUCTION("41D8790E", scvtf(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("41D8210E", scvtf(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41D8794E", scvtf(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("41D8214E", scvtf(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("41D8614E", scvtf(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("41E0C21E", scvtf(h1, w2, 8));
+ TEST_INSTRUCTION("41E0021E", scvtf(s1, w2, 8));
+ TEST_INSTRUCTION("41E0421E", scvtf(d1, w2, 8));
+ TEST_INSTRUCTION("41E0C29E", scvtf(h1, x2, 8));
+ TEST_INSTRUCTION("41E0029E", scvtf(s1, x2, 8));
+ TEST_INSTRUCTION("41E0429E", scvtf(d1, x2, 8));
+ TEST_INSTRUCTION("41E4185F", scvtf(h1, h2, 8));
+ TEST_INSTRUCTION("41E4385F", scvtf(s1, s2, 8));
+ TEST_INSTRUCTION("41E4785F", scvtf(d1, d2, 8));
+ TEST_INSTRUCTION("41E4180F", scvtf(v1.h4(), v2.h4(), 8));
+ TEST_INSTRUCTION("41E4380F", scvtf(v1.s2(), v2.s2(), 8));
+ TEST_INSTRUCTION("41E4184F", scvtf(v1.h8(), v2.h8(), 8));
+ TEST_INSTRUCTION("41E4384F", scvtf(v1.s4(), v2.s4(), 8));
+ TEST_INSTRUCTION("41E4784F", scvtf(v1.d2(), v2.d2(), 8));
+ TEST_INSTRUCTION("4194830E", sdot(v1.s2(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4194834E", sdot(v1.s4(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("41E0830F", sdot(v1.s2(), v2.b8(), v3.b4(0)));
+ TEST_INSTRUCTION("41E0A30F", sdot(v1.s2(), v2.b8(), v3.b4(1)));
+ TEST_INSTRUCTION("41E8830F", sdot(v1.s2(), v2.b8(), v3.b4(2)));
+ TEST_INSTRUCTION("41E8A30F", sdot(v1.s2(), v2.b8(), v3.b4(3)));
+ TEST_INSTRUCTION("41E0834F", sdot(v1.s4(), v2.b16(), v3.b4(0)));
+ TEST_INSTRUCTION("41E0A34F", sdot(v1.s4(), v2.b16(), v3.b4(1)));
+ TEST_INSTRUCTION("41E8834F", sdot(v1.s4(), v2.b16(), v3.b4(2)));
+ TEST_INSTRUCTION("41E8A34F", sdot(v1.s4(), v2.b16(), v3.b4(3)));
+ TEST_INSTRUCTION("4100035E", sha1c(q1, s2, v3.s4()));
+ TEST_INSTRUCTION("4108285E", sha1h(s1, s2));
+ TEST_INSTRUCTION("4120035E", sha1m(q1, s2, v3.s4()));
+ TEST_INSTRUCTION("4110035E", sha1p(q1, s2, v3.s4()));
+ TEST_INSTRUCTION("4130035E", sha1su0(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4118285E", sha1su1(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("4140035E", sha256h(q1, q2, v3.s4()));
+ TEST_INSTRUCTION("4150035E", sha256h2(q1, q2, v3.s4()));
+ TEST_INSTRUCTION("4128285E", sha256su0(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("4160035E", sha256su1(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4104230E", shadd(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4104630E", shadd(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4104A30E", shadd(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4104234E", shadd(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4104634E", shadd(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4104A34E", shadd(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41540F0F", shl(v1.b8(), v2.b8(), 7));
+ TEST_INSTRUCTION("41541F0F", shl(v1.h4(), v2.h4(), 15));
+ TEST_INSTRUCTION("41543F0F", shl(v1.s2(), v2.s2(), 31));
+ TEST_INSTRUCTION("41547F5F", shl(d1, d2, 63));
+ TEST_INSTRUCTION("41540F4F", shl(v1.b16(), v2.b16(), 7));
+ TEST_INSTRUCTION("41541F4F", shl(v1.h8(), v2.h8(), 15));
+ TEST_INSTRUCTION("41543F4F", shl(v1.s4(), v2.s4(), 31));
+ TEST_INSTRUCTION("41547F4F", shl(v1.d2(), v2.d2(), 63));
+ TEST_INSTRUCTION("4138212E", shll(v1.h8(), v2.b8(), 8));
+ TEST_INSTRUCTION("4138612E", shll(v1.s4(), v2.h4(), 16));
+ TEST_INSTRUCTION("4138A12E", shll(v1.d2(), v2.s2(), 32));
+ TEST_INSTRUCTION("4138216E", shll2(v1.h8(), v2.b16(), 8));
+ TEST_INSTRUCTION("4138616E", shll2(v1.s4(), v2.h8(), 16));
+ TEST_INSTRUCTION("4138A16E", shll2(v1.d2(), v2.s4(), 32));
+ TEST_INSTRUCTION("4184090F", shrn(v1.b8(), v2.h8(), 7));
+ TEST_INSTRUCTION("4184110F", shrn(v1.h4(), v2.s4(), 15));
+ TEST_INSTRUCTION("4184210F", shrn(v1.s2(), v2.d2(), 31));
+ TEST_INSTRUCTION("4184094F", shrn2(v1.b16(), v2.h8(), 7));
+ TEST_INSTRUCTION("4184114F", shrn2(v1.h8(), v2.s4(), 15));
+ TEST_INSTRUCTION("4184214F", shrn2(v1.s4(), v2.d2(), 31));
+ TEST_INSTRUCTION("4124230E", shsub(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4124630E", shsub(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4124A30E", shsub(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4124234E", shsub(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4124634E", shsub(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4124A34E", shsub(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41540F2F", sli(v1.b8(), v2.b8(), 7));
+ TEST_INSTRUCTION("41541F2F", sli(v1.h4(), v2.h4(), 15));
+ TEST_INSTRUCTION("41543F2F", sli(v1.s2(), v2.s2(), 31));
+ TEST_INSTRUCTION("41547F7F", sli(d1, d2, 63));
+ TEST_INSTRUCTION("41540F6F", sli(v1.b16(), v2.b16(), 7));
+ TEST_INSTRUCTION("41541F6F", sli(v1.h8(), v2.h8(), 15));
+ TEST_INSTRUCTION("41543F6F", sli(v1.s4(), v2.s4(), 31));
+ TEST_INSTRUCTION("41547F6F", sli(v1.d2(), v2.d2(), 63));
+ TEST_INSTRUCTION("41C063CE", sm3partw1(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41C463CE", sm3partw2(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("411043CE", sm3ss1(v1.s4(), v2.s4(), v3.s4(), v4.s4()));
+ TEST_INSTRUCTION("418044CE", sm3tt1a(v1.s4(), v2.s4(), v4.s(0)));
+ TEST_INSTRUCTION("41B044CE", sm3tt1a(v1.s4(), v2.s4(), v4.s(3)));
+ TEST_INSTRUCTION("418444CE", sm3tt1b(v1.s4(), v2.s4(), v4.s(0)));
+ TEST_INSTRUCTION("41B444CE", sm3tt1b(v1.s4(), v2.s4(), v4.s(3)));
+ TEST_INSTRUCTION("418844CE", sm3tt2a(v1.s4(), v2.s4(), v4.s(0)));
+ TEST_INSTRUCTION("41B844CE", sm3tt2a(v1.s4(), v2.s4(), v4.s(3)));
+ TEST_INSTRUCTION("418C44CE", sm3tt2b(v1.s4(), v2.s4(), v4.s(0)));
+ TEST_INSTRUCTION("41BC44CE", sm3tt2b(v1.s4(), v2.s4(), v4.s(3)));
+ TEST_INSTRUCTION("4184C0CE", sm4e(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("41C863CE", sm4ekey(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4164230E", smax(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4164630E", smax(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4164A30E", smax(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4164234E", smax(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4164634E", smax(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4164A34E", smax(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41A4230E", smaxp(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("41A4630E", smaxp(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41A4A30E", smaxp(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("41A4234E", smaxp(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("41A4634E", smaxp(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41A4A34E", smaxp(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41A8300E", smaxv(b1, v2.b8()));
+ TEST_INSTRUCTION("41A8304E", smaxv(b1, v2.b16()));
+ TEST_INSTRUCTION("41A8700E", smaxv(h1, v2.h4()));
+ TEST_INSTRUCTION("41A8704E", smaxv(h1, v2.h8()));
+ TEST_INSTRUCTION("41A8B04E", smaxv(s1, v2.s4()));
+ TEST_INSTRUCTION("416C230E", smin(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("416C630E", smin(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("416CA30E", smin(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("416C234E", smin(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("416C634E", smin(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("416CA34E", smin(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41AC230E", sminp(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("41AC630E", sminp(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41ACA30E", sminp(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("41AC234E", sminp(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("41AC634E", sminp(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41ACA34E", sminp(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41A8310E", sminv(b1, v2.b8()));
+ TEST_INSTRUCTION("41A8314E", sminv(b1, v2.b16()));
+ TEST_INSTRUCTION("41A8710E", sminv(h1, v2.h4()));
+ TEST_INSTRUCTION("41A8714E", sminv(h1, v2.h8()));
+ TEST_INSTRUCTION("41A8B14E", sminv(s1, v2.s4()));
+ TEST_INSTRUCTION("4180230E", smlal(v1.h8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4180630E", smlal(v1.s4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4180A30E", smlal(v1.d2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4120730F", smlal(v1.s4(), v2.h4(), v3.h(3)));
+ TEST_INSTRUCTION("4128A30F", smlal(v1.d2(), v2.s2(), v3.s(3)));
+ TEST_INSTRUCTION("4180234E", smlal2(v1.h8(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4180634E", smlal2(v1.s4(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4180A34E", smlal2(v1.d2(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4120734F", smlal2(v1.s4(), v2.h8(), v3.h(3)));
+ TEST_INSTRUCTION("4128A34F", smlal2(v1.d2(), v2.s4(), v3.s(3)));
+ TEST_INSTRUCTION("41A0230E", smlsl(v1.h8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("41A0630E", smlsl(v1.s4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41A0A30E", smlsl(v1.d2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4160730F", smlsl(v1.s4(), v2.h4(), v3.h(3)));
+ TEST_INSTRUCTION("4168A30F", smlsl(v1.d2(), v2.s2(), v3.s(3)));
+ TEST_INSTRUCTION("41A0234E", smlsl2(v1.h8(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("41A0634E", smlsl2(v1.s4(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41A0A34E", smlsl2(v1.d2(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4160734F", smlsl2(v1.s4(), v2.h8(), v3.h(3)));
+ TEST_INSTRUCTION("4168A34F", smlsl2(v1.d2(), v2.s4(), v3.s(3)));
+ TEST_INSTRUCTION("41A4834E", smmla(v1.s4(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("412C010E", smov(w1, v2.b(0)));
+ TEST_INSTRUCTION("412C1F0E", smov(w1, v2.b(15)));
+ TEST_INSTRUCTION("412C020E", smov(w1, v2.h(0)));
+ TEST_INSTRUCTION("412C1E0E", smov(w1, v2.h(7)));
+ TEST_INSTRUCTION("412C014E", smov(x1, v2.b(0)));
+ TEST_INSTRUCTION("412C1F4E", smov(x1, v2.b(15)));
+ TEST_INSTRUCTION("412C024E", smov(x1, v2.h(0)));
+ TEST_INSTRUCTION("412C1E4E", smov(x1, v2.h(7)));
+ TEST_INSTRUCTION("412C044E", smov(x1, v2.s(0)));
+ TEST_INSTRUCTION("412C1C4E", smov(x1, v2.s(3)));
+ TEST_INSTRUCTION("41C0230E", smull(v1.h8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("41C0630E", smull(v1.s4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41C0A30E", smull(v1.d2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("41A0730F", smull(v1.s4(), v2.h4(), v3.h(3)));
+ TEST_INSTRUCTION("41A8A30F", smull(v1.d2(), v2.s2(), v3.s(3)));
+ TEST_INSTRUCTION("41C0234E", smull2(v1.h8(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("41C0634E", smull2(v1.s4(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41C0A34E", smull2(v1.d2(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41A0734F", smull2(v1.s4(), v2.h8(), v3.h(3)));
+ TEST_INSTRUCTION("41A8A34F", smull2(v1.d2(), v2.s4(), v3.s(3)));
+ TEST_INSTRUCTION("4178205E", sqabs(b1, b2));
+ TEST_INSTRUCTION("4178605E", sqabs(h1, h2));
+ TEST_INSTRUCTION("4178A05E", sqabs(s1, s2));
+ TEST_INSTRUCTION("4178E05E", sqabs(d1, d2));
+ TEST_INSTRUCTION("4178200E", sqabs(v1.b8(), v2.b8()));
+ TEST_INSTRUCTION("4178600E", sqabs(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("4178A00E", sqabs(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("4178204E", sqabs(v1.b16(), v2.b16()));
+ TEST_INSTRUCTION("4178604E", sqabs(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("4178A04E", sqabs(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("4178E04E", sqabs(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("410C235E", sqadd(b1, b2, b3));
+ TEST_INSTRUCTION("410C635E", sqadd(h1, h2, h3));
+ TEST_INSTRUCTION("410CA35E", sqadd(s1, s2, s3));
+ TEST_INSTRUCTION("410CE35E", sqadd(d1, d2, d3));
+ TEST_INSTRUCTION("410C230E", sqadd(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("410C630E", sqadd(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("410CA30E", sqadd(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("410C234E", sqadd(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("410C634E", sqadd(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("410CA34E", sqadd(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("410CE34E", sqadd(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4190635E", sqdmlal(s1, h2, h3));
+ TEST_INSTRUCTION("4190A35E", sqdmlal(d1, s2, s3));
+ TEST_INSTRUCTION("4190630E", sqdmlal(v1.s4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4190A30E", sqdmlal(v1.d2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4130730F", sqdmlal(v1.s4(), v2.h4(), v3.h(3)));
+ TEST_INSTRUCTION("4138A30F", sqdmlal(v1.d2(), v2.s2(), v3.s(3)));
+ TEST_INSTRUCTION("4190634E", sqdmlal2(v1.s4(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4190A34E", sqdmlal2(v1.d2(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4130734F", sqdmlal2(v1.s4(), v2.h8(), v3.h(3)));
+ TEST_INSTRUCTION("4138A34F", sqdmlal2(v1.d2(), v2.s4(), v3.s(3)));
+ TEST_INSTRUCTION("41B0635E", sqdmlsl(s1, h2, h3));
+ TEST_INSTRUCTION("41B0A35E", sqdmlsl(d1, s2, s3));
+ TEST_INSTRUCTION("41B0630E", sqdmlsl(v1.s4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41B0A30E", sqdmlsl(v1.d2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4170730F", sqdmlsl(v1.s4(), v2.h4(), v3.h(3)));
+ TEST_INSTRUCTION("4178A30F", sqdmlsl(v1.d2(), v2.s2(), v3.s(3)));
+ TEST_INSTRUCTION("41B0634E", sqdmlsl2(v1.s4(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41B0A34E", sqdmlsl2(v1.d2(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4170734F", sqdmlsl2(v1.s4(), v2.h8(), v3.h(3)));
+ TEST_INSTRUCTION("4178A34F", sqdmlsl2(v1.d2(), v2.s4(), v3.s(3)));
+ TEST_INSTRUCTION("41B4635E", sqdmulh(h1, h2, h3));
+ TEST_INSTRUCTION("41B4A35E", sqdmulh(s1, s2, s3));
+ TEST_INSTRUCTION("41B4630E", sqdmulh(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41B4A30E", sqdmulh(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("41B4634E", sqdmulh(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41B4A34E", sqdmulh(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41C0730F", sqdmulh(v1.h4(), v2.h4(), v3.h(3)));
+ TEST_INSTRUCTION("41C8A30F", sqdmulh(v1.s2(), v2.s2(), v3.s(3)));
+ TEST_INSTRUCTION("41C0734F", sqdmulh(v1.h8(), v2.h8(), v3.h(3)));
+ TEST_INSTRUCTION("41C8A34F", sqdmulh(v1.s4(), v2.s4(), v3.s(3)));
+ TEST_INSTRUCTION("41D0635E", sqdmull(s1, h2, h3));
+ TEST_INSTRUCTION("41D0A35E", sqdmull(d1, s2, s3));
+ TEST_INSTRUCTION("41D0630E", sqdmull(v1.s4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41D0A30E", sqdmull(v1.d2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("41B0730F", sqdmull(v1.s4(), v2.h4(), v3.h(3)));
+ TEST_INSTRUCTION("41B8A30F", sqdmull(v1.d2(), v2.s2(), v3.s(3)));
+ TEST_INSTRUCTION("41D0634E", sqdmull2(v1.s4(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41D0A34E", sqdmull2(v1.d2(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41B0734F", sqdmull2(v1.s4(), v2.h8(), v3.h(3)));
+ TEST_INSTRUCTION("41B8A34F", sqdmull2(v1.d2(), v2.s4(), v3.s(3)));
+ TEST_INSTRUCTION("4178207E", sqneg(b1, b2));
+ TEST_INSTRUCTION("4178607E", sqneg(h1, h2));
+ TEST_INSTRUCTION("4178A07E", sqneg(s1, s2));
+ TEST_INSTRUCTION("4178E07E", sqneg(d1, d2));
+ TEST_INSTRUCTION("4178202E", sqneg(v1.b8(), v2.b8()));
+ TEST_INSTRUCTION("4178602E", sqneg(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("4178A02E", sqneg(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("4178206E", sqneg(v1.b16(), v2.b16()));
+ TEST_INSTRUCTION("4178606E", sqneg(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("4178A06E", sqneg(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("4178E06E", sqneg(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("4184437E", sqrdmlah(h1, h2, h3));
+ TEST_INSTRUCTION("4184837E", sqrdmlah(s1, s2, s3));
+ TEST_INSTRUCTION("4184432E", sqrdmlah(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4184832E", sqrdmlah(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("41D0732F", sqrdmlah(v1.h4(), v2.h4(), v3.h(3)));
+ TEST_INSTRUCTION("41D8A32F", sqrdmlah(v1.s2(), v2.s2(), v3.s(3)));
+ TEST_INSTRUCTION("4184436E", sqrdmlah(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4184836E", sqrdmlah(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41D0736F", sqrdmlah(v1.h8(), v2.h8(), v3.h(3)));
+ TEST_INSTRUCTION("41D8A36F", sqrdmlah(v1.s4(), v2.s4(), v3.s(3)));
+ TEST_INSTRUCTION("418C437E", sqrdmlsh(h1, h2, h3));
+ TEST_INSTRUCTION("418C837E", sqrdmlsh(s1, s2, s3));
+ TEST_INSTRUCTION("418C432E", sqrdmlsh(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("418C832E", sqrdmlsh(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("41F0732F", sqrdmlsh(v1.h4(), v2.h4(), v3.h(3)));
+ TEST_INSTRUCTION("41F8A32F", sqrdmlsh(v1.s2(), v2.s2(), v3.s(3)));
+ TEST_INSTRUCTION("418C436E", sqrdmlsh(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("418C836E", sqrdmlsh(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41F0736F", sqrdmlsh(v1.h8(), v2.h8(), v3.h(3)));
+ TEST_INSTRUCTION("41F8A36F", sqrdmlsh(v1.s4(), v2.s4(), v3.s(3)));
+ TEST_INSTRUCTION("41B4637E", sqrdmulh(h1, h2, h3));
+ TEST_INSTRUCTION("41B4A37E", sqrdmulh(s1, s2, s3));
+ TEST_INSTRUCTION("41B4632E", sqrdmulh(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41B4A32E", sqrdmulh(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("41D0730F", sqrdmulh(v1.h4(), v2.h4(), v3.h(3)));
+ TEST_INSTRUCTION("41D8A30F", sqrdmulh(v1.s2(), v2.s2(), v3.s(3)));
+ TEST_INSTRUCTION("41B4636E", sqrdmulh(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41B4A36E", sqrdmulh(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41D0734F", sqrdmulh(v1.h8(), v2.h8(), v3.h(3)));
+ TEST_INSTRUCTION("41D8A34F", sqrdmulh(v1.s4(), v2.s4(), v3.s(3)));
+ TEST_INSTRUCTION("415C235E", sqrshl(b1, b2, b3));
+ TEST_INSTRUCTION("415C635E", sqrshl(h1, h2, h3));
+ TEST_INSTRUCTION("415CA35E", sqrshl(s1, s2, s3));
+ TEST_INSTRUCTION("415C230E", sqrshl(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("415C630E", sqrshl(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("415CA30E", sqrshl(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("415CE35E", sqrshl(d1, d2, d3));
+ TEST_INSTRUCTION("415C234E", sqrshl(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("415C634E", sqrshl(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("415CA34E", sqrshl(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("415CE34E", sqrshl(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("419C085F", sqrshrn(b1, h2, 8));
+ TEST_INSTRUCTION("419C105F", sqrshrn(h1, s2, 16));
+ TEST_INSTRUCTION("419C205F", sqrshrn(s1, d2, 32));
+ TEST_INSTRUCTION("419C080F", sqrshrn(v1.b8(), v2.h8(), 8));
+ TEST_INSTRUCTION("419C100F", sqrshrn(v1.h4(), v2.s4(), 16));
+ TEST_INSTRUCTION("419C200F", sqrshrn(v1.s2(), v2.d2(), 32));
+ TEST_INSTRUCTION("419C084F", sqrshrn2(v1.b16(), v2.h8(), 8));
+ TEST_INSTRUCTION("419C104F", sqrshrn2(v1.h8(), v2.s4(), 16));
+ TEST_INSTRUCTION("419C204F", sqrshrn2(v1.s4(), v2.d2(), 32));
+ TEST_INSTRUCTION("418C087F", sqrshrun(b1, h2, 8));
+ TEST_INSTRUCTION("418C107F", sqrshrun(h1, s2, 16));
+ TEST_INSTRUCTION("418C207F", sqrshrun(s1, d2, 32));
+ TEST_INSTRUCTION("418C082F", sqrshrun(v1.b8(), v2.h8(), 8));
+ TEST_INSTRUCTION("418C102F", sqrshrun(v1.h4(), v2.s4(), 16));
+ TEST_INSTRUCTION("418C202F", sqrshrun(v1.s2(), v2.d2(), 32));
+ TEST_INSTRUCTION("418C086F", sqrshrun2(v1.b16(), v2.h8(), 8));
+ TEST_INSTRUCTION("418C106F", sqrshrun2(v1.h8(), v2.s4(), 16));
+ TEST_INSTRUCTION("418C206F", sqrshrun2(v1.s4(), v2.d2(), 32));
+ TEST_INSTRUCTION("4174095F", sqshl(b1, b2, 1));
+ TEST_INSTRUCTION("4174125F", sqshl(h1, h2, 2));
+ TEST_INSTRUCTION("4174235F", sqshl(s1, s2, 3));
+ TEST_INSTRUCTION("41740F0F", sqshl(v1.b8(), v2.b8(), 7));
+ TEST_INSTRUCTION("41741F0F", sqshl(v1.h4(), v2.h4(), 15));
+ TEST_INSTRUCTION("41743F0F", sqshl(v1.s2(), v2.s2(), 31));
+ TEST_INSTRUCTION("41747F5F", sqshl(d1, d2, 63));
+ TEST_INSTRUCTION("41740F4F", sqshl(v1.b16(), v2.b16(), 7));
+ TEST_INSTRUCTION("41741F4F", sqshl(v1.h8(), v2.h8(), 15));
+ TEST_INSTRUCTION("41743F4F", sqshl(v1.s4(), v2.s4(), 31));
+ TEST_INSTRUCTION("41747F4F", sqshl(v1.d2(), v2.d2(), 63));
+ TEST_INSTRUCTION("414C235E", sqshl(b1, b2, b3));
+ TEST_INSTRUCTION("414C635E", sqshl(h1, h2, h3));
+ TEST_INSTRUCTION("414CA35E", sqshl(s1, s2, s3));
+ TEST_INSTRUCTION("414C230E", sqshl(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("414C630E", sqshl(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("414CA30E", sqshl(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("414CE35E", sqshl(d1, d2, d3));
+ TEST_INSTRUCTION("414C234E", sqshl(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("414C634E", sqshl(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("414CA34E", sqshl(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("414CE34E", sqshl(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4164097F", sqshlu(b1, b2, 1));
+ TEST_INSTRUCTION("4164127F", sqshlu(h1, h2, 2));
+ TEST_INSTRUCTION("4164237F", sqshlu(s1, s2, 3));
+ TEST_INSTRUCTION("41640F2F", sqshlu(v1.b8(), v2.b8(), 7));
+ TEST_INSTRUCTION("41641F2F", sqshlu(v1.h4(), v2.h4(), 15));
+ TEST_INSTRUCTION("41643F2F", sqshlu(v1.s2(), v2.s2(), 31));
+ TEST_INSTRUCTION("41647F7F", sqshlu(d1, d2, 63));
+ TEST_INSTRUCTION("41640F6F", sqshlu(v1.b16(), v2.b16(), 7));
+ TEST_INSTRUCTION("41641F6F", sqshlu(v1.h8(), v2.h8(), 15));
+ TEST_INSTRUCTION("41643F6F", sqshlu(v1.s4(), v2.s4(), 31));
+ TEST_INSTRUCTION("41647F6F", sqshlu(v1.d2(), v2.d2(), 63));
+ TEST_INSTRUCTION("4194085F", sqshrn(b1, h2, 8));
+ TEST_INSTRUCTION("4194105F", sqshrn(h1, s2, 16));
+ TEST_INSTRUCTION("4194205F", sqshrn(s1, d2, 32));
+ TEST_INSTRUCTION("4194080F", sqshrn(v1.b8(), v2.h8(), 8));
+ TEST_INSTRUCTION("4194100F", sqshrn(v1.h4(), v2.s4(), 16));
+ TEST_INSTRUCTION("4194200F", sqshrn(v1.s2(), v2.d2(), 32));
+ TEST_INSTRUCTION("4194084F", sqshrn2(v1.b16(), v2.h8(), 8));
+ TEST_INSTRUCTION("4194104F", sqshrn2(v1.h8(), v2.s4(), 16));
+ TEST_INSTRUCTION("4194204F", sqshrn2(v1.s4(), v2.d2(), 32));
+ TEST_INSTRUCTION("4184087F", sqshrun(b1, h2, 8));
+ TEST_INSTRUCTION("4184107F", sqshrun(h1, s2, 16));
+ TEST_INSTRUCTION("4184207F", sqshrun(s1, d2, 32));
+ TEST_INSTRUCTION("4184082F", sqshrun(v1.b8(), v2.h8(), 8));
+ TEST_INSTRUCTION("4184102F", sqshrun(v1.h4(), v2.s4(), 16));
+ TEST_INSTRUCTION("4184202F", sqshrun(v1.s2(), v2.d2(), 32));
+ TEST_INSTRUCTION("4184086F", sqshrun2(v1.b16(), v2.h8(), 8));
+ TEST_INSTRUCTION("4184106F", sqshrun2(v1.h8(), v2.s4(), 16));
+ TEST_INSTRUCTION("4184206F", sqshrun2(v1.s4(), v2.d2(), 32));
+ TEST_INSTRUCTION("412C235E", sqsub(b1, b2, b3));
+ TEST_INSTRUCTION("412C635E", sqsub(h1, h2, h3));
+ TEST_INSTRUCTION("412CA35E", sqsub(s1, s2, s3));
+ TEST_INSTRUCTION("412CE35E", sqsub(d1, d2, d3));
+ TEST_INSTRUCTION("412C230E", sqsub(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("412C630E", sqsub(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("412CA30E", sqsub(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("412C234E", sqsub(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("412C634E", sqsub(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("412CA34E", sqsub(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("412CE34E", sqsub(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4148215E", sqxtn(b1, h2));
+ TEST_INSTRUCTION("4148615E", sqxtn(h1, s2));
+ TEST_INSTRUCTION("4148A15E", sqxtn(s1, d2));
+ TEST_INSTRUCTION("4148210E", sqxtn(v1.b8(), v2.h8()));
+ TEST_INSTRUCTION("4148610E", sqxtn(v1.h4(), v2.s4()));
+ TEST_INSTRUCTION("4148A10E", sqxtn(v1.s2(), v2.d2()));
+ TEST_INSTRUCTION("4148214E", sqxtn2(v1.b16(), v2.h8()));
+ TEST_INSTRUCTION("4148614E", sqxtn2(v1.h8(), v2.s4()));
+ TEST_INSTRUCTION("4148A14E", sqxtn2(v1.s4(), v2.d2()));
+ TEST_INSTRUCTION("4128217E", sqxtun(b1, h2));
+ TEST_INSTRUCTION("4128617E", sqxtun(h1, s2));
+ TEST_INSTRUCTION("4128A17E", sqxtun(s1, d2));
+ TEST_INSTRUCTION("4128212E", sqxtun(v1.b8(), v2.h8()));
+ TEST_INSTRUCTION("4128612E", sqxtun(v1.h4(), v2.s4()));
+ TEST_INSTRUCTION("4128A12E", sqxtun(v1.s2(), v2.d2()));
+ TEST_INSTRUCTION("4128216E", sqxtun2(v1.b16(), v2.h8()));
+ TEST_INSTRUCTION("4128616E", sqxtun2(v1.h8(), v2.s4()));
+ TEST_INSTRUCTION("4128A16E", sqxtun2(v1.s4(), v2.d2()));
+ TEST_INSTRUCTION("4114230E", srhadd(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4114630E", srhadd(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4114A30E", srhadd(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4114234E", srhadd(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4114634E", srhadd(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4114A34E", srhadd(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4144092F", sri(v1.b8(), v2.b8(), 7));
+ TEST_INSTRUCTION("4144112F", sri(v1.h4(), v2.h4(), 15));
+ TEST_INSTRUCTION("4144212F", sri(v1.s2(), v2.s2(), 31));
+ TEST_INSTRUCTION("4144417F", sri(d1, d2, 63));
+ TEST_INSTRUCTION("4144096F", sri(v1.b16(), v2.b16(), 7));
+ TEST_INSTRUCTION("4144116F", sri(v1.h8(), v2.h8(), 15));
+ TEST_INSTRUCTION("4144216F", sri(v1.s4(), v2.s4(), 31));
+ TEST_INSTRUCTION("4144416F", sri(v1.d2(), v2.d2(), 63));
+ TEST_INSTRUCTION("4154230E", srshl(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4154630E", srshl(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4154A30E", srshl(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4154E35E", srshl(d1, d2, d3));
+ TEST_INSTRUCTION("4154234E", srshl(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4154634E", srshl(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4154A34E", srshl(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4154E34E", srshl(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4124090F", srshr(v1.b8(), v2.b8(), 7));
+ TEST_INSTRUCTION("4124110F", srshr(v1.h4(), v2.h4(), 15));
+ TEST_INSTRUCTION("4124210F", srshr(v1.s2(), v2.s2(), 31));
+ TEST_INSTRUCTION("4124415F", srshr(d1, d2, 63));
+ TEST_INSTRUCTION("4124094F", srshr(v1.b16(), v2.b16(), 7));
+ TEST_INSTRUCTION("4124114F", srshr(v1.h8(), v2.h8(), 15));
+ TEST_INSTRUCTION("4124214F", srshr(v1.s4(), v2.s4(), 31));
+ TEST_INSTRUCTION("4124414F", srshr(v1.d2(), v2.d2(), 63));
+ TEST_INSTRUCTION("4134090F", srsra(v1.b8(), v2.b8(), 7));
+ TEST_INSTRUCTION("4134110F", srsra(v1.h4(), v2.h4(), 15));
+ TEST_INSTRUCTION("4134210F", srsra(v1.s2(), v2.s2(), 31));
+ TEST_INSTRUCTION("4134415F", srsra(d1, d2, 63));
+ TEST_INSTRUCTION("4134094F", srsra(v1.b16(), v2.b16(), 7));
+ TEST_INSTRUCTION("4134114F", srsra(v1.h8(), v2.h8(), 15));
+ TEST_INSTRUCTION("4134214F", srsra(v1.s4(), v2.s4(), 31));
+ TEST_INSTRUCTION("4134414F", srsra(v1.d2(), v2.d2(), 63));
+ TEST_INSTRUCTION("4144230E", sshl(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4144630E", sshl(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4144A30E", sshl(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4144E35E", sshl(d1, d2, d3));
+ TEST_INSTRUCTION("4144234E", sshl(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4144634E", sshl(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4144A34E", sshl(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4144E34E", sshl(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("41A40F0F", sshll(v1.h8(), v2.b8(), 7));
+ TEST_INSTRUCTION("41A41F0F", sshll(v1.s4(), v2.h4(), 15));
+ TEST_INSTRUCTION("41A43F0F", sshll(v1.d2(), v2.s2(), 31));
+ TEST_INSTRUCTION("41A40F4F", sshll2(v1.h8(), v2.b16(), 7));
+ TEST_INSTRUCTION("41A41F4F", sshll2(v1.s4(), v2.h8(), 15));
+ TEST_INSTRUCTION("41A43F4F", sshll2(v1.s2(), v2.s4(), 31));
+ TEST_INSTRUCTION("4104090F", sshr(v1.b8(), v2.b8(), 7));
+ TEST_INSTRUCTION("4104110F", sshr(v1.h4(), v2.h4(), 15));
+ TEST_INSTRUCTION("4104210F", sshr(v1.s2(), v2.s2(), 31));
+ TEST_INSTRUCTION("4104415F", sshr(d1, d2, 63));
+ TEST_INSTRUCTION("4104094F", sshr(v1.b16(), v2.b16(), 7));
+ TEST_INSTRUCTION("4104114F", sshr(v1.h8(), v2.h8(), 15));
+ TEST_INSTRUCTION("4104214F", sshr(v1.s4(), v2.s4(), 31));
+ TEST_INSTRUCTION("4104414F", sshr(v1.d2(), v2.d2(), 63));
+ TEST_INSTRUCTION("4114090F", ssra(v1.b8(), v2.b8(), 7));
+ TEST_INSTRUCTION("4114110F", ssra(v1.h4(), v2.h4(), 15));
+ TEST_INSTRUCTION("4114210F", ssra(v1.s2(), v2.s2(), 31));
+ TEST_INSTRUCTION("4114415F", ssra(d1, d2, 63));
+ TEST_INSTRUCTION("4114094F", ssra(v1.b16(), v2.b16(), 7));
+ TEST_INSTRUCTION("4114114F", ssra(v1.h8(), v2.h8(), 15));
+ TEST_INSTRUCTION("4114214F", ssra(v1.s4(), v2.s4(), 31));
+ TEST_INSTRUCTION("4114414F", ssra(v1.d2(), v2.d2(), 63));
+ TEST_INSTRUCTION("4120230E", ssubl(v1.h8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4120630E", ssubl(v1.s4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4120A30E", ssubl(v1.d2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4120234E", ssubl2(v1.h8(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4120634E", ssubl2(v1.s4(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4120A34E", ssubl2(v1.d2(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4130230E", ssubw(v1.h8(), v2.h8(), v3.b8()));
+ TEST_INSTRUCTION("4130630E", ssubw(v1.s4(), v2.s4(), v3.h4()));
+ TEST_INSTRUCTION("4130A30E", ssubw(v1.d2(), v2.d2(), v3.s2()));
+ TEST_INSTRUCTION("4130234E", ssubw2(v1.h8(), v2.h8(), v3.b16()));
+ TEST_INSTRUCTION("4130634E", ssubw2(v1.s4(), v2.s4(), v3.h8()));
+ TEST_INSTRUCTION("4130A34E", ssubw2(v1.d2(), v2.d2(), v3.s4()));
+ TEST_INSTRUCTION("4100000D", st1(v1.b(0), ptr(x2)));
+ TEST_INSTRUCTION("41009F0D", st1(v1.b(0), ptr_post(x2, 1)));
+ TEST_INSTRUCTION("4140000D", st1(v1.h(0), ptr(x2)));
+ TEST_INSTRUCTION("41409F0D", st1(v1.h(0), ptr_post(x2, 2)));
+ TEST_INSTRUCTION("4180000D", st1(v1.s(0), ptr(x2)));
+ TEST_INSTRUCTION("41809F0D", st1(v1.s(0), ptr_post(x2, 4)));
+ TEST_INSTRUCTION("4184000D", st1(v1.d(0), ptr(x2)));
+ TEST_INSTRUCTION("41849F0D", st1(v1.d(0), ptr_post(x2, 8)));
+ TEST_INSTRUCTION("411C004D", st1(v1.b(15), ptr(x2)));
+ TEST_INSTRUCTION("411C9F4D", st1(v1.b(15), ptr_post(x2, 1)));
+ TEST_INSTRUCTION("4158004D", st1(v1.h(7), ptr(x2)));
+ TEST_INSTRUCTION("41589F4D", st1(v1.h(7), ptr_post(x2, 2)));
+ TEST_INSTRUCTION("4190004D", st1(v1.s(3), ptr(x2)));
+ TEST_INSTRUCTION("41909F4D", st1(v1.s(3), ptr_post(x2, 4)));
+ TEST_INSTRUCTION("4184004D", st1(v1.d(1), ptr(x2)));
+ TEST_INSTRUCTION("41849F4D", st1(v1.d(1), ptr_post(x2, 8)));
+ TEST_INSTRUCTION("4170000C", st1(v1.b8(), ptr(x2)));
+ TEST_INSTRUCTION("41709F0C", st1(v1.b8(), ptr_post(x2, 8)));
+ TEST_INSTRUCTION("4170004C", st1(v1.b16(), ptr(x2)));
+ TEST_INSTRUCTION("41709F4C", st1(v1.b16(), ptr_post(x2, 16)));
+ TEST_INSTRUCTION("61A0000C", st1(v1.b8(), v2.b8(), ptr(x3)));
+ TEST_INSTRUCTION("61A09F0C", st1(v1.b8(), v2.b8(), ptr_post(x3, 16)));
+ TEST_INSTRUCTION("61A0004C", st1(v1.b16(), v2.b16(), ptr(x3)));
+ TEST_INSTRUCTION("61A09F4C", st1(v1.b16(), v2.b16(), ptr_post(x3, 32)));
+ TEST_INSTRUCTION("8160000C", st1(v1.b8(), v2.b8(), v3.b8(), ptr(x4)));
+ TEST_INSTRUCTION("81609F0C", st1(v1.b8(), v2.b8(), v3.b8(), ptr_post(x4, 24)));
+ TEST_INSTRUCTION("8160004C", st1(v1.b16(), v2.b16(), v3.b16(), ptr(x4)));
+ TEST_INSTRUCTION("81609F4C", st1(v1.b16(), v2.b16(), v3.b16(), ptr_post(x4, 48)));
+ TEST_INSTRUCTION("A120000C", st1(v1.b8(), v2.b8(), v3.b8(), v4.b8(), ptr(x5)));
+ TEST_INSTRUCTION("A1209F0C", st1(v1.b8(), v2.b8(), v3.b8(), v4.b8(), ptr_post(x5, 32)));
+ TEST_INSTRUCTION("A120004C", st1(v1.b16(), v2.b16(), v3.b16(), v4.b16(), ptr(x5)));
+ TEST_INSTRUCTION("A1209F4C", st1(v1.b16(), v2.b16(), v3.b16(), v4.b16(), ptr_post(x5, 64)));
+ TEST_INSTRUCTION("4174000C", st1(v1.h4(), ptr(x2)));
+ TEST_INSTRUCTION("41749F0C", st1(v1.h4(), ptr_post(x2, 8)));
+ TEST_INSTRUCTION("4174004C", st1(v1.h8(), ptr(x2)));
+ TEST_INSTRUCTION("41749F4C", st1(v1.h8(), ptr_post(x2, 16)));
+ TEST_INSTRUCTION("61A4000C", st1(v1.h4(), v2.h4(), ptr(x3)));
+ TEST_INSTRUCTION("61A49F0C", st1(v1.h4(), v2.h4(), ptr_post(x3, 16)));
+ TEST_INSTRUCTION("61A4004C", st1(v1.h8(), v2.h8(), ptr(x3)));
+ TEST_INSTRUCTION("61A49F4C", st1(v1.h8(), v2.h8(), ptr_post(x3, 32)));
+ TEST_INSTRUCTION("8164000C", st1(v1.h4(), v2.h4(), v3.h4(), ptr(x4)));
+ TEST_INSTRUCTION("81649F0C", st1(v1.h4(), v2.h4(), v3.h4(), ptr_post(x4, 24)));
+ TEST_INSTRUCTION("8164004C", st1(v1.h8(), v2.h8(), v3.h8(), ptr(x4)));
+ TEST_INSTRUCTION("81649F4C", st1(v1.h8(), v2.h8(), v3.h8(), ptr_post(x4, 48)));
+ TEST_INSTRUCTION("A124000C", st1(v1.h4(), v2.h4(), v3.h4(), v4.h4(), ptr(x5)));
+ TEST_INSTRUCTION("A1249F0C", st1(v1.h4(), v2.h4(), v3.h4(), v4.h4(), ptr_post(x5, 32)));
+ TEST_INSTRUCTION("A124004C", st1(v1.h8(), v2.h8(), v3.h8(), v4.h8(), ptr(x5)));
+ TEST_INSTRUCTION("A1249F4C", st1(v1.h8(), v2.h8(), v3.h8(), v4.h8(), ptr_post(x5, 64)));
+ TEST_INSTRUCTION("4178000C", st1(v1.s2(), ptr(x2)));
+ TEST_INSTRUCTION("41789F0C", st1(v1.s2(), ptr_post(x2, 8)));
+ TEST_INSTRUCTION("4178004C", st1(v1.s4(), ptr(x2)));
+ TEST_INSTRUCTION("41789F4C", st1(v1.s4(), ptr_post(x2, 16)));
+ TEST_INSTRUCTION("61A8000C", st1(v1.s2(), v2.s2(), ptr(x3)));
+ TEST_INSTRUCTION("61A89F0C", st1(v1.s2(), v2.s2(), ptr_post(x3, 16)));
+ TEST_INSTRUCTION("61A8004C", st1(v1.s4(), v2.s4(), ptr(x3)));
+ TEST_INSTRUCTION("61A89F4C", st1(v1.s4(), v2.s4(), ptr_post(x3, 32)));
+ TEST_INSTRUCTION("8168000C", st1(v1.s2(), v2.s2(), v3.s2(), ptr(x4)));
+ TEST_INSTRUCTION("81689F0C", st1(v1.s2(), v2.s2(), v3.s2(), ptr_post(x4, 24)));
+ TEST_INSTRUCTION("8168004C", st1(v1.s4(), v2.s4(), v3.s4(), ptr(x4)));
+ TEST_INSTRUCTION("81689F4C", st1(v1.s4(), v2.s4(), v3.s4(), ptr_post(x4, 48)));
+ TEST_INSTRUCTION("A128000C", st1(v1.s2(), v2.s2(), v3.s2(), v4.s2(), ptr(x5)));
+ TEST_INSTRUCTION("A1289F0C", st1(v1.s2(), v2.s2(), v3.s2(), v4.s2(), ptr_post(x5, 32)));
+ TEST_INSTRUCTION("A128004C", st1(v1.s4(), v2.s4(), v3.s4(), v4.s4(), ptr(x5)));
+ TEST_INSTRUCTION("A1289F4C", st1(v1.s4(), v2.s4(), v3.s4(), v4.s4(), ptr_post(x5, 64)));
+ TEST_INSTRUCTION("417C004C", st1(v1.d2(), ptr(x2)));
+ TEST_INSTRUCTION("417C9F4C", st1(v1.d2(), ptr_post(x2, 16)));
+ TEST_INSTRUCTION("61AC004C", st1(v1.d2(), v2.d2(), ptr(x3)));
+ TEST_INSTRUCTION("61AC9F4C", st1(v1.d2(), v2.d2(), ptr_post(x3, 32)));
+ TEST_INSTRUCTION("816C004C", st1(v1.d2(), v2.d2(), v3.d2(), ptr(x4)));
+ TEST_INSTRUCTION("816C9F4C", st1(v1.d2(), v2.d2(), v3.d2(), ptr_post(x4, 48)));
+ TEST_INSTRUCTION("A12C004C", st1(v1.d2(), v2.d2(), v3.d2(), v4.d2(), ptr(x5)));
+ TEST_INSTRUCTION("A12C9F4C", st1(v1.d2(), v2.d2(), v3.d2(), v4.d2(), ptr_post(x5, 64)));
+ TEST_INSTRUCTION("6100200D", st2(v1.b(0), v2.b(0), ptr(x3)));
+ TEST_INSTRUCTION("6100BF0D", st2(v1.b(0), v2.b(0), ptr_post(x3, 2)));
+ TEST_INSTRUCTION("6100AB0D", st2(v1.b(0), v2.b(0), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("6140200D", st2(v1.h(0), v2.h(0), ptr(x3)));
+ TEST_INSTRUCTION("6140BF0D", st2(v1.h(0), v2.h(0), ptr_post(x3, 4)));
+ TEST_INSTRUCTION("6140AB0D", st2(v1.h(0), v2.h(0), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("6180200D", st2(v1.s(0), v2.s(0), ptr(x3)));
+ TEST_INSTRUCTION("6180BF0D", st2(v1.s(0), v2.s(0), ptr_post(x3, 8)));
+ TEST_INSTRUCTION("6180AB0D", st2(v1.s(0), v2.s(0), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("6184200D", st2(v1.d(0), v2.d(0), ptr(x3)));
+ TEST_INSTRUCTION("6184BF0D", st2(v1.d(0), v2.d(0), ptr_post(x3, 16)));
+ TEST_INSTRUCTION("6184AB0D", st2(v1.d(0), v2.d(0), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("611C204D", st2(v1.b(15), v2.b(15), ptr(x3)));
+ TEST_INSTRUCTION("611CBF4D", st2(v1.b(15), v2.b(15), ptr_post(x3, 2)));
+ TEST_INSTRUCTION("611CAB4D", st2(v1.b(15), v2.b(15), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("6158204D", st2(v1.h(7), v2.h(7), ptr(x3)));
+ TEST_INSTRUCTION("6158BF4D", st2(v1.h(7), v2.h(7), ptr_post(x3, 4)));
+ TEST_INSTRUCTION("6158AB4D", st2(v1.h(7), v2.h(7), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("6190204D", st2(v1.s(3), v2.s(3), ptr(x3)));
+ TEST_INSTRUCTION("6190BF4D", st2(v1.s(3), v2.s(3), ptr_post(x3, 8)));
+ TEST_INSTRUCTION("6190AB4D", st2(v1.s(3), v2.s(3), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("6184204D", st2(v1.d(1), v2.d(1), ptr(x3)));
+ TEST_INSTRUCTION("6184BF4D", st2(v1.d(1), v2.d(1), ptr_post(x3, 16)));
+ TEST_INSTRUCTION("6184AB4D", st2(v1.d(1), v2.d(1), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("6180000C", st2(v1.b8(), v2.b8(), ptr(x3)));
+ TEST_INSTRUCTION("61809F0C", st2(v1.b8(), v2.b8(), ptr_post(x3, 16)));
+ TEST_INSTRUCTION("61808B0C", st2(v1.b8(), v2.b8(), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("6180004C", st2(v1.b16(), v2.b16(), ptr(x3)));
+ TEST_INSTRUCTION("61809F4C", st2(v1.b16(), v2.b16(), ptr_post(x3, 32)));
+ TEST_INSTRUCTION("61808B4C", st2(v1.b16(), v2.b16(), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("6184000C", st2(v1.h4(), v2.h4(), ptr(x3)));
+ TEST_INSTRUCTION("61849F0C", st2(v1.h4(), v2.h4(), ptr_post(x3, 16)));
+ TEST_INSTRUCTION("61848B0C", st2(v1.h4(), v2.h4(), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("6184004C", st2(v1.h8(), v2.h8(), ptr(x3)));
+ TEST_INSTRUCTION("61849F4C", st2(v1.h8(), v2.h8(), ptr_post(x3, 32)));
+ TEST_INSTRUCTION("61848B4C", st2(v1.h8(), v2.h8(), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("6188000C", st2(v1.s2(), v2.s2(), ptr(x3)));
+ TEST_INSTRUCTION("61889F0C", st2(v1.s2(), v2.s2(), ptr_post(x3, 16)));
+ TEST_INSTRUCTION("61888B0C", st2(v1.s2(), v2.s2(), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("6188004C", st2(v1.s4(), v2.s4(), ptr(x3)));
+ TEST_INSTRUCTION("61889F4C", st2(v1.s4(), v2.s4(), ptr_post(x3, 32)));
+ TEST_INSTRUCTION("61888B4C", st2(v1.s4(), v2.s4(), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("618C004C", st2(v1.d2(), v2.d2(), ptr(x3)));
+ TEST_INSTRUCTION("618C9F4C", st2(v1.d2(), v2.d2(), ptr_post(x3, 32)));
+ TEST_INSTRUCTION("618C8B4C", st2(v1.d2(), v2.d2(), ptr_post(x3, x11)));
+ TEST_INSTRUCTION("8120000D", st3(v1.b(0), v2.b(0), v3.b(0), ptr(x4)));
+ TEST_INSTRUCTION("81209F0D", st3(v1.b(0), v2.b(0), v3.b(0), ptr_post(x4, 3)));
+ TEST_INSTRUCTION("81208B0D", st3(v1.b(0), v2.b(0), v3.b(0), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("8160000D", st3(v1.h(0), v2.h(0), v3.h(0), ptr(x4)));
+ TEST_INSTRUCTION("81609F0D", st3(v1.h(0), v2.h(0), v3.h(0), ptr_post(x4, 6)));
+ TEST_INSTRUCTION("81608B0D", st3(v1.h(0), v2.h(0), v3.h(0), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("81A0000D", st3(v1.s(0), v2.s(0), v3.s(0), ptr(x4)));
+ TEST_INSTRUCTION("81A09F0D", st3(v1.s(0), v2.s(0), v3.s(0), ptr_post(x4, 12)));
+ TEST_INSTRUCTION("81A08B0D", st3(v1.s(0), v2.s(0), v3.s(0), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("81A4000D", st3(v1.d(0), v2.d(0), v3.d(0), ptr(x4)));
+ TEST_INSTRUCTION("81A49F0D", st3(v1.d(0), v2.d(0), v3.d(0), ptr_post(x4, 24)));
+ TEST_INSTRUCTION("81A48B0D", st3(v1.d(0), v2.d(0), v3.d(0), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("813C004D", st3(v1.b(15), v2.b(15), v3.b(15), ptr(x4)));
+ TEST_INSTRUCTION("813C9F4D", st3(v1.b(15), v2.b(15), v3.b(15), ptr_post(x4, 3)));
+ TEST_INSTRUCTION("813C8B4D", st3(v1.b(15), v2.b(15), v3.b(15), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("8178004D", st3(v1.h(7), v2.h(7), v3.h(7), ptr(x4)));
+ TEST_INSTRUCTION("81789F4D", st3(v1.h(7), v2.h(7), v3.h(7), ptr_post(x4, 6)));
+ TEST_INSTRUCTION("81788B4D", st3(v1.h(7), v2.h(7), v3.h(7), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("81B0004D", st3(v1.s(3), v2.s(3), v3.s(3), ptr(x4)));
+ TEST_INSTRUCTION("81B09F4D", st3(v1.s(3), v2.s(3), v3.s(3), ptr_post(x4, 12)));
+ TEST_INSTRUCTION("81B08B4D", st3(v1.s(3), v2.s(3), v3.s(3), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("81A4004D", st3(v1.d(1), v2.d(1), v3.d(1), ptr(x4)));
+ TEST_INSTRUCTION("81A49F4D", st3(v1.d(1), v2.d(1), v3.d(1), ptr_post(x4, 24)));
+ TEST_INSTRUCTION("81A48B4D", st3(v1.d(1), v2.d(1), v3.d(1), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("8140000C", st3(v1.b8(), v2.b8(), v3.b8(), ptr(x4)));
+ TEST_INSTRUCTION("81409F0C", st3(v1.b8(), v2.b8(), v3.b8(), ptr_post(x4, 24)));
+ TEST_INSTRUCTION("81408B0C", st3(v1.b8(), v2.b8(), v3.b8(), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("8140004C", st3(v1.b16(), v2.b16(), v3.b16(), ptr(x4)));
+ TEST_INSTRUCTION("81409F4C", st3(v1.b16(), v2.b16(), v3.b16(), ptr_post(x4, 48)));
+ TEST_INSTRUCTION("81408B4C", st3(v1.b16(), v2.b16(), v3.b16(), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("8144000C", st3(v1.h4(), v2.h4(), v3.h4(), ptr(x4)));
+ TEST_INSTRUCTION("81449F0C", st3(v1.h4(), v2.h4(), v3.h4(), ptr_post(x4, 24)));
+ TEST_INSTRUCTION("81448B0C", st3(v1.h4(), v2.h4(), v3.h4(), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("8144004C", st3(v1.h8(), v2.h8(), v3.h8(), ptr(x4)));
+ TEST_INSTRUCTION("81449F4C", st3(v1.h8(), v2.h8(), v3.h8(), ptr_post(x4, 48)));
+ TEST_INSTRUCTION("81448B4C", st3(v1.h8(), v2.h8(), v3.h8(), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("8148000C", st3(v1.s2(), v2.s2(), v3.s2(), ptr(x4)));
+ TEST_INSTRUCTION("81489F0C", st3(v1.s2(), v2.s2(), v3.s2(), ptr_post(x4, 24)));
+ TEST_INSTRUCTION("81488B0C", st3(v1.s2(), v2.s2(), v3.s2(), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("8148004C", st3(v1.s4(), v2.s4(), v3.s4(), ptr(x4)));
+ TEST_INSTRUCTION("81489F4C", st3(v1.s4(), v2.s4(), v3.s4(), ptr_post(x4, 48)));
+ TEST_INSTRUCTION("81488B4C", st3(v1.s4(), v2.s4(), v3.s4(), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("814C004C", st3(v1.d2(), v2.d2(), v3.d2(), ptr(x4)));
+ TEST_INSTRUCTION("814C9F4C", st3(v1.d2(), v2.d2(), v3.d2(), ptr_post(x4, 48)));
+ TEST_INSTRUCTION("814C8B4C", st3(v1.d2(), v2.d2(), v3.d2(), ptr_post(x4, x11)));
+ TEST_INSTRUCTION("A120200D", st4(v1.b(0), v2.b(0), v3.b(0), v4.b(0), ptr(x5)));
+ TEST_INSTRUCTION("A120BF0D", st4(v1.b(0), v2.b(0), v3.b(0), v4.b(0), ptr_post(x5, 4)));
+ TEST_INSTRUCTION("A120AB0D", st4(v1.b(0), v2.b(0), v3.b(0), v4.b(0), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A160200D", st4(v1.h(0), v2.h(0), v3.h(0), v4.h(0), ptr(x5)));
+ TEST_INSTRUCTION("A160BF0D", st4(v1.h(0), v2.h(0), v3.h(0), v4.h(0), ptr_post(x5, 8)));
+ TEST_INSTRUCTION("A160AB0D", st4(v1.h(0), v2.h(0), v3.h(0), v4.h(0), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A1A0200D", st4(v1.s(0), v2.s(0), v3.s(0), v4.s(0), ptr(x5)));
+ TEST_INSTRUCTION("A1A0BF0D", st4(v1.s(0), v2.s(0), v3.s(0), v4.s(0), ptr_post(x5, 16)));
+ TEST_INSTRUCTION("A1A0AB0D", st4(v1.s(0), v2.s(0), v3.s(0), v4.s(0), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A1A4200D", st4(v1.d(0), v2.d(0), v3.d(0), v4.d(0), ptr(x5)));
+ TEST_INSTRUCTION("A1A4BF0D", st4(v1.d(0), v2.d(0), v3.d(0), v4.d(0), ptr_post(x5, 32)));
+ TEST_INSTRUCTION("A1A4AB0D", st4(v1.d(0), v2.d(0), v3.d(0), v4.d(0), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A13C204D", st4(v1.b(15), v2.b(15), v3.b(15), v4.b(15), ptr(x5)));
+ TEST_INSTRUCTION("A13CBF4D", st4(v1.b(15), v2.b(15), v3.b(15), v4.b(15), ptr_post(x5, 4)));
+ TEST_INSTRUCTION("A13CAB4D", st4(v1.b(15), v2.b(15), v3.b(15), v4.b(15), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A178204D", st4(v1.h(7), v2.h(7), v3.h(7), v4.h(7), ptr(x5)));
+ TEST_INSTRUCTION("A178BF4D", st4(v1.h(7), v2.h(7), v3.h(7), v4.h(7), ptr_post(x5, 8)));
+ TEST_INSTRUCTION("A178AB4D", st4(v1.h(7), v2.h(7), v3.h(7), v4.h(7), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A1B0204D", st4(v1.s(3), v2.s(3), v3.s(3), v4.s(3), ptr(x5)));
+ TEST_INSTRUCTION("A1B0BF4D", st4(v1.s(3), v2.s(3), v3.s(3), v4.s(3), ptr_post(x5, 16)));
+ TEST_INSTRUCTION("A1B0AB4D", st4(v1.s(3), v2.s(3), v3.s(3), v4.s(3), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A1A4204D", st4(v1.d(1), v2.d(1), v3.d(1), v4.d(1), ptr(x5)));
+ TEST_INSTRUCTION("A1A4BF4D", st4(v1.d(1), v2.d(1), v3.d(1), v4.d(1), ptr_post(x5, 32)));
+ TEST_INSTRUCTION("A1A4AB4D", st4(v1.d(1), v2.d(1), v3.d(1), v4.d(1), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A100000C", st4(v1.b8(), v2.b8(), v3.b8(), v4.b8(), ptr(x5)));
+ TEST_INSTRUCTION("A1009F0C", st4(v1.b8(), v2.b8(), v3.b8(), v4.b8(), ptr_post(x5, 32)));
+ TEST_INSTRUCTION("A1008B0C", st4(v1.b8(), v2.b8(), v3.b8(), v4.b8(), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A100004C", st4(v1.b16(), v2.b16(), v3.b16(), v4.b16(), ptr(x5)));
+ TEST_INSTRUCTION("A1009F4C", st4(v1.b16(), v2.b16(), v3.b16(), v4.b16(), ptr_post(x5, 64)));
+ TEST_INSTRUCTION("A1008B4C", st4(v1.b16(), v2.b16(), v3.b16(), v4.b16(), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A104000C", st4(v1.h4(), v2.h4(), v3.h4(), v4.h4(), ptr(x5)));
+ TEST_INSTRUCTION("A1049F0C", st4(v1.h4(), v2.h4(), v3.h4(), v4.h4(), ptr_post(x5, 32)));
+ TEST_INSTRUCTION("A1048B0C", st4(v1.h4(), v2.h4(), v3.h4(), v4.h4(), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A104004C", st4(v1.h8(), v2.h8(), v3.h8(), v4.h8(), ptr(x5)));
+ TEST_INSTRUCTION("A1049F4C", st4(v1.h8(), v2.h8(), v3.h8(), v4.h8(), ptr_post(x5, 64)));
+ TEST_INSTRUCTION("A1048B4C", st4(v1.h8(), v2.h8(), v3.h8(), v4.h8(), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A108000C", st4(v1.s2(), v2.s2(), v3.s2(), v4.s2(), ptr(x5)));
+ TEST_INSTRUCTION("A1089F0C", st4(v1.s2(), v2.s2(), v3.s2(), v4.s2(), ptr_post(x5, 32)));
+ TEST_INSTRUCTION("A1088B0C", st4(v1.s2(), v2.s2(), v3.s2(), v4.s2(), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A108004C", st4(v1.s4(), v2.s4(), v3.s4(), v4.s4(), ptr(x5)));
+ TEST_INSTRUCTION("A1089F4C", st4(v1.s4(), v2.s4(), v3.s4(), v4.s4(), ptr_post(x5, 64)));
+ TEST_INSTRUCTION("A1088B4C", st4(v1.s4(), v2.s4(), v3.s4(), v4.s4(), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("A10C004C", st4(v1.d2(), v2.d2(), v3.d2(), v4.d2(), ptr(x5)));
+ TEST_INSTRUCTION("A10C9F4C", st4(v1.d2(), v2.d2(), v3.d2(), v4.d2(), ptr_post(x5, 64)));
+ TEST_INSTRUCTION("A10C8B4C", st4(v1.d2(), v2.d2(), v3.d2(), v4.d2(), ptr_post(x5, x11)));
+ TEST_INSTRUCTION("8109002C", stnp(s1, s2, ptr(x12)));
+ TEST_INSTRUCTION("8189002C", stnp(s1, s2, ptr(x12, 4)));
+ TEST_INSTRUCTION("8109302C", stnp(s1, s2, ptr(x12, -128)));
+ TEST_INSTRUCTION("E10B002C", stnp(s1, s2, ptr(sp)));
+ TEST_INSTRUCTION("E18B002C", stnp(s1, s2, ptr(sp, 4)));
+ TEST_INSTRUCTION("E10B102C", stnp(s1, s2, ptr(sp, 128)));
+ TEST_INSTRUCTION("8109006C", stnp(d1, d2, ptr(x12)));
+ TEST_INSTRUCTION("8189006C", stnp(d1, d2, ptr(x12, 8)));
+ TEST_INSTRUCTION("8109386C", stnp(d1, d2, ptr(x12, -128)));
+ TEST_INSTRUCTION("E10B006C", stnp(d1, d2, ptr(sp)));
+ TEST_INSTRUCTION("E18B006C", stnp(d1, d2, ptr(sp, 8)));
+ TEST_INSTRUCTION("E10B086C", stnp(d1, d2, ptr(sp, 128)));
+ TEST_INSTRUCTION("810900AC", stnp(q1, q2, ptr(x12)));
+ TEST_INSTRUCTION("818900AC", stnp(q1, q2, ptr(x12, 16)));
+ TEST_INSTRUCTION("81093CAC", stnp(q1, q2, ptr(x12, -128)));
+ TEST_INSTRUCTION("E10B00AC", stnp(q1, q2, ptr(sp)));
+ TEST_INSTRUCTION("E18B00AC", stnp(q1, q2, ptr(sp, 16)));
+ TEST_INSTRUCTION("E10B04AC", stnp(q1, q2, ptr(sp, 128)));
+ TEST_INSTRUCTION("8109002D", stp(s1, s2, ptr(x12)));
+ TEST_INSTRUCTION("8189002D", stp(s1, s2, ptr(x12, 4)));
+ TEST_INSTRUCTION("8109302D", stp(s1, s2, ptr(x12, -128)));
+ TEST_INSTRUCTION("8189802D", stp(s1, s2, ptr_pre(x12, 4)));
+ TEST_INSTRUCTION("8189802C", stp(s1, s2, ptr_post(x12, 4)));
+ TEST_INSTRUCTION("E10B002D", stp(s1, s2, ptr(sp)));
+ TEST_INSTRUCTION("E18B002D", stp(s1, s2, ptr(sp, 4)));
+ TEST_INSTRUCTION("E10B102D", stp(s1, s2, ptr(sp, 128)));
+ TEST_INSTRUCTION("E18B802D", stp(s1, s2, ptr_pre(sp, 4)));
+ TEST_INSTRUCTION("E18B802C", stp(s1, s2, ptr_post(sp, 4)));
+ TEST_INSTRUCTION("8109006D", stp(d1, d2, ptr(x12)));
+ TEST_INSTRUCTION("8189006D", stp(d1, d2, ptr(x12, 8)));
+ TEST_INSTRUCTION("8109386D", stp(d1, d2, ptr(x12, -128)));
+ TEST_INSTRUCTION("8189806D", stp(d1, d2, ptr_pre(x12, 8)));
+ TEST_INSTRUCTION("8189806C", stp(d1, d2, ptr_post(x12, 8)));
+ TEST_INSTRUCTION("E10B006D", stp(d1, d2, ptr(sp)));
+ TEST_INSTRUCTION("E18B006D", stp(d1, d2, ptr(sp, 8)));
+ TEST_INSTRUCTION("E10B086D", stp(d1, d2, ptr(sp, 128)));
+ TEST_INSTRUCTION("E18B806D", stp(d1, d2, ptr_pre(sp, 8)));
+ TEST_INSTRUCTION("E18B806C", stp(d1, d2, ptr_post(sp, 8)));
+ TEST_INSTRUCTION("810900AD", stp(q1, q2, ptr(x12)));
+ TEST_INSTRUCTION("818900AD", stp(q1, q2, ptr(x12, 16)));
+ TEST_INSTRUCTION("81093CAD", stp(q1, q2, ptr(x12, -128)));
+ TEST_INSTRUCTION("818980AD", stp(q1, q2, ptr_pre(x12, 16)));
+ TEST_INSTRUCTION("818980AC", stp(q1, q2, ptr_post(x12, 16)));
+ TEST_INSTRUCTION("E10B00AD", stp(q1, q2, ptr(sp)));
+ TEST_INSTRUCTION("E18B00AD", stp(q1, q2, ptr(sp, 16)));
+ TEST_INSTRUCTION("E10B04AD", stp(q1, q2, ptr(sp, 128)));
+ TEST_INSTRUCTION("E18B80AD", stp(q1, q2, ptr_pre(sp, 16)));
+ TEST_INSTRUCTION("E18B80AC", stp(q1, q2, ptr_post(sp, 16)));
+ TEST_INSTRUCTION("4100003D", str(b1, ptr(x2)));
+ TEST_INSTRUCTION("4114003C", str(b1, ptr_post(x2, 1)));
+ TEST_INSTRUCTION("4104003D", str(b1, ptr(x2, 1)));
+ TEST_INSTRUCTION("411C003C", str(b1, ptr_pre(x2, 1)));
+ TEST_INSTRUCTION("4114083C", str(b1, ptr_post(x2, 129)));
+ TEST_INSTRUCTION("4100007D", str(h1, ptr(x2)));
+ TEST_INSTRUCTION("4124007C", str(h1, ptr_post(x2, 2)));
+ TEST_INSTRUCTION("4104007D", str(h1, ptr(x2, 2)));
+ TEST_INSTRUCTION("412C007C", str(h1, ptr_pre(x2, 2)));
+ TEST_INSTRUCTION("4124087C", str(h1, ptr_post(x2, 130)));
+ TEST_INSTRUCTION("410000BD", str(s1, ptr(x2)));
+ TEST_INSTRUCTION("414400BC", str(s1, ptr_post(x2, 4)));
+ TEST_INSTRUCTION("410400BD", str(s1, ptr(x2, 4)));
+ TEST_INSTRUCTION("414C00BC", str(s1, ptr_pre(x2, 4)));
+ TEST_INSTRUCTION("414408BC", str(s1, ptr_post(x2, 132)));
+ TEST_INSTRUCTION("410000FD", str(d1, ptr(x2)));
+ TEST_INSTRUCTION("418400FC", str(d1, ptr_post(x2, 8)));
+ TEST_INSTRUCTION("410400FD", str(d1, ptr(x2, 8)));
+ TEST_INSTRUCTION("418C00FC", str(d1, ptr_pre(x2, 8)));
+ TEST_INSTRUCTION("414408FC", str(d1, ptr_post(x2, 132)));
+ TEST_INSTRUCTION("4168233C", str(b1, ptr(x2, x3)));
+ TEST_INSTRUCTION("4148233C", str(b1, ptr(x2, w3, uxtw(0))));
+ TEST_INSTRUCTION("41C8233C", str(b1, ptr(x2, w3, sxtw(0))));
+ TEST_INSTRUCTION("4168237C", str(h1, ptr(x2, x3)));
+ TEST_INSTRUCTION("4178237C", str(h1, ptr(x2, x3, lsl(1))));
+ TEST_INSTRUCTION("4148237C", str(h1, ptr(x2, w3, uxtw(0))));
+ TEST_INSTRUCTION("4158237C", str(h1, ptr(x2, w3, uxtw(1))));
+ TEST_INSTRUCTION("41C8237C", str(h1, ptr(x2, w3, sxtw(0))));
+ TEST_INSTRUCTION("41D8237C", str(h1, ptr(x2, w3, sxtw(1))));
+ TEST_INSTRUCTION("416823BC", str(s1, ptr(x2, x3)));
+ TEST_INSTRUCTION("417823BC", str(s1, ptr(x2, x3, lsl(2))));
+ TEST_INSTRUCTION("414823BC", str(s1, ptr(x2, w3, uxtw(0))));
+ TEST_INSTRUCTION("415823BC", str(s1, ptr(x2, w3, uxtw(2))));
+ TEST_INSTRUCTION("41C823BC", str(s1, ptr(x2, w3, sxtw(0))));
+ TEST_INSTRUCTION("41D823BC", str(s1, ptr(x2, w3, sxtw(2))));
+ TEST_INSTRUCTION("416823FC", str(d1, ptr(x2, x3)));
+ TEST_INSTRUCTION("417823FC", str(d1, ptr(x2, x3, lsl(3))));
+ TEST_INSTRUCTION("414823FC", str(d1, ptr(x2, w3, uxtw(0))));
+ TEST_INSTRUCTION("415823FC", str(d1, ptr(x2, w3, uxtw(3))));
+ TEST_INSTRUCTION("41C823FC", str(d1, ptr(x2, w3, sxtw(0))));
+ TEST_INSTRUCTION("41D823FC", str(d1, ptr(x2, w3, sxtw(3))));
+ TEST_INSTRUCTION("4104003D", str(b1, ptr(x2, 1)));
+ TEST_INSTRUCTION("41F01F3C", str(b1, ptr(x2, -1))); // STUR
+ TEST_INSTRUCTION("4110007C", str(h1, ptr(x2, 1))); // STUR
+ TEST_INSTRUCTION("41F01F7C", str(h1, ptr(x2, -1))); // STUR
+ TEST_INSTRUCTION("411000BC", str(s1, ptr(x2, 1))); // STUR
+ TEST_INSTRUCTION("41F01FBC", str(s1, ptr(x2, -1))); // STUR
+ TEST_INSTRUCTION("411000FC", str(d1, ptr(x2, 1))); // STUR
+ TEST_INSTRUCTION("41F01FFC", str(d1, ptr(x2, -1))); // STUR
+ TEST_INSTRUCTION("8101003C", stur(b1, ptr(x12)));
+ TEST_INSTRUCTION("8131003C", stur(b1, ptr(x12, 3)));
+ TEST_INSTRUCTION("8131063C", stur(b1, ptr(x12, 99)));
+ TEST_INSTRUCTION("81F10F3C", stur(b1, ptr(x12, 255)));
+ TEST_INSTRUCTION("8101103C", stur(b1, ptr(x12, -256)));
+ TEST_INSTRUCTION("E103003C", stur(b1, ptr(sp)));
+ TEST_INSTRUCTION("E153083C", stur(b1, ptr(sp, 133)));
+ TEST_INSTRUCTION("8101007C", stur(h1, ptr(x12)));
+ TEST_INSTRUCTION("8131007C", stur(h1, ptr(x12, 3)));
+ TEST_INSTRUCTION("8131067C", stur(h1, ptr(x12, 99)));
+ TEST_INSTRUCTION("81F10F7C", stur(h1, ptr(x12, 255)));
+ TEST_INSTRUCTION("8101107C", stur(h1, ptr(x12, -256)));
+ TEST_INSTRUCTION("E103007C", stur(h1, ptr(sp)));
+ TEST_INSTRUCTION("E153087C", stur(h1, ptr(sp, 133)));
+ TEST_INSTRUCTION("810100BC", stur(s1, ptr(x12)));
+ TEST_INSTRUCTION("813100BC", stur(s1, ptr(x12, 3)));
+ TEST_INSTRUCTION("813106BC", stur(s1, ptr(x12, 99)));
+ TEST_INSTRUCTION("81F10FBC", stur(s1, ptr(x12, 255)));
+ TEST_INSTRUCTION("810110BC", stur(s1, ptr(x12, -256)));
+ TEST_INSTRUCTION("E10300BC", stur(s1, ptr(sp)));
+ TEST_INSTRUCTION("E15308BC", stur(s1, ptr(sp, 133)));
+ TEST_INSTRUCTION("810100FC", stur(d1, ptr(x12)));
+ TEST_INSTRUCTION("813100FC", stur(d1, ptr(x12, 3)));
+ TEST_INSTRUCTION("813106FC", stur(d1, ptr(x12, 99)));
+ TEST_INSTRUCTION("81F10FFC", stur(d1, ptr(x12, 255)));
+ TEST_INSTRUCTION("810110FC", stur(d1, ptr(x12, -256)));
+ TEST_INSTRUCTION("E10300FC", stur(d1, ptr(sp)));
+ TEST_INSTRUCTION("E15308FC", stur(d1, ptr(sp, 133)));
+ TEST_INSTRUCTION("8101803C", stur(q1, ptr(x12)));
+ TEST_INSTRUCTION("8131803C", stur(q1, ptr(x12, 3)));
+ TEST_INSTRUCTION("8131863C", stur(q1, ptr(x12, 99)));
+ TEST_INSTRUCTION("81F18F3C", stur(q1, ptr(x12, 255)));
+ TEST_INSTRUCTION("8101903C", stur(q1, ptr(x12, -256)));
+ TEST_INSTRUCTION("E103803C", stur(q1, ptr(sp)));
+ TEST_INSTRUCTION("E153883C", stur(q1, ptr(sp, 133)));
+ TEST_INSTRUCTION("4184232E", sub(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4184632E", sub(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4184A32E", sub(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4184E37E", sub(d1, d2, d3));
+ TEST_INSTRUCTION("4184236E", sub(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4184636E", sub(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4184A36E", sub(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4184E36E", sub(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4160230E", subhn(v1.b8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4160630E", subhn(v1.h4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4160A30E", subhn(v1.s2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4160234E", subhn2(v1.b16(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4160634E", subhn2(v1.h8(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4160A34E", subhn2(v1.s4(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("41F0030F", sudot(v1.s2(), v2.b8(), v3.b4(0)));
+ TEST_INSTRUCTION("41F0230F", sudot(v1.s2(), v2.b8(), v3.b4(1)));
+ TEST_INSTRUCTION("41F8030F", sudot(v1.s2(), v2.b8(), v3.b4(2)));
+ TEST_INSTRUCTION("41F8230F", sudot(v1.s2(), v2.b8(), v3.b4(3)));
+ TEST_INSTRUCTION("41F0034F", sudot(v1.s4(), v2.b16(), v3.b4(0)));
+ TEST_INSTRUCTION("41F0234F", sudot(v1.s4(), v2.b16(), v3.b4(1)));
+ TEST_INSTRUCTION("41F8034F", sudot(v1.s4(), v2.b16(), v3.b4(2)));
+ TEST_INSTRUCTION("41F8234F", sudot(v1.s4(), v2.b16(), v3.b4(3)));
+ TEST_INSTRUCTION("4138205E", suqadd(b1, b2));
+ TEST_INSTRUCTION("4138605E", suqadd(h1, h2));
+ TEST_INSTRUCTION("4138A05E", suqadd(s1, s2));
+ TEST_INSTRUCTION("4138E05E", suqadd(d1, d2));
+ TEST_INSTRUCTION("4138200E", suqadd(v1.b8(), v2.b8()));
+ TEST_INSTRUCTION("4138600E", suqadd(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("4138A00E", suqadd(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("4138204E", suqadd(v1.b16(), v2.b16()));
+ TEST_INSTRUCTION("4138604E", suqadd(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("4138A04E", suqadd(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("4138E04E", suqadd(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("41A4080F", sxtl(v1.h8(), v2.b8()));
+ TEST_INSTRUCTION("41A4100F", sxtl(v1.s4(), v2.h4()));
+ TEST_INSTRUCTION("41A4200F", sxtl(v1.d2(), v2.s2()));
+ TEST_INSTRUCTION("41A4084F", sxtl2(v1.h8(), v2.b16()));
+ TEST_INSTRUCTION("41A4104F", sxtl2(v1.s4(), v2.h8()));
+ TEST_INSTRUCTION("41A4204F", sxtl2(v1.d2(), v2.s4()));
+ TEST_INSTRUCTION("4100030E", tbl(v1.b8(), v2.b16(), v3.b8()));
+ TEST_INSTRUCTION("4120040E", tbl(v1.b8(), v2.b16(), v3.b16(), v4.b8()));
+ TEST_INSTRUCTION("4140050E", tbl(v1.b8(), v2.b16(), v3.b16(), v4.b16(), v5.b8()));
+ TEST_INSTRUCTION("4160060E", tbl(v1.b8(), v2.b16(), v3.b16(), v4.b16(), v5.b16(), v6.b8()));
+ TEST_INSTRUCTION("4100034E", tbl(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4120044E", tbl(v1.b16(), v2.b16(), v3.b16(), v4.b16()));
+ TEST_INSTRUCTION("4140054E", tbl(v1.b16(), v2.b16(), v3.b16(), v4.b16(), v5.b16()));
+ TEST_INSTRUCTION("4160064E", tbl(v1.b16(), v2.b16(), v3.b16(), v4.b16(), v5.b16(), v6.b16()));
+ TEST_INSTRUCTION("4110030E", tbx(v1.b8(), v2.b16(), v3.b8()));
+ TEST_INSTRUCTION("4130040E", tbx(v1.b8(), v2.b16(), v3.b16(), v4.b8()));
+ TEST_INSTRUCTION("4150050E", tbx(v1.b8(), v2.b16(), v3.b16(), v4.b16(), v5.b8()));
+ TEST_INSTRUCTION("4170060E", tbx(v1.b8(), v2.b16(), v3.b16(), v4.b16(), v5.b16(), v6.b8()));
+ TEST_INSTRUCTION("4110034E", tbx(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4130044E", tbx(v1.b16(), v2.b16(), v3.b16(), v4.b16()));
+ TEST_INSTRUCTION("4150054E", tbx(v1.b16(), v2.b16(), v3.b16(), v4.b16(), v5.b16()));
+ TEST_INSTRUCTION("4170064E", tbx(v1.b16(), v2.b16(), v3.b16(), v4.b16(), v5.b16(), v6.b16()));
+ TEST_INSTRUCTION("4128030E", trn1(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4128430E", trn1(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4128830E", trn1(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4128034E", trn1(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4128434E", trn1(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4128834E", trn1(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4128C34E", trn1(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4168030E", trn2(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4168430E", trn2(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4168830E", trn2(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4168034E", trn2(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4168434E", trn2(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4168834E", trn2(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4168C34E", trn2(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("417C232E", uaba(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("417C632E", uaba(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("417CA32E", uaba(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("417C236E", uaba(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("417C636E", uaba(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("417CA36E", uaba(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4150232E", uabal(v1.h8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4150632E", uabal(v1.s4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4150A32E", uabal(v1.d2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4150236E", uabal2(v1.h8(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4150636E", uabal2(v1.s4(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4150A36E", uabal2(v1.d2(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4174232E", uabd(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4174632E", uabd(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4174A32E", uabd(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4174236E", uabd(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4174636E", uabd(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4174A36E", uabd(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4170232E", uabdl(v1.h8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4170632E", uabdl(v1.s4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4170A32E", uabdl(v1.d2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4170236E", uabdl2(v1.h8(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4170636E", uabdl2(v1.s4(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4170A36E", uabdl2(v1.d2(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4168202E", uadalp(v1.h4(), v2.b8()));
+ TEST_INSTRUCTION("4168602E", uadalp(v1.s2(), v2.h4()));
+ TEST_INSTRUCTION("4168A02E", uadalp(d1, v2.s2()));
+ TEST_INSTRUCTION("4168206E", uadalp(v1.h8(), v2.b16()));
+ TEST_INSTRUCTION("4168606E", uadalp(v1.s4(), v2.h8()));
+ TEST_INSTRUCTION("4168A06E", uadalp(v1.d2(), v2.s4()));
+ TEST_INSTRUCTION("4100232E", uaddl(v1.h8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4100632E", uaddl(v1.s4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4100A32E", uaddl(v1.d2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4100236E", uaddl2(v1.h8(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4100636E", uaddl2(v1.s4(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4100A36E", uaddl2(v1.d2(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4128202E", uaddlp(v1.h4(), v2.b8()));
+ TEST_INSTRUCTION("4128602E", uaddlp(v1.s2(), v2.h4()));
+ TEST_INSTRUCTION("4128A02E", uaddlp(d1, v2.s2()));
+ TEST_INSTRUCTION("4128206E", uaddlp(v1.h8(), v2.b16()));
+ TEST_INSTRUCTION("4128606E", uaddlp(v1.s4(), v2.h8()));
+ TEST_INSTRUCTION("4128A06E", uaddlp(v1.d2(), v2.s4()));
+ TEST_INSTRUCTION("4138302E", uaddlv(h1, v2.b8()));
+ TEST_INSTRUCTION("4138306E", uaddlv(h1, v2.b16()));
+ TEST_INSTRUCTION("4138702E", uaddlv(s1, v2.h4()));
+ TEST_INSTRUCTION("4138706E", uaddlv(s1, v2.h8()));
+ TEST_INSTRUCTION("4138B06E", uaddlv(d1, v2.s4()));
+ TEST_INSTRUCTION("4110232E", uaddw(v1.h8(), v2.h8(), v3.b8()));
+ TEST_INSTRUCTION("4110632E", uaddw(v1.s4(), v2.s4(), v3.h4()));
+ TEST_INSTRUCTION("4110A32E", uaddw(v1.d2(), v2.d2(), v3.s2()));
+ TEST_INSTRUCTION("4110236E", uaddw2(v1.h8(), v2.h8(), v3.b16()));
+ TEST_INSTRUCTION("4110636E", uaddw2(v1.s4(), v2.s4(), v3.h8()));
+ TEST_INSTRUCTION("4110A36E", uaddw2(v1.d2(), v2.d2(), v3.s4()));
+ TEST_INSTRUCTION("4100E31E", ucvtf(h1, w2));
+ TEST_INSTRUCTION("4100231E", ucvtf(s1, w2));
+ TEST_INSTRUCTION("4100631E", ucvtf(d1, w2));
+ TEST_INSTRUCTION("4100E39E", ucvtf(h1, x2));
+ TEST_INSTRUCTION("4100239E", ucvtf(s1, x2));
+ TEST_INSTRUCTION("4100639E", ucvtf(d1, x2));
+ TEST_INSTRUCTION("41D8797E", ucvtf(h1, h2));
+ TEST_INSTRUCTION("41D8217E", ucvtf(s1, s2));
+ TEST_INSTRUCTION("41D8617E", ucvtf(d1, d2));
+ TEST_INSTRUCTION("41D8792E", ucvtf(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("41D8212E", ucvtf(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41D8796E", ucvtf(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("41D8216E", ucvtf(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("41D8616E", ucvtf(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("41E0C31E", ucvtf(h1, w2, 8));
+ TEST_INSTRUCTION("41E0031E", ucvtf(s1, w2, 8));
+ TEST_INSTRUCTION("41E0431E", ucvtf(d1, w2, 8));
+ TEST_INSTRUCTION("41E0C39E", ucvtf(h1, x2, 8));
+ TEST_INSTRUCTION("41E0039E", ucvtf(s1, x2, 8));
+ TEST_INSTRUCTION("41E0439E", ucvtf(d1, x2, 8));
+ TEST_INSTRUCTION("41E4187F", ucvtf(h1, h2, 8));
+ TEST_INSTRUCTION("41E4387F", ucvtf(s1, s2, 8));
+ TEST_INSTRUCTION("41E4787F", ucvtf(d1, d2, 8));
+ TEST_INSTRUCTION("41E4182F", ucvtf(v1.h4(), v2.h4(), 8));
+ TEST_INSTRUCTION("41E4382F", ucvtf(v1.s2(), v2.s2(), 8));
+ TEST_INSTRUCTION("41E4186F", ucvtf(v1.h8(), v2.h8(), 8));
+ TEST_INSTRUCTION("41E4386F", ucvtf(v1.s4(), v2.s4(), 8));
+ TEST_INSTRUCTION("41E4786F", ucvtf(v1.d2(), v2.d2(), 8));
+ TEST_INSTRUCTION("4194832E", udot(v1.s2(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4194836E", udot(v1.s4(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("41E0832F", udot(v1.s2(), v2.b8(), v3.b4(0)));
+ TEST_INSTRUCTION("41E0A32F", udot(v1.s2(), v2.b8(), v3.b4(1)));
+ TEST_INSTRUCTION("41E8832F", udot(v1.s2(), v2.b8(), v3.b4(2)));
+ TEST_INSTRUCTION("41E8A32F", udot(v1.s2(), v2.b8(), v3.b4(3)));
+ TEST_INSTRUCTION("41E0836F", udot(v1.s4(), v2.b16(), v3.b4(0)));
+ TEST_INSTRUCTION("41E0A36F", udot(v1.s4(), v2.b16(), v3.b4(1)));
+ TEST_INSTRUCTION("41E8836F", udot(v1.s4(), v2.b16(), v3.b4(2)));
+ TEST_INSTRUCTION("41E8A36F", udot(v1.s4(), v2.b16(), v3.b4(3)));
+ TEST_INSTRUCTION("4104232E", uhadd(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4104632E", uhadd(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4104A32E", uhadd(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4104236E", uhadd(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4104636E", uhadd(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4104A36E", uhadd(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4124232E", uhsub(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4124632E", uhsub(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4124A32E", uhsub(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4124236E", uhsub(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4124636E", uhsub(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4124A36E", uhsub(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4164232E", umax(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4164632E", umax(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4164A32E", umax(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4164236E", umax(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4164636E", umax(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4164A36E", umax(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41A4232E", umaxp(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("41A4632E", umaxp(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41A4A32E", umaxp(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("41A4236E", umaxp(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("41A4636E", umaxp(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41A4A36E", umaxp(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41A8302E", umaxv(b1, v2.b8()));
+ TEST_INSTRUCTION("41A8306E", umaxv(b1, v2.b16()));
+ TEST_INSTRUCTION("41A8702E", umaxv(h1, v2.h4()));
+ TEST_INSTRUCTION("41A8706E", umaxv(h1, v2.h8()));
+ TEST_INSTRUCTION("41A8B06E", umaxv(s1, v2.s4()));
+ TEST_INSTRUCTION("416C232E", umin(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("416C632E", umin(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("416CA32E", umin(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("416C236E", umin(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("416C636E", umin(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("416CA36E", umin(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41AC232E", uminp(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("41AC632E", uminp(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41ACA32E", uminp(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("41AC236E", uminp(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("41AC636E", uminp(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41ACA36E", uminp(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41A8312E", uminv(b1, v2.b8()));
+ TEST_INSTRUCTION("41A8316E", uminv(b1, v2.b16()));
+ TEST_INSTRUCTION("41A8712E", uminv(h1, v2.h4()));
+ TEST_INSTRUCTION("41A8716E", uminv(h1, v2.h8()));
+ TEST_INSTRUCTION("41A8B16E", uminv(s1, v2.s4()));
+ TEST_INSTRUCTION("4180232E", umlal(v1.h8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4180632E", umlal(v1.s4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4180A32E", umlal(v1.d2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4120732F", umlal(v1.s4(), v2.h4(), v3.h(3)));
+ TEST_INSTRUCTION("4128A32F", umlal(v1.d2(), v2.s2(), v3.s(3)));
+ TEST_INSTRUCTION("4180236E", umlal2(v1.h8(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4180636E", umlal2(v1.s4(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4180A36E", umlal2(v1.d2(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4120736F", umlal2(v1.s4(), v2.h8(), v3.h(3)));
+ TEST_INSTRUCTION("4128A36F", umlal2(v1.d2(), v2.s4(), v3.s(3)));
+ TEST_INSTRUCTION("41A0232E", umlsl(v1.h8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("41A0632E", umlsl(v1.s4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41A0A32E", umlsl(v1.d2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4160732F", umlsl(v1.s4(), v2.h4(), v3.h(3)));
+ TEST_INSTRUCTION("4168A32F", umlsl(v1.d2(), v2.s2(), v3.s(3)));
+ TEST_INSTRUCTION("41A0236E", umlsl2(v1.h8(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("41A0636E", umlsl2(v1.s4(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41A0A36E", umlsl2(v1.d2(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4160736F", umlsl2(v1.s4(), v2.h8(), v3.h(3)));
+ TEST_INSTRUCTION("4168A36F", umlsl2(v1.d2(), v2.s4(), v3.s(3)));
+ TEST_INSTRUCTION("41A4836E", ummla(v1.s4(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("413C010E", umov(w1, v2.b(0)));
+ TEST_INSTRUCTION("413C1F0E", umov(w1, v2.b(15)));
+ TEST_INSTRUCTION("413C020E", umov(w1, v2.h(0)));
+ TEST_INSTRUCTION("413C1E0E", umov(w1, v2.h(7)));
+ TEST_INSTRUCTION("413C040E", umov(w1, v2.s(0)));
+ TEST_INSTRUCTION("413C1C0E", umov(w1, v2.s(3)));
+ TEST_INSTRUCTION("413C084E", umov(x1, v2.d(0)));
+ TEST_INSTRUCTION("413C184E", umov(x1, v2.d(1)));
+ TEST_INSTRUCTION("41C0232E", umull(v1.h8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("41C0632E", umull(v1.s4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("41C0A32E", umull(v1.d2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("41A0732F", umull(v1.s4(), v2.h4(), v3.h(3)));
+ TEST_INSTRUCTION("41A8A32F", umull(v1.d2(), v2.s2(), v3.s(3)));
+ TEST_INSTRUCTION("41C0236E", umull2(v1.h8(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("41C0636E", umull2(v1.s4(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("41C0A36E", umull2(v1.d2(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("41A0736F", umull2(v1.s4(), v2.h8(), v3.h(3)));
+ TEST_INSTRUCTION("41A8A36F", umull2(v1.d2(), v2.s4(), v3.s(3)));
+ TEST_INSTRUCTION("410C237E", uqadd(b1, b2, b3));
+ TEST_INSTRUCTION("410C637E", uqadd(h1, h2, h3));
+ TEST_INSTRUCTION("410CA37E", uqadd(s1, s2, s3));
+ TEST_INSTRUCTION("410CE37E", uqadd(d1, d2, d3));
+ TEST_INSTRUCTION("410C232E", uqadd(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("410C632E", uqadd(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("410CA32E", uqadd(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("410C236E", uqadd(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("410C636E", uqadd(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("410CA36E", uqadd(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("410CE36E", uqadd(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("415C237E", uqrshl(b1, b2, b3));
+ TEST_INSTRUCTION("415C637E", uqrshl(h1, h2, h3));
+ TEST_INSTRUCTION("415CA37E", uqrshl(s1, s2, s3));
+ TEST_INSTRUCTION("415C232E", uqrshl(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("415C632E", uqrshl(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("415CA32E", uqrshl(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("415CE37E", uqrshl(d1, d2, d3));
+ TEST_INSTRUCTION("415C236E", uqrshl(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("415C636E", uqrshl(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("415CA36E", uqrshl(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("415CE36E", uqrshl(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("419C087F", uqrshrn(b1, h2, 8));
+ TEST_INSTRUCTION("419C107F", uqrshrn(h1, s2, 16));
+ TEST_INSTRUCTION("419C207F", uqrshrn(s1, d2, 32));
+ TEST_INSTRUCTION("419C082F", uqrshrn(v1.b8(), v2.h8(), 8));
+ TEST_INSTRUCTION("419C102F", uqrshrn(v1.h4(), v2.s4(), 16));
+ TEST_INSTRUCTION("419C202F", uqrshrn(v1.s2(), v2.d2(), 32));
+ TEST_INSTRUCTION("419C086F", uqrshrn2(v1.b16(), v2.h8(), 8));
+ TEST_INSTRUCTION("419C106F", uqrshrn2(v1.h8(), v2.s4(), 16));
+ TEST_INSTRUCTION("419C206F", uqrshrn2(v1.s4(), v2.d2(), 32));
+ TEST_INSTRUCTION("4174097F", uqshl(b1, b2, 1));
+ TEST_INSTRUCTION("4174127F", uqshl(h1, h2, 2));
+ TEST_INSTRUCTION("4174237F", uqshl(s1, s2, 3));
+ TEST_INSTRUCTION("41740F2F", uqshl(v1.b8(), v2.b8(), 7));
+ TEST_INSTRUCTION("41741F2F", uqshl(v1.h4(), v2.h4(), 15));
+ TEST_INSTRUCTION("41743F2F", uqshl(v1.s2(), v2.s2(), 31));
+ TEST_INSTRUCTION("41747F7F", uqshl(d1, d2, 63));
+ TEST_INSTRUCTION("41740F6F", uqshl(v1.b16(), v2.b16(), 7));
+ TEST_INSTRUCTION("41741F6F", uqshl(v1.h8(), v2.h8(), 15));
+ TEST_INSTRUCTION("41743F6F", uqshl(v1.s4(), v2.s4(), 31));
+ TEST_INSTRUCTION("41747F6F", uqshl(v1.d2(), v2.d2(), 63));
+ TEST_INSTRUCTION("414C237E", uqshl(b1, b2, b3));
+ TEST_INSTRUCTION("414C637E", uqshl(h1, h2, h3));
+ TEST_INSTRUCTION("414CA37E", uqshl(s1, s2, s3));
+ TEST_INSTRUCTION("414C232E", uqshl(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("414C632E", uqshl(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("414CA32E", uqshl(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("414CE37E", uqshl(d1, d2, d3));
+ TEST_INSTRUCTION("414C236E", uqshl(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("414C636E", uqshl(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("414CA36E", uqshl(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("414CE36E", uqshl(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4194087F", uqshrn(b1, h2, 8));
+ TEST_INSTRUCTION("4194107F", uqshrn(h1, s2, 16));
+ TEST_INSTRUCTION("4194207F", uqshrn(s1, d2, 32));
+ TEST_INSTRUCTION("4194082F", uqshrn(v1.b8(), v2.h8(), 8));
+ TEST_INSTRUCTION("4194102F", uqshrn(v1.h4(), v2.s4(), 16));
+ TEST_INSTRUCTION("4194202F", uqshrn(v1.s2(), v2.d2(), 32));
+ TEST_INSTRUCTION("4194086F", uqshrn2(v1.b16(), v2.h8(), 8));
+ TEST_INSTRUCTION("4194106F", uqshrn2(v1.h8(), v2.s4(), 16));
+ TEST_INSTRUCTION("4194206F", uqshrn2(v1.s4(), v2.d2(), 32));
+ TEST_INSTRUCTION("412C237E", uqsub(b1, b2, b3));
+ TEST_INSTRUCTION("412C637E", uqsub(h1, h2, h3));
+ TEST_INSTRUCTION("412CA37E", uqsub(s1, s2, s3));
+ TEST_INSTRUCTION("412CE37E", uqsub(d1, d2, d3));
+ TEST_INSTRUCTION("412C232E", uqsub(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("412C632E", uqsub(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("412CA32E", uqsub(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("412C236E", uqsub(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("412C636E", uqsub(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("412CA36E", uqsub(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("412CE36E", uqsub(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4148217E", uqxtn(b1, h2));
+ TEST_INSTRUCTION("4148617E", uqxtn(h1, s2));
+ TEST_INSTRUCTION("4148A17E", uqxtn(s1, d2));
+ TEST_INSTRUCTION("4148212E", uqxtn(v1.b8(), v2.h8()));
+ TEST_INSTRUCTION("4148612E", uqxtn(v1.h4(), v2.s4()));
+ TEST_INSTRUCTION("4148A12E", uqxtn(v1.s2(), v2.d2()));
+ TEST_INSTRUCTION("4148216E", uqxtn2(v1.b16(), v2.h8()));
+ TEST_INSTRUCTION("4148616E", uqxtn2(v1.h8(), v2.s4()));
+ TEST_INSTRUCTION("4148A16E", uqxtn2(v1.s4(), v2.d2()));
+ TEST_INSTRUCTION("41C8A10E", urecpe(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41C8A14E", urecpe(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("4114232E", urhadd(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4114632E", urhadd(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4114A32E", urhadd(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4114236E", urhadd(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4114636E", urhadd(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4114A36E", urhadd(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4154232E", urshl(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4154632E", urshl(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4154A32E", urshl(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4154E37E", urshl(d1, d2, d3));
+ TEST_INSTRUCTION("4154236E", urshl(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4154636E", urshl(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4154A36E", urshl(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4154E36E", urshl(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4124092F", urshr(v1.b8(), v2.b8(), 7));
+ TEST_INSTRUCTION("4124112F", urshr(v1.h4(), v2.h4(), 15));
+ TEST_INSTRUCTION("4124212F", urshr(v1.s2(), v2.s2(), 31));
+ TEST_INSTRUCTION("4124417F", urshr(d1, d2, 63));
+ TEST_INSTRUCTION("4124096F", urshr(v1.b16(), v2.b16(), 7));
+ TEST_INSTRUCTION("4124116F", urshr(v1.h8(), v2.h8(), 15));
+ TEST_INSTRUCTION("4124216F", urshr(v1.s4(), v2.s4(), 31));
+ TEST_INSTRUCTION("4124416F", urshr(v1.d2(), v2.d2(), 63));
+ TEST_INSTRUCTION("41C8A12E", ursqrte(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("41C8A16E", ursqrte(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("4134092F", ursra(v1.b8(), v2.b8(), 7));
+ TEST_INSTRUCTION("4134112F", ursra(v1.h4(), v2.h4(), 15));
+ TEST_INSTRUCTION("4134212F", ursra(v1.s2(), v2.s2(), 31));
+ TEST_INSTRUCTION("4134417F", ursra(d1, d2, 63));
+ TEST_INSTRUCTION("4134096F", ursra(v1.b16(), v2.b16(), 7));
+ TEST_INSTRUCTION("4134116F", ursra(v1.h8(), v2.h8(), 15));
+ TEST_INSTRUCTION("4134216F", ursra(v1.s4(), v2.s4(), 31));
+ TEST_INSTRUCTION("4134416F", ursra(v1.d2(), v2.d2(), 63));
+ TEST_INSTRUCTION("419C830E", usdot(v1.s2(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("419C834E", usdot(v1.s4(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("41F0830F", usdot(v1.s2(), v2.b8(), v3.b4(0)));
+ TEST_INSTRUCTION("41F0A30F", usdot(v1.s2(), v2.b8(), v3.b4(1)));
+ TEST_INSTRUCTION("41F8830F", usdot(v1.s2(), v2.b8(), v3.b4(2)));
+ TEST_INSTRUCTION("41F8A30F", usdot(v1.s2(), v2.b8(), v3.b4(3)));
+ TEST_INSTRUCTION("41F0834F", usdot(v1.s4(), v2.b16(), v3.b4(0)));
+ TEST_INSTRUCTION("41F0A34F", usdot(v1.s4(), v2.b16(), v3.b4(1)));
+ TEST_INSTRUCTION("41F8834F", usdot(v1.s4(), v2.b16(), v3.b4(2)));
+ TEST_INSTRUCTION("41F8A34F", usdot(v1.s4(), v2.b16(), v3.b4(3)));
+ TEST_INSTRUCTION("4144232E", ushl(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4144632E", ushl(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4144A32E", ushl(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4144E37E", ushl(d1, d2, d3));
+ TEST_INSTRUCTION("4144236E", ushl(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4144636E", ushl(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4144A36E", ushl(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4144E36E", ushl(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("41A40F2F", ushll(v1.h8(), v2.b8(), 7));
+ TEST_INSTRUCTION("41A41F2F", ushll(v1.s4(), v2.h4(), 15));
+ TEST_INSTRUCTION("41A43F2F", ushll(v1.d2(), v2.s2(), 31));
+ TEST_INSTRUCTION("41A40F6F", ushll2(v1.h8(), v2.b16(), 7));
+ TEST_INSTRUCTION("41A41F6F", ushll2(v1.s4(), v2.h8(), 15));
+ TEST_INSTRUCTION("41A43F6F", ushll2(v1.s2(), v2.s4(), 31));
+ TEST_INSTRUCTION("4104092F", ushr(v1.b8(), v2.b8(), 7));
+ TEST_INSTRUCTION("4104112F", ushr(v1.h4(), v2.h4(), 15));
+ TEST_INSTRUCTION("4104212F", ushr(v1.s2(), v2.s2(), 31));
+ TEST_INSTRUCTION("4104417F", ushr(d1, d2, 63));
+ TEST_INSTRUCTION("4104096F", ushr(v1.b16(), v2.b16(), 7));
+ TEST_INSTRUCTION("4104116F", ushr(v1.h8(), v2.h8(), 15));
+ TEST_INSTRUCTION("4104216F", ushr(v1.s4(), v2.s4(), 31));
+ TEST_INSTRUCTION("4104416F", ushr(v1.d2(), v2.d2(), 63));
+ TEST_INSTRUCTION("41AC834E", usmmla(v1.s4(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4138207E", usqadd(b1, b2));
+ TEST_INSTRUCTION("4138607E", usqadd(h1, h2));
+ TEST_INSTRUCTION("4138A07E", usqadd(s1, s2));
+ TEST_INSTRUCTION("4138E07E", usqadd(d1, d2));
+ TEST_INSTRUCTION("4138202E", usqadd(v1.b8(), v2.b8()));
+ TEST_INSTRUCTION("4138602E", usqadd(v1.h4(), v2.h4()));
+ TEST_INSTRUCTION("4138A02E", usqadd(v1.s2(), v2.s2()));
+ TEST_INSTRUCTION("4138206E", usqadd(v1.b16(), v2.b16()));
+ TEST_INSTRUCTION("4138606E", usqadd(v1.h8(), v2.h8()));
+ TEST_INSTRUCTION("4138A06E", usqadd(v1.s4(), v2.s4()));
+ TEST_INSTRUCTION("4138E06E", usqadd(v1.d2(), v2.d2()));
+ TEST_INSTRUCTION("4114092F", usra(v1.b8(), v2.b8(), 7));
+ TEST_INSTRUCTION("4114112F", usra(v1.h4(), v2.h4(), 15));
+ TEST_INSTRUCTION("4114212F", usra(v1.s2(), v2.s2(), 31));
+ TEST_INSTRUCTION("4114417F", usra(d1, d2, 63));
+ TEST_INSTRUCTION("4114096F", usra(v1.b16(), v2.b16(), 7));
+ TEST_INSTRUCTION("4114116F", usra(v1.h8(), v2.h8(), 15));
+ TEST_INSTRUCTION("4114216F", usra(v1.s4(), v2.s4(), 31));
+ TEST_INSTRUCTION("4114416F", usra(v1.d2(), v2.d2(), 63));
+ TEST_INSTRUCTION("4120232E", usubl(v1.h8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4120632E", usubl(v1.s4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4120A32E", usubl(v1.d2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4120236E", usubl2(v1.h8(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4120636E", usubl2(v1.s4(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4120A36E", usubl2(v1.d2(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4130232E", usubw(v1.h8(), v2.h8(), v3.b8()));
+ TEST_INSTRUCTION("4130632E", usubw(v1.s4(), v2.s4(), v3.h4()));
+ TEST_INSTRUCTION("4130A32E", usubw(v1.d2(), v2.d2(), v3.s2()));
+ TEST_INSTRUCTION("4130236E", usubw2(v1.h8(), v2.h8(), v3.b16()));
+ TEST_INSTRUCTION("4130636E", usubw2(v1.s4(), v2.s4(), v3.h8()));
+ TEST_INSTRUCTION("4130A36E", usubw2(v1.d2(), v2.d2(), v3.s4()));
+ TEST_INSTRUCTION("41A4082F", uxtl(v1.h8(), v2.b8()));
+ TEST_INSTRUCTION("41A4102F", uxtl(v1.s4(), v2.h4()));
+ TEST_INSTRUCTION("41A4202F", uxtl(v1.d2(), v2.s2()));
+ TEST_INSTRUCTION("41A4086F", uxtl2(v1.h8(), v2.b16()));
+ TEST_INSTRUCTION("41A4106F", uxtl2(v1.s4(), v2.h8()));
+ TEST_INSTRUCTION("41A4206F", uxtl2(v1.d2(), v2.s4()));
+ TEST_INSTRUCTION("4118030E", uzp1(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4118430E", uzp1(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4118830E", uzp1(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4118034E", uzp1(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4118434E", uzp1(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4118834E", uzp1(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4118C34E", uzp1(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4158030E", uzp2(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4158430E", uzp2(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4158830E", uzp2(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4158034E", uzp2(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4158434E", uzp2(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4158834E", uzp2(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4158C34E", uzp2(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4128210E", xtn(v1.b8(), v2.h8()));
+ TEST_INSTRUCTION("4128610E", xtn(v1.h4(), v2.s4()));
+ TEST_INSTRUCTION("4128A10E", xtn(v1.s2(), v2.d2()));
+ TEST_INSTRUCTION("4128214E", xtn2(v1.b16(), v2.h8()));
+ TEST_INSTRUCTION("4128614E", xtn2(v1.h8(), v2.s4()));
+ TEST_INSTRUCTION("4128A14E", xtn2(v1.s4(), v2.d2()));
+ TEST_INSTRUCTION("4138030E", zip1(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4138430E", zip1(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4138830E", zip1(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4138034E", zip1(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4138434E", zip1(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4138834E", zip1(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4138C34E", zip1(v1.d2(), v2.d2(), v3.d2()));
+ TEST_INSTRUCTION("4178030E", zip2(v1.b8(), v2.b8(), v3.b8()));
+ TEST_INSTRUCTION("4178430E", zip2(v1.h4(), v2.h4(), v3.h4()));
+ TEST_INSTRUCTION("4178830E", zip2(v1.s2(), v2.s2(), v3.s2()));
+ TEST_INSTRUCTION("4178034E", zip2(v1.b16(), v2.b16(), v3.b16()));
+ TEST_INSTRUCTION("4178434E", zip2(v1.h8(), v2.h8(), v3.h8()));
+ TEST_INSTRUCTION("4178834E", zip2(v1.s4(), v2.s4(), v3.s4()));
+ TEST_INSTRUCTION("4178C34E", zip2(v1.d2(), v2.d2(), v3.d2()));
+}
+
+static void ASMJIT_NOINLINE testA64AssemblerExtras(AssemblerTester<a64::Assembler>& tester) noexcept {
+ using namespace a64;
+
+ // AsmJit additions - AArch64 assembler accepts variety of immediates in
+ // MOVI instruction that it encodes by changing the size of its operands.
+ TEST_INSTRUCTION("C1E7074F", movi(v1.b16(), 0xFE));
+ TEST_INSTRUCTION("C1E7074F", movi(v1.h8(), 0xFEFE));
+ TEST_INSTRUCTION("C1E7074F", movi(v1.s4(), 0xFEFEFEFE));
+ TEST_INSTRUCTION("C1E7074F", movi(v1.d2(), 0xFEFEFEFEFEFEFEFE));
+ TEST_INSTRUCTION("C1A7074F", movi(v1.h8(), 0xFE, lsl(8)));
+ TEST_INSTRUCTION("C1A7074F", movi(v1.h8(), 0xFE00));
+ TEST_INSTRUCTION("C1A7074F", movi(v1.s4(), 0xFE00FE00));
+ TEST_INSTRUCTION("C1A7074F", movi(v1.d2(), 0xFE00FE00FE00FE00));
+ TEST_INSTRUCTION("C147074F", movi(v1.s4(), 0xFE, lsl(16)));
+ TEST_INSTRUCTION("C147074F", movi(v1.s4(), 0x00FE0000));
+ TEST_INSTRUCTION("C147074F", movi(v1.d2(), 0x00FE000000FE0000));
+ TEST_INSTRUCTION("C167074F", movi(v1.s4(), 0xFE, lsl(24)));
+ TEST_INSTRUCTION("C167074F", movi(v1.s4(), 0xFE000000));
+ TEST_INSTRUCTION("C167074F", movi(v1.d2(), 0xFE000000FE000000));
+}
+
+bool testA64Assembler(const TestSettings& settings) noexcept {
+ using namespace a64;
+
+ AssemblerTester<Assembler> tester(Arch::kAArch64, settings);
+ tester.printHeader("AArch64");
+
+ testA64AssemblerBase(tester);
+ testA64AssemblerRel(tester);
+ testA64AssemblerSIMD(tester);
+ testA64AssemblerExtras(tester);
+
+ tester.printSummary();
+ return tester.didPass();
+}
+
+#undef TEST_INSTRUCTION
+
+#endif // !ASMJIT_NO_AARCH64
diff --git a/test/asmjit_test_compiler.cpp b/test/asmjit_test_compiler.cpp
index 70a24a9..f2bc306 100644
--- a/test/asmjit_test_compiler.cpp
+++ b/test/asmjit_test_compiler.cpp
@@ -24,7 +24,7 @@
void compiler_add_x86_tests(TestApp& app);
#endif
-#if defined(ASMJIT_BUILD_ARM) && ASMJIT_ARCH_ARM == 64
+#if !defined(ASMJIT_NO_AARCH64) && ASMJIT_ARCH_ARM == 64
#include <asmjit/a64.h>
void compiler_add_a64_tests(TestApp& app);
#endif
@@ -33,7 +33,7 @@ void compiler_add_a64_tests(TestApp& app);
#define ASMJIT_HAVE_WORKING_JIT
#endif
-#if defined(ASMJIT_BUILD_ARM) && ASMJIT_ARCH_ARM == 64
+#if !defined(ASMJIT_NO_AARCH64) && ASMJIT_ARCH_ARM == 64
#define ASMJIT_HAVE_WORKING_JIT
#endif
@@ -118,8 +118,8 @@ int TestApp::run() {
x86::Compiler cc(&code);
#endif
-#if defined(ASMJIT_BUILD_ARM) && ASMJIT_ARCH_ARM == 64
- arm::Compiler cc(&code);
+#if !defined(ASMJIT_NO_AARCH64) && ASMJIT_ARCH_ARM == 64
+ a64::Compiler cc(&code);
#endif
#ifndef ASMJIT_NO_LOGGING
@@ -245,7 +245,7 @@ int main(int argc, char* argv[]) {
compiler_add_x86_tests(app);
#endif
-#if defined(ASMJIT_BUILD_ARM) && ASMJIT_ARCH_ARM == 64
+#if !defined(ASMJIT_NO_AARCH64) && ASMJIT_ARCH_ARM == 64
compiler_add_a64_tests(app);
#endif
diff --git a/test/asmjit_test_compiler_a64.cpp b/test/asmjit_test_compiler_a64.cpp
new file mode 100644
index 0000000..4fc362e
--- /dev/null
+++ b/test/asmjit_test_compiler_a64.cpp
@@ -0,0 +1,690 @@
+// 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 <asmjit/core.h>
+#if !defined(ASMJIT_NO_AARCH64) && ASMJIT_ARCH_ARM == 64
+
+#include <asmjit/a64.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "./asmjit_test_compiler.h"
+
+using namespace asmjit;
+
+// a64::Compiler - A64TestCase
+// ===========================
+
+class A64TestCase : public TestCase {
+public:
+ A64TestCase(const char* name = nullptr)
+ : TestCase(name) {}
+
+ virtual void compile(BaseCompiler& cc) override {
+ compile(static_cast<a64::Compiler&>(cc));
+ }
+
+ virtual void compile(a64::Compiler& cc) = 0;
+};
+
+// a64::Compiler - A64Test_GpArgs
+// ==============================
+
+class A64Test_GpArgs : public A64TestCase {
+public:
+ uint32_t _argCount;
+ bool _preserveFP;
+
+ A64Test_GpArgs(uint32_t argCount, bool preserveFP)
+ : _argCount(argCount),
+ _preserveFP(preserveFP) {
+ _name.assignFormat("GpArgs {NumArgs=%u PreserveFP=%c}", argCount, preserveFP ? 'Y' : 'N');
+ }
+
+ static void add(TestApp& app) {
+ for (uint32_t i = 0; i <= 16; i++) {
+ app.add(new A64Test_GpArgs(i, true));
+ app.add(new A64Test_GpArgs(i, false));
+ }
+ }
+
+ virtual void compile(a64::Compiler& cc) {
+ uint32_t i;
+ uint32_t argCount = _argCount;
+
+ FuncSignatureBuilder signature;
+ signature.setRetT<int>();
+ for (i = 0; i < argCount; i++)
+ signature.addArgT<int>();
+
+ FuncNode* funcNode = cc.addFunc(signature);
+ if (_preserveFP)
+ funcNode->frame().setPreservedFP();
+
+ arm::Gp sum;
+
+ if (argCount) {
+ for (i = 0; i < argCount; i++) {
+ arm::Gp iReg = cc.newInt32("i%u", i);
+ funcNode->setArg(i, iReg);
+
+ if (i == 0)
+ sum = iReg;
+ else
+ cc.add(sum, sum, iReg);
+ }
+ }
+ else {
+ sum = cc.newInt32("i");
+ cc.mov(sum, 0);
+ }
+
+ cc.ret(sum);
+ cc.endFunc();
+ }
+
+ virtual bool run(void* _func, String& result, String& expect) {
+ typedef unsigned int U;
+
+ typedef U (*Func0)();
+ typedef U (*Func1)(U);
+ typedef U (*Func2)(U, U);
+ typedef U (*Func3)(U, U, U);
+ typedef U (*Func4)(U, U, U, U);
+ typedef U (*Func5)(U, U, U, U, U);
+ typedef U (*Func6)(U, U, U, U, U, U);
+ typedef U (*Func7)(U, U, U, U, U, U, U);
+ typedef U (*Func8)(U, U, U, U, U, U, U, U);
+ typedef U (*Func9)(U, U, U, U, U, U, U, U, U);
+ typedef U (*Func10)(U, U, U, U, U, U, U, U, U, U);
+ typedef U (*Func11)(U, U, U, U, U, U, U, U, U, U, U);
+ typedef U (*Func12)(U, U, U, U, U, U, U, U, U, U, U, U);
+ typedef U (*Func13)(U, U, U, U, U, U, U, U, U, U, U, U, U);
+ typedef U (*Func14)(U, U, U, U, U, U, U, U, U, U, U, U, U, U);
+ typedef U (*Func15)(U, U, U, U, U, U, U, U, U, U, U, U, U, U, U);
+ typedef U (*Func16)(U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U);
+
+ unsigned int resultRet = 0;
+ unsigned int expectRet = 0;
+
+ switch (_argCount) {
+ case 0:
+ resultRet = ptr_as_func<Func0>(_func)();
+ expectRet = 0;
+ break;
+ case 1:
+ resultRet = ptr_as_func<Func1>(_func)(1);
+ expectRet = 1;
+ break;
+ case 2:
+ resultRet = ptr_as_func<Func2>(_func)(1, 2);
+ expectRet = 1 + 2;
+ break;
+ case 3:
+ resultRet = ptr_as_func<Func3>(_func)(1, 2, 3);
+ expectRet = 1 + 2 + 3;
+ break;
+ case 4:
+ resultRet = ptr_as_func<Func4>(_func)(1, 2, 3, 4);
+ expectRet = 1 + 2 + 3 + 4;
+ break;
+ case 5:
+ resultRet = ptr_as_func<Func5>(_func)(1, 2, 3, 4, 5);
+ expectRet = 1 + 2 + 3 + 4 + 5;
+ break;
+ case 6:
+ resultRet = ptr_as_func<Func6>(_func)(1, 2, 3, 4, 5, 6);
+ expectRet = 1 + 2 + 3 + 4 + 5 + 6;
+ break;
+ case 7:
+ resultRet = ptr_as_func<Func7>(_func)(1, 2, 3, 4, 5, 6, 7);
+ expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7;
+ break;
+ case 8:
+ resultRet = ptr_as_func<Func8>(_func)(1, 2, 3, 4, 5, 6, 7, 8);
+ expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8;
+ break;
+ case 9:
+ resultRet = ptr_as_func<Func9>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9);
+ expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9;
+ break;
+ case 10:
+ resultRet = ptr_as_func<Func10>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+ expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10;
+ break;
+ case 11:
+ resultRet = ptr_as_func<Func11>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
+ expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11;
+ break;
+ case 12:
+ resultRet = ptr_as_func<Func12>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
+ expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12;
+ break;
+ case 13:
+ resultRet = ptr_as_func<Func13>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
+ expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13;
+ break;
+ case 14:
+ resultRet = ptr_as_func<Func14>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
+ expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14;
+ break;
+ case 15:
+ resultRet = ptr_as_func<Func15>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
+ expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15;
+ break;
+ case 16:
+ resultRet = ptr_as_func<Func16>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
+ expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16;
+ break;
+ }
+
+ result.assignFormat("ret={%u, %u}", resultRet >> 28, resultRet & 0x0FFFFFFFu);
+ expect.assignFormat("ret={%u, %u}", expectRet >> 28, expectRet & 0x0FFFFFFFu);
+
+ return resultRet == expectRet;
+ }
+};
+
+// a64::Compiler - A64Test_Simd1
+// =============================
+
+class A64Test_Simd1 : public A64TestCase {
+public:
+ A64Test_Simd1()
+ : A64TestCase("Simd1") {}
+
+ static void add(TestApp& app) {
+ app.add(new A64Test_Simd1());
+ }
+
+ virtual void compile(a64::Compiler& cc) {
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<void, void*, const void*, const void*>());
+
+ arm::Gp dst = cc.newUIntPtr("dst");
+ arm::Gp src1 = cc.newUIntPtr("src1");
+ arm::Gp src2 = cc.newUIntPtr("src2");
+
+ funcNode->setArg(0, dst);
+ funcNode->setArg(1, src1);
+ funcNode->setArg(2, src2);
+
+ arm::Vec v1 = cc.newVecQ("vec1");
+ arm::Vec v2 = cc.newVecQ("vec2");
+ arm::Vec v3 = cc.newVecQ("vec3");
+
+ cc.ldr(v2, arm::ptr(src1));
+ cc.ldr(v3, arm::ptr(src2));
+ cc.add(v1.b16(), v2.b16(), v3.b16());
+ cc.str(v1, arm::ptr(dst));
+
+ cc.endFunc();
+ }
+
+ virtual bool run(void* _func, String& result, String& expect) {
+ typedef void (*Func)(void*, const void*, const void*);
+
+ uint32_t dst[4];
+ uint32_t aSrc[4] = { 0 , 1 , 2 , 255 };
+ uint32_t bSrc[4] = { 99, 17, 33, 1 };
+
+ // NOTE: It's a byte-add, so uint8_t(255+1) == 0.
+ uint32_t ref[4] = { 99, 18, 35, 0 };
+
+ ptr_as_func<Func>(_func)(dst, aSrc, bSrc);
+
+ unsigned int resultRet = 0;
+ unsigned int expectRet = 0;
+
+ result.assignFormat("ret={%u, %u, %u, %u}", dst[0], dst[1], dst[2], dst[3]);
+ expect.assignFormat("ret={%u, %u, %u, %u}", ref[0], ref[1], ref[2], ref[3]);
+
+ return resultRet == expectRet;
+ }
+};
+
+// a64::Compiler - A64Test_ManyRegs
+// ================================
+
+class A64Test_ManyRegs : public A64TestCase {
+public:
+ uint32_t _regCount;
+
+ A64Test_ManyRegs(uint32_t n)
+ : A64TestCase(),
+ _regCount(n) {
+ _name.assignFormat("GpRegs {NumRegs=%u}", n);
+ }
+
+ static void add(TestApp& app) {
+ for (uint32_t i = 2; i < 64; i++)
+ app.add(new A64Test_ManyRegs(i));
+ }
+
+ virtual void compile(a64::Compiler& cc) {
+ cc.addFunc(FuncSignatureT<int>());
+
+ arm::Gp* regs = static_cast<arm::Gp*>(malloc(_regCount * sizeof(arm::Gp)));
+
+ for (uint32_t i = 0; i < _regCount; i++) {
+ regs[i] = cc.newUInt32("reg%u", i);
+ cc.mov(regs[i], i + 1);
+ }
+
+ arm::Gp sum = cc.newUInt32("sum");
+ cc.mov(sum, 0);
+
+ for (uint32_t i = 0; i < _regCount; i++) {
+ cc.add(sum, sum, regs[i]);
+ }
+
+ cc.ret(sum);
+ cc.endFunc();
+
+ free(regs);
+ }
+
+ virtual bool run(void* _func, String& result, String& expect) {
+ typedef int (*Func)(void);
+ Func func = ptr_as_func<Func>(_func);
+
+ result.assignFormat("ret={%d}", func());
+ expect.assignFormat("ret={%d}", calcSum());
+
+ return result == expect;
+ }
+
+ uint32_t calcSum() const {
+ return (_regCount | 1) * ((_regCount + 1) / 2);
+ }
+};
+
+// a64::Compiler - A64Test_Adr
+// ===========================
+
+class A64Test_Adr : public A64TestCase {
+public:
+ A64Test_Adr()
+ : A64TestCase("Adr") {}
+
+ static void add(TestApp& app) {
+ app.add(new A64Test_Adr());
+ }
+
+ virtual void compile(a64::Compiler& cc) {
+ cc.addFunc(FuncSignatureT<int>());
+
+ arm::Gp addr = cc.newIntPtr("addr");
+ arm::Gp val = cc.newIntPtr("val");
+
+ Label L_Table = cc.newLabel();
+
+ cc.adr(addr, L_Table);
+ cc.ldrsw(val, arm::ptr(addr, 8));
+ cc.ret(val);
+ cc.endFunc();
+
+ cc.bind(L_Table);
+ cc.embedInt32(1);
+ cc.embedInt32(2);
+ cc.embedInt32(3);
+ cc.embedInt32(4);
+ cc.embedInt32(5);
+ }
+
+ virtual bool run(void* _func, String& result, String& expect) {
+ typedef int (*Func)(void);
+ Func func = ptr_as_func<Func>(_func);
+
+ result.assignFormat("ret={%d}", func());
+ expect.assignFormat("ret={%d}", 3);
+
+ return result == expect;
+ }
+};
+
+// a64::Compiler - A64Test_Branch1
+// ===============================
+
+class A64Test_Branch1 : public A64TestCase {
+public:
+ A64Test_Branch1()
+ : A64TestCase("Branch1") {}
+
+ static void add(TestApp& app) {
+ app.add(new A64Test_Branch1());
+ }
+
+ virtual void compile(a64::Compiler& cc) {
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<void, void*, size_t>());
+
+ arm::Gp p = cc.newIntPtr("p");
+ arm::Gp count = cc.newIntPtr("count");
+ arm::Gp i = cc.newIntPtr("i");
+ Label L = cc.newLabel();
+
+ funcNode->setArg(0, p);
+ funcNode->setArg(1, count);
+
+ cc.mov(i, 0);
+
+ cc.bind(L);
+ cc.strb(i.w(), a64::ptr(p, i));
+ cc.add(i, i, 1);
+ cc.cmp(i, count);
+ cc.b_ne(L);
+
+ cc.endFunc();
+ }
+
+ virtual bool run(void* _func, String& result, String& expect) {
+ typedef void (*Func)(void* p, size_t n);
+ Func func = ptr_as_func<Func>(_func);
+
+ uint8_t array[16];
+ func(array, 16);
+
+ expect.assign("ret={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}");
+
+ result.assign("ret={");
+ for (size_t i = 0; i < 16; i++) {
+ if (i)
+ result.append(", ");
+ result.appendFormat("%d", int(array[i]));
+ }
+ result.append("}");
+
+ return result == expect;
+ }
+};
+
+// a64::Compiler - A64Test_Invoke1
+// ===============================
+
+class A64Test_Invoke1 : public A64TestCase {
+public:
+ A64Test_Invoke1()
+ : A64TestCase("Invoke1") {}
+
+ static void add(TestApp& app) {
+ app.add(new A64Test_Invoke1());
+ }
+
+ virtual void compile(a64::Compiler& cc) {
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<uint32_t, uint32_t, uint32_t>());
+
+ arm::Gp x = cc.newUInt32("x");
+ arm::Gp y = cc.newUInt32("y");
+ arm::Gp r = cc.newUInt32("r");
+ arm::Gp fn = cc.newUIntPtr("fn");
+
+ funcNode->setArg(0, x);
+ funcNode->setArg(1, y);
+
+ cc.mov(fn, (uint64_t)calledFunc);
+
+ InvokeNode* invokeNode;
+ cc.invoke(&invokeNode, fn, FuncSignatureT<uint32_t, uint32_t, uint32_t>(CallConvId::kHost));
+ invokeNode->setArg(0, x);
+ invokeNode->setArg(1, y);
+ invokeNode->setRet(0, r);
+
+ cc.ret(r);
+ cc.endFunc();
+ }
+
+ virtual bool run(void* _func, String& result, String& expect) {
+ typedef uint32_t (*Func)(uint32_t, uint32_t);
+ Func func = ptr_as_func<Func>(_func);
+
+ uint32_t x = 49;
+ uint32_t y = 7;
+
+ result.assignFormat("ret={%u}", func(x, y));
+ expect.assignFormat("ret={%u}", x - y);
+
+ return result == expect;
+ }
+
+ static uint32_t calledFunc(uint32_t x, uint32_t y) {
+ return x - y;
+ }
+};
+
+// a64::Compiler - A64Test_Invoke2
+// ===============================
+
+class A64Test_Invoke2 : public A64TestCase {
+public:
+ A64Test_Invoke2()
+ : A64TestCase("Invoke2") {}
+
+ static void add(TestApp& app) {
+ app.add(new A64Test_Invoke2());
+ }
+
+ virtual void compile(a64::Compiler& cc) {
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<double, double, double>());
+
+ arm::Vec x = cc.newVecD("x");
+ arm::Vec y = cc.newVecD("y");
+ arm::Vec r = cc.newVecD("r");
+ arm::Gp fn = cc.newUIntPtr("fn");
+
+ funcNode->setArg(0, x);
+ funcNode->setArg(1, y);
+ cc.mov(fn, (uint64_t)calledFunc);
+
+ InvokeNode* invokeNode;
+ cc.invoke(&invokeNode, fn, FuncSignatureT<double, double, double>(CallConvId::kHost));
+ invokeNode->setArg(0, x);
+ invokeNode->setArg(1, y);
+ invokeNode->setRet(0, r);
+
+ cc.ret(r);
+ cc.endFunc();
+ }
+
+ virtual bool run(void* _func, String& result, String& expect) {
+ typedef double (*Func)(double, double);
+ Func func = ptr_as_func<Func>(_func);
+
+ double x = 49;
+ double y = 7;
+
+ result.assignFormat("ret={%f}", func(x, y));
+ expect.assignFormat("ret={%f}", calledFunc(x, y));
+
+ return result == expect;
+ }
+
+ static double calledFunc(double x, double y) {
+ return x - y;
+ }
+};
+
+// a64::Compiler - A64Test_Invoke3
+// ===============================
+
+class A64Test_Invoke3 : public A64TestCase {
+public:
+ A64Test_Invoke3()
+ : A64TestCase("Invoke3") {}
+
+ static void add(TestApp& app) {
+ app.add(new A64Test_Invoke3());
+ }
+
+ virtual void compile(a64::Compiler& cc) {
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<double, double, double>());
+
+ arm::Vec x = cc.newVecD("x");
+ arm::Vec y = cc.newVecD("y");
+ arm::Vec r = cc.newVecD("r");
+ arm::Gp fn = cc.newUIntPtr("fn");
+
+ funcNode->setArg(0, x);
+ funcNode->setArg(1, y);
+ cc.mov(fn, (uint64_t)calledFunc);
+
+ InvokeNode* invokeNode;
+ cc.invoke(&invokeNode, fn, FuncSignatureT<double, double, double>(CallConvId::kHost));
+ invokeNode->setArg(0, y);
+ invokeNode->setArg(1, x);
+ invokeNode->setRet(0, r);
+
+ cc.ret(r);
+ cc.endFunc();
+ }
+
+ virtual bool run(void* _func, String& result, String& expect) {
+ typedef double (*Func)(double, double);
+ Func func = ptr_as_func<Func>(_func);
+
+ double x = 49;
+ double y = 7;
+
+ result.assignFormat("ret={%f}", func(x, y));
+ expect.assignFormat("ret={%f}", calledFunc(y, x));
+
+ return result == expect;
+ }
+
+ static double calledFunc(double x, double y) {
+ return x - y;
+ }
+};
+
+// a64::Compiler - A64Test_JumpTable
+// =================================
+
+class A64Test_JumpTable : public A64TestCase {
+public:
+ bool _annotated;
+
+ A64Test_JumpTable(bool annotated)
+ : A64TestCase("A64Test_JumpTable"),
+ _annotated(annotated) {
+ _name.assignFormat("JumpTable {%s}", annotated ? "Annotated" : "Unknown Target");
+ }
+
+ enum Operator {
+ kOperatorAdd = 0,
+ kOperatorSub = 1,
+ kOperatorMul = 2,
+ kOperatorDiv = 3
+ };
+
+ static void add(TestApp& app) {
+ app.add(new A64Test_JumpTable(false));
+ app.add(new A64Test_JumpTable(true));
+ }
+
+ virtual void compile(a64::Compiler& cc) {
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<float, float, float, uint32_t>());
+
+ arm::Vec a = cc.newVecS("a");
+ arm::Vec b = cc.newVecS("b");
+ arm::Gp op = cc.newUInt32("op");
+
+ arm::Gp target = cc.newIntPtr("target");
+ arm::Gp offset = cc.newIntPtr("offset");
+
+ Label L_End = cc.newLabel();
+
+ Label L_Table = cc.newLabel();
+ Label L_Add = cc.newLabel();
+ Label L_Sub = cc.newLabel();
+ Label L_Mul = cc.newLabel();
+ Label L_Div = cc.newLabel();
+
+ funcNode->setArg(0, a);
+ funcNode->setArg(1, b);
+ funcNode->setArg(2, op);
+
+ cc.adr(target, L_Table);
+ cc.ldrsw(offset, arm::ptr(target, op, arm::sxtw(2)));
+ cc.add(target, target, offset);
+
+ // JumpAnnotation allows to annotate all possible jump targets of
+ // instructions where it cannot be deduced from operands.
+ if (_annotated) {
+ JumpAnnotation* annotation = cc.newJumpAnnotation();
+ annotation->addLabel(L_Add);
+ annotation->addLabel(L_Sub);
+ annotation->addLabel(L_Mul);
+ annotation->addLabel(L_Div);
+ cc.br(target, annotation);
+ }
+ else {
+ cc.br(target);
+ }
+
+ cc.bind(L_Add);
+ cc.fadd(a, a, b);
+ cc.b(L_End);
+
+ cc.bind(L_Sub);
+ cc.fsub(a, a, b);
+ cc.b(L_End);
+
+ cc.bind(L_Mul);
+ cc.fmul(a, a, b);
+ cc.b(L_End);
+
+ cc.bind(L_Div);
+ cc.fdiv(a, a, b);
+
+ cc.bind(L_End);
+ cc.ret(a);
+ cc.endFunc();
+
+ cc.bind(L_Table);
+ cc.embedLabelDelta(L_Add, L_Table, 4);
+ cc.embedLabelDelta(L_Sub, L_Table, 4);
+ cc.embedLabelDelta(L_Mul, L_Table, 4);
+ cc.embedLabelDelta(L_Div, L_Table, 4);
+ }
+
+ virtual bool run(void* _func, String& result, String& expect) {
+ typedef float (*Func)(float, float, uint32_t);
+ Func func = ptr_as_func<Func>(_func);
+
+ float dst[4];
+ float ref[4];
+
+ dst[0] = func(33.0f, 14.0f, kOperatorAdd);
+ dst[1] = func(33.0f, 14.0f, kOperatorSub);
+ dst[2] = func(10.0f, 6.0f, kOperatorMul);
+ dst[3] = func(80.0f, 8.0f, kOperatorDiv);
+
+ ref[0] = 47.0f;
+ ref[1] = 19.0f;
+ ref[2] = 60.0f;
+ ref[3] = 10.0f;
+
+ result.assignFormat("ret={%f, %f, %f, %f}", dst[0], dst[1], dst[2], dst[3]);
+ expect.assignFormat("ret={%f, %f, %f, %f}", ref[0], ref[1], ref[2], ref[3]);
+
+ return result == expect;
+ }
+};
+
+// a64::Compiler - Export
+// ======================
+
+void compiler_add_a64_tests(TestApp& app) {
+ app.addT<A64Test_GpArgs>();
+ app.addT<A64Test_ManyRegs>();
+ app.addT<A64Test_Simd1>();
+ app.addT<A64Test_Adr>();
+ app.addT<A64Test_Branch1>();
+ app.addT<A64Test_Invoke1>();
+ app.addT<A64Test_Invoke2>();
+ app.addT<A64Test_Invoke3>();
+ app.addT<A64Test_JumpTable>();
+}
+
+#endif // !ASMJIT_NO_AARCH64 && ASMJIT_ARCH_ARM == 64
diff --git a/test/asmjit_test_perf.cpp b/test/asmjit_test_perf.cpp
index 2ade96c..ab96594 100644
--- a/test/asmjit_test_perf.cpp
+++ b/test/asmjit_test_perf.cpp
@@ -16,6 +16,10 @@ using namespace asmjit;
void benchmarkX86Emitters(uint32_t numIterations, bool testX86, bool testX64) noexcept;
#endif
+#if !defined(ASMJIT_NO_AARCH64)
+void benchmarkA64Emitters(uint32_t numIterations);
+#endif
+
int main(int argc, char* argv[]) {
CmdLine cmdLine(argc, argv);
uint32_t numIterations = 20000;
@@ -47,5 +51,12 @@ int main(int argc, char* argv[]) {
benchmarkX86Emitters(numIterations, testX86, testX64);
#endif
+#if !defined(ASMJIT_NO_AARCH64)
+ bool testAArch64 = strcmp(arch, "all") == 0 || strcmp(arch, "aarch64") == 0;
+
+ if (testAArch64)
+ benchmarkA64Emitters(numIterations);
+#endif
+
return 0;
}
diff --git a/test/asmjit_test_perf_a64.cpp b/test/asmjit_test_perf_a64.cpp
new file mode 100644
index 0000000..4f4aebb
--- /dev/null
+++ b/test/asmjit_test_perf_a64.cpp
@@ -0,0 +1,699 @@
+// 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 <asmjit/core.h>
+
+#if !defined(ASMJIT_NO_AARCH64)
+#include <asmjit/a64.h>
+
+#include <limits>
+#include <stdio.h>
+#include <string.h>
+
+#include "asmjit_test_perf.h"
+
+using namespace asmjit;
+
+// Generates a long sequence of GP instructions.
+template<typename Emitter>
+static void generateGpSequenceInternal(
+ Emitter& cc,
+ const a64::Gp& a, const a64::Gp& b, const a64::Gp& c, const a64::Gp& d) {
+
+ using namespace asmjit::a64;
+
+ Gp wA = a.w();
+ Gp wB = b.w();
+ Gp wC = c.w();
+ Gp wD = d.w();
+
+ Gp xA = a.x();
+ Gp xB = b.x();
+ Gp xC = c.x();
+ Gp xD = d.x();
+
+ Mem m = ptr(xD);
+
+ cc.mov(wA, 0);
+ cc.mov(wB, 1);
+ cc.mov(wC, 2);
+ cc.mov(wD, 3);
+
+ cc.adc(wA, wB, wC);
+ cc.adc(xA, xB, xC);
+ cc.adc(wA, wzr, wC);
+ cc.adc(xA, xzr, xC);
+ cc.adc(wzr, wB, wC);
+ cc.adc(xzr, xB, xC);
+ cc.adcs(wA, wB, wC);
+ cc.adcs(xA, xB, xC);
+ cc.add(wA, wB, wC);
+ cc.add(xA, xB, xC);
+ cc.add(wA, wB, wC, lsl(3));
+ cc.add(xA, xB, xC, lsl(3));
+ cc.add(wA, wzr, wC);
+ cc.add(xA, xzr, xC);
+ cc.add(wzr, wB, wC);
+ cc.add(xzr, xB, xC);
+ cc.add(wC, wD, 0, lsl(12));
+ cc.add(xC, xD, 0, lsl(12));
+ cc.add(wC, wD, 1024, lsl(12));
+ cc.add(xC, xD, 1024, lsl(12));
+ cc.add(wC, wD, 1024, lsl(12));
+ cc.add(xC, xD, 1024, lsl(12));
+ cc.adds(wA, wB, wC);
+ cc.adds(xA, xB, xC);
+ cc.adr(xA, 0);
+ cc.adr(xA, 256);
+ cc.adrp(xA, 4096);
+ cc.and_(wA, wB, wC);
+ cc.and_(xA, xB, xC);
+ cc.and_(wA, wB, 1);
+ cc.and_(xA, xB, 1);
+ cc.and_(wA, wB, 15);
+ cc.and_(xA, xB, 15);
+ cc.and_(wA, wzr, wC);
+ cc.and_(xA, xzr, xC);
+ cc.and_(wzr, wB, wC);
+ cc.and_(xzr, xB, xC);
+ cc.and_(wA, wB, 0x1);
+ cc.and_(xA, xB, 0x1);
+ cc.and_(wA, wB, 0xf);
+ cc.and_(xA, xB, 0xf);
+ cc.ands(wA, wB, wC);
+ cc.ands(xA, xB, xC);
+ cc.ands(wA, wzr, wC);
+ cc.ands(xA, xzr, xC);
+ cc.ands(wzr, wB, wC);
+ cc.ands(xzr, xB, xC);
+ cc.ands(wA, wB, 0x1);
+ cc.ands(xA, xB, 0x1);
+ cc.ands(wA, wB, 0xf);
+ cc.ands(xA, xB, 0xf);
+ cc.asr(wA, wB, 15);
+ cc.asr(xA, xB, 15);
+ cc.asrv(wA, wB, wC);
+ cc.asrv(xA, xB, xC);
+ cc.bfc(wA, 8, 16);
+ cc.bfc(xA, 8, 16);
+ cc.bfi(wA, wB, 8, 16);
+ cc.bfi(xA, xB, 8, 16);
+ cc.bfm(wA, wB, 8, 16);
+ cc.bfm(xA, xB, 8, 16);
+ cc.bfxil(wA, wB, 8, 16);
+ cc.bfxil(xA, xB, 8, 16);
+ cc.bic(wA, wB, wC, lsl(4));
+ cc.bic(xA, xB, xC, lsl(4));
+ cc.bic(wA, wzr, wC);
+ cc.bic(xA, xzr, xC);
+ cc.bics(wA, wB, wC, lsl(4));
+ cc.bics(xA, xB, xC, lsl(4));
+ cc.bics(wA, wzr, wC);
+ cc.bics(xA, xzr, xC);
+ cc.cas(wA, wB, m);
+ cc.cas(xA, xB, m);
+ cc.casa(wA, wB, m);
+ cc.casa(xA, xB, m);
+ cc.casab(wA, wB, m);
+ cc.casah(wA, wB, m);
+ cc.casal(wA, wB, m);
+ cc.casal(xA, xB, m);
+ cc.casalb(wA, wB, m);
+ cc.casalh(wA, wB, m);
+ cc.casb(wA, wB, m);
+ cc.cash(wA, wB, m);
+ cc.casl(wA, wB, m);
+ cc.casl(xA, xB, m);
+ cc.caslb(wA, wB, m);
+ cc.caslh(wA, wB, m);
+ cc.casp(wA, wB, wC, wD, m);
+ cc.casp(xA, xB, xC, xD, m);
+ cc.caspa(wA, wB, wC, wD, m);
+ cc.caspa(xA, xB, xC, xD, m);
+ cc.caspal(wA, wB, wC, wD, m);
+ cc.caspal(xA, xB, xC, xD, m);
+ cc.caspl(wA, wB, wC, wD, m);
+ cc.caspl(xA, xB, xC, xD, m);
+ cc.ccmn(wA, wB, 3, CondCode::kEQ);
+ cc.ccmn(xA, xB, 3, CondCode::kEQ);
+ cc.ccmn(wA, 2, 3, CondCode::kEQ);
+ cc.ccmn(xA, 2, 3, CondCode::kEQ);
+ cc.ccmn(wA, wzr, 3, CondCode::kEQ);
+ cc.ccmn(xA, xzr, 3, CondCode::kEQ);
+ cc.ccmp(wA, wB, 3, CondCode::kEQ);
+ cc.ccmp(xA, xB, 3, CondCode::kEQ);
+ cc.ccmp(wA, 2, 3, CondCode::kEQ);
+ cc.ccmp(xA, 2, 3, CondCode::kEQ);
+ cc.ccmp(wA, wzr, 3, CondCode::kEQ);
+ cc.ccmp(xA, xzr, 3, CondCode::kEQ);
+ cc.cinc(wA, wB, CondCode::kEQ);
+ cc.cinc(xA, xB, CondCode::kEQ);
+ cc.cinc(wzr, wB, CondCode::kEQ);
+ cc.cinc(wA, wzr, CondCode::kEQ);
+ cc.cinc(xzr, xB, CondCode::kEQ);
+ cc.cinc(xA, xzr, CondCode::kEQ);
+ cc.cinv(wA, wB, CondCode::kEQ);
+ cc.cinv(xA, xB, CondCode::kEQ);
+ cc.cinv(wzr, wB, CondCode::kEQ);
+ cc.cinv(wA, wzr, CondCode::kEQ);
+ cc.cinv(xzr, xB, CondCode::kEQ);
+ cc.cinv(xA, xzr, CondCode::kEQ);
+ cc.cls(wA, wB);
+ cc.cls(xA, xB);
+ cc.cls(wA, wzr);
+ cc.cls(xA, xzr);
+ cc.cls(wzr, wB);
+ cc.cls(xzr, xB);
+ cc.clz(wA, wB);
+ cc.clz(xA, xB);
+ cc.clz(wA, wzr);
+ cc.clz(xA, xzr);
+ cc.clz(wzr, wB);
+ cc.clz(xzr, xB);
+ cc.cmn(wA, 33);
+ cc.cmn(xA, 33);
+ cc.cmn(wA, wB);
+ cc.cmn(xA, xB);
+ cc.cmn(wA, wB, uxtb(2));
+ cc.cmn(xA, xB, uxtb(2));
+ cc.cmp(wA, 33);
+ cc.cmp(xA, 33);
+ cc.cmp(wA, wB);
+ cc.cmp(xA, xB);
+ cc.cmp(wA, wB, uxtb(2));
+ cc.cmp(xA, xB, uxtb(2));
+ cc.crc32b(wA, wB, wC);
+ cc.crc32b(wzr, wB, wC);
+ cc.crc32b(wA, wzr, wC);
+ cc.crc32b(wA, wB, wzr);
+ cc.crc32cb(wA, wB, wC);
+ cc.crc32cb(wzr, wB, wC);
+ cc.crc32cb(wA, wzr, wC);
+ cc.crc32cb(wA, wB, wzr);
+ cc.crc32ch(wA, wB, wC);
+ cc.crc32ch(wzr, wB, wC);
+ cc.crc32ch(wA, wzr, wC);
+ cc.crc32ch(wA, wB, wzr);
+ cc.crc32cw(wA, wB, wC);
+ cc.crc32cw(wzr, wB, wC);
+ cc.crc32cw(wA, wzr, wC);
+ cc.crc32cw(wA, wB, wzr);
+ cc.crc32cx(wA, wB, xC);
+ cc.crc32cx(wzr, wB, xC);
+ cc.crc32cx(wA, wzr, xC);
+ cc.crc32cx(wA, wB, xzr);
+ cc.crc32h(wA, wB, wC);
+ cc.crc32h(wzr, wB, wC);
+ cc.crc32h(wA, wzr, wC);
+ cc.crc32h(wA, wB, wzr);
+ cc.crc32w(wA, wB, wC);
+ cc.crc32w(wzr, wB, wC);
+ cc.crc32w(wA, wzr, wC);
+ cc.crc32w(wA, wB, wzr);
+ cc.crc32x(wA, wB, xC);
+ cc.crc32x(wzr, wB, xC);
+ cc.crc32x(wA, wzr, xC);
+ cc.crc32x(wA, wB, xzr);
+ cc.csel(wA, wB, wC, CondCode::kEQ);
+ cc.csel(xA, xB, xC, CondCode::kEQ);
+ cc.cset(wA, CondCode::kEQ);
+ cc.cset(xA, CondCode::kEQ);
+ cc.cset(wA, CondCode::kEQ);
+ cc.cset(xA, CondCode::kEQ);
+ cc.csetm(wA, CondCode::kEQ);
+ cc.csetm(xA, CondCode::kEQ);
+ cc.csinc(wA, wB, wC, CondCode::kEQ);
+ cc.csinc(xA, xB, xC, CondCode::kEQ);
+ cc.csinv(wA, wB, wC, CondCode::kEQ);
+ cc.csinv(xA, xB, xC, CondCode::kEQ);
+ cc.csneg(wA, wB, wC, CondCode::kEQ);
+ cc.csneg(xA, xB, xC, CondCode::kEQ);
+ cc.eon(wA, wB, wC);
+ cc.eon(wzr, wB, wC);
+ cc.eon(wA, wzr, wC);
+ cc.eon(wA, wB, wzr);
+ cc.eon(wA, wB, wC, lsl(4));
+ cc.eon(xA, xB, xC);
+ cc.eon(xzr, xB, xC);
+ cc.eon(xA, xzr, xC);
+ cc.eon(xA, xB, xzr);
+ cc.eon(xA, xB, xC, lsl(4));
+ cc.eor(wA, wB, wC);
+ cc.eor(wzr, wB, wC);
+ cc.eor(wA, wzr, wC);
+ cc.eor(wA, wB, wzr);
+ cc.eor(xA, xB, xC);
+ cc.eor(xzr, xB, xC);
+ cc.eor(xA, xzr, xC);
+ cc.eor(xA, xB, xzr);
+ cc.eor(wA, wB, wC, lsl(4));
+ cc.eor(xA, xB, xC, lsl(4));
+ cc.eor(wA, wB, 0x4000);
+ cc.eor(xA, xB, 0x8000);
+ cc.extr(wA, wB, wC, 15);
+ cc.extr(wzr, wB, wC, 15);
+ cc.extr(wA, wzr, wC, 15);
+ cc.extr(wA, wB, wzr, 15);
+ cc.extr(xA, xB, xC, 15);
+ cc.extr(xzr, xB, xC, 15);
+ cc.extr(xA, xzr, xC, 15);
+ cc.extr(xA, xB, xzr, 15);
+ cc.ldadd(wA, wB, m);
+ cc.ldadd(xA, xB, m);
+ cc.ldadda(wA, wB, m);
+ cc.ldadda(xA, xB, m);
+ cc.ldaddab(wA, wB, m);
+ cc.ldaddah(wA, wB, m);
+ cc.ldaddal(wA, wB, m);
+ cc.ldaddal(xA, xB, m);
+ cc.ldaddalb(wA, wB, m);
+ cc.ldaddalh(wA, wB, m);
+ cc.ldaddb(wA, wB, m);
+ cc.ldaddh(wA, wB, m);
+ cc.ldaddl(wA, wB, m);
+ cc.ldaddl(xA, xB, m);
+ cc.ldaddlb(wA, wB, m);
+ cc.ldaddlh(wA, wB, m);
+ cc.ldclr(wA, wB, m);
+ cc.ldclr(xA, xB, m);
+ cc.ldclra(wA, wB, m);
+ cc.ldclra(xA, xB, m);
+ cc.ldclrab(wA, wB, m);
+ cc.ldclrah(wA, wB, m);
+ cc.ldclral(wA, wB, m);
+ cc.ldclral(xA, xB, m);
+ cc.ldclralb(wA, wB, m);
+ cc.ldclralh(wA, wB, m);
+ cc.ldclrb(wA, wB, m);
+ cc.ldclrh(wA, wB, m);
+ cc.ldclrl(wA, wB, m);
+ cc.ldclrl(xA, xB, m);
+ cc.ldclrlb(wA, wB, m);
+ cc.ldclrlh(wA, wB, m);
+ cc.ldeor(wA, wB, m);
+ cc.ldeor(xA, xB, m);
+ cc.ldeora(wA, wB, m);
+ cc.ldeora(xA, xB, m);
+ cc.ldeorab(wA, wB, m);
+ cc.ldeorah(wA, wB, m);
+ cc.ldeoral(wA, wB, m);
+ cc.ldeoral(xA, xB, m);
+ cc.ldeoralb(wA, wB, m);
+ cc.ldeoralh(wA, wB, m);
+ cc.ldeorb(wA, wB, m);
+ cc.ldeorh(wA, wB, m);
+ cc.ldeorl(wA, wB, m);
+ cc.ldeorl(xA, xB, m);
+ cc.ldeorlb(wA, wB, m);
+ cc.ldeorlh(wA, wB, m);
+ cc.ldlar(wA, m);
+ cc.ldlar(xA, m);
+ cc.ldlarb(wA, m);
+ cc.ldlarh(wA, m);
+ cc.ldnp(wA, wB, m);
+ cc.ldnp(xA, xB, m);
+ cc.ldp(wA, wB, m);
+ cc.ldp(xA, xB, m);
+ cc.ldpsw(xA, xB, m);
+ cc.ldr(wA, m);
+ cc.ldr(xA, m);
+ cc.ldrb(wA, m);
+ cc.ldrh(wA, m);
+ cc.ldrsw(xA, m);
+ cc.ldraa(xA, m);
+ cc.ldrab(xA, m);
+ cc.ldset(wA, wB, m);
+ cc.ldset(xA, xB, m);
+ cc.ldseta(wA, wB, m);
+ cc.ldseta(xA, xB, m);
+ cc.ldsetab(wA, wB, m);
+ cc.ldsetah(wA, wB, m);
+ cc.ldsetal(wA, wB, m);
+ cc.ldsetal(xA, xB, m);
+ cc.ldsetalh(wA, wB, m);
+ cc.ldsetalb(wA, wB, m);
+ cc.ldsetb(wA, wB, m);
+ cc.ldseth(wA, wB, m);
+ cc.ldsetl(wA, wB, m);
+ cc.ldsetl(xA, xB, m);
+ cc.ldsetlb(wA, wB, m);
+ cc.ldsetlh(wA, wB, m);
+ cc.ldsmax(wA, wB, m);
+ cc.ldsmax(xA, xB, m);
+ cc.ldsmaxa(wA, wB, m);
+ cc.ldsmaxa(xA, xB, m);
+ cc.ldsmaxab(wA, wB, m);
+ cc.ldsmaxah(wA, wB, m);
+ cc.ldsmaxal(wA, wB, m);
+ cc.ldsmaxal(xA, xB, m);
+ cc.ldsmaxalb(wA, wB, m);
+ cc.ldsmaxalh(wA, wB, m);
+ cc.ldsmaxb(wA, wB, m);
+ cc.ldsmaxh(wA, wB, m);
+ cc.ldsmaxl(wA, wB, m);
+ cc.ldsmaxl(xA, xB, m);
+ cc.ldsmaxlb(wA, wB, m);
+ cc.ldsmaxlh(wA, wB, m);
+ cc.ldsmin(wA, wB, m);
+ cc.ldsmin(xA, xB, m);
+ cc.ldsmina(wA, wB, m);
+ cc.ldsmina(xA, xB, m);
+ cc.ldsminab(wA, wB, m);
+ cc.ldsminah(wA, wB, m);
+ cc.ldsminal(wA, wB, m);
+ cc.ldsminal(xA, xB, m);
+ cc.ldsminalb(wA, wB, m);
+ cc.ldsminalh(wA, wB, m);
+ cc.ldsminb(wA, wB, m);
+ cc.ldsminh(wA, wB, m);
+ cc.ldsminl(wA, wB, m);
+ cc.ldsminl(xA, xB, m);
+ cc.ldsminlb(wA, wB, m);
+ cc.ldsminlh(wA, wB, m);
+ cc.ldtr(wA, m);
+ cc.ldtr(xA, m);
+ cc.ldtrb(wA, m);
+ cc.ldtrh(wA, m);
+ cc.ldtrsb(wA, m);
+ cc.ldtrsh(wA, m);
+ cc.ldtrsw(xA, m);
+ cc.ldumax(wA, wB, m);
+ cc.ldumax(xA, xB, m);
+ cc.ldumaxa(wA, wB, m);
+ cc.ldumaxa(xA, xB, m);
+ cc.ldumaxab(wA, wB, m);
+ cc.ldumaxah(wA, wB, m);
+ cc.ldumaxal(wA, wB, m);
+ cc.ldumaxal(xA, xB, m);
+ cc.ldumaxalb(wA, wB, m);
+ cc.ldumaxalh(wA, wB, m);
+ cc.ldumaxb(wA, wB, m);
+ cc.ldumaxh(wA, wB, m);
+ cc.ldumaxl(wA, wB, m);
+ cc.ldumaxl(xA, xB, m);
+ cc.ldumaxlb(wA, wB, m);
+ cc.ldumaxlh(wA, wB, m);
+ cc.ldumin(wA, wB, m);
+ cc.ldumin(xA, xB, m);
+ cc.ldumina(wA, wB, m);
+ cc.ldumina(xA, xB, m);
+ cc.lduminab(wA, wB, m);
+ cc.lduminah(wA, wB, m);
+ cc.lduminal(wA, wB, m);
+ cc.lduminal(xA, xB, m);
+ cc.lduminalb(wA, wB, m);
+ cc.lduminalh(wA, wB, m);
+ cc.lduminb(wA, wB, m);
+ cc.lduminh(wA, wB, m);
+ cc.lduminl(wA, wB, m);
+ cc.lduminl(xA, xB, m);
+ cc.lduminlb(wA, wB, m);
+ cc.lduminlh(wA, wB, m);
+ cc.ldur(wA, m);
+ cc.ldur(xA, m);
+ cc.ldurb(wA, m);
+ cc.ldurh(wA, m);
+ cc.ldursb(wA, m);
+ cc.ldursh(wA, m);
+ cc.ldursw(xA, m);
+ cc.ldxp(wA, wB, m);
+ cc.ldxp(xA, xB, m);
+ cc.ldxr(wA, m);
+ cc.ldxr(xA, m);
+ cc.ldxrb(wA, m);
+ cc.ldxrh(wA, m);
+ cc.lsl(wA, wB, wC);
+ cc.lsl(xA, xB, xC);
+ cc.lsl(wA, wB, 15);
+ cc.lsl(xA, xB, 15);
+ cc.lslv(wA, wB, wC);
+ cc.lslv(xA, xB, xC);
+ cc.lsr(wA, wB, wC);
+ cc.lsr(xA, xB, xC);
+ cc.lsr(wA, wB, 15);
+ cc.lsr(xA, xB, 15);
+ cc.lsrv(wA, wB, wC);
+ cc.lsrv(xA, xB, xC);
+ cc.madd(wA, wB, wC, wD);
+ cc.madd(xA, xB, xC, xD);
+ cc.mneg(wA, wB, wC);
+ cc.mneg(xA, xB, xC);
+ cc.mov(wA, wB);
+ cc.mov(xA, xB);
+ cc.mov(wA, 0);
+ cc.mov(wA, 1);
+ cc.mov(wA, 2);
+ cc.mov(wA, 3);
+ cc.mov(wA, 4);
+ cc.mov(wA, 5);
+ cc.mov(wA, 6);
+ cc.mov(wA, 7);
+ cc.mov(wA, 8);
+ cc.mov(wA, 9);
+ cc.mov(wA, 10);
+ cc.mov(wA, 0xA234);
+ cc.mov(xA, 0xA23400000000);
+ cc.msub(wA, wB, wC, wD);
+ cc.msub(xA, xB, xC, xD);
+ cc.mul(wA, wB, wC);
+ cc.mul(xA, xB, xC);
+ cc.mvn(wA, wB);
+ cc.mvn(xA, xB);
+ cc.mvn(wA, wB, lsl(4));
+ cc.mvn(xA, xB, lsl(4));
+ cc.neg(wA, wB);
+ cc.neg(xA, xB);
+ cc.neg(wA, wB, lsl(4));
+ cc.neg(xA, xB, lsl(4));
+ cc.negs(wA, wB);
+ cc.negs(xA, xB);
+ cc.negs(wA, wB, lsl(4));
+ cc.negs(xA, xB, lsl(4));
+ cc.ngc(wA, wB);
+ cc.ngc(xA, xB);
+ cc.ngcs(wA, wB);
+ cc.ngcs(xA, xB);
+ cc.orn(wA, wB, wC);
+ cc.orn(xA, xB, xC);
+ cc.orn(wA, wB, wC, lsl(4));
+ cc.orn(xA, xB, xC, lsl(4));
+ cc.orr(wA, wB, wC);
+ cc.orr(xA, xB, xC);
+ cc.orr(wA, wB, wC, lsl(4));
+ cc.orr(xA, xB, xC, lsl(4));
+ cc.orr(wA, wB, 0x4000);
+ cc.orr(xA, xB, 0x8000);
+ cc.rbit(wA, wB);
+ cc.rbit(xA, xB);
+ cc.rev(wA, wB);
+ cc.rev(xA, xB);
+ cc.rev16(wA, wB);
+ cc.rev16(xA, xB);
+ cc.rev32(xA, xB);
+ cc.rev64(xA, xB);
+ cc.ror(wA, wB, wC);
+ cc.ror(xA, xB, xC);
+ cc.ror(wA, wB, 15);
+ cc.ror(xA, xB, 15);
+ cc.rorv(wA, wB, wC);
+ cc.rorv(xA, xB, xC);
+ cc.sbc(wA, wB, wC);
+ cc.sbc(xA, xB, xC);
+ cc.sbcs(wA, wB, wC);
+ cc.sbcs(xA, xB, xC);
+ cc.sbfiz(wA, wB, 5, 10);
+ cc.sbfiz(xA, xB, 5, 10);
+ cc.sbfm(wA, wB, 5, 10);
+ cc.sbfm(xA, xB, 5, 10);
+ cc.sbfx(wA, wB, 5, 10);
+ cc.sbfx(xA, xB, 5, 10);
+ cc.sdiv(wA, wB, wC);
+ cc.sdiv(xA, xB, xC);
+ cc.smaddl(xA, wB, wC, xD);
+ cc.smnegl(xA, wB, wC);
+ cc.smsubl(xA, wB, wC, xD);
+ cc.smulh(xA, xB, xC);
+ cc.smull(xA, wB, wC);
+ cc.stp(wA, wB, m);
+ cc.stp(xA, xB, m);
+ cc.sttr(wA, m);
+ cc.sttr(xA, m);
+ cc.sttrb(wA, m);
+ cc.sttrh(wA, m);
+ cc.stur(wA, m);
+ cc.stur(xA, m);
+ cc.sturb(wA, m);
+ cc.sturh(wA, m);
+ cc.stxp(wA, wB, wC, m);
+ cc.stxp(wA, xB, xC, m);
+ cc.stxr(wA, wB, m);
+ cc.stxr(wA, xB, m);
+ cc.stxrb(wA, wB, m);
+ cc.stxrh(wA, wB, m);
+ cc.sub(wA, wB, wC);
+ cc.sub(xA, xB, xC);
+ cc.sub(wA, wB, wC, lsl(3));
+ cc.sub(xA, xB, xC, lsl(3));
+ cc.subg(xA, xB, 32, 11);
+ cc.subp(xA, xB, xC);
+ cc.subps(xA, xB, xC);
+ cc.subs(wA, wB, wC);
+ cc.subs(xA, xB, xC);
+ cc.subs(wA, wB, wC, lsl(3));
+ cc.subs(xA, xB, xC, lsl(3));
+ cc.sxtb(wA, wB);
+ cc.sxtb(xA, wB);
+ cc.sxth(wA, wB);
+ cc.sxth(xA, wB);
+ cc.sxtw(xA, wB);
+ cc.tst(wA, 1);
+ cc.tst(xA, 1);
+ cc.tst(wA, wB);
+ cc.tst(xA, xB);
+ cc.tst(wA, wB, lsl(4));
+ cc.tst(xA, xB, lsl(4));
+ cc.udiv(wA, wB, wC);
+ cc.udiv(xA, xB, xC);
+ cc.ubfiz(wA, wB, 5, 10);
+ cc.ubfiz(xA, xB, 5, 10);
+ cc.ubfm(wA, wB, 5, 10);
+ cc.ubfm(xA, xB, 5, 10);
+ cc.ubfx(wA, wB, 5, 10);
+ cc.ubfx(xA, xB, 5, 10);
+ cc.umaddl(xA, wB, wC, xD);
+ cc.umnegl(xA, wB, wC);
+ cc.umsubl(xA, wB, wC, xD);
+ cc.umulh(xA, xB, xC);
+ cc.umull(xA, wB, wC);
+ cc.uxtb(wA, wB);
+ cc.uxth(wA, wB);
+}
+
+static void generateGpSequence(BaseEmitter& emitter, bool emitPrologEpilog) {
+ if (emitter.isAssembler()) {
+ a64::Assembler& cc = *emitter.as<a64::Assembler>();
+
+ a64::Gp a = a64::x0;
+ a64::Gp b = a64::x1;
+ a64::Gp c = a64::x2;
+ a64::Gp d = a64::x3;
+
+ if (emitPrologEpilog) {
+ FuncDetail func;
+ func.init(FuncSignatureT<void, void*, const void*, size_t>(CallConvId::kHost), cc.environment());
+
+ FuncFrame frame;
+ frame.init(func);
+ frame.addDirtyRegs(a, b, c, d);
+ frame.finalize();
+
+ cc.emitProlog(frame);
+ generateGpSequenceInternal(cc, a, b, c, d);
+ cc.emitEpilog(frame);
+ }
+ else {
+ generateGpSequenceInternal(cc, a, b, c, d);
+ }
+ }
+#ifndef ASMJIT_NO_BUILDER
+ else if (emitter.isBuilder()) {
+ a64::Builder& cc = *emitter.as<a64::Builder>();
+
+ a64::Gp a = a64::x0;
+ a64::Gp b = a64::x1;
+ a64::Gp c = a64::x2;
+ a64::Gp d = a64::x3;
+
+ if (emitPrologEpilog) {
+ FuncDetail func;
+ func.init(FuncSignatureT<void, void*, const void*, size_t>(CallConvId::kHost), cc.environment());
+
+ FuncFrame frame;
+ frame.init(func);
+ frame.addDirtyRegs(a, b, c, d);
+ frame.finalize();
+
+ cc.emitProlog(frame);
+ generateGpSequenceInternal(cc, a, b, c, d);
+ cc.emitEpilog(frame);
+ }
+ else {
+ generateGpSequenceInternal(cc, a, b, c, d);
+ }
+ }
+#endif
+#ifndef ASMJIT_NO_COMPILER
+ else if (emitter.isCompiler()) {
+ a64::Compiler& cc = *emitter.as<a64::Compiler>();
+
+ a64::Gp a = cc.newIntPtr("a");
+ a64::Gp b = cc.newIntPtr("b");
+ a64::Gp c = cc.newIntPtr("c");
+ a64::Gp d = cc.newIntPtr("d");
+
+ cc.addFunc(FuncSignatureT<void>(CallConvId::kHost));
+ generateGpSequenceInternal(cc, a, b, c, d);
+ cc.endFunc();
+ }
+#endif
+}
+
+template<typename EmitterFn>
+static void benchmarkA64Function(Arch arch, uint32_t numIterations, const char* description, const EmitterFn& emitterFn) noexcept {
+ CodeHolder code;
+ printf("%s:\n", description);
+
+ bench<a64::Assembler>(code, arch, numIterations, "[raw]", [&](a64::Assembler& cc) {
+ emitterFn(cc, false);
+ });
+
+ bench<a64::Assembler>(code, arch, numIterations, "[validated]", [&](a64::Assembler& cc) {
+ cc.addDiagnosticOptions(DiagnosticOptions::kValidateAssembler);
+ emitterFn(cc, false);
+ });
+
+ bench<a64::Assembler>(code, arch, numIterations, "[prolog/epilog]", [&](a64::Assembler& cc) {
+ cc.addDiagnosticOptions(DiagnosticOptions::kValidateAssembler);
+ emitterFn(cc, true);
+ });
+
+#ifndef ASMJIT_NO_BUILDER
+ bench<a64::Builder>(code, arch, numIterations, "[no-asm]", [&](a64::Builder& cc) {
+ emitterFn(cc, false);
+ });
+
+ bench<a64::Builder>(code, arch, numIterations, "[finalized]", [&](a64::Builder& cc) {
+ emitterFn(cc, false);
+ cc.finalize();
+ });
+
+ bench<a64::Builder>(code, arch, numIterations, "[prolog/epilog]", [&](a64::Builder& cc) {
+ emitterFn(cc, true);
+ cc.finalize();
+ });
+#endif
+
+#ifndef ASMJIT_NO_COMPILER
+ bench<a64::Compiler>(code, arch, numIterations, "[no-asm]", [&](a64::Compiler& cc) {
+ emitterFn(cc, true);
+ });
+
+ bench<a64::Compiler>(code, arch, numIterations, "[finalized]", [&](a64::Compiler& cc) {
+ emitterFn(cc, true);
+ cc.finalize();
+ });
+#endif
+
+ printf("\n");
+}
+
+void benchmarkA64Emitters(uint32_t numIterations) {
+ static const char description[] = "GpSequence (Sequence of GP instructions - reg/mem)";
+ benchmarkA64Function(Arch::kAArch64, numIterations, description, [](BaseEmitter& emitter, bool emitPrologEpilog) {
+ generateGpSequence(emitter, emitPrologEpilog);
+ });
+}
+
+#endif // !ASMJIT_NO_AARCH64
diff --git a/test/asmjit_test_x86_sections.cpp b/test/asmjit_test_x86_sections.cpp
index afd5807..353b5e4 100644
--- a/test/asmjit_test_x86_sections.cpp
+++ b/test/asmjit_test_x86_sections.cpp
@@ -136,12 +136,17 @@ int main() {
// Relocate to the base-address of the allocated memory.
code.relocateToBase(uint64_t(uintptr_t(rxPtr)));
+ VirtMem::protectJitMemory(VirtMem::ProtectJitAccess::kReadWrite);
+
// Copy the flattened code into `mem.rw`. There are two ways. You can either copy
// everything manually by iterating over all sections or use `copyFlattenedData`.
// This code is similar to what `copyFlattenedData(p, codeSize, 0)` would do:
for (Section* section : code.sectionsByOrder())
memcpy(static_cast<uint8_t*>(rwPtr) + size_t(section->offset()), section->data(), section->bufferSize());
+ VirtMem::protectJitMemory(VirtMem::ProtectJitAccess::kReadExecute);
+ VirtMem::flushInstructionCache(rwPtr, code.codeSize());
+
// Execute the function and test whether it works.
typedef size_t (*Func)(size_t idx);
Func fn = (Func)rxPtr;
diff --git a/tools/tablegen-arm.js b/tools/tablegen-arm.js
new file mode 100644
index 0000000..e1c8293
--- /dev/null
+++ b/tools/tablegen-arm.js
@@ -0,0 +1,365 @@
+// [AsmJit]
+// Machine Code Generation for C++.
+//
+// [License]
+// ZLIB - See LICENSE.md file in the package.
+
+// ============================================================================
+// tablegen-arm.js
+// ============================================================================
+
+"use strict";
+
+const { executionAsyncResource } = require("async_hooks");
+const core = require("./tablegen.js");
+const hasOwn = Object.prototype.hasOwnProperty;
+
+const asmdb = core.asmdb;
+const kIndent = core.kIndent;
+const IndexedArray = core.IndexedArray;
+const StringUtils = core.StringUtils;
+
+const FAIL = core.FAIL;
+
+// ============================================================================
+// [ArmDB]
+// ============================================================================
+
+// Create ARM ISA.
+const isa = new asmdb.arm.ISA();
+
+// ============================================================================
+// [tablegen.arm.GenUtils]
+// ============================================================================
+
+class GenUtils {
+ // Get a list of instructions based on `name` and optional `mode`.
+ static query(name, mode) {
+ const insts = isa.query(name);
+ return !mode ? insts : insts.filter(function(inst) { return inst.arch === mode; });
+ }
+
+ static archOf(records) {
+ var t16Arch = false;
+ var t32Arch = false;
+ var a32Arch = false;
+ var a64Arch = false;
+
+ for (var i = 0; i < records.length; i++) {
+ const record = records[i];
+ if (record.encoding === "T16") t16Arch = true;
+ if (record.encoding === "T32") t32Arch = true;
+ if (record.encoding === "A32") a32Arch = true;
+ if (record.encoding === "A64") a64Arch = true;
+ }
+
+ var s = (t16Arch && !t32Arch) ? "T16" :
+ (t32Arch && !t16Arch) ? "T32" :
+ (t16Arch && t32Arch) ? "Txx" : "---";
+ s += " ";
+ s += (a32Arch) ? "A32" : "---";
+ s += " ";
+ s += (a64Arch) ? "A64" : "---";
+
+ return `[${s}]`;
+ }
+
+ static featuresOf(records) {
+ const exts = Object.create(null);
+ for (var i = 0; i < records.length; i++) {
+ const record = records[i];
+ for (var k in record.extensions)
+ exts[k] = true;
+ }
+ const arr = Object.keys(exts);
+ arr.sort();
+ return arr;
+ }
+}
+
+// ============================================================================
+// [tablegen.arm.ArmTableGen]
+// ============================================================================
+
+class ArmTableGen extends core.TableGen {
+ constructor() {
+ super("A64");
+ }
+
+ // --------------------------------------------------------------------------
+ // [Parse / Merge]
+ // --------------------------------------------------------------------------
+
+ parse() {
+ const rawData = this.dataOfFile("src/asmjit/arm/a64instdb.cpp");
+ const stringData = StringUtils.extract(rawData, "// ${InstInfo:Begin}", "// ${InstInfo:End");
+
+ const re = new RegExp(
+ "INST\\(\\s*" +
+ // [01] Instruction.
+ "(" +
+ "[A-Za-z0-9_]+" +
+ ")\\s*,\\s*" +
+
+ // [02] Encoding.
+ "(" +
+ "[^,]+" +
+ ")\\s*,\\s*" +
+
+ // [03] OpcodeData.
+ "(" +
+ "\\([^\\)]+\\)" +
+ ")\\s*,\\s*" +
+
+ // [04] RWInfo.
+ "(" +
+ "[^,]+" +
+ ")\\s*,\\s*" +
+
+ // [05] InstructionFlags.
+ "(\\s*" +
+ "(?:" +
+ "(?:" +
+ "[\\d]+" +
+ "|" +
+ "F\\([^\\)]*\\)" +
+ ")" +
+ "\\s*" +
+ "[|]?\\s*" +
+ ")+" +
+ ")\\s*,\\s*" +
+
+ // --- autogenerated fields ---
+
+ // [06] OpcodeDataIndex.
+ "([^\\)]+)" +
+ "\\s*,\\s*" +
+
+ // [07] NameDataIndex.
+ "([^\\)]+)" +
+ "\\s*\\)"
+ , "g");
+
+ var m;
+ while ((m = re.exec(stringData)) !== null) {
+ var enum_ = m[1];
+ var name = enum_ === "None" ? "" : enum_.toLowerCase();
+ var encoding = m[2].trim();
+ var opcodeData = m[3].trim();
+ var rwInfo = m[4].trim();
+ var instFlags = m[5].trim();
+
+ var displayName = name;
+ if (name.endsWith("_v"))
+ displayName = name.substring(0, name.length - 2);
+
+ // We have just matched #define INST()
+ if (name == "id" &&
+ encoding === "encoding" &&
+ encodingDataIndex === "encodingDataIndex")
+ continue;
+
+ this.addInst({
+ id : 0, // Instruction id (numeric value).
+ name : name, // Instruction name.
+ displayName : displayName, // Instruction name to display.
+ enum : enum_, // Instruction enum without `kId` prefix.
+ encoding : encoding, // Opcode encoding.
+ opcodeData : opcodeData, // Opcode data.
+ opcodeDataIndex : -1, // Opcode data index.
+ rwInfo : rwInfo, // RW info.
+ flags : instFlags, // Instruction flags.
+
+ nameIndex : -1 // Index to InstDB::_nameData.
+ });
+ }
+
+ if (this.insts.length === 0 || this.insts.length !== StringUtils.countOf(stringData, "INST("))
+ FAIL("ARMTableGen.parse(): Invalid parsing regexp (no data parsed)");
+
+ console.log("Number of Instructions: " + this.insts.length);
+ }
+
+ merge() {
+ var s = StringUtils.format(this.insts, "", true, function(inst) {
+ return "INST(" +
+ String(inst.enum ).padEnd(17) + ", " +
+ String(inst.encoding ).padEnd(19) + ", " +
+ String(inst.opcodeData ).padEnd(86) + ", " +
+ String(inst.rwInfo ).padEnd(10) + ", " +
+ String(inst.flags ).padEnd(26) + ", " +
+ String(inst.opcodeDataIndex ).padEnd( 3) + ", " +
+ String(inst.nameIndex ).padEnd( 4) + ")";
+ }) + "\n";
+ return this.inject("InstInfo", s, this.insts.length * 4);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Hooks]
+ // --------------------------------------------------------------------------
+
+ onBeforeRun() {
+ this.load([
+ "src/asmjit/arm/a64emitter.h",
+ "src/asmjit/arm/a64globals.h",
+ "src/asmjit/arm/a64instdb.cpp",
+ "src/asmjit/arm/a64instdb.h",
+ "src/asmjit/arm/a64instdb_p.h"
+ ]);
+ this.parse();
+ }
+
+ onAfterRun() {
+ this.merge();
+ this.save();
+ this.dumpTableSizes();
+ }
+}
+
+// ============================================================================
+// [tablegen.arm.IdEnum]
+// ============================================================================
+
+class IdEnum extends core.IdEnum {
+ constructor() {
+ super("IdEnum");
+ }
+
+ comment(inst) {
+ let name = inst.name;
+ let ext = [];
+
+ if (name.endsWith("_v")) {
+ name = name.substr(0, name.length - 2);
+ ext.push("ASIMD");
+ }
+
+ let exts = "";
+ if (ext.length)
+ exts = " {" + ext.join("&") + "}";
+
+ return `Instruction '${name}'${exts}.`;
+ }
+}
+
+// ============================================================================
+// [tablegen.arm.NameTable]
+// ============================================================================
+
+class NameTable extends core.NameTable {
+ constructor() {
+ super("NameTable");
+ }
+}
+
+// ============================================================================
+// [tablegen.arm.EncodingTable]
+// ============================================================================
+
+class EncodingTable extends core.Task {
+ constructor() {
+ super("EncodingTable");
+ }
+
+ run() {
+ const insts = this.ctx.insts;
+ const map = {};
+
+ for (var i = 0; i < insts.length; i++) {
+ const inst = insts[i];
+
+ const encoding = inst.encoding;
+ const opcodeData = inst.opcodeData.replace(/\(/g, "{ ").replace(/\)/g, " }");
+
+ if (!hasOwn.call(map, encoding))
+ map[encoding] = [];
+
+ if (inst.opcodeData === "(_)") {
+ inst.opcodeDataIndex = 0;
+ continue;
+ }
+
+ const opcodeTable = map[encoding];
+ const opcodeDataIndex = opcodeTable.length;
+
+ opcodeTable.push({ name: inst.name, data: opcodeData });
+ inst.opcodeDataIndex = opcodeDataIndex;
+ }
+
+ const keys = Object.keys(map);
+ keys.sort();
+
+ var tableSource = "";
+ var tableHeader = "";
+ var encodingIds = "";
+
+ encodingIds += "enum EncodingId : uint32_t {\n"
+ encodingIds += " kEncodingNone = 0";
+
+ keys.forEach((dataClass) => {
+ const dataName = dataClass[0].toLowerCase() + dataClass.substr(1);
+ const opcodeTable = map[dataClass];
+ const count = opcodeTable.length;
+
+ if (dataClass !== "None") {
+ encodingIds += ",\n"
+ encodingIds += " kEncoding" + dataClass;
+ }
+
+ if (count) {
+ tableHeader += `extern const ${dataClass} ${dataName}[${count}];\n`;
+
+ if (tableSource)
+ tableSource += "\n";
+
+ tableSource += `const ${dataClass} ${dataName}[${count}] = {\n`;
+ for (var i = 0; i < count; i++) {
+ tableSource += ` ${opcodeTable[i].data}` + (i == count - 1 ? " " : ",") + " // " + opcodeTable[i].name + "\n";
+ }
+ tableSource += `};\n`;
+ }
+ });
+
+ encodingIds += "\n};\n";
+
+ return this.ctx.inject("EncodingId" , StringUtils.disclaimer(encodingIds), 0) +
+ this.ctx.inject("EncodingDataForward", StringUtils.disclaimer(tableHeader), 0) +
+ this.ctx.inject("EncodingData" , StringUtils.disclaimer(tableSource), 0);
+ }
+}
+// ============================================================================
+// [tablegen.arm.CommonTable]
+// ============================================================================
+
+class CommonTable extends core.Task {
+ constructor() {
+ super("CommonTable", [
+ "IdEnum",
+ "NameTable"
+ ]);
+ }
+
+ run() {
+ //const table = new IndexedArray();
+
+ //for (var i = 0; i < insts.length; i++) {
+ // const inst = insts[i];
+ // const item = "{ " + "0" + "}";
+ // inst.commonIndex = table.addIndexed(item);
+ //}
+
+ // return this.ctx.inject("InstInfo", StringUtils.disclaimer(s), 0);
+ return 0;
+ }
+}
+
+// ============================================================================
+// [Main]
+// ============================================================================
+
+new ArmTableGen()
+ .addTask(new IdEnum())
+ .addTask(new NameTable())
+ .addTask(new EncodingTable())
+ .addTask(new CommonTable())
+ .run();
diff --git a/tools/tablegen-arm.sh b/tools/tablegen-arm.sh
new file mode 100755
index 0000000..8545c1e
--- /dev/null
+++ b/tools/tablegen-arm.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+node ./tablegen-arm.js
diff --git a/tools/tablegen-x86.js b/tools/tablegen-x86.js
index 6b2110b..61fc734 100644
--- a/tools/tablegen-x86.js
+++ b/tools/tablegen-x86.js
@@ -524,6 +524,7 @@ class X86TableGen extends core.TableGen {
this.addInst({
id : 0, // Instruction id (numeric value).
name : name, // Instruction name.
+ displayName : name, // Instruction name to display.
enum : enum_, // Instruction enum without `kId` prefix.
dbInsts : dbInsts, // All dbInsts returned from asmdb query.
encoding : encoding, // Instruction encoding.
diff --git a/tools/tablegen-x86.sh b/tools/tablegen-x86.sh
new file mode 100755
index 0000000..40facf3
--- /dev/null
+++ b/tools/tablegen-x86.sh
@@ -0,0 +1,3 @@
+#!/usr/bin/env sh
+set -e
+node ./tablegen-x86.js $@
diff --git a/tools/tablegen.js b/tools/tablegen.js
index 75d81b1..fdc65fd 100644
--- a/tools/tablegen.js
+++ b/tools/tablegen.js
@@ -160,6 +160,21 @@ exports.Lang = Lang;
class StringUtils {
static asString(x) { return String(x); }
+ static countOf(s, pattern) {
+ if (!pattern)
+ FAIL(`Pattern cannot be empty`);
+
+ var n = 0;
+ var pos = 0;
+
+ while ((pos = s.indexOf(pattern, pos)) >= 0) {
+ n++;
+ pos += pattern.length;
+ }
+
+ return n;
+ }
+
static capitalize(s) {
s = String(s);
return !s ? s : s[0].toUpperCase() + s.substr(1);
@@ -258,15 +273,28 @@ class StringUtils {
return lines.join("\n");
}
+ static extract(s, start, end) {
+ var iStart = s.indexOf(start);
+ var iEnd = s.indexOf(end);
+
+ if (iStart === -1)
+ FAIL(`StringUtils.extract(): Couldn't locate start mark '${start}'`);
+
+ if (iEnd === -1)
+ FAIL(`StringUtils.extract(): Couldn't locate end mark '${end}'`);
+
+ return s.substring(iStart + start.length, iEnd).trim();
+ }
+
static inject(s, start, end, code) {
var iStart = s.indexOf(start);
var iEnd = s.indexOf(end);
if (iStart === -1)
- FAIL(`Utils.inject(): Couldn't locate start mark '${start}'`);
+ FAIL(`StringUtils.inject(): Couldn't locate start mark '${start}'`);
if (iEnd === -1)
- FAIL(`Utils.inject(): Couldn't locate end mark '${end}'`);
+ FAIL(`StringUtils.inject(): Couldn't locate end mark '${end}'`);
var nIndent = 0;
while (iStart > 0 && s[iStart-1] === " ") {
@@ -875,14 +903,14 @@ class NameTable extends Task {
var maxLength = 0;
for (var i = 0; i < insts.length; i++) {
const inst = insts[i];
- instNames.add(inst.name);
- maxLength = Math.max(maxLength, inst.name.length);
+ instNames.add(inst.displayName);
+ maxLength = Math.max(maxLength, inst.displayName.length);
}
instNames.index();
for (var i = 0; i < insts.length; i++) {
const inst = insts[i];
- const name = inst.name;
+ const name = inst.displayName;
const nameIndex = instNames.getIndex(name);
const index = name.charCodeAt(0) - 'a'.charCodeAt(0);
diff --git a/tools/tablegen.sh b/tools/tablegen.sh
index 40facf3..b2c9cac 100755
--- a/tools/tablegen.sh
+++ b/tools/tablegen.sh
@@ -1,3 +1,4 @@
#!/usr/bin/env sh
set -e
+node ./tablegen-arm.js $@
node ./tablegen-x86.js $@