Allow users to specify a home register hint (compiler)

This commit is contained in:
kobalicek
2025-05-08 07:02:26 +02:00
parent 4cd9198a6c
commit 9eb6edbf71
8 changed files with 99 additions and 52 deletions

View File

@@ -17,7 +17,7 @@ namespace asmjit {
//! functionality is within \ref asmjit namespace and architecture specific functionality is always in its own //! 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. //! namespace. For example \ref asmjit::x86 provides both 32-bit and 64-bit X86 code generation.
//! //!
//! \section main_groups Documentation Groups //! \section doc_groups Documentation Groups
//! //!
//! AsmJit documentation is structured into groups. Groups can be followed in order to learn AsmJit, but knowledge //! 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: //! from multiple groups is required to use AsmJit properly:
@@ -78,7 +78,7 @@ namespace asmjit {
//! output from \ref Logger is always necessary when filling bug reports. In other words, using logging and proper error //! 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. //! handling can save a lot of time during the development and can also save users from submitting issues.
//! //!
//! \section main_other Other Pages //! \section other_pages Other Pages
//! //!
//! - <a href="annotated.html">Class List</a> - List of classes sorted alphabetically //! - <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 //! - <a href="namespaceasmjit.html">AsmJit Namespace</a> - List of symbols provided by `asmjit` namespace
@@ -96,6 +96,8 @@ namespace asmjit {
//! your project and to define \ref ASMJIT_STATIC. AsmJit can be just updated from time to time without any changes to //! 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. //! this integration process. Do not embed AsmJit's `test` files in such case as these are used exclusively for testing.
//! //!
//! \section supported_environment Supported Operating Systems, Compilers, and Build Tools
//!
//! ### Supported C++ Compilers //! ### Supported C++ Compilers
//! //!
//! - Requirements: //! - Requirements:
@@ -147,7 +149,7 @@ namespace asmjit {
//! - **X86** and **X86_64** - Both 32-bit and 64-bit backends tested on CI. //! - **X86** and **X86_64** - Both 32-bit and 64-bit backends tested on CI.
//! - **AArch64** - Tested on CI (Native Apple runners and Linux emulated via QEMU). //! - **AArch64** - Tested on CI (Native Apple runners and Linux emulated via QEMU).
//! //!
//! ### Static Builds and Embedding //! \section build_mode Static Builds and Embedding
//! //!
//! These definitions can be used to enable static library build. Embed is used when AsmJit's source code is embedded //! 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. //! directly in another project, implies static build as well.
@@ -159,7 +161,31 @@ namespace asmjit {
//! otherwise AsmJit would use dynamic library imports in \ref ASMJIT_API decorator. The recommendation is to define //! 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. //! this macro across the whole project that uses AsmJit this way.
//! //!
//! ### Build Configuration //! \section cmake_integration CMake Integration
//!
//! AsmJit has a first-class CMake support. When consuming AsmJit as a cmake dependency, just use `asmjit::asmjit`
//! as a link dependency, which would instrument cmake to setup everything else, including include paths, and build
//! flags (either defining `ASMJIT_STATIC` or not, and possibly defining other AsmJit feature macros). For example
//! considering that AsmJit was fetched to `3rdparty/asmjit` directory in your project as an external dependency,
//! you can just use the following CMake snippet that integrates AsmJit with your own CMake project:
//!
//! ```cmake
//! cmake_minimum_required(VERSION 3.30)
//!
//! project(asmjit_consumer C CXX) # Both C and CXX are required.
//! set(CMAKE_CXX_STANDARD 17) # C++11 and never is supported.
//!
//! set(ASMJIT_DIR "3rdparty/asmjit") # Location of AsmJit.
//! set(ASMJIT_STATIC TRUE) # Force static build.
//!
//! add_subdirectory("${ASMJIT_DIR}") # This adds AsmJit as a part of your project.
//!
//! add_executable(asmjit_consumer asmjit_consumer.cpp)
//! target_link_libraries(
//! asmjit_consumer asmjit::asmjit) # This adds AsmJit as a dependency to your target.
//! ```
//!
//! \section build_type Build Type Configuration
//! //!
//! These definitions control whether asserts are active or not. By default AsmJit would autodetect 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 //! from existing pre-processor definitions, but this behavior can be overridden, for example to enable debug asserts
@@ -173,7 +199,7 @@ namespace asmjit {
//! were not used. We only recommend using build configuration overrides in special situations, like using AsmJit in //! 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. //! release configuration with asserts enabled for whatever reason.
//! //!
//! ### AsmJit Backends //! \section build_backends AsmJit Backends
//! //!
//! AsmJit currently supports only X86/X64 backend, but the plan is to add more backends in the future. 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. //! AsmJit builds only the host backend, which is auto-detected at compile-time, but this can be overridden.
@@ -182,7 +208,7 @@ namespace asmjit {
//! - \ref ASMJIT_NO_AARCH64 - Disables AArch64 backend. //! - \ref ASMJIT_NO_AARCH64 - Disables AArch64 backend.
//! - \ref ASMJIT_NO_FOREIGN - Disables the support for foreign architecture backends, only keeps a native backend. //! - \ref ASMJIT_NO_FOREIGN - Disables the support for foreign architecture backends, only keeps a native backend.
//! //!
//! ### AsmJit Compilation Options //! \section build_options Build Options
//! //!
//! - \ref ASMJIT_NO_DEPRECATED - Disables deprecated API at compile time so it won't be available and the //! - \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, //! compilation will fail if there is attempt to use such API. This includes deprecated classes, namespaces,
@@ -195,9 +221,9 @@ namespace asmjit {
//! versions are used at the same time. This option can be debugging a little simpler as there would not be ABI //! 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. //! tag after `asmjit::` namespace. Otherwise asmjit would look like `asmjit::_abi_1_13::`, for example.
//! //!
//! ### Features Selection //! \section build_features Build Features
//! //!
//! AsmJit builds by defaults all supported features, which includes all emitters, logging, instruction validation and //! AsmJit builds by default 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_...` //! introspection, and JIT memory allocation. Features can be disabled at compile time by using `ASMJIT_NO_...`
//! definitions. //! definitions.
//! - \ref ASMJIT_NO_JIT - Disables JIT memory management and \ref JitRuntime. //! - \ref ASMJIT_NO_JIT - Disables JIT memory management and \ref JitRuntime.
@@ -235,7 +261,7 @@ namespace asmjit {
//! removed APIs and should serve as a how-to guide for people that want to port existing code to work with the //! removed APIs and should serve as a how-to guide for people that want to port existing code to work with the
//! newest AsmJit. //! newest AsmJit.
//! //!
//! ### Tips //! \section tips Tips
//! //!
//! Useful tips before you start: //! Useful tips before you start:
//! //!
@@ -247,6 +273,8 @@ namespace asmjit {
//! because some compilers would warn about that. If your project compiles fine with `ASMJIT_NO_DEPRECATED` //! because some compilers would warn about that. If your project compiles fine with `ASMJIT_NO_DEPRECATED`
//! it's not using anything, which was deprecated. //! it's not using anything, which was deprecated.
//! //!
//! \section api_changes API Changes
//!
//! ### Changes committed at 2024-01-01 //! ### Changes committed at 2024-01-01
//! //!
//! Core changes: //! Core changes:
@@ -513,7 +541,7 @@ namespace asmjit {
//! //!
//! \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 //! \section code_holder_and_emitters CodeHolder & Emitters
//! //!
//! The example below shows how the mentioned classes interact to generate X86 code: //! The example below shows how the mentioned classes interact to generate X86 code:
//! //!
@@ -562,7 +590,7 @@ namespace asmjit {
//! - \ref asmjit_builder - Low-level emitter that emits to a \ref BaseNode list. //! - \ref asmjit_builder - Low-level emitter that emits to a \ref BaseNode list.
//! - \ref asmjit_compiler - High-level emitter that provides register allocation. //! - \ref asmjit_compiler - High-level emitter that provides register allocation.
//! //!
//! ### Targets and JitRuntime //! \section targets_and_jit_runtime Targets and JitRuntime
//! //!
//! AsmJit's \ref Target is an interface that provides basic target abstraction. At the moment AsmJit provides only //! 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 //! one implementation called \ref JitRuntime, which as the name suggests provides JIT code target and execution
@@ -631,7 +659,7 @@ namespace asmjit {
//! } //! }
//! ``` //! ```
//! //!
//! ### Explicit Code Relocation //! \section explicit_code_relocation Explicit Code Relocation
//! //!
//! In addition to \ref Environment, \ref CodeHolder can be configured to specify a base-address (or a virtual base //! 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 //! address in a linker terminology), which could be static (useful when you know the location where the target's
@@ -817,7 +845,7 @@ namespace asmjit {
//! } //! }
//! ``` //! ```
//! //!
//! ### Label Offsets and Links //! \section labels 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 //! 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 //! a \ref LabelEntry. These links are also created if a label is used in a different section than in which it was
@@ -871,7 +899,7 @@ namespace asmjit {
//! } //! }
//! ``` //! ```
//! //!
//! ### Sections //! \section code_sections Code & Data Sections
//! //!
//! AsmJit allows to create multiple sections within the same \ref CodeHolder. A test-case //! 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) //! [asmjit_test_x86_sections.cpp](https://github.com/asmjit/asmjit/blob/master/test/asmjit_test_x86_sections.cpp)
@@ -988,7 +1016,7 @@ namespace asmjit {
//! //!
//! \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 //! \section operand_basics Operand Basics
//! //!
//! Let's start with operands. \ref Operand is a data structure that defines a data layout of any operand. It can be //! 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. //! inherited, but any class inheriting it cannot add any members to it, only the existing layout can be reused.
@@ -1028,7 +1056,7 @@ namespace asmjit {
//! - \ref Label - used to reference a location in code or data. Labels must be created by the \ref BaseEmitter or //! - \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. //! by \ref CodeHolder. Each label has its unique id per \ref CodeHolder instance.
//! //!
//! ### Operand Manipulation //! \section operand_manipulation Operand Manipulation
//! //!
//! AsmJit allows to construct operands dynamically, to store them, and to query a complete information about them at //! 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 //! run-time. Operands are small (always 16 bytes per `Operand`) and should be always copied (by value) if you intend
@@ -1099,7 +1127,7 @@ namespace asmjit {
//! BaseEmitter::newLabel(), which creates a label entry and returns a \ref Label operand with the id that refers //! 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. //! to it. Such label then can be used by emitters.
//! //!
//! ### Memory Operands //! \section memory_operands Memory Operands
//! //!
//! Some architectures like X86 provide a complex memory addressing model that allows to encode addresses having a //! 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). //! BASE register, INDEX register with a possible scale (left shift), and displacement (called offset in AsmJit).
@@ -1232,7 +1260,7 @@ namespace asmjit {
//! } //! }
//! ``` //! ```
//! //!
//! ### Assembler Examples //! \section examples Assembler Examples
//! //!
//! - \ref x86::Assembler provides many X86/X64 examples. //! - \ref x86::Assembler provides many X86/X64 examples.
@@ -1252,7 +1280,7 @@ namespace asmjit {
//! compatibility with the existing \ref BaseAssembler emitter so users can move from assembler to builder when needed, //! 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. //! for example to implement post-processing, which is not possible with Assembler.
//! //!
//! ### Builder Nodes //! \section builder_nodes Builder Nodes
//! //!
//! \ref BaseBuilder doesn't generate machine code directly, it uses an intermediate representation based on 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. //! however, it allows to serialize to \ref BaseAssembler when the code is ready to be encoded.
@@ -1278,7 +1306,7 @@ namespace asmjit {
//! //!
//! - Other nodes are provided by \ref asmjit_compiler infrastructure. //! - Other nodes are provided by \ref asmjit_compiler infrastructure.
//! //!
//! ### Builder Examples //! \section builder_examples Examples
//! //!
//! - \ref x86::Builder - Builder implementation targeting X86 and X86_64 architectures. //! - \ref x86::Builder - Builder implementation targeting X86 and X86_64 architectures.
//! - \ref a64::Builder - Builder implementation targeting AArch64 architecture. //! - \ref a64::Builder - Builder implementation targeting AArch64 architecture.
@@ -1305,7 +1333,7 @@ namespace asmjit {
//! return value(s) are handled by assigning virtual registers to them. Similarly, function calls are handled the same //! return value(s) are handled by assigning virtual registers to them. Similarly, function calls are handled the same
//! way. //! way.
//! //!
//! ### Compiler Nodes //! \section compiler_nodes 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:
//! //!
@@ -1316,12 +1344,12 @@ namespace asmjit {
//! \ref BaseCompiler also makes the use of passes (\ref Pass) and automatically adds an architecture-dependent //! \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. //! register allocator pass to the list of passes when attached to \ref CodeHolder.
//! //!
//! ### Compiler Examples //! \section compiler_examples Compiler Examples
//! //!
//! - \ref x86::Compiler - Compiler implementation targeting X86 and X86_64 architectures. //! - \ref x86::Compiler - Compiler implementation targeting X86 and X86_64 architectures.
//! - \ref a64::Compiler - Compiler implementation targeting AArch64 architecture. //! - \ref a64::Compiler - Compiler implementation targeting AArch64 architecture.
//! //!
//! ### Compiler Tips //! \section compiler_tips 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:
//! //!
@@ -1423,7 +1451,7 @@ namespace asmjit {
//! - \ref FormatFlags //! - \ref FormatFlags
//! - \ref FormatIndentationGroup //! - \ref FormatIndentationGroup
//! //!
//! ### Logging //! \section logging Logging
//! //!
//! A \ref Logger is typically attached to a \ref CodeHolder, which propagates it to all attached emitters //! 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: //! automatically. The example below illustrates how to use \ref FileLogger that outputs to standard output:
@@ -1481,7 +1509,7 @@ namespace asmjit {
//! } //! }
//! ``` //! ```
//! //!
//! ### Formatting //! \section formatting Formatting
//! //!
//! AsmJit uses \ref Formatter to format inputs that are then passed to \ref Logger. Formatting is public and can be //! 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 //! used by AsmJit users as well. The most important thing to know regarding formatting is that \ref Formatter always
@@ -1631,7 +1659,7 @@ namespace asmjit {
//! Zone memory and the ownership of memory it allocates always ends with the instance that allocated it. If //! 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 this approach please never jump outside the life-time of \ref CodeHolder and \ref BaseEmitter.
//! //!
//! ### Using ErrorHandler //! \section using_error_handler Using ErrorHandler
//! //!
//! An example of attaching \ref ErrorHandler to \ref CodeHolder. //! An example of attaching \ref ErrorHandler to \ref CodeHolder.
//! //!
@@ -1695,7 +1723,7 @@ namespace asmjit {
//! valid. This is useful for making sure that what user tries to emit is correct and it can be also used by other //! 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. //! projects that parse user input, like AsmTK project.
//! //!
//! ### Query API //! \section instruction_query Instruction Queries
//! //!
//! 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:
//! //!
@@ -1709,7 +1737,7 @@ namespace asmjit {
//! - <a href="https://github.com/asmjit/asmjit/blob/master/test/asmjit_test_instinfo.cpp">asmjit_test_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. //! can be also used as a reference about accessing instruction information.
//! //!
//! ### Validation API //! \section instruction_validation Instruction Validation
//! //!
//! The instruction validation API is provided by \ref InstAPI namespace in the similar fashion like the Query 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: //! however, validation can also be turned on at \ref BaseEmitter level. The following is possible:
@@ -1748,7 +1776,7 @@ namespace asmjit {
//! example. \ref JitAllocator then tracks used space of each page it maintains. Internally, \ref JitAllocator uses //! 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. //! two bit arrays to track occupied regions in each allocated block of pages.
//! //!
//! ### Hardened Environments //! \section hardened_environments Hardened Environments
//! //!
//! In the past, allocating virtual memory with Read+Write+Execute (RWX) access permissions was easy. However, modern //! 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 //! operating systems and runtime environments often use hardening, which typically prohibits mapping pages with both
@@ -1796,7 +1824,7 @@ namespace asmjit {
//! its data in destructor or in their reset() member function for a future reuse. For this purpose all containers in //! 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 are also zone allocated.
//! //!
//! ### Zone Allocation //! \section zone_allocation Zone Allocation
//! //!
//! - \ref Zone - Incremental zone memory allocator with minimum features. It can only allocate memory without the //! - \ref Zone - Incremental zone memory allocator with minimum features. It can only allocate memory without the
//! possibility to return it back to the allocator. //! possibility to return it back to the allocator.
@@ -1808,7 +1836,7 @@ namespace asmjit {
//! - \ref ZoneAllocator - A wrapper of \ref Zone that provides the capability of returning memory to the allocator. //! - \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. //! Such memory is stored in a pool for later reuse.
//! //!
//! ### Zone Allocated Containers //! \section zone_containers Zone Allocated Containers
//! //!
//! - \ref ZoneString - Zone allocated string. //! - \ref ZoneString - Zone allocated string.
//! - \ref ZoneHash - Zone allocated hash table. //! - \ref ZoneHash - Zone allocated hash table.
@@ -1818,7 +1846,7 @@ namespace asmjit {
//! - \ref ZoneVector - Zone allocated vector. //! - \ref ZoneVector - Zone allocated vector.
//! - \ref ZoneBitVector - Zone allocated vector of bits. //! - \ref ZoneBitVector - Zone allocated vector of bits.
//! //!
//! ### Using Zone Allocated Containers //! \section using_zone_containers Using Zone Allocated Containers
//! //!
//! The most common data structure exposed by AsmJit is \ref ZoneVector. It's very similar to `std::vector`, but the //! 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 //! implementation doesn't use exceptions and uses the mentioned \ref ZoneAllocator for performance reasons. You don't
@@ -1862,7 +1890,7 @@ namespace asmjit {
//! } //! }
//! ``` //! ```
//! //!
//! ### Design Considerations //! \section design_considerations Design Considerations
//! //!
//! Zone-allocated containers do not store the allocator within the container. This decision was made to reduce the //! 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 //! footprint of such containers as AsmJit tooling, especially Compiler's register allocation, may use many instances
@@ -1923,7 +1951,7 @@ namespace asmjit {
//! AsmJit uses and provides utility classes and functions, that can be used with AsmJit. The functionality can be //! AsmJit uses and provides utility classes and functions, that can be used with AsmJit. The functionality can be
//! divided into the following topics: //! divided into the following topics:
//! //!
//! ### String Functionality //! \section string_utilities String Utilities
//! //!
//! - \ref String - AsmJit's string container, which is used internally and which doesn't use exceptions and has //! - \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. //! a stable layout, which is not dependent on C++ standard library.
@@ -1933,11 +1961,11 @@ namespace asmjit {
//! //!
//! - \ref FixedString - Fixed string container limited up to N characters. //! - \ref FixedString - Fixed string container limited up to N characters.
//! //!
//! ### Code Generation Utilities //! \section codegen_utilities 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 //! \section support_utilities Support Functionality Used by AsmJit
//! //!
//! - \ref Support namespace provides many other utility functions and classes that are used by AsmJit, and made //! - \ref Support namespace provides many other utility functions and classes that are used by AsmJit, and made
//! public. //! public.

View File

@@ -196,7 +196,7 @@ struct ArchTraits {
//! Maps scalar TypeId values (from TypeId::_kIdBaseStart) to register types, see \ref TypeId. //! Maps scalar TypeId values (from TypeId::_kIdBaseStart) to register types, see \ref TypeId.
Support::Array<RegType, 32> _typeIdToRegType; Support::Array<RegType, 32> _typeIdToRegType;
//! Word name identifiers of 8-bit, 16-bit, 32-biit, and 64-bit quantities that appear in formatted text. //! Word name identifiers of 8-bit, 16-bit, 32-bit, and 64-bit quantities that appear in formatted text.
ArchTypeNameId _typeNameIdTable[4]; ArchTypeNameId _typeNameIdTable[4];
//! \} //! \}

View File

@@ -17,10 +17,9 @@ ASMJIT_BEGIN_NAMESPACE
//! Base assembler. //! Base assembler.
//! //!
//! This is a base class that provides interface used by architecture specific //! This is a base class that provides interface used by architecture specific assembler implementations. Assembler
//! assembler implementations. Assembler doesn't hold any data, instead it's //! doesn't hold any data, instead it's attached to \ref CodeHolder, which provides all the data that Assembler needs
//! attached to \ref CodeHolder, which provides all the data that Assembler //! and which can be altered by it.
//! needs and which can be altered by it.
//! //!
//! Check out architecture specific assemblers for more details and examples: //! Check out architecture specific assemblers for more details and examples:
//! //!
@@ -63,8 +62,7 @@ public:
//! Sets the current position in the CodeBuffer to `offset`. //! Sets the current position in the CodeBuffer to `offset`.
//! //!
//! \note The `offset` cannot be greater than buffer size even if it's //! \note The `offset` cannot be greater than buffer size even if it's within the buffer's capacity.
//! within the buffer's capacity.
ASMJIT_API Error setOffset(size_t offset); ASMJIT_API Error setOffset(size_t offset);
//! Returns the start of the CodeBuffer in the current section. //! Returns the start of the CodeBuffer in the current section.

View File

@@ -609,14 +609,12 @@ public:
template<typename T> template<typename T>
ASMJIT_INLINE_NODEBUG const T* as() const noexcept { return static_cast<const T*>(this); } ASMJIT_INLINE_NODEBUG const T* as() const noexcept { return static_cast<const T*>(this); }
//! Returns previous node or `nullptr` if this node is either first or not //! Returns previous node or `nullptr` if this node is either first or not part of Builder/Compiler node-list.
//! part of Builder/Compiler node-list.
ASMJIT_INLINE_NODEBUG BaseNode* prev() const noexcept { return _prev; } ASMJIT_INLINE_NODEBUG BaseNode* prev() const noexcept { return _prev; }
//! Returns next node or `nullptr` if this node is either last or not part //! Returns next node or `nullptr` if this node is either last or not part of Builder/Compiler node-list.
//! of Builder/Compiler node-list.
ASMJIT_INLINE_NODEBUG BaseNode* next() const noexcept { return _next; } ASMJIT_INLINE_NODEBUG BaseNode* next() const noexcept { return _next; }
//! Returns the type of the node, see `NodeType`. //! Returns the type of the node, see \ref NodeType.
ASMJIT_INLINE_NODEBUG NodeType type() const noexcept { return _any._nodeType; } ASMJIT_INLINE_NODEBUG NodeType type() const noexcept { return _any._nodeType; }
//! Sets the type of the node, see `NodeType` (internal). //! Sets the type of the node, see `NodeType` (internal).

View File

@@ -18,7 +18,18 @@ class RAWorkReg;
//! \addtogroup asmjit_compiler //! \addtogroup asmjit_compiler
//! \{ //! \{
//! Virtual register data, managed by \ref BaseCompiler. //! Public virtual register interface, managed by \ref BaseCompiler.
//!
//! When a virtual register is created by \ref BaseCompiler a `VirtReg` is linked with the register operand id it
//! returns. This `VirtReg` can be accessed via \ref BaseCompiler::virtRegByReg() function, which returns a pointer
//! to `VirtReg`.
//!
//! In general, `VirtReg` should be only introspected as it contains important variables that are needed and managed
//! by AsmJit, however, the `VirtReg` API can also be used to influence register allocation. For example there is
//! a \ref VirtReg::setWeight() function, which could be used to increase a weight of a virtual register (thus make
//! it hard to spill, for example). In addition, there is a \ref VirtReg::setHomeIdHint() function, which can be used
//! to do an initial assignment of a physical register of a virtual register. However, AsmJit could still override
//! the physical register assigned in some special cases.
class VirtReg { class VirtReg {
public: public:
ASMJIT_NONCOPYABLE(VirtReg) ASMJIT_NONCOPYABLE(VirtReg)
@@ -45,6 +56,8 @@ public:
//! True if this virtual register has assigned stack offset (can be only valid after register allocation pass). //! True if this virtual register has assigned stack offset (can be only valid after register allocation pass).
uint8_t _hasStackSlot : 1; uint8_t _hasStackSlot : 1;
uint8_t _reservedBits : 5; uint8_t _reservedBits : 5;
//! Home register hint for the register allocator (initially unassigned).
uint8_t _homeIdHint = BaseReg::kIdBad;
//! Stack offset assigned by the register allocator relative to stack pointer (can be negative as well). //! Stack offset assigned by the register allocator relative to stack pointer (can be negative as well).
int32_t _stackOffset = 0; int32_t _stackOffset = 0;
@@ -145,6 +158,15 @@ public:
_stackOffset = stackOffset; _stackOffset = stackOffset;
} }
//! Tests whether this virtual register has assigned a physical register as a hint to the register allocator.
ASMJIT_INLINE_NODEBUG bool hasHomeIdHint() const noexcept { return _homeIdHint != BaseReg::kIdBad; }
//! Returns a physical register hint, which will be used by the register allocator.
ASMJIT_INLINE_NODEBUG uint32_t homeIdHint() const noexcept { return _homeIdHint; }
//! Assigns a physical register hint, which will be used by the register allocator.
ASMJIT_INLINE_NODEBUG void setHomeIdHint(uint32_t homeId) noexcept { _homeIdHint = uint8_t(homeId); }
//! Resets a physical register hint.
ASMJIT_INLINE_NODEBUG void resetHomeIdHint() noexcept { _homeIdHint = BaseReg::kIdBad; }
//! Returns a stack offset associated with a virtual register or explicit stack allocation. //! Returns a stack offset associated with a virtual register or explicit stack allocation.
//! //!
//! \note Always verify that the stack offset has been assigned by calling \ref hasStackSlot(). The return //! \note Always verify that the stack offset has been assigned by calling \ref hasStackSlot(). The return

View File

@@ -488,7 +488,7 @@ static ASMJIT_FAVOR_SIZE void detectX86Cpu(CpuInfo& cpu) noexcept {
// The highest EAX that we understand. // The highest EAX that we understand.
constexpr uint32_t kHighestProcessedEAX = 0x8000001Fu; constexpr uint32_t kHighestProcessedEAX = 0x8000001Fu;
// Several CPUID calls are required to get the whole branc string. It's easier // Several CPUID calls are required to get the whole brand string. It's easier
// to copy one DWORD at a time instead of copying the string a byte by byte. // to copy one DWORD at a time instead of copying the string a byte by byte.
uint32_t* brand = cpu._brand.u32; uint32_t* brand = cpu._brand.u32;
do { do {

View File

@@ -180,7 +180,7 @@ public:
#endif // !ASMJIT_NO_DEPRECATED #endif // !ASMJIT_NO_DEPRECATED
//! \} //! \}
}; };
//! X86 specific features data. //! X86 specific features data.
struct X86 : public Data { struct X86 : public Data {

View File

@@ -1120,7 +1120,8 @@ public:
: _workId(workId), : _workId(workId),
_virtId(vReg->id()), _virtId(vReg->id()),
_virtReg(vReg), _virtReg(vReg),
_signature(vReg->signature()) {} _signature(vReg->signature()),
_hintRegId(uint8_t(vReg->homeIdHint())) {}
//! \} //! \}