summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/asmjit/src/asmjit/core.h
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/asmjit/src/asmjit/core.h')
-rw-r--r--3rdparty/asmjit/src/asmjit/core.h1632
1 files changed, 782 insertions, 850 deletions
diff --git a/3rdparty/asmjit/src/asmjit/core.h b/3rdparty/asmjit/src/asmjit/core.h
index d0fb214d0ce..66cbce642a3 100644
--- a/3rdparty/asmjit/src/asmjit/core.h
+++ b/3rdparty/asmjit/src/asmjit/core.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_H_INCLUDED
#define ASMJIT_CORE_H_INCLUDED
@@ -27,62 +9,48 @@
//! Root namespace used by AsmJit.
namespace asmjit {
-// ============================================================================
-// [Documentation - mainpage]
-// ============================================================================
-
//! \mainpage API Reference
//!
//! AsmJit C++ API reference documentation generated by Doxygen.
//!
-//! AsmJit library uses one global namespace called \ref asmjit, which provides
-//! the whole functionality. Core functionality is within \ref asmjit namespace
-//! and architecture specific functionality is always in its own namespace. For
-//! example \ref asmjit::x86 provides both 32-bit and 64-bit X86 code generation.
+//! AsmJit library uses one global namespace called \ref asmjit, which provides the whole functionality. Core
+//! functionality is within \ref asmjit namespace and architecture specific functionality is always in its own
+//! namespace. For example \ref asmjit::x86 provides both 32-bit and 64-bit X86 code generation.
//!
//! \section main_groups Documentation Groups
//!
-//! AsmJit documentation is structured into groups. Groups can be followed in
-//! order to learn AsmJit, but knowledge from multiple groups is required to
-//! use AsmJit properly:
+//! AsmJit documentation is structured into groups. Groups can be followed in order to learn AsmJit, but knowledge
+//! from multiple groups is required to use AsmJit properly:
//!
//! $$DOCS_GROUP_OVERVIEW$$
//!
-//! \note It's important to understand that in order to learn AsmJit all groups
-//! are important. Some groups can be omitted if a particular tool is out of
-//! interest - for example \ref asmjit_assembler users don't need to know about
-//! \ref asmjit_builder, but it's not the opposite. \ref asmjit_builder users
-//! must know about \ref asmjit_assembler as it also uses operands, labels, and
-//! other concepts. Similarly \ref asmjit_compiler users must know how both \ref
-//! asmjit_assembler and \ref asmjit_builder tools work.
+//! \note It's important to understand that in order to learn AsmJit all groups are important. Some groups can be
+//! omitted if a particular tool is out of interest - for example \ref asmjit_assembler users don't need to know
+//! about \ref asmjit_builder, but it's not the opposite. \ref asmjit_builder users should know about \ref
+//! asmjit_assembler as it also uses operands, labels, and other concepts. Similarly \ref asmjit_compiler users
+//! should know how both \ref asmjit_assembler and \ref asmjit_builder tools work.
//!
//! \section where_to_start Where To Start
//!
-//! AsmJit \ref asmjit_core provides the following two classes that are essential
-//! from the code generation perspective:
+//! AsmJit \ref asmjit_core provides the following two classes that are essential from the code generation perspective:
//!
-//! - \ref CodeHolder provides functionality
-//! to temporarily hold the generated code. It stores all the necessary
-//! information about the code - code buffers, sections, labels, symbols,
-//! and information about relocations.
+//! - \ref CodeHolder provides functionality to temporarily hold the generated code. It stores all the necessary
+//! information about the code - code buffers, sections, labels, symbols, and information about relocations.
//!
-//! - \ref BaseEmitter provides interface used
-//! by emitter implementations. The interface provides basic building blocks
-//! that are then implemented by \ref BaseAssembler, \ref BaseBuilder, and
-//! \ref BaseCompiler.
+//! - \ref BaseEmitter provides interface used by emitter implementations. The interface provides basic building
+//! blocks that are then implemented by \ref BaseAssembler, \ref BaseBuilder, and \ref BaseCompiler.
//!
//! Code emitters:
//!
//! - \ref asmjit_assembler - provides direct machine code generation.
//!
-//! - \ref asmjit_builder - provides intermediate code generation that can
-//! be processed before it's serialized to \ref BaseAssembler.
+//! - \ref asmjit_builder - provides intermediate code generation that can be processed before it's serialized to
+//! \ref BaseAssembler.
//!
-//! - \ref asmjit_compiler - provides high-level code generation with built-in
-//! register allocation.
+//! - \ref asmjit_compiler - provides high-level code generation with built-in register allocation.
//!
-//! - \ref FuncNode - provides insight into how function looks from the Compiler
-//! perspective and how it's stored in a node-list.
+//! - \ref FuncNode - provides insight into how function looks from the Compiler perspective and how it's stored in
+//! a node-list.
//!
//! \section main_recommendations Recommendations
//!
@@ -92,336 +60,403 @@ namespace asmjit {
//!
//! - Make sure that you use \ref ErrorHandler, see \ref asmjit_error_handling.
//!
-//! - Instruction validation in your debug builds can reveal problems too.
-//! AsmJit provides validation at instruction level, that can be enabled
-//! by \ref BaseEmitter::addValidationOptions().
+//! - Instruction validation in your debug builds can reveal problems too. AsmJit provides validation at instruction
+//! level that can be enabled via \ref BaseEmitter::addDiagnosticOptions(). See \ref DiagnosticOptions for more
+//! details.
//!
-//! See \ref BaseEmitter::ValidationOptions for more details.
+//! - If you are a Compiler user, use diagnostic options and read carefully if anything suspicious pops out.
+//! Diagnostic options can be enabled via \ref BaseEmitter::addDiagnosticOptions(). If unsure which ones to use,
+//! enable annotations and all debug options: `DiagnosticOptions::kRAAnnotate | DiagnosticOptions::kRADebugAll`.
//!
-//! - Make sure you put a breakpoint into \ref DebugUtils::errored() function
-//! if you have a problem with AsmJit returning errors during instruction
-//! encoding or register allocation. Having an active breakpoint there can
-//! help to reveal the origin of the error, to inspect variables and other
-//! conditions that caused to it.
+//! - Make sure you put a breakpoint into \ref DebugUtils::errored() function if you have a problem with AsmJit
+//! returning errors during instruction encoding or register allocation. Having an active breakpoint there can
+//! help to reveal the origin of the error, to inspect variables and other conditions that caused it.
//!
-//! The reason for using \ref Logger and \ref ErrorHandler is that they provide
-//! a very useful information about what's happening inside emitters. In many
-//! cases the information provided by these two is crucial to quickly fix issues
-//! that happen during development (for example wrong instruction, address, or
-//! register used). In addition, output from \ref Logger is always necessary
-//! when filling bug reports. In other words, using logging and proper error
-//! handling can save a lot of time during the development.
+//! The reason for using \ref Logger and \ref ErrorHandler is that they provide a very useful information about what's
+//! happening inside emitters. In many cases the information provided by these two is crucial to quickly 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
//!
//! - <a href="annotated.html">Class List</a> - List of classes sorted alphabetically
//! - <a href="namespaceasmjit.html">AsmJit Namespace</a> - List of symbols provided by `asmjit` namespace
-// ============================================================================
-// [Documentation - asmjit_build]
-// ============================================================================
//! \defgroup asmjit_build Build Instructions
//! \brief Build instructions, supported environments, and feature selection.
//!
//! ### Overview
//!
-//! AsmJit is designed to be easy embeddable in any project. However, it depends
-//! on some compile-time definitions that can be used to enable or disable
-//! features to decrease the resulting binary size. A typical way of building
-//! AsmJit is to use [cmake](https://www.cmake.org), but it's also possible to
-//! just include AsmJit source code in your project and to just build it. The
-//! easiest way to include AsmJit in your project is to just include **src**
-//! directory in your project and to define \ref ASMJIT_STATIC. AsmJit can be
-//! just updated from time to time without any changes to this integration
-//! process. Do not embed AsmJit's `test` files in such case as these are used
-//! exclusively for testing.
+//! AsmJit is designed to be easy embeddable in any project. However, it depends on some compile-time definitions that
+//! can be used to enable or disable features to decrease the resulting binary size. A typical way of building AsmJit
+//! is to use [cmake](https://www.cmake.org), but it's also possible to just include AsmJit source code in your project
+//! and to just build it. The easiest way to include AsmJit in your project is to just include **src** directory in
+//! your project and to define \ref ASMJIT_STATIC. AsmJit can be just updated from time to time without any changes to
+//! this integration process. Do not embed AsmJit's `test` files in such case as these are used exclusively for testing.
//!
//! ### Supported C++ Compilers
//!
//! - Requirements:
//!
-//! - AsmJit won't build without C++11 enabled. If you use older GCC or Clang
-//! you would have to enable at least C++11 standard through compiler flags.
+//! - AsmJit won't build without C++11 enabled. If you use older GCC or Clang you would have to enable at least
+//! C++11 standard through compiler flags.
//!
//! - Tested:
//!
-//! - **Clang** - Tested by Travis-CI - Clang 3.9+ (with C++11 enabled) is
-//! officially supported (older Clang versions having C++11 support are
-//! probably fine, but are not regularly tested).
-//!
-//! - **GNU** - Tested by Travis-CI - GCC 4.8+ (with C++11 enabled) is
-//! officially supported.
+//! - **Clang** - Tested by GitHub Actions - Clang 10+ is officially supported and tested by CI, older Clang versions
+//! having C++11 should work, but are not tested anymore due to upgraded CI images.
//!
-//! - **MINGW** - Tested by Travis-CI - Use the latest version, if possible.
+//! - **GNU** - Tested by GitHub Actions - GCC 7+ is officially supported, older GCC versions from 4.8+ having C++11
+//! enabled should also work, but are not tested anymore due to upgraded CI images.
//!
-//! - **MSVC** - Tested by Travis-CI - VS2017+ is officially supported, VS2015
-//! is reported to work.
+//! - **MINGW** - Reported to work, but not tested in our CI environment (help welcome).
//!
-//! - Untested:
-//!
-//! - **Intel** - No maintainers and no CI environment to regularly test
-//! this compiler.
-//!
-//! - **Other** C++ compilers would require basic support in
-//! [core/api-config.h](https://github.com/asmjit/asmjit/tree/master/src/asmjit/core/api-config.h).
+//! - **MSVC** - Tested by GitHub Actions - VS2019+ is officially supported, VS2015 and VS2017 is reported to work,
+//! but not tested by CI anymore.
//!
//! ### Supported Operating Systems and Platforms
//!
//! - Tested:
//!
-//! - **Linux** - Tested by Travis-CI (any distribution is generally supported).
+//! - **BSD** - FreeBSD, NetBSD, and OpenBSD tested by GitHub Actions (only recent images are tested by CI). BSD
+//! runners only test BSD images with clang compiler.
//!
-//! - **OSX** - Tested by Travis-CI (any version is supported).
+//! - **Linux** - Tested by GitHub Actions (only recent Ubuntu images are tested by CI, in general any distribution
+//! should be supported as AsmJit has no dependencies).
//!
-//! - **Windows** - Tested by Travis-CI - (Windows 7+ is officially supported).
+//! - **Mac OS** - Tested by GitHub Actions.
//!
-//! - **Emscripten** - Works if compiled with \ref ASMJIT_NO_JIT. AsmJit
-//! cannot generate WASM code, but can be used to generate X86/X64 code
-//! within a browser, for example.
+//! - **Windows** - Tested by GitHub Actions - (Windows 7+ is officially supported).
//!
-//! - Untested:
+//! - **Emscripten** - Works if compiled with \ref ASMJIT_NO_JIT. AsmJit cannot generate WASM code, but can be
+//! used to generate X86/X64/AArch64 code within a browser, for example.
//!
-//! - **BSDs** - No maintainers, no CI environment to regularly test BSDs,
-//! but they should work out of box.
+//! - Untested:
//!
-//! - **Haiku** - Not regularly tested, but reported to work.
+//! - **Haiku** - Reported to work, not tested by CI.
//!
-//! - **Other** operating systems would require some testing and support in
-//! the following files:
+//! - **Other** operating systems would require some testing and support in the following files:
//! - [core/api-config.h](https://github.com/asmjit/asmjit/tree/master/src/asmjit/core/api-config.h)
//! - [core/osutils.cpp](https://github.com/asmjit/asmjit/tree/master/src/asmjit/core/osutils.cpp)
//! - [core/virtmem.cpp](https://github.com/asmjit/asmjit/tree/master/src/asmjit/core/virtmem.cpp)
//!
//! ### Supported Backends / Architectures
//!
-//! - **X86** - Both 32-bit and 64-bit backends tested by Travis-CI.
-//! - **ARM** - Work-in-progress (not public at the moment).
+//! - **X86** 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
//!
-//! These definitions can be used to enable static library build. Embed is used
-//! when AsmJit's source code is embedded directly in another project, implies
-//! static build as well.
+//! These definitions can be used to enable static library build. Embed is used when AsmJit's source code is embedded
+//! directly in another project, implies static build as well.
//!
//! - \ref ASMJIT_EMBED - Asmjit is embedded, implies \ref ASMJIT_STATIC.
//! - \ref ASMJIT_STATIC - Enable static-library build.
//!
-//! \note Projects that use AsmJit statically must define \ref ASMJIT_STATIC in
-//! all compilation units that use AsmJit, otherwise AsmJit would use dynamic
-//! library imports in \ref ASMJIT_API decorator. The recommendation is to
-//! define this macro across the whole project that uses AsmJit this way.
+//! \note Projects that use AsmJit statically must define \ref ASMJIT_STATIC in all compilation units that use AsmJit,
+//! otherwise AsmJit would use dynamic library imports in \ref ASMJIT_API decorator. The recommendation is to define
+//! this macro across the whole project that uses AsmJit this way.
//!
//! ### Build Configuration
//!
-//! These definitions control whether asserts are active or not. By default
-//! AsmJit would autodetect build configuration from existing pre-processor
-//! definitions, but this behavior can be overridden, for example to enable
-//! debug asserts in release configuration.
+//! These definitions control whether asserts are active or not. By default AsmJit would autodetect build configuration
+//! from existing pre-processor definitions, but this behavior can be overridden, for example to enable debug asserts
+//! in release configuration.
//!
-//! - \ref ASMJIT_BUILD_DEBUG - Overrides build configuration to debug,
-//! asserts will be enabled in this case.
-//! - \ref ASMJIT_BUILD_RELEASE - Overrides build configuration to release,
-//! asserts will be disabled in this case.
+//! - \ref ASMJIT_BUILD_DEBUG - Overrides build configuration to debug, asserts will be enabled in this case.
+//! - \ref ASMJIT_BUILD_RELEASE - Overrides build configuration to release, asserts will be disabled in this case.
//!
-//! \note There is usually no need to override the build configuration. AsmJit
-//! detects the build configuration by checking whether `NDEBUG` is defined and
-//! automatically defines \ref ASMJIT_BUILD_RELEASE if configuration overrides
-//! were not used. We only recommend using build configuration overrides in
-//! special situations, like using AsmJit in release configuration with asserts
-//! enabled for whatever reason.
+//! \note There is usually no need to override the build configuration. AsmJit detects the build configuration by
+//! checking whether `NDEBUG` is defined and automatically defines \ref ASMJIT_BUILD_RELEASE if configuration overrides
+//! were not used. We only recommend using build configuration overrides in special situations, like using AsmJit in
+//! release configuration with asserts enabled for whatever reason.
//!
//! ### AsmJit Backends
//!
-//! AsmJit currently supports only X86/X64 backend, but the plan is to add more
-//! backends in the future. By default AsmJit builds only the host backend, which
-//! is autodetected at compile-time, but this can be overridden.
-//!
-//! - \ref ASMJIT_BUILD_X86 - Always build X86 backend (X86 and X86_64).
-//! - \ref ASMJIT_BUILD_ARM - Always build ARM backend (ARM and AArch64).
-//! - \ref ASMJIT_BUILD_HOST - Always build the host backend, implied by default.
+//! AsmJit currently supports only X86/X64 backend, but the plan is to add more backends in the future. By default
+//! AsmJit builds only the host backend, which is auto-detected at compile-time, but this can be overridden.
//!
-//! ### Features Selection
+//! - \ref ASMJIT_NO_X86 - Disables both X86 and X86_64 backends.
+//! - \ref ASMJIT_NO_AARCH64 - Disables AArch64 backend.
+//! - \ref ASMJIT_NO_FOREIGN - Disables the support for foreign architecture backends, only keeps a native backend.
//!
-//! AsmJit builds by defaults all supported features, which includes all emitters,
-//! logging, instruction validation and introspection, and JIT memory allocation.
-//! Features can be disabled at compile time by using `ASMJIT_NO_...` definitions.
+//! ### AsmJit Compilation Options
//!
-//! - \ref ASMJIT_NO_DEPRECATED - Disables deprecated API at compile time
-//! so it won't be available and the compilation will fail if there is
-//! attempt to use such API. This includes deprecated classes, namespaces,
+//! - \ref ASMJIT_NO_DEPRECATED - Disables deprecated API at compile time so it won't be available and the
+//! compilation will fail if there is attempt to use such API. This includes deprecated classes, namespaces,
//! enumerations, and functions.
//!
-//! - \ref ASMJIT_NO_BUILDER - Disables \ref asmjit_builder functionality
-//! completely. This implies \ref ASMJIT_NO_COMPILER as \ref asmjit_compiler
-//! cannot be used without \ref asmjit_builder.
+//! - \ref ASMJIT_NO_SHM_OPEN - Disables functionality that uses `shm_open()`.
//!
-//! - \ref ASMJIT_NO_COMPILER - Disables \ref asmjit_compiler functionality
-//! completely.
+//! - \ref ASMJIT_NO_ABI_NAMESPACE - Disables inline ABI namespace within `asmjit` namespace. This is only provided
+//! for users that control all the dependencies (even transitive ones) and that make sure that no two AsmJit
+//! versions are used at the same time. This option can be debugging a little simpler as there would not be ABI
+//! tag after `asmjit::` namespace. Otherwise asmjit would look like `asmjit::_abi_1_13::`, for example.
//!
+//! ### Features Selection
+//!
+//! AsmJit builds by defaults all supported features, which includes all emitters, logging, instruction validation and
+//! introspection, and JIT memory allocation. Features can be disabled at compile time by using `ASMJIT_NO_...`
+//! definitions.
//! - \ref ASMJIT_NO_JIT - Disables JIT memory management and \ref JitRuntime.
//!
-//! - \ref ASMJIT_NO_LOGGING - Disables \ref Logger and \ref Formatter.
+//! - \ref ASMJIT_NO_TEXT - Disables everything that contains string representation of AsmJit constants, should
+//! be used together with \ref ASMJIT_NO_LOGGING as logging doesn't make sense without the ability to query
+//! instruction names, register names, etc...
//!
-//! - \ref ASMJIT_NO_TEXT - Disables everything that contains string
-//! representation of AsmJit constants, should be used together with
-//! \ref ASMJIT_NO_LOGGING as logging doesn't make sense without the
-//! ability to quiry instruction names, register names, etc...
+//! - \ref ASMJIT_NO_LOGGING - Disables \ref Logger and \ref Formatter.
//!
//! - \ref ASMJIT_NO_VALIDATION - Disables validation API.
//!
-//! - \ref ASMJIT_NO_INTROSPECTION - Disables instruction introspection API,
-//! must be used together with \ref ASMJIT_NO_COMPILER as \ref asmjit_compiler
-//! requires introspection for its liveness analysis and register allocation.
+//! - \ref ASMJIT_NO_INTROSPECTION - Disables instruction introspection API, must be used together with \ref
+//! ASMJIT_NO_COMPILER as \ref asmjit_compiler requires introspection for its liveness analysis and register
+//! allocation.
+//!
+//! - \ref ASMJIT_NO_BUILDER - Disables \ref asmjit_builder functionality completely. This implies \ref
+//! ASMJIT_NO_COMPILER as \ref asmjit_compiler cannot be used without \ref asmjit_builder.
+//!
+//! - \ref ASMJIT_NO_COMPILER - Disables \ref asmjit_compiler functionality completely.
//!
-//! \note It's not recommended to disable features if you plan to build AsmJit
-//! as a shared library that will be used by multiple projects that you don't
-//! control how AsmJit was built (for example AsmJit in a Linux distribution).
-//! The possibility to disable certain features exists mainly for customized
-//! AsmJit builds.
+//! \note It's not recommended to disable features if you plan to build AsmJit as a shared library that will be
+//! used by multiple projects that you don't control how AsmJit was built (for example AsmJit in a Linux distribution).
+//! The possibility to disable certain features exists mainly for customized AsmJit builds.
-// ============================================================================
-// [Documentation - asmjit_breaking_changes]
-// ============================================================================
//! \defgroup asmjit_breaking_changes Breaking Changes
//! \brief Documentation of breaking changes
//!
//! ### Overview
//!
-//! AsmJit is a live project that is being actively developed. Deprecating the
-//! existing API in favor of a new one is preferred, but it's not always
-//! possible if the changes are significant. AsmJit authors prefer to do
-//! accumulated breaking changes at once instead of breaking the API often.
-//! This page documents deprecated and removed APIs and should serve as a how-to
-//! guide for people that want to port existing code to work with the newest AsmJit.
+//! AsmJit is a live project that is being actively developed. Deprecating the existing API in favor of a new
+//! one is preferred, but it's not always possible if the changes are significant. AsmJit authors prefer to do
+//! accumulated breaking changes at once instead of breaking the API often. This page documents deprecated and
+//! removed APIs and should serve as a how-to guide for people that want to port existing code to work with the
+//! newest AsmJit.
//!
//! ### Tips
//!
//! Useful tips before you start:
//!
-//! - Visit our [Public Gitter Channel](https://gitter.im/asmjit/asmjit) if
-//! you need a quick help.
+//! - Visit our [Public Gitter Chat](https://app.gitter.im/#/room/#asmjit:gitter.im) if you need a quick help.
+//!
+//! - Build AsmJit with `ASMJIT_NO_DEPRECATED` macro defined to make sure that you are not using deprecated
+//! functionality at all. Deprecated functions are decorated with `ASMJIT_DEPRECATED()` macro, but sometimes
+//! it's not possible to decorate everything like classes, which are used by deprecated functions as well,
+//! because some compilers would warn about that. If your project compiles fine with `ASMJIT_NO_DEPRECATED`
+//! it's not using anything, which was deprecated.
+//!
+//! ### Changes committed at 2024-01-01
+//!
+//! Core changes:
+//!
+//! - Renamed equality functions `eq()` to `equals()` - Only related to `String`, `ZoneVector`, and `CpuFeatures`.
+//! Old function names were deprecated.
+//!
+//! - Removed `CallConvId::kNone` in favor of `CallConvId::kCDecl`, which is now the default calling convention.
//!
-//! - Build AsmJit with `ASMJIT_NO_DEPRECATED` macro defined to make sure that
-//! you are not using deprecated functionality at all. Deprecated functions
-//! are decorated with `ASMJIT_DEPRECATED()` macro, but sometimes it's not
-//! possible to decorate everything like classes, which are used by deprecated
-//! functions as well, because some compilers would warn about that. If your
-//! project compiles fine with `ASMJIT_NO_DEPRECATED` it's not using anything,
-//! which was deprecated.
+//! - Deprecated `CallConvId::kHost` in favor of `CallConvId::kCDecl` - host calling convention is now not part
+//! of CallConvId, it can be calculated from CallConvId and Environment instead.
+//!
+//! ### Changes committed at 2023-12-27
+//!
+//! Core changes:
+//!
+//! - Renamed `a64::Vec::ElementType` to `a64::VecElementType` and made it a typed enum. This enum was used mostly
+//! internally, but there is a public API using it, so it's a breaking change.
+//!
+//! - Refactored `FuncSignature`, `FuncSignatureT`, and `FuncSignatureBuilder`. There is only `FuncSignature` now,
+//! which acts as a function signature holder and builder. Replace `FuncSignatureBuilder` with `FuncSignature`
+//! and use `FuncSignature::build<args>` instead of `FuncSignatureT<args>`. The old API has been deprecated.
+//!
+//! - The maximum number of function arguments was raised from 16 to 32.
+//!
+//! ### Changes committed at 2023-12-26
+//!
+//! Core changes:
+//!
+//! - Reworked InstNode and InstExNode to be friendlier to static analysis and to not cause undefined behavior.
+//! InstNode has no operands visually embedded within the struct so there is no _opArray (which was internal).
+//! This means that sizeof(InstNode) changed, but since it's allocated by AsmJit this should be fine. Moreover,
+//! there is no longer InstExNode as that was more a hack, instead there is now InstNodeWithOperands, which is
+//! a template and specifies the number of operands embedded (InstNode accesses these). All nodes that inherited
+//! InstExNode now just inherit InstNodeWithOperands<InstNode::kBaseOpCapacity>, which would provide the same
+//! number of nodes as InstNode.
+//!
+//! - Moved GP and Vec registers from asmjit::arm namespace to asmjit::a64 namespace. At this time there was
+//! no prior deprecation as having arm::Vec would collide with a64::Vec as arm namespace is used within a64
+//! namespace. Just change `arm::Gp` to `a64::Gp` and `arm::Vec` to `a64::Vec`.
+//!
+//! ### Changes committed at 2023-09-10
+//!
+//! Core changes:
+//!
+//! - Changed allocation API to work with spans (JitAllocator).
+//!
+//! - This change is required to support more hardened platforms in the future that make it very difficult
+//! to write JIT compilers.
+//! - `JitAllocator::Span` now represents a memory that the user can access. It abstracts both regular and
+//! dual mappings.
+//! - The `Span` is mostly designed to make it possible to write into it, so in general the read+execute
+//! pointer is what user is intended to keep. Use `span.rx()` to access RX pointer. `Span` is not needed
+//! after the memory it references has been modified, only remember `span.rx()` pointer, which is then
+//! used to deallocate or change the memory the span references.
+//! - Use a new `JitAllocator::alloc()` to allocate a `Span`, then pass the populated Span to `JitAllocator`
+//! write API such as `JitAllocator::write()` - note that JitAllocator can also establish a scope, so you
+//! can use a lambda function that would perform the write, but since it's going through JitAllocator it's
+//! able to ensure that the memory is actually writable.
+//! - If you need to repopulate a `Span` from rx pointer, use `JitAllocator::query(<span-out>, rx)` to get it.
+//! - Study what JitRuntime is doing to better understand how this new API works in detail.
+//! - Users of JitRuntime do not have to do anything as JitRuntime properly abstracts the allocation.
+//!
+//! - Renamed some X86 CPU features to make them compatible with architecture manuals:
+//!
+//! - Changed `AVX512_CDI` to `AVX512_CD`.
+//! - Changed `AVX512_ERI` to `AVX512_ER`.
+//! - Changed `AVX512_PFI` to `AVX512_PF`.
+//!
+//! - Old names were deprecated.
+//!
+//! ### Changes committed at 2021-12-13
+//!
+//! Core changes:
+//!
+//! - Removed old deprecated API.
+//!
+//! - Many enumerations were changed to enum class, and many public APIs were changed to use such enums instead
+//! of uint32_t. This change makes some APIs backward incompatible - there are no deprecations this time.
+//!
+//! - Extracted operand signature manipulation to `OperandSignature`.
+//! - Setting function arguments through `Compiler::setArg()` was deprecated, use FuncNode::setArg() instead.
+//! - Moved `{arch}::Features::k` to `CpuFeatures::{arch}::k`.
+//! - Moved `BaseEmitter::kEncodingOption` to `EncodingOptions::k`.
+//! - Moved `BaseEmitter::kFlag` to `EmitterFlags::k`.
+//! - Moved `BaseEmitter::kType` to `EmitterType::k`.
+//! - Moved `BaseEmitter::kValidationOption` to `DiagnosticOptions::kValidate`.
+//! - Moved `BaseFeatures` to `CpuFeatures`.
+//! - Moved `BaseInst::kControl` to `InstControlFlow::k`.
+//! - Moved `BaseInst::kOption` and `x86::Inst::kOption` to `InstOptions::k`.
+//! - Moved `BaseNode::kNode` to `NodeType::k`.
+//! - Moved `BaseReg::kGroup` and `x86::Reg::kGroup` to `RegGroup::k`.
+//! - Moved `BaseReg::kType` and `x86::Reg::kType` to `RegType::k`.
+//! - Moved `CallConv::kFlag` to `CallConvFlags::k`.
+//! - Moved `CallConv::kId` to `CallConvId::k`.
+//! - Moved `CallConv::kStrategy` to `CallConvStrategy::k`.
+//! - Moved `CodeBuffer::kFlag` to `CodeBufferFlags`.
+//! - Moved `ConstPool::kScope` to `ConstPoolScope::k`.
+//! - Moved `Environment::kArch` to `Arch::k`.
+//! - Moved `Environment::kSubArch` to `SubArch::k`.
+//! - Moved `Environment::kFormat` to `OjectFormat::k`.
+//! - Moved `Environment::kPlatform` to `Platform::k`.
+//! - Moved `Environment::kAbi` to `PlatformABI::k`.
+//! - Moved `Environment::kVendor` to `Vendor::k`.
+//! - Moved `FormatOptions::kFlag` to `FormatFlags::k` and `DiagnosticOptions::k` (Compiler diagnostics flags).
+//! - Moved `FormatOptions::kIndentation` to `FormatIndentationGroup::k`.
+//! - Moved `FuncFrame::kAttr` to `FuncAttributes::k`.
+//! - Moved `Globals::kReset` to `ResetPolicy::k`.
+//! - Moved `InstDB::kAvx512Flag` to `InstDB::Avx512Flags::k`.
+//! - Moved `InstDB::kFlag` to `InstDB::InstFlags::k`.
+//! - Moved `InstDB::kMemFlag` to `InstDB::OpFlags::kMem`.
+//! - Moved `InstDB::kMode` to `InstDB::Mode::k`.
+//! - Moved `InstDB::kOpFlag` to `InstDB::OpFlags::k{OpType}...`.
+//! - Moved `JitAllocator::kOption` to `JitAllocatorOptions::k`.
+//! - Moved `Label::kType` to `LabelType::k`.
+//! - Moved `Operand::kOpType` to `OperandType::k`.
+//! - Moved `OpRWInfo::kFlag` to `OpRWFlags::k`.
+//! - Moved `Type::kId` to `TypeId::k`.
+//! - Moved `VirtMem::k` to `VirtMem::MemoryFlags::k`.
//!
//! ### Changes committed at 2020-05-30
//!
-//! AsmJit has been cleaned up significantly, many todo items have been fixed
-//! and many functions and classes have been redesigned, some in an incompatible
-//! way.
+//! AsmJit has been cleaned up significantly, many todo items have been fixed and many functions and classes have
+//! been redesigned, some in an incompatible way.
//!
//! Core changes:
//!
-//! - \ref Imm operand has now only \ref Imm::value() and \ref Imm::valueAs()
-//! functions that return its value content, and \ref Imm::setValue() function
-//! that sets the content. Functions like `setI8()`, `setU8()` were deprecated.
+//! - `Imm` operand has now only `Imm::value()` and `Imm::valueAs()` functions that return its value content,
+//! and `Imm::setValue()` function that sets the content. Functions like `setI8()`, `setU8()` were deprecated.
//!
//! Old functions were deprecated, but code using them should still compile.
//!
-//! - `ArchInfo` has been replaced with \ref Environment. Environment provides
-//! more details about the architecture, but drops some properties that
-//! were used by arch info - `gpSize(`) and `gpCount()`. `gpSize()` can
-//! be replaced with `registerSize()` getter, which returns a native register
-//! size of the architecture the environment uses. However, `gpCount()` was
-//! removed - at the moment \ref ArchRegs can be used to access such properties.
+//! - `ArchInfo` has been replaced with `Environment`. Environment provides more details about the architecture,
+//! but drops some properties that were used by arch info - `gpSize(`) and `gpCount()`. `gpSize()` can be replaced
+//! with `registerSize()` getter, which returns a native register size of the architecture the environment uses.
+//! However, `gpCount()` was removed - at the moment `ArchTraits` can be used to access such properties.
//!
-//! Some other functions were renamed, like `ArchInfo::isX86Family()` is
-//! now \ref Environment::isFamilyX86(), etc. The reason for changing the
-//! order was support for more propertries and all the accessors now
-//! start with the type of the property, like \ref Environment::isPlatformWindows().
+//! Some other functions were renamed, like `ArchInfo::isX86Family()` is now `Environment::isFamilyX86()`, etc.
+//! The reason for changing the order was support for more properties and all the accessors now start with the
+//! type of the property, like `Environment::isPlatformWindows()`.
//!
-//! This function causes many other classes to provide `environment()` getter
-//! instead of `archInfo()` getter. In addition, AsmJit now uses `arch()` to
-//! get an architecture instead of `archId()`. `ArchInfo::kIdXXX` was renamed
-//! to `Environment::kArchXXX`.
+//! This function causes many other classes to provide `environment()` getter instead of `archInfo()` getter.
+//! In addition, AsmJit now uses `arch()` to get an architecture instead of `archId()`. `ArchInfo::kIdXXX` was
+//! renamed to `Environment::kArchXXX`.
//!
//! Some functions were deprecated, some removed...
//!
-//! - `CodeInfo` has been removed in favor of \ref Environment. If you used
-//! `CodeInfo` to set architecture and base address, this is now possible
-//! with \ref Environment and setting base address explicitly by \ref
-//! CodeHolder::init() - the first argument is \ref Environment, and the
-//! second argument is base address, which defaults to \ref
-//! Globals::kNoBaseAddress.
+//! - `CodeInfo` has been removed in favor of `Environment`. If you used `CodeInfo` to set architecture and base
+//! address, this is now possible with `Environment` and setting base address explicitly by `CodeHolder::init()`
+//! - the first argument is `Environment`, and the second argument is base address, which defaults to
+//! `Globals::kNoBaseAddress`.
//!
-//! CodeInfo class was deprecated, but the code using it should still
-//! compile with warnings.
+//! CodeInfo class was deprecated, but the code using it should still compile with warnings.
//!
-//! - \ref CallConv has been updated to offer a more unified way of representing
-//! calling conventions - many calling conventions were abstracted to follow
-//! standard naming like \ref CallConv::kIdCDecl or \ref CallConv::kIdStdCall.
+//! - `CallConv` has been updated to offer a more unified way of representing calling conventions - many calling
+//! conventions were abstracted to follow standard naming like `CallConvId::kCDecl` or `CallConvId::kStdCall`.
//!
-//! This change means that other APIs like \ref FuncDetail::init() now
-//! require both, calling convention and target \ref Environment.
+//! This change means that other APIs like `FuncDetail::init()` now require both, calling convention and target
+//! `Environment`.
//!
-//! - `Logging` namespace has been renamed to \ref Formatter, which now
-//! provides general functionality for formatting in AsmJit.
+//! - `Logging` namespace has been renamed to `Formatter`, which now provides general functionality for formatting
+//! in AsmJit.
//!
-//! Logging namespace should still work, but its use is deprecated.
-//! Unfortunately this will be without deprecation warnings, so please
-//! make sure you don't use it.
+//! Logging namespace should still work, but its use is deprecated. Unfortunately this will be without deprecation
+//! warnings, so make sure you don't use it.
//!
-//! - `Data64`, `Data128`, and `Data256` structs were deprecated and should
-//! no longer be used. There is no replacement, AsmJit users should simply
-//! create their own structures if they need them or use the new repeated
-//! embed API in emitters, see \ref BaseEmitter::embedDataArray().
+//! - `Data64`, `Data128`, and `Data256` structs were deprecated and should no longer be used. There is no replacement,
+//! AsmJit users should simply create their own structures if they need them or use the new repeated embed API in
+//! emitters, see `BaseEmitter::embedDataArray()`.
//!
//! Emitter changes:
//!
-//! - \ref BaseEmitter::emit() function signature has been changed to accept
-//! 3 operands by reference and the rest 3 operands as a continuous array.
-//! This change is purely cosmetic and shouldn't affect users as emit()
-//! has many overloads that dispatch to the right function.
+//! - `BaseEmitter::emit()` function signature has been changed to accept 3 operands by reference and the rest 3
+//! operands as a continuous array. This change is purely cosmetic and shouldn't affect users as emit() has many
+//! overloads that dispatch to the right function.
//!
-//! - \ref x86::Emitter (Assembler, Builder, Compiler) deprecates embed
-//! utilities like `dint8()`, `duint8()`, `duint16()`, `dxmm()`, etc...
-//! in favor of a new and more powerful \ref BaseEmitter::embedDataArray().
-//! This function also allows emitting repeated values and/or patterns,
-//! which is used by helpers \ref BaseEmitter::embedUInt8(), and others...
+//! - `x86::Emitter` (Assembler, Builder, Compiler) deprecates embed utilities like `dint8()`, `duint8()`, `duint16()`,
+//! `dxmm()`, etc... in favor of a new and more powerful `BaseEmitter::embedDataArray()`. This function also allows
+//! emitting repeated values and/or patterns, which is used by helpers `BaseEmitter::embedUInt8()`, and others...
//!
-//! - Validation is now available through \ref BaseEmitter::ValidationOptions,
-//! which can be enabled/disabled through \ref BaseEmitter::addValidationOptions()
-//! and \ref BaseEmitter::clearValidationOptions(), respectively. Validation
-//! options now separate between encoding and Builder/Compiler so it's possible
-//! to choose the granularity required.
+//! - Validation is now available through `BaseEmitter::DiagnosticOptions`, which can be enabled/disabled through
+//! `BaseEmitter::addDiagnosticOptions()` and `BaseEmitter::clearDiagnosticOptions()`, respectively. Validation
+//! options now separate between encoding and Builder/Compiler so it's possible to choose the granularity required.
//!
//! Builder changes:
//!
-//! - Internal functions for creating nodes were redesigned. They now accept
-//! a pointer to the node created as a first parameter. These changes should
-//! not affect AsmJit users as these functions were used internally.
+//! - Internal functions for creating nodes were redesigned. They now accept a pointer to the node created as
+//! a first parameter. These changes should not affect AsmJit users as these functions were used internally.
//!
//! Compiler changes:
//!
-//! - `FuncCallNode` has been renamed to \ref InvokeNode. Additionally, function
-//! calls should now use \ref x86::Compiler::invoke() instead of `call()`.
-//! The reason behind this is to remove the confusion between a `call`
-//! instruction and AsmJit's `call()` intrinsic, which is now `invoke()`.
+//! - `FuncCallNode` has been renamed to `InvokeNode`. Additionally, function calls should now use
+//! `x86::Compiler::invoke()` instead of `call()`. The reason behind this is to remove the confusion between a
+//! `call` instruction and AsmJit's `call()` intrinsic, which is now `invoke()`.
//!
-//! - Creating new nodes also changed. Now the preferred way of invoking a
-//! function is to call \ref x86::Compiler::invoke() where the first
-//! argument is `InvokeNode**`. The function now returns an error and would
-//! call \ref ErrorHandler in case of a failure. Error handling was
-//! unspecified in the past - the function was marked noexcept, but called
-//! error handler, which could throw.
+//! - Creating new nodes also changed. Now the preferred way of invoking a function is to call
+//! `x86::Compiler::invoke()` where the first argument is `InvokeNode**`. The function now returns an error and
+//! would call `ErrorHandler` in case of a failure. Error handling was unspecified in the past - the function was
+//! marked noexcept, but called error handler, which could throw.
//!
-//! The reason behind this change is to make the API consistent with other
-//! changes and to also make it possible to inspect the possible error. In
-//! the previous API it returned a new node or `nullptr` in case of error,
-//! which the user couldn't inspect unless there was an attached \ref
-//! ErrorHandler.
+//! The reason behind this change is to make the API consistent with other changes and to also make it possible
+//! to inspect the possible error. In the previous API it returned a new node or `nullptr` in case of error,
+//! which the user couldn't inspect unless there was an attached `ErrorHandler`.
//!
//! Samples:
//!
//! ```
//! #include <asmjit/x86.h>
+//!
//! using namespace asmjit;
//!
//! // The basic setup of JitRuntime and CodeHolder changed, use environment()
@@ -434,59 +469,50 @@ namespace asmjit {
//! // Calling a function (Compiler) changed - use invoke() instead of call().
//! void functionInvocation(x86::Compiler& cc) {
//! InvokeNode* invokeNode;
-//! cc.invoke(&invokeNode, targetOperand, FuncSignatureT<...>(...));
+//! cc.invoke(&invokeNode, targetOperand, FuncSignature::build<...>(...));
//! }
//! ```
-// ============================================================================
-// [Documentation - asmjit_core]
-// ============================================================================
//! \defgroup asmjit_core Core
//! \brief Globals, code storage, and emitter interface.
//!
//! ### Overview
//!
-//! AsmJit library uses \ref CodeHolder to hold code during code generation and
-//! emitters inheriting from \ref BaseEmitter to emit code. CodeHolder uses
-//! containers to manage its data:
+//! AsmJit library uses \ref CodeHolder to hold code during code generation and emitters inheriting from \ref
+//! BaseEmitter to emit code. CodeHolder uses containers to manage its data:
//!
//! - \ref Section - stores information about a code or data section.
//! - \ref CodeBuffer - stores actual code or data, part of \ref Section.
-//! - \ref LabelEntry - stores information about a label - its name, offset,
-//! section where it belongs to, and other bits.
-//! - \ref LabelLink - stores information about yet unbound label, which was
-//! already used by the assembler.
+//! - \ref LabelEntry - stores information about a label - its name, offset, section where it belongs to, and
+//! other bits.
+//! - \ref LabelLink - stores information about yet unbound label, which was already used by the assembler.
//! - \ref RelocEntry - stores information about a relocation.
-//! - \ref AddressTableEntry - stores information about an address, which was
-//! used in a jump or call. Such address may need relocation.
+//! - \ref AddressTableEntry - stores information about an address, which was used in a jump or call. Such
+//! address may need relocation.
//!
//! To generate code you would need to instantiate at least the following classes:
//!
//! - \ref CodeHolder - to hold code during code generation.
//! - \ref BaseEmitter - to emit code into \ref CodeHolder.
-//! - \ref Target (optional) - most likely \ref JitRuntime to keep the generated
-//! code in executable memory. \ref Target can be customized by inheriting from
-//! it.
+//! - \ref Target (optional) - most likely \ref JitRuntime to keep the generated code in executable memory. \ref
+//! Target can be customized by inheriting from it.
//!
//! There are also other core classes that are important:
//!
-//! - \ref Environment - describes where the code will run. Environment brings
-//! the concept of target triples or tuples into AsmJit, which means that users
-//! can specify target architecture, platform, and ABI.
-//! - \ref Type - encapsulates lightweight type functionality that can be used
-//! to describe primitive and vector types. Types are used by higher level
-//! utilities, for example by \ref asmjit_function and \ref asmjit_compiler.
-//! - \ref CpuInfo - encapsulates CPU information - stores both CPU information
-//! and features described by \ref BaseFeatures.
+//! - \ref Environment - describes where the code will run. Environment brings the concept of target triples or
+//! tuples into AsmJit, which means that users can specify target architecture, platform, and ABI.
+//! - \ref TypeId - encapsulates lightweight type functionality that can be used to describe primitive and vector
+//! types. Types are used by higher level utilities, for example by \ref asmjit_function and \ref asmjit_compiler.
+//! - \ref CpuInfo - encapsulates CPU information - stores both CPU information and CPU features described by \ref
+//! CpuFeatures.
//!
//! AsmJit also provides global constants:
//!
//! - \ref Globals - namespace that provides global constants.
//! - \ref ByteOrder - byte-order constants and functionality.
//!
-//! \note CodeHolder examples use \ref x86::Assembler as abstract interfaces cannot
-//! be used to generate code.
+//! \note CodeHolder examples use \ref x86::Assembler as abstract interfaces cannot be used to generate code.
//!
//! ### CodeHolder & Emitters
//!
@@ -505,7 +531,8 @@ namespace asmjit {
//! JitRuntime rt; // Runtime specialized for JIT code execution.
//!
//! CodeHolder code; // Holds code and relocation information.
-//! code.init(rt.environment()); // Initialize code to match the JIT environment.
+//! code.init(rt.environment(), // Initialize code to match the JIT environment.
+//! rt.cpuFeatures());
//!
//! x86::Assembler a(&code); // Create and attach x86::Assembler to code.
//! a.mov(x86::eax, 1); // Move one to eax register.
@@ -529,8 +556,8 @@ namespace asmjit {
//! }
//! ```
//!
-//! The example above used \ref x86::Assembler as an emitter. AsmJit provides the
-//! following emitters that offer various levels of abstraction:
+//! The example above used \ref x86::Assembler as an emitter. AsmJit provides the following emitters that offer various
+//! levels of abstraction:
//!
//! - \ref asmjit_assembler - Low-level emitter that emits directly to \ref CodeBuffer.
//! - \ref asmjit_builder - Low-level emitter that emits to a \ref BaseNode list.
@@ -538,30 +565,25 @@ namespace asmjit {
//!
//! ### Targets and JitRuntime
//!
-//! AsmJit's \ref Target is an interface that provides basic target abstraction.
-//! At the moment AsmJit provides only one implementation called \ref JitRuntime,
-//! which as the name suggests provides JIT code target and execution runtime.
-//! \ref JitRuntime provides all the necessary stuff to implement a simple JIT
-//! compiler with basic memory management. It only provides \ref JitRuntime::add()
-//! and \ref JitRuntime::release() functions that are used to either add code
-//! to the runtime or release it. \ref JitRuntime doesn't do any decisions on
-//! when the code should be released, the decision is up to the developer.
+//! AsmJit's \ref Target is an interface that provides basic target abstraction. At the moment AsmJit provides only
+//! one implementation called \ref JitRuntime, which as the name suggests provides JIT code target and execution
+//! runtime. \ref JitRuntime provides all the necessary stuff to implement a simple JIT compiler with basic memory
+//! management. It only provides \ref JitRuntime::add() and \ref JitRuntime::release() functions that are used to
+//! either add code to the runtime or release it. \ref JitRuntime doesn't do any decisions on when the code should be
+//! released, the decision is up to the developer.
//!
//! See more at \ref asmjit_virtual_memory group.
//!
//! ### More About Environment
//!
-//! In the previous example the \ref Environment is retrieved from \ref JitRuntime.
-//! It's logical as \ref JitRuntime always returns an \ref Environment that is
-//! compatible with the host. For example if your application runs in 64-bit mode
-//! the \ref Environment returned will use \ref Environment::kArchX64 architecture
-//! in contrast to \ref Environment::kArchX86, which will be used in 32-bit mode on
-//! any X86 platform.
+//! In the previous example the \ref Environment is retrieved from \ref JitRuntime. It's logical as \ref JitRuntime
+//! always returns an \ref Environment that is compatible with the host. For example if your application runs on X86_64
+//! CPU the \ref Environment returned will use \ref Arch::kX64 architecture in contrast to \ref Arch::kX86, which will
+//! be used in 32-bit mode on an X86 target.
//!
-//! AsmJit allows to setup the \ref Environment manually and to select a different
-//! architecture and ABI when necessary. So let's do something else this time, let's
-//! always generate a 32-bit code and print its binary representation. To do that, we
-//! can create our own \ref Environment and initialize it to \ref Environment::kArchX86.
+//! AsmJit allows to setup the \ref Environment manually and to select a different architecture and ABI when necessary.
+//! So let's do something else this time, let's always generate a 32-bit code and print its binary representation. To
+//! do that, we can create our own \ref Environment and initialize it to \ref Arch::kX86.
//!
//! ```
//! #include <asmjit/x86.h>
@@ -574,7 +596,7 @@ namespace asmjit {
//!
//! // Create a custom environment initialized to 32-bit X86 architecture.
//! Environment env;
-//! env.setArch(Environment::kArchX86);
+//! env.setArch(Arch::kX86);
//!
//! CodeHolder code; // Create a CodeHolder.
//! code.init(env); // Initialize CodeHolder with custom environment.
@@ -612,46 +634,37 @@ namespace asmjit {
//!
//! ### Explicit Code Relocation
//!
-//! In addition to \ref Environment, \ref CodeHolder can be configured to
-//! specify a base-address (or a virtual base-address in a linker terminology),
-//! which could be static (useful when you know the location where the target's
-//! machine code will be) or dynamic. AsmJit assumes dynamic base-address by
-//! default and relocates the code held by \ref CodeHolder to a user provided
-//! address on-demand. To be able to relocate to a user provided address it needs
-//! to store some information about relocations, which is represented by \ref
-//! RelocEntry. Relocation entries are only required if you call external functions
-//! from the generated code that cannot be encoded by using a 32-bit displacement
-//! (64-bit displacements are not provided by aby supported architecture).
-//!
-//! There is also a concept called \ref LabelLink - label link is a lightweight
-//! data structure that doesn't have any identifier and is stored in \ref LabelEntry
-//! as a single-linked list. Label link represents either unbound yet used label
-//! and cross-sections links (only relevant to code that uses multiple sections).
-//! Since crossing sections is something that cannot be resolved immediately these
-//! links persist until offsets of these sections are assigned and until
-//! \ref CodeHolder::resolveUnresolvedLinks() is called. It's an error if you end
-//! up with code that has unresolved label links after flattening. You can verify
-//! it by calling \ref CodeHolder::hasUnresolvedLinks(), which inspects the value
-//! returned by \ref CodeHolder::unresolvedLinkCount().
-//!
-//! AsmJit can flatten code that uses multiple sections by assigning each section
-//! an incrementing offset that respects its alignment. Use \ref CodeHolder::flatten()
-//! to do that. After the sections are flattened their offsets and virtual-sizes
-//! are adjusted to respect each section's buffer size and alignment. The \ref
-//! CodeHolder::resolveUnresolvedLinks() function must be called before relocating
-//! the code held by \ref CodeHolder. You can also flatten your code manually by
-//! iterating over all sections and calculating their offsets (relative to base)
-//! by your own algorithm. In that case \ref CodeHolder::flatten() should not be
-//! called, however, \ref CodeHolder::resolveUnresolvedLinks() should be.
-//!
-//! The example below shows how to use a built-in virtual memory allocator
-//! \ref JitAllocator instead of using \ref JitRuntime (just in case you want
-//! to use your own memory management) and how to relocate the generated code
-//! into your own memory block - you can use your own virtual memory allocator
-//! if you prefer that, but that's OS specific and not covered by the documentation.
-//!
-//! The following code is similar to the previous one, but implements a function
-//! working in both 32-bit and 64-bit environments:
+//! In addition to \ref Environment, \ref CodeHolder can be configured to specify a base-address (or a virtual base
+//! address in a linker terminology), which could be static (useful when you know the location where the target's
+//! machine code will be) or dynamic. AsmJit assumes dynamic base-address by default and relocates the code held by
+//! \ref CodeHolder to a user provided address on-demand. To be able to relocate to a user provided address it needs
+//! to store some information about relocations, which is represented by \ref RelocEntry. Relocation entries are only
+//! required if you call external functions from the generated code that cannot be encoded by using a 32-bit
+//! displacement (64-bit displacements are not provided by aby supported architecture).
+//!
+//! There is also a concept called \ref LabelLink - label link is a lightweight data structure that doesn't have any
+//! identifier and is stored in \ref LabelEntry as a single-linked list. Label link represents either unbound yet used
+//! label and cross-sections links (only relevant to code that uses multiple sections). Since crossing sections is
+//! something that cannot be resolved immediately these links persist until offsets of these sections are assigned and
+//! until \ref CodeHolder::resolveUnresolvedLinks() is called. It's an error if you end up with code that has
+//! unresolved label links after flattening. You can verify it by calling \ref CodeHolder::hasUnresolvedLinks(), which
+//! inspects the value returned by \ref CodeHolder::unresolvedLinkCount().
+//!
+//! AsmJit can flatten code that uses multiple sections by assigning each section an incrementing offset that respects
+//! its alignment. Use \ref CodeHolder::flatten() to do that. After the sections are flattened their offsets and
+//! virtual sizes are adjusted to respect each section's buffer size and alignment. The \ref
+//! CodeHolder::resolveUnresolvedLinks() function must be called before relocating the code held by \ref CodeHolder.
+//! You can also flatten your code manually by iterating over all sections and calculating their offsets (relative to
+//! base) by your own algorithm. In that case \ref CodeHolder::flatten() should not be called, however,
+//! \ref CodeHolder::resolveUnresolvedLinks() should be.
+//!
+//! The example below shows how to use a built-in virtual memory allocator \ref JitAllocator instead of using \ref
+//! JitRuntime (just in case you want to use your own memory management) and how to relocate the generated code
+//! into your own memory block - you can use your own virtual memory allocator if you prefer that, but that's OS
+//! specific and not covered by the documentation.
+//!
+//! The following code is similar to the previous one, but implements a function working in both 32-bit and 64-bit
+//! environments:
//!
//! ```
//! #include <asmjit/x86.h>
@@ -663,10 +676,11 @@ namespace asmjit {
//!
//! int main() {
//! // Create a custom environment that matches the current host environment.
-//! Environment env = hostEnvironment();
+//! Environment env = Environment::host();
+//! CpuFeatures cpuFeatures = CpuInfo::host().features();
//!
//! CodeHolder code; // Create a CodeHolder.
-//! code.init(env); // Initialize CodeHolder with environment.
+//! code.init(env, cpuFeatures); // Initialize CodeHolder with environment.
//!
//! x86::Assembler a(&code); // Create and attach x86::Assembler to `code`.
//!
@@ -752,7 +766,7 @@ namespace asmjit {
//! // memcpy((uint8_t*)p + section->offset(),
//! // section->data(),
//! // section->bufferSize());
-//! code.copyFlattenedData(p, codeSize, CodeHolder::kCopyPadSectionBuffer);
+//! code.copyFlattenedData(p, codeSize, CopySectionFlags::kPadSectionBuffer);
//!
//! // Execute the generated function.
//! int inA[4] = { 4, 3, 2, 1 };
@@ -774,37 +788,39 @@ namespace asmjit {
//! }
//! ```
//!
-//! If you know the base-address in advance (before the code generation) it can
-//! be passed as a second argument to \ref CodeHolder::init(). In that case the
-//! Assembler will know the absolute position of each instruction and would be
-//! able to use it during instruction encoding to prevent relocations where
-//! possible. The following example shows how to configure the base address:
+//! If you know the base-address in advance (before the code generation) it can be passed as a second argument to
+//! \ref CodeHolder::init(). In that case the Assembler will know the absolute position of each instruction and
+//! would be able to use it during instruction encoding to prevent relocations where possible. The following example
+//! shows how to configure the base address:
//!
//! ```
//! #include <asmjit/x86.h>
//! #include <stdio.h>
//!
+//! using namespace asmjit;
+//!
//! void initializeCodeHolder(CodeHolder& code) {
-//! Environment env = hostEnvironment();
+//! Environment env = Environment::host();
+//! CpuFeatures cpuFeatures = CpuInfo::host().features();
//! uint64_t baseAddress = uint64_t(0x1234);
//!
//! // initialize CodeHolder with environment and custom base address.
-//! code.init(env, baseAddress);
+//! code.init(env, cpuFeatures, baseAddress);
//! }
//! ```
//!
//! ### Label Offsets and Links
//!
-//! When a label that is not yet bound is used by the Assembler, it creates a
-//! \ref LabelLink, which is then added to a \ref LabelEntry. These links are
-//! also created if a label is used in a different section than in which it
-//! was bound. Let's examine some functions that can be used to check whether
-//! there are any unresolved links.
+//! When a label that is not yet bound is used by the Assembler, it creates a \ref LabelLink, which is then added to
+//! a \ref LabelEntry. These links are also created if a label is used in a different section than in which it was
+//! bound. Let's examine some functions that can be used to check whether there are any unresolved links.
//!
//! ```
//! #include <asmjit/core.h>
//! #include <stdio.h>
//!
+//! using namespace asmjit;
+//!
//! void labelLinksExample(CodeHolder& code, const Label& label) {
//! // Tests whether the `label` is bound.
//! bool isBound = code.isLabelBound(label);
@@ -819,16 +835,17 @@ namespace asmjit {
//! }
//! ```
//!
-//! There is no function that would return the number of unbound labels as this
-//! is completely unimportant from CodeHolder's perspective. If a label is not
-//! used then it doesn't matter whether it's bound or not, only actually used
-//! labels matter. After a Label is bound it's possible to query its offset
-//! offset relative to the start of the section where it was bound:
+//! There is no function that would return the number of unbound labels as this is completely unimportant from
+//! CodeHolder's perspective. If a label is not used then it doesn't matter whether it's bound or not, only actually
+//! used labels matter. After a Label is bound it's possible to query its offset relative to the start of the
+//! section where it was bound:
//!
//! ```
//! #include <asmjit/core.h>
//! #include <stdio.h>
//!
+//! using namespace asmjit;
+//!
//! void labelOffsetExample(CodeHolder& code, const Label& label) {
//! // Label offset is known after it's bound. The offset provided is relative
//! // to the start of the section, see below for alternative. If the given
@@ -848,15 +865,16 @@ namespace asmjit {
//!
//! ### Sections
//!
-//! AsmJit allows to create multiple sections within the same \ref CodeHolder.
-//! A test-case [asmjit_test_x86_sections.cpp](https://github.com/asmjit/asmjit/blob/master/test/asmjit_test_x86_sections.cpp)
-//! can be used as a reference point although the following example should
-//! also provide a useful insight:
+//! AsmJit allows to create multiple sections within the same \ref CodeHolder. A test-case
+//! [asmjit_test_x86_sections.cpp](https://github.com/asmjit/asmjit/blob/master/test/asmjit_test_x86_sections.cpp)
+//! can be used as a reference point although the following example should also provide a useful insight:
//!
//! ```
//! #include <asmjit/x86.h>
//! #include <stdio.h>
//!
+//! using namespace asmjit;
+//!
//! void sectionsExample(CodeHolder& code) {
//! // Text section is always provided as the first section.
//! Section* text = code.textSection(); // or code.sectionById(0);
@@ -864,10 +882,11 @@ namespace asmjit {
//! // To create another section use CodeHolder::newSection().
//! Section* data;
//! Error err = code.newSection(&data,
-//! ".data", // Section name
-//! SIZE_MAX, // Name length if the name is not null terminated (or SIZE_MAX).
-//! 0, // Section flags, see Section::Flags.
-//! 8); // Section alignment, must be power of 2.
+//! ".data", // Section name
+//! SIZE_MAX, // Name length if the name is not null terminated (or SIZE_MAX).
+//! SectionFlags::kNone, // Section flags, see SectionFlags.
+//! 8, // Section alignment, must be power of 2.
+//! 0); // Section order value (optional, default 0).
//!
//! // When you switch sections in Assembler, Builder, or Compiler the cursor
//! // will always move to the end of that section. When you create an Assembler
@@ -892,17 +911,17 @@ namespace asmjit {
//! }
//! ```
//!
-//! The last line in the example above shows that a LabelLink would be created
-//! even for bound labels that cross sections. In this case a referenced label
-//! was bound in another section, which means that the link couldn't be resolved
-//! at that moment. If your code uses sections, but you wish AsmJit to flatten
-//! these sections (you don't plan to flatten them manually) then there is an
-//! API for that.
+//! The last line in the example above shows that a LabelLink would be created even for bound labels that cross
+//! sections. In this case a referenced label was bound in another section, which means that the link couldn't be
+//! resolved at that moment. If your code uses sections, but you wish AsmJit to flatten these sections (you don't
+//! plan to flatten them manually) then there is an API for that.
//!
//! ```
//! #include <asmjit/x86.h>
//! #include <stdio.h>
//!
+//! using namespace asmjit;
+//!
//! // ... (continuing the previous example) ...
//! void sectionsExampleContinued(CodeHolder& code) {
//! // Suppose we have some code that contains multiple sections and
@@ -931,105 +950,86 @@ namespace asmjit {
//!
//! if (code.hasUnresolvedLinks()) {
//! // This would mean either unbound label or some other issue.
-//! printf("The code has %zu unbound labels\n", code.unresovedLinkCount());
+//! printf("The code has %zu unbound labels\n", code.unresolvedLinkCount());
//! exit(1);
//! }
//! }
//! ```
-// ============================================================================
-// [Documentation - asmjit_assembler]
-// ============================================================================
//! \defgroup asmjit_assembler Assembler
//! \brief Assembler interface and operands.
//!
//! ### Overview
//!
-//! AsmJit's Assembler is used to emit machine code directly into a \ref
-//! CodeBuffer. In general, code generation with assembler requires the knowledge
-//! of the following:
+//! AsmJit's Assembler is used to emit machine code directly into a \ref CodeBuffer. In general, code generation
+//! with assembler requires the knowledge of the following:
//!
//! - \ref BaseAssembler and architecture-specific assemblers:
-//! - \ref x86::Assembler - Assembler specific to X86 architecture
+//! - \ref x86::Assembler - Assembler implementation targeting X86 and X86_64 architectures.
+//! - \ref a64::Assembler - Assembler implementation targeting AArch64 architecture.
//! - \ref Operand and its variations:
//! - \ref BaseReg - Base class for a register operand, inherited by:
-//! - \ref x86::Reg - Register operand specific to X86 architecture.
+//! - \ref x86::Reg - Register operand specific to X86 and X86_64 architectures.
+//! - \ref arm::Reg - Register operand specific to AArch64 architecture.
//! - \ref BaseMem - Base class for a memory operand, inherited by:
//! - \ref x86::Mem - Memory operand specific to X86 architecture.
+//! - \ref arm::Mem - Memory operand specific to AArch64 architecture.
//! - \ref Imm - Immediate (value) operand.
//! - \ref Label - Label operand.
//!
-//! \note Assembler examples use \ref x86::Assembler as abstract interfaces cannot
-//! be used to generate code.
+//! \note Assembler examples use \ref x86::Assembler as abstract interfaces cannot be used to generate code.
//!
//! ### Operand Basics
//!
-//! Let's start with operands. \ref Operand is a data structure that defines a
-//! data layout of any operand. It can be inherited, but any class inheriting
-//! it cannot add any members to it, only the existing layout can be reused.
-//! AsmJit allows to construct operands dynamically, to store them, and to query
-//! a complete information about them at run-time. Operands are small (always 16
-//! bytes per \ref Operand) and can be copied and passed by value. Please never
-//! allocate individual operands dynamically by using a `new` keyword - it would
-//! work, but then you would have to be responsible for deleting such operands.
-//! In AsmJit operands are always part of some other data structures like \ref
-//! InstNode, which is part of \ref asmjit_builder tool.
-//!
-//! Operands contain only identifiers, but not pointers to any code-generation data.
-//! For example \ref Label operand only provides label identifier, but not a pointer
-//! to \ref LabelEntry structure. In AsmJit such IDs are used to link stuff together
-//! without having to deal with pointers.
-//!
-//! AsmJit's operands all inherit from a base class called \ref Operand. Operands
-//! have the following properties that are commonly accessible by getters and setters:
-//!
-//! - \ref Operand - Base operand, which only provides accessors that are common
-//! to all operand types.
-//! - \ref BaseReg - Describes either physical or virtual register. Physical
-//! registers have id that matches the target's machine id directly whereas
-//! virtual registers must be allocated into physical registers by a register
+//! Let's start with operands. \ref Operand is a data structure that defines a data layout of any operand. It can be
+//! inherited, but any class inheriting it cannot add any members to it, only the existing layout can be reused.
+//! AsmJit allows to construct operands dynamically, to store them, and to query a complete information about them
+//! at run-time. Operands are small (always 16 bytes per \ref Operand) and can be copied and passed by value. Please
+//! never allocate individual operands dynamically by using a `new` keyword - it would work, but then you would have
+//! to be responsible for deleting such operands. In AsmJit operands are always part of some other data structures
+//! like \ref InstNode, which is part of \ref asmjit_builder tool.
+//!
+//! Operands contain only identifiers, but not pointers to any code-generation data. For example \ref Label operand
+//! only provides label identifier, but not a pointer to \ref LabelEntry structure. In AsmJit such IDs are used to
+//! link stuff together without having to deal with pointers.
+//!
+//! AsmJit's operands all inherit from a base class called \ref Operand. Operands have the following properties that
+//! are commonly accessible by getters and setters:
+//!
+//! - \ref Operand - Base operand, which only provides accessors that are common to all operand types.
+//! - \ref BaseReg - Describes either physical or virtual register. Physical registers have id that matches the
+//! target's machine id directly whereas virtual registers must be allocated into physical registers by a register
//! allocator pass. Register operand provides:
-//! - Register Type - Unique id that describes each possible register provided
-//! by the target architecture - for example X86 backend provides \ref
-//! x86::Reg::RegType, which defines all variations of general purpose registers
-//! (GPB-LO, GPB-HI, GPW, GPD, and GPQ) and all types of other registers like K,
-//! MM, BND, XMM, YMM, and ZMM.
-//! - Register Group - Groups multiple register types under a single group - for
-//! example all general-purpose registers (of all sizes) on X86 are part of
-//! \ref x86::Reg::kGroupGp and all SIMD registers (XMM, YMM, ZMM) are part
-//! of \ref x86::Reg::kGroupVec.
-//! - Register Size - Contains the size of the register in bytes. If the size
-//! depends on the mode (32-bit vs 64-bit) then generally the higher size is
-//! used (for example RIP register has size 8 by default).
+//! - Register Type (\ref RegType) - Unique id that describes each possible register provided by the target
+//! architecture - for example X86 backend provides general purpose registers (GPB-LO, GPB-HI, GPW, GPD, and GPQ)
+//! and all types of other registers like K, MM, BND, XMM, YMM, ZMM, and TMM.
+//! - Register Group (\ref RegGroup) - Groups multiple register types under a single group - for example all
+//! general-purpose registers (of all sizes) on X86 are part of \ref RegGroup::kGp and all SIMD registers
+//! (XMM, YMM, ZMM) are part of \ref RegGroup::kVec.
+//! - Register Size - Contains the size of the register in bytes. If the size depends on the mode (32-bit vs
+//! 64-bit) then generally the higher size is used (for example RIP register has size 8 by default).
//! - Register Id - Contains physical or virtual id of the register.
//! - \ref BaseMem - Used to reference a memory location. Memory operand provides:
//! - Base Register - A base register type and id (physical or virtual).
//! - Index Register - An index register type and id (physical or virtual).
-//! - Offset - Displacement or absolute address to be referenced (32-bit if base
-//! register is used and 64-bit if base register is not used).
-//! - Flags that can describe various architecture dependent information (like
-//! scale and segment-override on X86).
-//! - \ref Imm - Immediate values are usually part of instructions (encoded within
-//! the instruction itself) or data.
-//! - \ref Label - used to reference a location in code or data. Labels must be
-//! created by the \ref BaseEmitter or by \ref CodeHolder. Each label has its
-//! unique id per \ref CodeHolder instance.
+//! - Offset - Displacement or absolute address to be referenced (32-bit if base register is used and 64-bit if
+//! base register is not used).
+//! - Flags that can describe various architecture dependent information (like scale and segment-override on X86).
+//! - \ref Imm - Immediate values are usually part of instructions (encoded within the instruction itself) or data.
+//! - \ref Label - used to reference a location in code or data. Labels must be created by the \ref BaseEmitter or
+//! by \ref CodeHolder. Each label has its unique id per \ref CodeHolder instance.
//!
//! ### Operand Manipulation
//!
-//! AsmJit allows to construct operands dynamically, to store them, and to query
-//! a complete information about them at run-time. Operands are small (always 16
-//! bytes per `Operand`) and should be always copied (by value) if you intend to
-//! store them (don't create operands by using `new` keyword, it's not recommended).
-//! Operands are safe to be passed to `memcpy()` and `memset()`, which becomes
-//! handy when working with arrays of operands. If you set all members of an \ref
-//! Operand to zero the operand would become NONE operand, which is the same as a
-//! default constructed Operand.
+//! AsmJit allows to construct operands dynamically, to store them, and to query a complete information about them at
+//! run-time. Operands are small (always 16 bytes per `Operand`) and should be always copied (by value) if you intend
+//! to store them (don't create operands by using `new` keyword, it's not recommended). Operands are safe to be passed
+//! to `memcpy()` and `memset()`, which becomes handy when working with arrays of operands. If you set all members of
+//! an \ref Operand to zero the operand would become NONE operand, which is the same as a default constructed Operand.
//!
-//! The example below illustrates how operands can be used and modified even
-//! without using any other code generation classes. The example uses X86
-//! architecture-specific operands.
+//! The example below illustrates how operands can be used and modified even without using any other code generation
+//! classes. The example uses X86 architecture-specific operands.
//!
//! ```
//! #include <asmjit/x86.h>
@@ -1049,7 +1049,7 @@ namespace asmjit {
//! // Constructs [src + idx] memory address - referencing [rax + r10].
//! x86::Mem m = x86::ptr(src, idx);
//!
-//! // Examine `m`: Returns `x86::Reg::kTypeGpq`.
+//! // Examine `m`: Returns `RegType::kX86_Gpq`.
//! m.indexType();
//! // Examine `m`: Returns 10 (`r10`).
//! m.indexId();
@@ -1082,28 +1082,25 @@ namespace asmjit {
//!
//! // Type-unsafe, but possible.
//! a.emit(x86::Inst::kIdMov, dst, m);
-//! // Also possible, `emit()` is typeless and can be used with raw Operand.
+//! // Also possible, `emit()` is type-less and can be used with raw Operand.
//! a.emit(x86::Inst::kIdMov, dst, op);
//! }
//! ```
//!
-//! Some operands have to be created explicitly by emitters. For example labels
-//! must be created by \ref BaseEmitter::newLabel(), which creates a label entry
-//! and returns a \ref Label operand with the id that refers to it. Such label
-//! then can be used by emitters.
+//! Some operands have to be created explicitly by emitters. For example labels must be created by \ref
+//! BaseEmitter::newLabel(), which creates a label entry and returns a \ref Label operand with the id that refers
+//! to it. Such label then can be used by emitters.
//!
//! ### Memory Operands
//!
-//! Some architectures like X86 provide a complex memory addressing model that
-//! allows to encode addresses having a BASE register, INDEX register with a
-//! possible scale (left shift), and displacement (called offset in AsmJit).
-//! Memory address on X86 can also specify memory segment (segment-override in
-//! X86 terminology) and some instructions (gather / scatter) require INDEX to
-//! be a \ref x86::Vec register instead of a general-purpose register.
+//! Some architectures like X86 provide a complex memory addressing model that allows to encode addresses having a
+//! BASE register, INDEX register with a possible scale (left shift), and displacement (called offset in AsmJit).
+//! Memory address on X86 can also specify memory segment (segment-override in X86 terminology) and some instructions
+//! (gather / scatter) require INDEX to be a \ref x86::Vec register instead of a general-purpose register.
//!
-//! AsmJit allows to encode and work with all forms of addresses mentioned and
-//! implemented by X86. In addition, it also allows to construct absolute 64-bit
-//! memory address operands, which is only allowed in one form of 'mov' instruction.
+//! AsmJit allows to encode and work with all forms of addresses mentioned and implemented by X86. In addition, it
+//! also allows to construct absolute 64-bit memory address operands, which is only allowed in one form of 'mov'
+//! instruction.
//!
//! ```
//! #include <asmjit/x86.h>
@@ -1128,7 +1125,7 @@ namespace asmjit {
//! Mem g = ptr(rax, xmm1, 2); // g = [rax + xmm1 << 2]
//! Mem h = ptr(rax, xmm1, 2, 15); // h = [rax + xmm1 << 2 + 15]
//!
-//! // Absolute adddress:
+//! // Absolute address:
//! uint64_t addr = (uint64_t)0x1234;
//! Mem i = ptr(addr); // i = [0x1234]
//! Mem j = ptr(addr, rbx); // j = [0x1234 + rbx]
@@ -1146,9 +1143,8 @@ namespace asmjit {
//! }
//! ```
//!
-//! Memory operands can optionally contain memory size. This is required by
-//! instructions where the memory size cannot be deduced from other operands,
-//! like `inc` and `dec` on X86:
+//! Memory operands can optionally contain memory size. This is required by instructions where the memory size cannot
+//! be deduced from other operands, like `inc` and `dec` on X86:
//!
//! ```
//! #include <asmjit/x86.h>
@@ -1157,10 +1153,10 @@ namespace asmjit {
//!
//! void testX86Mem() {
//! // The same as: dword ptr [rax + rbx].
-//! x86::Mem a = x86::dword_ptr(rax, rbx);
+//! x86::Mem a = x86::dword_ptr(x86::rax, x86::rbx);
//!
//! // The same as: qword ptr [rdx + rsi << 0 + 1].
-//! x86::Mem b = x86::qword_ptr(rdx, rsi, 0, 1);
+//! x86::Mem b = x86::qword_ptr(x86::rdx, x86::rsi, 0, 1);
//! }
//! ```
//!
@@ -1173,18 +1169,18 @@ namespace asmjit {
//!
//! void testX86Mem() {
//! // The same as: dword ptr [rax + 12].
-//! x86::Mem mem = x86::dword_ptr(rax, 12);
+//! x86::Mem mem = x86::dword_ptr(x86::rax, 12);
//!
//! mem.hasBase(); // true.
//! mem.hasIndex(); // false.
//! mem.size(); // 4.
//! mem.offset(); // 12.
//!
-//! mem.setSize(0); // Sets the size to 0 (makes it sizeless).
+//! mem.setSize(0); // Sets the size to 0 (makes it size-less).
//! mem.addOffset(-1); // Adds -1 to the offset and makes it 11.
//! mem.setOffset(0); // Sets the offset to 0.
-//! mem.setBase(rcx); // Changes BASE to RCX.
-//! mem.setIndex(rax); // Changes INDEX to RAX.
+//! mem.setBase(x86::rcx); // Changes BASE to RCX.
+//! mem.setIndex(x86::rax); // Changes INDEX to RAX.
//! mem.hasIndex(); // true.
//! }
//! // ...
@@ -1232,34 +1228,26 @@ namespace asmjit {
//!
//! - \ref x86::Assembler provides many X86/X64 examples.
-// ============================================================================
-// [Documentation - asmjit_builder]
-// ============================================================================
//! \defgroup asmjit_builder Builder
//! \brief Builder interface, nodes, and passes.
//!
//! ### Overview
//!
-//! Both \ref BaseBuilder and \ref BaseCompiler interfaces describe emitters
-//! that emit into a representation that allows further processing. The code
-//! stored in such representation is completely safe to be patched, simplified,
-//! reordered, obfuscated, removed, injected, analyzed, or processed some other
-//! way. Each instruction, label, directive, or other building block is stored
-//! as \ref BaseNode (or derived class like \ref InstNode or \ref LabelNode)
-//! and contains all the information necessary to pass that node later to the
-//! assembler.
-//!
-//! \ref BaseBuilder is an emitter that inherits from \ref BaseEmitter interface.
-//! It was designed to provide a maximum compatibility with the existing \ref
-//! BaseAssembler emitter so users can move from assembler to builder when needed,
+//! Both \ref BaseBuilder and \ref BaseCompiler interfaces describe emitters that emit into a representation that
+//! allows further processing. The code stored in such representation is completely safe to be patched, simplified,
+//! reordered, obfuscated, removed, injected, analyzed, or processed some other way. Each instruction, label,
+//! directive, or other building block is stored as \ref BaseNode (or derived class like \ref InstNode or \ref
+//! LabelNode) and contains all the information necessary to pass that node later to the assembler.
+//!
+//! \ref BaseBuilder is an emitter that inherits from \ref BaseEmitter interface. It was designed to provide a maximum
+//! compatibility with the existing \ref BaseAssembler emitter so users can move from assembler to builder when needed,
//! for example to implement post-processing, which is not possible with Assembler.
//!
//! ### Builder Nodes
//!
-//! \ref BaseBuilder doesn't generate machine code directly, it uses an intermediate
-//! representation based on nodes, however, it allows to serialize to \ref BaseAssembler
-//! when the code is ready to be encoded.
+//! \ref BaseBuilder doesn't generate machine code directly, it uses an intermediate representation based on nodes,
+//! however, it allows to serialize to \ref BaseAssembler when the code is ready to be encoded.
//!
//! There are multiple node types used by both \ref BaseBuilder and \ref BaseCompiler :
//!
@@ -1272,199 +1260,165 @@ namespace asmjit {
//! - Data nodes:
//! - \ref EmbedDataNode - Represents data.
//! - \ref EmbedLabelNode - Represents \ref Label address embedded as data.
-//! - \ref EmbedLabelDeltaNode - Represents a difference of two labels
-//! embedded in data.
+//! - \ref EmbedLabelDeltaNode - Represents a difference of two labels embedded in data.
//! - \ref ConstPoolNode - Represents a constant pool data embedded as data.
//!
//! - Informative nodes:
-//! - \ref CommentNode - Represents a comment string, doesn't affect code
-//! generation.
-//! - \ref SentinelNode - A marker that can be used to remember certain
-//! position in code or data, doesn't affect code generation. Used by
-//! \ref FuncNode to mark the end of a function.
+//! - \ref CommentNode - Represents a comment string, doesn't affect code generation.
+//! - \ref SentinelNode - A marker that can be used to remember certain position in code or data, doesn't affect
+//! code generation. Used by \ref FuncNode to mark the end of a function.
//!
//! - Other nodes are provided by \ref asmjit_compiler infrastructure.
//!
//! ### Builder Examples
//!
-//! - \ref x86::Builder provides many X86/X64 examples.
+//! - \ref x86::Builder - Builder implementation targeting X86 and X86_64 architectures.
+//! - \ref a64::Builder - Builder implementation targeting AArch64 architecture.
-// ============================================================================
-// [Documentation - asmjit_compiler]
-// ============================================================================
//! \defgroup asmjit_compiler Compiler
//! \brief Compiler interface.
//!
//! ### Overview
//!
-//! \ref BaseCompiler is a high-level interface built on top of \ref BaseBuilder
-//! interface, which provides register allocation and support for defining and
-//! invoking functions. At the moment it's the easiest way of generating code
-//! in AsmJit as most architecture and OS specifics is properly abstracted and
-//! handled by AsmJit automatically. However, abstractions also mean restrictions,
-//! which means that \ref BaseCompiler has more limitations that \ref BaseAssembler
-//! or \ref BaseBuilder.
-//!
-//! Since \ref BaseCompiler provides register allocation it also establishes the
-//! concept of functions - a function in Compiler sense is a unit in which virtual
-//! registers are allocated into physical registers by the register allocator.
-//! In addition, it enables to use such virtual registers in function invocations.
-//!
-//! \ref BaseCompiler automatically handles function calling conventions. It's
-//! still architecture dependent, but makes the code generation much easies.
-//! Functions are essential; the first-step to generate some code is to define a
-//! signature of the function to be generated (before generating the function body
-//! itself). Function arguments and return value(s) are handled by assigning
-//! virtual registers to them. Similarly, function calls are handled the same way.
+//! \ref BaseCompiler is a high-level interface, which provides register allocation and support for defining and
+//! invoking functions, built on top of \ref BaseBuilder interface At the moment it's the easiest way of generating
+//! code in AsmJit as most architecture and OS specifics is properly abstracted and handled by AsmJit automatically.
+//! However, abstractions also mean restrictions, which means that \ref BaseCompiler has more limitations than \ref
+//! BaseAssembler or \ref BaseBuilder.
+//!
+//! Since \ref BaseCompiler provides register allocation it also establishes the concept of functions - a function
+//! in Compiler sense is a unit in which virtual registers are allocated into physical registers by the register
+//! allocator. In addition, it enables to use such virtual registers in function invocations.
+//!
+//! \ref BaseCompiler automatically handles function calling conventions. It's still architecture dependent, but
+//! makes the code generation much easies. Functions are essential; the first-step to generate some code is to define
+//! a signature of the function to be generated (before generating the function body itself). Function arguments and
+//! return value(s) are handled by assigning virtual registers to them. Similarly, function calls are handled the same
+//! way.
//!
//! ### Compiler Nodes
//!
-//! \ref BaseCompiler adds some nodes that are required for function generation
-//! and invocation:
+//! \ref BaseCompiler adds some nodes that are required for function generation and invocation:
//!
//! - \ref FuncNode - Represents a function definition.
//! - \ref FuncRetNode - Represents a function return.
//! - \ref InvokeNode - Represents a function invocation.
//!
-//! \ref BaseCompiler also makes the use of passes (\ref Pass) and automatically
-//! adds an architecture-dependent register allocator pass to the list of passes
-//! when attached to \ref CodeHolder.
+//! \ref BaseCompiler also makes the use of passes (\ref Pass) and automatically adds an architecture-dependent
+//! register allocator pass to the list of passes when attached to \ref CodeHolder.
//!
//! ### Compiler Examples
//!
-//! - \ref x86::Compiler provides many X86/X64 examples.
+//! - \ref x86::Compiler - Compiler implementation targeting X86 and X86_64 architectures.
+//! - \ref a64::Compiler - Compiler implementation targeting AArch64 architecture.
//!
//! ### Compiler Tips
//!
-//! Users of AsmJit have done mistakes in the past, this section should provide
-//! some useful tips for beginners:
+//! Users of AsmJit have done mistakes in the past, this section should provide some useful tips for beginners:
//!
-//! - Virtual registers in compiler are bound to a single function. At the
-//! moment the implementation doesn't care whether a single virtual register
-//! is used in multiple functions, but it sees it as two independent virtual
-//! registers in that case. This means that virtual registers cannot be used
-//! to implement global variables. Global variables are basically memory
-//! addresses which functions can read from and write to, and they have to
-//! be implemented in the same way.
+//! - Virtual registers in compiler are bound to a single function. At the moment the implementation doesn't
+//! care whether a single virtual register is used in multiple functions, but it sees it as two independent
+//! virtual registers in that case. This means that virtual registers cannot be used to implement global
+//! variables. Global variables are basically memory addresses which functions can read from and write to,
+//! and they have to be implemented in the same way.
//!
-//! - Compiler provides a useful debugging functionality, which can be turned
-//! on through \ref FormatOptions::Flags. Use \ref Logger::addFlags() to
-//! turn on additional logging features when using Compiler.
+//! - Compiler provides a useful debugging functionality, which can be turned on through \ref FormatFlags. Use
+//! \ref Logger::addFlags() to turn on additional logging features when using Compiler.
-// ============================================================================
-// [Documentation - asmjit_function]
-// ============================================================================
//! \defgroup asmjit_function Function
//! \brief Function definitions.
//!
//! ### Overview
//!
-//! AsmJit provides functionality that can be used to define function signatures
-//! and to calculate automatically optimal function frame that can be used directly
-//! by a prolog and epilog insertion. This feature was exclusive to AsmJit's Compiler
-//! for a very long time, but was abstracted out and is now available for all users
-//! regardless of the emitter they use. The following use cases are possible:
+//! AsmJit provides functionality that can be used to define function signatures and to calculate automatically
+//! optimal function frame that can be used directly by a prolog and epilog insertion. This feature was exclusive
+//! to AsmJit's Compiler for a very long time, but was abstracted out and is now available for all users regardless
+//! of the emitter they use. The following use cases are possible:
//!
-//! - Calculate function frame before the function is generated - this is the
-//! only way available to \ref BaseAssembler users and it will be described
-//! in this section.
+//! - Calculate function frame before the function is generated - this is the only way available to \ref
+//! BaseAssembler users and it will be described in this section.
//!
-//! - Calculate function frame after the function is generated - this way is
-//! generally used by \ref BaseBuilder and \ref BaseCompiler emitters and
-//! this way is generally described in \ref asmjit_compiler section.
+//! - Calculate function frame after the function is generated - this way is generally used by \ref BaseBuilder
+//! and \ref BaseCompiler emitters and this way is generally described in \ref asmjit_compiler section.
//!
//! The following concepts are used to describe and create functions in AsmJit:
//!
-//! - \ref Type::Id - Type-id is an 8-bit value that describes a platform
-//! independent type as we know from C/C++. It provides abstractions for
-//! most common types like `int8_t`, `uint32_t`, `uintptr_t`, `float`,
-//! `double`, and all possible vector types to match ISAs up to AVX512.
-//! \ref Type::Id was introduced originally for \ref asmjit_compiler, but
-//! it's now used by \ref FuncSignature as well.
-//!
-//! - \ref CallConv - Describes a calling convention - this class contains
-//! instructions to assign registers and stack addresses to function
-//! arguments and return value(s), but doesn't specify any function
-//! signature itself. Calling conventions are architecture and OS dependent.
-//!
-//! - \ref FuncSignature - Describes a function signature, for example
-//! `int func(int, int)`. FuncSignature contains a function calling convention
-//! id, return value type, and function arguments. The signature itself is
-//! platform independent and uses \ref Type::Id to describe types of function
-//! arguments and function return value(s).
-//!
-//! - \ref FuncDetail - Architecture and ABI dependent information that describes
-//! \ref CallConv and expanded \ref FuncSignature. Each function argument and
-//! return value is represented as \ref FuncValue that contains the original
-//! \ref Type::Id enriched with additional information that specifies whether
-//! the value is passed or returned by register (and which register) or by
-//! stack. Each value also contains some other metadata that provide additional
-//! information required to handle it properly (for example whether a vector is
-//! passed indirectly by a pointer as required by WIN64 calling convention).
-//!
-//! - \ref FuncFrame - Contains information about the function frame that can
-//! be used by prolog/epilog inserter (PEI). Holds call stack size size and
-//! alignment, local stack size and alignment, and various attributes that
-//! describe how prolog and epilog should be constructed. `FuncFrame` doesn't
-//! know anything about function's arguments or return values, it hold only
-//! information necessary to create a valid and ABI conforming function prologs
-//! and epilogs.
-//!
-//! - \ref FuncArgsAssignment - A helper class that can be used to reassign
-//! function arguments into user specified registers. It's architecture and
-//! ABI dependent mapping from function arguments described by \ref CallConv
+//! - \ref TypeId - Type-id is an 8-bit value that describes a platform independent type as we know from C/C++.
+//! It provides abstractions for most common types like `int8_t`, `uint32_t`, `uintptr_t`, `float`, `double`,
+//! and all possible vector types to match ISAs up to AVX512. \ref TypeId was introduced originally for \ref
+//! asmjit_compiler, but it's now used by \ref FuncSignature as well.
+//!
+//! - \ref CallConv - Describes a calling convention - this class contains instructions to assign registers and
+//! stack addresses to function arguments and return value(s), but doesn't specify any function signature itself.
+//! Calling conventions are architecture and OS dependent.
+//!
+//! - \ref FuncSignature - Describes a function signature, for example `int func(int, int)`. FuncSignature contains
+//! a function calling convention id, return value type, and function arguments. The signature itself is platform
+//! independent and uses \ref TypeId to describe types of function arguments and function return value(s).
+//!
+//! - \ref FuncDetail - Architecture and ABI dependent information that describes \ref CallConv and expanded \ref
+//! FuncSignature. Each function argument and return value is represented as \ref FuncValue that contains the
+//! original \ref TypeId enriched with additional information that specifies whether the value is passed or
+//! returned by register (and which register) or by stack. Each value also contains some other metadata that
+//! provide additional information required to handle it properly (for example whether a vector is passed
+//! indirectly by a pointer as required by WIN64 calling convention).
+//!
+//! - \ref FuncFrame - Contains information about the function frame that can be used by prolog/epilog inserter
+//! (PEI). Holds call stack size size and alignment, local stack size and alignment, and various attributes that
+//! describe how prolog and epilog should be constructed. `FuncFrame` doesn't know anything about function's
+//! arguments or return values, it hold only information necessary to create a valid and ABI conforming function
+//! prologs and epilogs.
+//!
+//! - \ref FuncArgsAssignment - A helper class that can be used to reassign function arguments into user specified
+//! registers. It's architecture and ABI dependent mapping from function arguments described by \ref CallConv
//! and \ref FuncDetail into registers specified by the user.
//!
-//! It's a lot of concepts where each represents one step in a function frame
-//! calculation. It can be used to create function prologs, epilogs, and also
-//! to calculate information necessary to perform function calls.
+//! It's a lot of concepts where each represents one step in a function frame calculation. It can be used to create
+//! function prologs, epilogs, and also to calculate information necessary to perform function calls.
-// ============================================================================
-// [Documentation - asmjit_logging]
-// ============================================================================
//! \defgroup asmjit_logging Logging
//! \brief Logging and formatting.
//!
//! ### Overview
//!
-//! The initial phase of a project that generates machine code is not always smooth.
-//! Failure cases are common not just at the beginning phase, but also during the
-//! development or refactoring. AsmJit provides logging functionality to address
-//! this issue. AsmJit does already a good job with function overloading to prevent
-//! from emitting unencodable instructions, but it can't prevent from emitting machine
-//! code that is correct at instruction level, but doesn't work when it's executed as
-//! a whole. Logging has always been an important part of AsmJit's infrastructure and
-//! looking at logs can sometimes reveal code generation issues quickly.
+//! The initial phase of a project that generates machine code is not always smooth. Failure cases are common not just
+//! at the beginning phase, but also during the development or refactoring. AsmJit provides logging functionality to
+//! address this issue. AsmJit does already a good job with function overloading to prevent from emitting unencodable
+//! instructions, but it can't prevent from emitting machine code that is correct at instruction level, but doesn't
+//! work when it's executed asa whole. Logging has always been an important part of AsmJit's infrastructure and looking
+//! at logs can sometimes reveal code generation issues quickly.
//!
//! AsmJit provides API for logging and formatting:
-//! - \ref Logger - A logger that you can pass to \ref CodeHolder and all emitters
-//! that inherit from \ref BaseEmitter.
-//! - \ref FormatOptions - Formatting options that can change how instructions and
-//! operands are formatted.
-//! - \ref Formatter - A namespace that provides functions that can format input
-//! data like \ref Operand, \ref BaseReg, \ref Label, and \ref BaseNode into
-//! \ref String.
+//!
+//! - \ref Logger - A logger that you can pass to \ref CodeHolder and all emitters that inherit from \ref BaseEmitter.
+//!
+//! - \ref FormatOptions - Formatting options that can change how instructions and operands are formatted.
+//!
+//! - \ref Formatter - A namespace that provides functions that can format input data like \ref Operand, \ref BaseReg,
+//! \ref Label, and \ref BaseNode into \ref String.
//!
//! AsmJit's \ref Logger serves the following purposes:
+//!
//! - Provides a basic foundation for logging.
-//! - Abstract class leaving the implementation on users. The following built-in
-//! inplementations are provided for simplicty:
+//!
+//! - Abstract class leaving the implementation on users. The following built-in implementations are provided for
+//! simplicity:
+//!
//! - \ref FileLogger implements logging into a standard `FILE` stream.
//! - \ref StringLogger serializes all logs into a \ref String instance.
//!
-//! AsmJit's \ref FormatOptions provides the following to customize the formatting of
-//! instructions and operands through:
-//! - \ref FormatOptions::Flags
-//! - \ref FormatOptions::IndentationType
+//! AsmJit's \ref FormatOptions provides the following to customize the formatting of instructions and operands through:
+//!
+//! - \ref FormatFlags
+//! - \ref FormatIndentationGroup
//!
//! ### Logging
//!
-//! A \ref Logger is typically attached to a \ref CodeHolder, which propagates it
-//! to all attached emitters automatically. The example below illustrates how to
-//! use \ref FileLogger that outputs to standard output:
+//! A \ref Logger is typically attached to a \ref CodeHolder, which propagates it to all attached emitters
+//! automatically. The example below illustrates how to use \ref FileLogger that outputs to standard output:
//!
//! ```
//! #include <asmjit/core.h>
@@ -1477,7 +1431,8 @@ namespace asmjit {
//! FileLogger logger(stdout); // Logger should always survive CodeHolder.
//!
//! CodeHolder code; // Holds code and relocation information.
-//! code.init(rt.environment()); // Initialize to the same arch as JIT runtime.
+//! code.init(rt.environment(), // Initialize code to match the JIT environment.
+//! rt.cpuFeatures());
//! code.setLogger(&logger); // Attach the `logger` to `code` holder.
//!
//! // ... code as usual, everything emitted will be logged to `stdout` ...
@@ -1485,8 +1440,8 @@ namespace asmjit {
//! }
//! ```
//!
-//! If output to FILE stream is not desired it's possible to use \ref StringLogger,
-//! which concatenates everything into a multi-line string:
+//! If output to FILE stream is not desired it's possible to use \ref StringLogger, which concatenates everything
+//! into a multi-line string:
//!
//! ```
//! #include <asmjit/core.h>
@@ -1500,7 +1455,8 @@ namespace asmjit {
//! StringLogger logger; // Logger should always survive CodeHolder.
//!
//! CodeHolder code; // Holds code and relocation information.
-//! code.init(rt.environment()); // Initialize to the same arch as JIT runtime.
+//! code.init(rt.environment(), // Initialize code to match the JIT environment.
+//! rt.cpuFeatures());
//! code.setLogger(&logger); // Attach the `logger` to `code` holder.
//!
//! // ... code as usual, logging will be concatenated to logger string ...
@@ -1519,26 +1475,25 @@ namespace asmjit {
//!
//! ### Formatting
//!
-//! AsmJit uses \ref Formatter to format inputs that are then passed to \ref
-//! Logger. Formatting is public and can be used by AsmJit users as well. The
-//! most important thing to know regarding formatting is that \ref Formatter
-//! always appends to the output string, so it can be used to build complex
-//! strings without having to concatenate intermediate strings.
+//! AsmJit uses \ref Formatter to format inputs that are then passed to \ref Logger. Formatting is public and can be
+//! used by AsmJit users as well. The most important thing to know regarding formatting is that \ref Formatter always
+//! appends to the output string, so it can be used to build complex strings without having to concatenate
+//! intermediate strings.
//!
//! The first example illustrates how to format operands:
//!
//! ```
-//! #include <asmjit/core.h>
+//! #include <asmjit/x86.h>
//! #include <stdio.h>
//!
//! using namespace asmjit;
//!
-//! void logOperand(uint32_t arch, const Operand_& op) {
+//! void logOperand(Arch arch, const Operand_& op) {
//! // The emitter is optional (named labels and virtual registers need it).
//! BaseEmitter* emitter = nullptr;
//!
//! // No flags by default.
-//! uint32_t formatFlags = FormatOptions::kNoFlags;
+//! FormatFlags formatFlags = FormatFlags::kNone;
//!
//! StringTmp<128> sb;
//! Formatter::formatOperand(sb, formatFlags, emitter, arch, op);
@@ -1551,34 +1506,34 @@ namespace asmjit {
//! // Architecture is not part of operand, it must be passed explicitly.
//! // Format flags. We pass it explicitly also to 'logOperand' to make
//! // compatible with what AsmJit normally does.
-//! uint32_t arch = Environment::kArchX64;
+//! Arch arch = Arch::kX64;
//!
-//! log(arch, rax); // Prints 'rax'.
-//! log(arch, ptr(rax, rbx, 2)); // Prints '[rax + rbx * 4]`.
-//! log(arch, dword_ptr(rax, rbx, 2)); // Prints 'dword [rax + rbx * 4]`.
-//! log(arch, imm(42)); // Prints '42'.
+//! logOperand(arch, rax); // Prints 'rax'.
+//! logOperand(arch, ptr(rax, rbx, 2)); // Prints '[rax + rbx * 4]`.
+//! logOperand(arch, dword_ptr(rax, rbx, 2)); // Prints 'dword [rax + rbx * 4]`.
+//! logOperand(arch, imm(42)); // Prints '42'.
//! }
//! ```
//!
//! Next example illustrates how to format whole instructions:
//!
//! ```
-//! #include <asmjit/core.h>
+//! #include <asmjit/x86.h>
//! #include <stdio.h>
//! #include <utility>
//!
//! using namespace asmjit;
//!
//! template<typename... Args>
-//! void logInstruction(uint32_t arch, const BaseInst& inst, Args&&... args) {
+//! void logInstruction(Arch arch, const BaseInst& inst, Args&&... args) {
//! // The emitter is optional (named labels and virtual registers need it).
//! BaseEmitter* emitter = nullptr;
//!
//! // No flags by default.
-//! uint32_t formatFlags = FormatOptions::kNoFlags;
+//! FormatFlags formatFlags = FormatFlags::kNone;
//!
//! // The formatter expects operands in an array.
-//! Operand_ operands { std::forward<Args>(args)... };
+//! Operand_ operands[] { std::forward<Args>(args)... };
//!
//! StringTmp<128> sb;
//! Formatter::formatInstruction(
@@ -1592,7 +1547,7 @@ namespace asmjit {
//! // Architecture is not part of operand, it must be passed explicitly.
//! // Format flags. We pass it explicitly also to 'logOperand' to make
//! // compatible with what AsmJit normally does.
-//! uint32_t arch = Environment::kArchX64;
+//! Arch arch = Arch::kX64;
//!
//! // Prints 'mov rax, rcx'.
//! logInstruction(arch, BaseInst(Inst::kIdMov), rax, rcx);
@@ -1600,24 +1555,24 @@ namespace asmjit {
//! // Prints 'vaddpd zmm0, zmm1, [rax] {1to8}'.
//! logInstruction(arch,
//! BaseInst(Inst::kIdVaddpd),
-//! zmm0, zmm1, ptr(rax)._1toN());
+//! zmm0, zmm1, ptr(rax)._1to8());
//!
//! // BaseInst abstracts instruction id, instruction options, and extraReg.
//! // Prints 'lock add [rax], rcx'.
//! logInstruction(arch,
-//! BaseInst(Inst::kIdAdd, Inst::kOptionLock),
-//! x86::ptr(rax), rcx);
+//! BaseInst(Inst::kIdAdd, InstOptions::kX86_Lock),
+//! ptr(rax), rcx);
//!
//! // Similarly an extra register (like AVX-512 selector) can be used.
//! // Prints 'vaddpd zmm0 {k2} {z}, zmm1, [rax]'.
//! logInstruction(arch,
-//! BaseInst(Inst::kIdAdd, Inst::kOptionZMask, k2),
+//! BaseInst(Inst::kIdAdd, InstOptions::kX86_ZMask, k2),
//! zmm0, zmm1, ptr(rax));
//! }
//! ```
//!
-//! And finally, the example below illustrates how to use a built-in function
-//! to format the content of \ref BaseBuilder, which consists of nodes:
+//! And finally, the example below illustrates how to use a built-in function to format the content of
+//! \ref BaseBuilder, which consists of nodes:
//!
//! ```
//! #include <asmjit/core.h>
@@ -1626,7 +1581,7 @@ namespace asmjit {
//! using namespace asmjit;
//!
//! void formattingExample(BaseBuilder* builder) {
-//! uint32_t formatFlags = FormatOptions::kNoFlags;
+//! FormatOptions formatOptions {};
//!
//! // This also shows how temporary strings can be used.
//! StringTmp<512> sb;
@@ -1635,7 +1590,7 @@ namespace asmjit {
//! // were zero (no extra flags), and the builder instance, which we have
//! // provided. An overloaded version also exists, which accepts begin and
//! // and end nodes, which can be used to only format a range of nodes.
-//! Formatter::formatNodeList(sb, formatFlags, builder);
+//! Formatter::formatNodeList(sb, formatOptions, builder);
//!
//! // You can do whatever else with the string, it's always null terminated,
//! // so it can be passed to C functions like printf().
@@ -1643,40 +1598,30 @@ namespace asmjit {
//! }
//! ```
-// ============================================================================
-// [Documentation - asmjit_error_handling]
-// ============================================================================
//! \defgroup asmjit_error_handling Error Handling
//! \brief Error handling.
//!
//! ### Overview
//!
-//! AsmJit uses error codes to represent and return errors. Every function that
-//! can fail returns an \ref Error code. Exceptions are never thrown by AsmJit
-//! itself even in extreme conditions like out-of-memory, but it's possible to
-//! override \ref ErrorHandler::handleError() to throw, in that case no error
-//! will be returned and exception will be thrown instead. All functions where
-//! this can happen are not marked `noexcept`.
+//! AsmJit uses error codes to represent and return errors. Every function that can fail returns an \ref Error code.
+//! Exceptions are never thrown by AsmJit itself even in extreme conditions like out-of-memory, but it's possible to
+//! override \ref ErrorHandler::handleError() to throw, in that case no error will be returned and exception will be
+//! thrown instead. All functions where this can happen are not marked `noexcept`.
//!
-//! Errors should never be ignored, however, checking errors after each AsmJit
-//! API call would simply overcomplicate the whole code generation experience.
-//! \ref ErrorHandler exists to make the use of AsmJit API simpler as it allows
+//! Errors should never be ignored, however, checking errors after each AsmJit API call would simply over-complicate
+//! the whole code generation experience. \ref ErrorHandler exists to make the use of AsmJit API simpler as it allows
//! to customize how errors can be handled:
//!
//! - Record the error and continue (the way how the error is user-implemented).
-//! - Throw an exception. AsmJit doesn't use exceptions and is completely
-//! exception-safe, but it's perfectly legal to throw an exception from
-//! the error handler.
-//! - Use plain old C's `setjmp()` and `longjmp()`. Asmjit always puts Assembler,
-//! Builder and Compiler to a consistent state before calling \ref
-//! ErrorHandler::handleError(), so `longjmp()` can be used without issues to
-//! cancel the code-generation if an error occurred. This method can be used if
-//! exception handling in your project is turned off and you still want some
-//! comfort. In most cases it should be safe as AsmJit uses \ref Zone memory
-//! and the ownership of memory it allocates always ends with the instance that
-//! allocated it. If using this approach please never jump outside the life-time
-//! of \ref CodeHolder and \ref BaseEmitter.
+//! - Throw an exception. AsmJit doesn't use exceptions and is completely exception-safe, but it's perfectly legal
+//! to throw an exception from the error handler.
+//! - Use plain old C's `setjmp()` and `longjmp()`. Asmjit always puts Assembler, Builder and Compiler to a
+//! consistent state before calling \ref ErrorHandler::handleError(), so `longjmp()` can be used without issues
+//! to cancel the code-generation if an error occurred. This method can be used if exception handling in your
+//! project is turned off and you still want some comfort. In most cases it should be safe as AsmJit uses \ref
+//! Zone memory and the ownership of memory it allocates always ends with the instance that allocated it. If
+//! using this approach please never jump outside the life-time of \ref CodeHolder and \ref BaseEmitter.
//!
//! ### Using ErrorHandler
//!
@@ -1702,7 +1647,7 @@ namespace asmjit {
//! MyErrorHandler myErrorHandler;
//! CodeHolder code;
//!
-//! code.init(rt.environment());
+//! code.init(rt.environment(), rt.cpuFeatures());
//! code.setErrorHandler(&myErrorHandler);
//!
//! x86::Assembler a(&code);
@@ -1718,123 +1663,142 @@ namespace asmjit {
//! - See \ref Error that lists error codes that AsmJit uses.
//! - See \ref ErrorHandler for more details about error handling.
-// ============================================================================
-// [Documentation - asmjit_instruction_db]
-// ============================================================================
//! \defgroup asmjit_instruction_db Instruction DB
//! \brief Instruction database (introspection, read/write, validation, ...).
//!
//! ### Overview
//!
-//! AsmJit provides a public instruction database that can be used to query
-//! information about a complete instruction. The instruction database requires
-//! the knowledge of the following:
+//! AsmJit provides a public instruction database that can be used to query information about a complete instruction.
+//! The instruction database requires the knowledge of the following:
+//!
+//! - \ref BaseInst - Base instruction that contains instruction id, options, and a possible extra-register that
+//! represents either REP prefix counter or AVX-512 selector (mask).
//!
-//! - \ref BaseInst - Base instruction that contains instruction id, options,
-//! and a possible extra-register that represents either REP prefix counter
-//! or AVX-512 selector (mask).
//! - \ref Operand - Represents operands of an instruction.
//!
//! Each instruction can be then queried for the following information:
//!
-//! - \ref InstRWInfo - Read/write information of instruction and its oprands.
-//! - \ref OpRWInfo - Read/write information of a single operand, part of
-//! \ref InstRWInfo data structure.
-//! - \ref BaseFeatures - CPU features required to execute the instruction.
+//! - \ref InstRWInfo - Read/write information of instruction and its operands (includes \ref OpRWInfo).
+//!
+//! - \ref CpuFeatures - CPU features required to execute the instruction.
//!
-//! In addition to query functionality AsmJit is also able to validate whether
-//! an instruction and its operands are valid. This is useful for making sure
-//! that what user tries to emit is correct and it can be also used by other
+//! In addition to query functionality AsmJit is also able to validate whether an instruction and its operands are
+//! valid. This is useful for making sure that what user tries to emit is correct and it can be also used by other
//! projects that parse user input, like AsmTK project.
//!
//! ### Query API
//!
-//! The instruction query API is provided by \ref InstAPI namespace. The
-//! following queries are possible:
+//! The instruction query API is provided by \ref InstAPI namespace. The following queries are possible:
//!
-//! - \ref InstAPI::queryRWInfo() - queries read/write information of the
-//! given instruction and its operands. Includes also CPU flags read/written.
+//! - \ref InstAPI::queryRWInfo() - queries read/write information of the given instruction and its operands.
+//! Includes also CPU flags read/written.
//!
-//! - \ref InstAPI::queryFeatures() - queries CPU features that are required
-//! to execute the given instruction. A full instruction with operands must
-//! be given as some architectures like X86 may require different features
-//! for the same instruction based on its operands.
+//! - \ref InstAPI::queryFeatures() - queries CPU features that are required to execute the given instruction. A full
+//! instruction with operands must be given as some architectures like X86 may require different features for the
+//! same instruction based on its operands.
//!
-//! - <a href="https://github.com/asmjit/asmjit/blob/master/test/asmjit_test_x86_instinfo.cpp">asmjit_test_x86_instinfo.cpp</a>
+//! - <a href="https://github.com/asmjit/asmjit/blob/master/test/asmjit_test_instinfo.cpp">asmjit_test_instinfo.cpp</a>
//! can be also used as a reference about accessing instruction information.
//!
//! ### Validation API
//!
-//! The instruction validation API is provided by \ref InstAPI namespace in the
-//! similar fashion like the Query API, however, validation can also be turned
-//! on at \ref BaseEmitter level. The following is possible:
+//! The instruction validation API is provided by \ref InstAPI namespace in the similar fashion like the Query API,
+//! however, validation can also be turned on at \ref BaseEmitter level. The following is possible:
//!
-//! - \ref InstAPI::validate() - low-level instruction validation function
-//! that is used internally by emitters if strict validation is enabled.
+//! - \ref InstAPI::validate() - low-level instruction validation function that is used internally by emitters
+//! if strict validation is enabled.
//!
-//! - \ref BaseEmitter::addValidationOptions() - can be used to enable
-//! validation at emitter level, see \ref BaseEmitter::ValidationOptions.
+//! - \ref BaseEmitter::addDiagnosticOptions() - can be used to enable validation at emitter level, see \ref
+//! DiagnosticOptions.
-// ============================================================================
-// [Documentation - asmjit_virtual_memory]
-// ============================================================================
-
//! \defgroup asmjit_virtual_memory Virtual Memory
//! \brief Virtual memory management.
//!
//! ### Overview
//!
-//! AsmJit's virtual memory management is divided into two main categories:
-//!
-//! - Low level API that provides cross-platform abstractions for virtual
-//! memory allocation. Implemented in \ref VirtMem namespace.
-//! - High level API that makes it very easy to store generated code for
-//! execution. See \ref JitRuntime, which is used by many examples for its
-//! simplicity and easy integration with \ref CodeHolder. There is also
-//! \ref JitAllocator, which lays somewhere between RAW memory allocation
-//! and \ref JitRuntime.
+//! AsmJit's virtual memory management is divided into three main categories:
+//!
+//! - Low level interface that provides cross-platform abstractions for virtual memory allocation. Implemented in
+//! \ref VirtMem namespace. This API is a thin wrapper around operating system specific calls such as
+//! `VirtualAlloc()` and `mmap()` and it's intended to be used by AsmJit's higher level API. Low-level virtual
+//! memory functions can be used to allocate virtual memory, change its permissions, and to release it.
+//! Additionally, an API that allows to create dual mapping (to support hardened environments) is provided.
+//!
+//! - Middle level API that is provided by \ref JitAllocator, which uses \ref VirtMem internally and offers nicer
+//! API that can be used by users to allocate executable memory conveniently. \ref JitAllocator tries to be smart,
+//! for example automatically using dual mapping or `MAP_JIT` on hardened environments.
+//!
+//! - High level API that is provided by \ref JitRuntime, which implements \ref Target interface and uses \ref
+//! JitAllocator under the hood. Since \ref JitRuntime inherits from \ref Target it makes it easy to use with
+//! \ref CodeHolder. Many AsmJit examples use \ref JitRuntime for its simplicity and easy integration.
+//!
+//! The main difference between \ref VirtMem and \ref JitAllocator is that \ref VirtMem can only be used to allocate
+//! whole pages, whereas \ref JitAllocator has `malloc()` like API that allows to allocate smaller quantities that
+//! usually represent the size of an assembled function or a chunk of functions that can represent a module, for
+//! example. \ref JitAllocator then tracks used space of each page it maintains. Internally, \ref JitAllocator uses
+//! two bit arrays to track occupied regions in each allocated block of pages.
+//!
+//! ### Hardened Environments
+//!
+//! In the past, allocating virtual memory with Read+Write+Execute (RWX) access permissions was easy. However, modern
+//! operating systems and runtime environments often use hardening, which typically prohibits mapping pages with both
+//! Write and Execute permissions (known as the W^X policy). This presents a challenge for JIT compilers because
+//! generated code for a single function is unlikely to fit in exactly N pages without leaving some space empty. To
+//! accommodate this, the execution environment may need to temporarily change the permissions of existing pages to
+//! read+write (RW) to insert new code into them, however, sometimes it's not possible to ensure that no thread is
+//! executing code in such affected pages in a multithreaded environment, in which multiple threads may be executing
+//! generated code.
+//!
+//! Such restrictions leave a lot of complexity on the application, so AsmJit implements a dual mapping technique to
+//! make the life of AsmJit users easier. In this technique, a region of memory is mapped to two different virtual
+//! addresses with different access permissions. One virtual address is mapped with read and write (RW) access, which
+//! is used by the JIT compiler to write generated code. The other virtual address is mapped with read and execute (RX)
+//! access, which is used by the application to execute the generated code.
+//!
+//! However, implementing dual mapping can be challenging because it typically requires obtaining an anonymous file
+//! descriptor on most Unix-like operating systems. This file descriptor is then passed to mmap() twice to create
+//! the two mappings. AsmJit handles this challenge by using system-specific techniques such as `memfd_create()` on
+//! Linux, `shm_open(SHM_ANON)` on BSD, and `MAP_REMAPDUP` with `mremap()` on NetBSD. The latter approach does not
+//! require a file descriptor. If none of these options are available, AsmJit uses a plain `open()` call followed by
+//! `unlink()`.
+//!
+//! The most challenging part is actually obtaining a file descriptor that can be passed to `mmap()` with `PROT_EXEC`.
+//! This is still something that may fail, for example the environment could be hardened in a way that this would
+//! not be possible at all, and thus dual mapping would not work.
+//!
+//! Dual mapping is provided by both \ref VirtMem and \ref JitAllocator.
-// ============================================================================
-// [Documentation - asmjit_zone_memory]
-// ============================================================================
//! \defgroup asmjit_zone Zone Memory
//! \brief Zone memory allocator and containers.
//!
//! ### Overview
//!
-//! AsmJit uses zone memory allocation (also known as Arena allocation) to allocate
-//! most of the data it uses. It's a fast allocator that allows AsmJit to allocate
-//! a lot of small data structures fast and without `malloc()` overhead. Since
-//! code generators and all related classes are usually short-lived this approach
-//! decreases memory usage and fragmentation as arena-based allocators always
-//! allocate larger blocks of memory, which are then split into smaller chunks.
-//!
-//! Another advantage of zone memory allocation is that since the whole library
-//! uses this strategy it's very easy to deallocate everything that a particular
-//! instance is holding by simply releasing the memory the allocator holds. This
-//! improves destruction time of such objects as there is no destruction at all.
-//! Long-lived objects just reset its data in destructor or in their reset()
-//! member function for a future reuse. For this purpose all containers in AsmJit
-//! are also zone allocated.
+//! AsmJit uses zone memory allocation (also known as Arena allocation) to allocate most of the data it uses. It's a
+//! fast allocator that allows AsmJit to allocate a lot of small data structures fast and without `malloc()` overhead.
+//! Since code generators and all related classes are usually short-lived this approach decreases memory usage and
+//! fragmentation as arena-based allocators always allocate larger blocks of memory, which are then split into smaller
+//! chunks.
+//!
+//! Another advantage of zone memory allocation is that since the whole library uses this strategy it's very easy to
+//! deallocate everything that a particular instance is holding by simply releasing the memory the allocator holds.
+//! This improves destruction time of such objects as there is no destruction at all. Long-lived objects just reset
+//! its data in destructor or in their reset() member function for a future reuse. For this purpose all containers in
+//! AsmJit are also zone allocated.
//!
//! ### Zone Allocation
//!
-//! - \ref Zone - Incremental zone memory allocator with minimum features. It
-//! can only allocate memory without the possibility to return it back to
-//! the allocator.
+//! - \ref Zone - Incremental zone memory allocator with minimum features. It can only allocate memory without the
+//! possibility to return it back to the allocator.
//!
-//! - \ref ZoneTmp - A temporary \ref Zone with some initial static storage.
-//! If the allocation requests fit the static storage allocated then there
-//! will be no dynamic memory allocation during the lifetime of \ref ZoneTmp,
-//! otherwise it would act as \ref Zone with one preallocated block on the
-//! stack.
+//! - \ref ZoneTmp - A temporary \ref Zone with some initial static storage. If the allocation requests fit the
+//! static storage allocated then there will be no dynamic memory allocation during the lifetime of \ref ZoneTmp,
+//! otherwise it would act as \ref Zone with one preallocated block on the stack.
//!
-//! - \ref ZoneAllocator - A wrapper of \ref Zone that provides the capability
-//! of returning memory to the allocator. Such memory is stored in a pool for
-//! later reuse.
+//! - \ref ZoneAllocator - A wrapper of \ref Zone that provides the capability of returning memory to the allocator.
+//! Such memory is stored in a pool for later reuse.
//!
//! ### Zone Allocated Containers
//!
@@ -1848,11 +1812,10 @@ namespace asmjit {
//!
//! ### Using Zone Allocated Containers
//!
-//! The most common data structure exposed by AsmJit is \ref ZoneVector. It's very
-//! similar to `std::vector`, but the implementation doesn't use exceptions and
-//! uses the mentioned \ref ZoneAllocator for performance reasons. You don't have
-//! to worry about allocations as you should not need to add items to AsmJit's
-//! data structures directly as there should be API for all required operations.
+//! The most common data structure exposed by AsmJit is \ref ZoneVector. It's very similar to `std::vector`, but the
+//! implementation doesn't use exceptions and uses the mentioned \ref ZoneAllocator for performance reasons. You don't
+//! have to worry about allocations as you should not need to add items to AsmJit's data structures directly as there
+//! should be API for all required operations.
//!
//! The following APIs in \ref CodeHolder returns \ref ZoneVector reference:
//!
@@ -1874,10 +1837,9 @@ namespace asmjit {
//! }
//! ```
//!
-//! \ref ZoneVector has overloaded array access operator to make it possible
-//! to access its elements through operator[]. Some standard functions like
-//! \ref ZoneVector::empty(), \ref ZoneVector::size(), and \ref ZoneVector::data()
-//! are provided as well. Vectors are also iterable through a range-based for loop:
+//! \ref ZoneVector has overloaded array access operator to make it possible to access its elements through operator[].
+//! Some standard functions like \ref ZoneVector::empty(), \ref ZoneVector::size(), and \ref ZoneVector::data() are
+//! provided as well. Vectors are also iterable through a range-based for loop:
//!
//! ```
//! using namespace asmjit;
@@ -1894,15 +1856,13 @@ namespace asmjit {
//!
//! ### Design Considerations
//!
-//! Zone-allocated containers do not store the allocator within the container.
-//! This decision was made to reduce the footprint of such containers as AsmJit
-//! tooling, especially Compiler's register allocation, may use many instances
+//! Zone-allocated containers do not store the allocator within the container. This decision was made to reduce the
+//! footprint of such containers as AsmJit tooling, especially Compiler's register allocation, may use many instances
//! of such containers to perform code analysis and register allocation.
//!
-//! For example to append an item into a \ref ZoneVector it's required to pass
-//! the allocator as the first argument, so it can be used in case that the
-//! vector needs a reallocation. Such function also returns an error, which
-//! must be propagated to the caller.
+//! For example to append an item into a \ref ZoneVector it's required to pass the allocator as the first argument,
+//! so it can be used in case that the vector needs a reallocation. Such function also returns an error, which must
+//! be propagated to the caller.
//!
//! ```
//! using namespace asmjit
@@ -1926,10 +1886,9 @@ namespace asmjit {
//! }
//! ```
//!
-//! Containers like \ref ZoneVector also provide a functionality to reserve a
-//! certain number of items before any items are added to it. This approach is
-//! used internally in most places as it allows to prepare space for data that
-//! will be added to some container before the data itself was created.
+//! Containers like \ref ZoneVector also provide a functionality to reserve a certain number of items before any items
+//! are added to it. This approach is used internally in most places as it allows to prepare space for data that will
+//! be added to some container before the data itself was created.
//!
//! ```
//! using namespace asmjit
@@ -1947,48 +1906,46 @@ namespace asmjit {
//! }
//! ```
-// ============================================================================
-// [Documentation - asmjit_utilities]
-// ============================================================================
//! \defgroup asmjit_utilities Utilities
//! \brief Utility classes and functions.
//!
//! ### Overview
//!
-//! AsmJit uses and provides utility classes and functions, that can be used
-//! with AsmJit. The functionality can be divided into the following topics:
+//! AsmJit uses and provides utility classes and functions, that can be used with AsmJit. The functionality can be
+//! divided into the following topics:
//!
//! ### String Functionality
//!
-//! - \ref String - AsmJit's string container, which is used internally
-//! and which doesn't use exceptions and has a stable layout, which is
-//! not dependent on C++ standard library.
-//! - \ref StringTmp - String that can have base storage allocated on
-//! stack. The amount of storage on stack can be specified as a template
-//! parameter.
+//! - \ref String - AsmJit's string container, which is used internally and which doesn't use exceptions and has
+//! a stable layout, which is not dependent on C++ standard library.
+//!
+//! - \ref StringTmp - String that can have base storage allocated on stack. The amount of storage on stack can
+//! be specified as a template parameter.
+//!
//! - \ref FixedString - Fixed string container limited up to N characters.
//!
//! ### Code Generation Utilities
//!
-//! - \ref ConstPool - Constant pool used by \ref BaseCompiler, but also
-//! available to users that may find use of it.
+//! - \ref ConstPool - Constant pool used by \ref BaseCompiler, but also available to users that may find use of it.
//!
//! ### Support Functionality Used by AsmJit
//!
-//! - \ref Support namespace provides many other utility functions and
-//! classes that are used by AsmJit, and made public.
+//! - \ref Support namespace provides many other utility functions and classes that are used by AsmJit, and made
+//! public.
-// ============================================================================
-// [Documentation - asmjit_<arch> backends]
-// ============================================================================
//! \defgroup asmjit_x86 X86 Backend
//! \brief X86/X64 backend.
-// ============================================================================
-// [Documentation - asmjit_ra]
-// ============================================================================
+
+//! \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
@@ -1997,63 +1954,38 @@ namespace asmjit {
} // {asmjit}
-// ============================================================================
-// [Core Headers]
-// ============================================================================
-
-#include "./core/globals.h"
-
-#include "./core/arch.h"
-#include "./core/assembler.h"
-#include "./core/builder.h"
-#include "./core/callconv.h"
-#include "./core/codeholder.h"
-#include "./core/compiler.h"
-#include "./core/constpool.h"
-#include "./core/cpuinfo.h"
-#include "./core/datatypes.h"
-#include "./core/emitter.h"
-#include "./core/environment.h"
-#include "./core/errorhandler.h"
-#include "./core/features.h"
-#include "./core/formatter.h"
-#include "./core/func.h"
-#include "./core/inst.h"
-#include "./core/jitallocator.h"
-#include "./core/jitruntime.h"
-#include "./core/logger.h"
-#include "./core/operand.h"
-#include "./core/osutils.h"
-#include "./core/string.h"
-#include "./core/support.h"
-#include "./core/target.h"
-#include "./core/type.h"
-#include "./core/virtmem.h"
-#include "./core/zone.h"
-#include "./core/zonehash.h"
-#include "./core/zonelist.h"
-#include "./core/zonetree.h"
-#include "./core/zonestack.h"
-#include "./core/zonestring.h"
-#include "./core/zonevector.h"
-
-// ============================================================================
-// [Deprecated]
-// ============================================================================
-
-#ifndef ASMJIT_NO_DEPRECATED
-namespace asmjit {
-
-#ifndef ASMJIT_NO_COMPILER
-ASMJIT_DEPRECATED("Use InvokeNode instead of FuncCallNode")
-typedef InvokeNode FuncCallNode;
-#endif // !ASMJIT_NO_COMPILER
-
-#ifndef ASMJIT_NO_LOGGING
-namespace Logging { using namespace Formatter; }
-#endif //! ASMJIT_NO_LOGGING
-
-} // {asmjit}
-#endif // !ASMJIT_NO_DEPRECATED
+#include "asmjit-scope-begin.h"
+#include "core/archtraits.h"
+#include "core/assembler.h"
+#include "core/builder.h"
+#include "core/codeholder.h"
+#include "core/compiler.h"
+#include "core/constpool.h"
+#include "core/cpuinfo.h"
+#include "core/emitter.h"
+#include "core/environment.h"
+#include "core/errorhandler.h"
+#include "core/formatter.h"
+#include "core/func.h"
+#include "core/globals.h"
+#include "core/inst.h"
+#include "core/jitallocator.h"
+#include "core/jitruntime.h"
+#include "core/logger.h"
+#include "core/operand.h"
+#include "core/osutils.h"
+#include "core/string.h"
+#include "core/support.h"
+#include "core/target.h"
+#include "core/type.h"
+#include "core/virtmem.h"
+#include "core/zone.h"
+#include "core/zonehash.h"
+#include "core/zonelist.h"
+#include "core/zonetree.h"
+#include "core/zonestack.h"
+#include "core/zonestring.h"
+#include "core/zonevector.h"
+#include "asmjit-scope-end.h"
#endif // ASMJIT_CORE_H_INCLUDED