diff --git a/Andromeda-CS2-Base.sln b/Andromeda-CS2-Base.sln
index 077df24..d3ec9bf 100644
--- a/Andromeda-CS2-Base.sln
+++ b/Andromeda-CS2-Base.sln
@@ -1,10 +1,12 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
-VisualStudioVersion = 17.14.36603.0 d17.14
+VisualStudioVersion = 17.14.36603.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Andromeda-CS2-Base", "Andromeda-CS2-Base\Andromeda-CS2-Base.vcxproj", "{0011461C-0E5F-401C-AC58-23719D1EF845}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Andromeda-Injector", "Andromeda-Injector\Andromeda-Injector.vcxproj", "{CCCB11FE-9B54-44BF-8C77-29DBB3B83B74}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -21,6 +23,14 @@ Global
{0011461C-0E5F-401C-AC58-23719D1EF845}.Release|x64.Build.0 = Release|x64
{0011461C-0E5F-401C-AC58-23719D1EF845}.Release|x86.ActiveCfg = Release|Win32
{0011461C-0E5F-401C-AC58-23719D1EF845}.Release|x86.Build.0 = Release|Win32
+ {CCCB11FE-9B54-44BF-8C77-29DBB3B83B74}.Debug|x64.ActiveCfg = Release|x64
+ {CCCB11FE-9B54-44BF-8C77-29DBB3B83B74}.Debug|x64.Build.0 = Release|x64
+ {CCCB11FE-9B54-44BF-8C77-29DBB3B83B74}.Debug|x86.ActiveCfg = Release|x64
+ {CCCB11FE-9B54-44BF-8C77-29DBB3B83B74}.Debug|x86.Build.0 = Release|x64
+ {CCCB11FE-9B54-44BF-8C77-29DBB3B83B74}.Release|x64.ActiveCfg = Release|x64
+ {CCCB11FE-9B54-44BF-8C77-29DBB3B83B74}.Release|x64.Build.0 = Release|x64
+ {CCCB11FE-9B54-44BF-8C77-29DBB3B83B74}.Release|x86.ActiveCfg = Release|x64
+ {CCCB11FE-9B54-44BF-8C77-29DBB3B83B74}.Release|x86.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/Common/Include/Config.hpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/Common/Include/Config.hpp
index d67eefc..6525f5b 100644
--- a/Andromeda-CS2-Base/Andromeda-CS2-Base/Common/Include/Config.hpp
+++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/Common/Include/Config.hpp
@@ -14,7 +14,7 @@
#ifdef RELEASE_BUILD
#define ENABLE_CONSOLE_DEBUG 1
-#define ENABLE_MANUAL_MAP 0
+#define ENABLE_MANUAL_MAP 1
#define ENABLE_CPP_EH_EXCEPTION 0
#define LOG_SDK 1
diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/DllLauncher.hpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/DllLauncher.hpp
index 03baa2c..5e9e054 100644
--- a/Andromeda-CS2-Base/Andromeda-CS2-Base/DllLauncher.hpp
+++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/DllLauncher.hpp
@@ -6,7 +6,6 @@
struct ManualMapParam_t
{
uint64_t ArgsSize = 0;
- DWORD64 DllLoaderCode = 0;
char DllPath[MAX_PATH] = { 0 };
};
diff --git a/Andromeda-Injector/Andromeda-Injector.vcxproj b/Andromeda-Injector/Andromeda-Injector.vcxproj
new file mode 100644
index 0000000..6554476
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector.vcxproj
@@ -0,0 +1,73 @@
+
+
+
+
+ Release
+ x64
+
+
+
+ 17.0
+ Win32Proj
+ {cccb11fe-9b54-44bf-8c77-29dbb3b83b74}
+ AndromedaInjector
+ 10.0
+
+
+
+ Application
+ false
+ v143
+ true
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+ $(MSBuildProjectDirectory)\Andromeda-Injector\Common\Include\;$(IncludePath)
+ Andromeda-CS2-Base
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ stdcpplatest
+ stdclatest
+ MultiThreaded
+ true
+
+
+ Console
+ true
+ RequireAdministrator
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Andromeda-Injector/Andromeda-Injector.vcxproj.filters b/Andromeda-Injector/Andromeda-Injector.vcxproj.filters
new file mode 100644
index 0000000..c3aadea
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector.vcxproj.filters
@@ -0,0 +1,37 @@
+
+
+
+
+ {9c07d84f-e39a-4705-8217-1dbb5ae8bdb2}
+
+
+ {59b7c3b3-cff8-4adf-854f-183274448de6}
+
+
+
+
+ Andromeda-Injector
+
+
+ Andromeda-Injector
+
+
+
+
+ Andromeda-Injector
+
+
+ Andromeda-Injector
+
+
+ Andromeda-Injector\Common
+
+
+ Andromeda-Injector\Common
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Andromeda-Injector/Andromeda-Injector/CInjector.cpp b/Andromeda-Injector/Andromeda-Injector/CInjector.cpp
new file mode 100644
index 0000000..88f600b
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/CInjector.cpp
@@ -0,0 +1,188 @@
+#include "CInjector.h"
+
+#include
+
+auto CInjector::Init() -> bool
+{
+ GetModuleFileNameA( 0 , szDllFilePath , MAX_PATH );
+ GetCurrentDirectoryA( MAX_PATH , szCurrentDir );
+
+ int len = lstrlenA( szDllFilePath );
+
+ szDllFilePath[len - 1] = 'l';
+ szDllFilePath[len - 2] = 'l';
+ szDllFilePath[len - 3] = 'd';
+
+ if ( GetPrivileges() && FileExist( szDllFilePath ) )
+ return true;
+
+ return false;
+}
+
+auto CInjector::GetPrivileges() -> bool
+{
+ HANDLE hToken = NULL;
+ LUID luid;
+ TOKEN_PRIVILEGES tp;
+
+ OpenProcessToken( GetCurrentProcess() , TOKEN_ALL_ACCESS , &hToken );
+
+ LookupPrivilegeValue( NULL , SE_DEBUG_NAME , &luid );
+
+ tp.PrivilegeCount = 1;
+ tp.Privileges[0].Luid = luid;
+ tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+ if ( AdjustTokenPrivileges( hToken , FALSE , &tp , sizeof( TOKEN_PRIVILEGES ) , NULL , NULL ) )
+ {
+ CloseHandle( hToken );
+ return true;
+ }
+
+ return false;
+}
+
+auto CInjector::GetProcessIdByName( const char* szProcName )->DWORD
+{
+ HANDLE hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS , 0 );
+ DWORD dwGetProcessID = 0;
+
+ if ( hSnapshot != INVALID_HANDLE_VALUE )
+ {
+ PROCESSENTRY32 ProcEntry32 = { 0 };
+ ProcEntry32.dwSize = sizeof( MODULEENTRY32 );
+
+ if ( Process32First( hSnapshot , &ProcEntry32 ) )
+ {
+ do
+ {
+ if ( _stricmp( ProcEntry32.szExeFile , szProcName ) == 0 )
+ {
+ dwGetProcessID = (DWORD)ProcEntry32.th32ProcessID;
+ break;
+ }
+ } while ( Process32Next( hSnapshot , &ProcEntry32 ) );
+ }
+
+ CloseHandle( hSnapshot );
+ }
+
+ return dwGetProcessID;
+}
+
+auto CInjector::InjectManualMap( const char* szProcessName ) -> bool
+{
+ bool Result = false;
+ DWORD PID = 0;
+
+ DEV_LOG( "[info] Wait for start %s\n" , szProcessName );
+
+ while ( !PID )
+ {
+ PID = GetProcessIdByName( szProcessName );
+ Sleep( 100 );
+ }
+
+ m_hProcess = OpenProcess( PROCESS_ALL_ACCESS , FALSE , PID );
+
+ if ( !m_hProcess )
+ {
+ DEV_LOG( "[-] inject code: #1\n" );
+ return false;
+ }
+
+ // Read Dll File
+ {
+ auto hFile = CreateFileA( szDllFilePath , GENERIC_READ , 0 , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL );
+
+ if ( !hFile )
+ {
+ DEV_LOG( "[-] inject code: #2\n" );
+ CloseHandle( m_hProcess );
+ return false;
+ }
+
+ auto dwLength = GetFileSize( hFile , NULL );
+
+ if ( dwLength == INVALID_FILE_SIZE || dwLength == 0 )
+ {
+ DEV_LOG( "[-] inject code: #3\n" );
+
+ CloseHandle( hFile );
+ CloseHandle( m_hProcess );
+
+ return false;
+ }
+
+ m_pDllFile = (PBYTE)HeapAlloc( GetProcessHeap() , 0 , dwLength );
+
+ if ( !m_pDllFile )
+ {
+ DEV_LOG( "[-] inject code: #4\n" );
+
+ CloseHandle( hFile );
+ CloseHandle( m_hProcess );
+
+ return false;
+ }
+
+ if ( ReadFile( hFile , m_pDllFile , dwLength , &m_DllFileSize , NULL ) == FALSE )
+ {
+ DEV_LOG( "[-] inject code: #5\n" );
+
+ CloseHandle( hFile );
+ CloseHandle( m_hProcess );
+
+ return false;
+ }
+
+ if ( dwLength != m_DllFileSize )
+ {
+ DEV_LOG( "[-] inject code: #6\n" );
+
+ CloseHandle( hFile );
+ CloseHandle( m_hProcess );
+
+ return false;
+ }
+
+ CloseHandle( hFile );
+ }
+
+ DllLoaderData_t LoaderData = { 0 };
+
+ // Loader Data
+ memcpy( LoaderData.DllPath , szCurrentDir , MAX_PATH );
+
+ // Inject To Process
+ {
+ blackbone::Process CS2Process;
+ CS2Process.Attach( m_hProcess );
+
+ blackbone::CustomArgs_t Args;
+
+ Args.push_back( &LoaderData , sizeof( DllLoaderData_t ) );
+
+ auto pImage = CS2Process.mmap().MapImage( m_DllFileSize , m_pDllFile , false , blackbone::WipeHeader , nullptr , nullptr , &Args );
+
+ if ( pImage )
+ Result = true;
+ else
+ DEV_LOG( "[-] inject: %ws\n" , blackbone::Utils::GetErrorDescription( pImage.status ).c_str() );
+ }
+
+ // Free And Close
+ {
+ if ( m_pDllFile )
+ HeapFree( GetProcessHeap() , 0 , m_pDllFile );
+
+ CloseHandle( m_hProcess );
+ }
+
+ return Result;
+}
+
+auto GetInjector() -> CInjector*
+{
+ return CInjector::Instance();
+}
diff --git a/Andromeda-Injector/Andromeda-Injector/CInjector.h b/Andromeda-Injector/Andromeda-Injector/CInjector.h
new file mode 100644
index 0000000..90a17db
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/CInjector.h
@@ -0,0 +1,41 @@
+#pragma once
+
+#include "Main.h"
+
+struct DllLoaderData_t
+{
+ char DllPath[MAX_PATH] = { 0 };
+};
+
+class CInjector : Singleton
+{
+public:
+ auto Init() -> bool;
+
+public:
+ auto InjectManualMap( const char* szProcessName ) -> bool;
+
+private:
+ auto GetPrivileges() -> bool;
+ auto GetProcessIdByName( const char* szName ) -> DWORD;
+
+private:
+ bool __forceinline FileExist( const char* szFileName )
+ {
+ return GetFileAttributesA( szFileName ) != INVALID_FILE_ATTRIBUTES;
+ }
+
+public:
+ char szCurrentDir[MAX_PATH] = { 0 };
+ char szDllFilePath[MAX_PATH] = { 0 };
+
+private:
+ HANDLE m_hProcess;
+ PBYTE m_pDllFile = nullptr;
+ DWORD m_DllFileSize = 0;
+
+private:
+ friend auto GetInjector() -> CInjector*;
+};
+
+auto GetInjector() -> CInjector*;
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Common.h b/Andromeda-Injector/Andromeda-Injector/Common/Common.h
new file mode 100644
index 0000000..a99bd09
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Common.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "Singleton.h"
+
+#pragma warning( disable : 26812 )
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/ApiBegin.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/ApiBegin.h
new file mode 100644
index 0000000..b025e2e
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/ApiBegin.h
@@ -0,0 +1,49 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+#if !defined(_ASMJIT_BUILD_H)
+#include "build.h"
+#endif // !_ASMJIT_BUILD_H
+
+// ============================================================================
+// [MSVC]
+// ============================================================================
+
+#if defined(_MSC_VER)
+// Disable some warnings we know about
+# pragma warning(push)
+# pragma warning(disable: 4127) // conditional expression is constant
+# pragma warning(disable: 4201) // nameless struct/union
+# pragma warning(disable: 4244) // '+=' : conversion from 'int' to 'x', possible
+ // loss of data
+# pragma warning(disable: 4251) // struct needs to have dll-interface to be used
+ // by clients of struct ...
+# pragma warning(disable: 4275) // non dll-interface struct ... used as base for
+ // dll-interface struct
+# pragma warning(disable: 4355) // this used in base member initializer list
+# pragma warning(disable: 4480) // specifying underlying type for enum
+# pragma warning(disable: 4800) // forcing value to bool 'true' or 'false'
+
+// Rename symbols.
+# if !defined(vsnprintf)
+# define ASMJIT_DEFINED_VSNPRINTF
+# define vsnprintf _vsnprintf
+# endif // !vsnprintf
+# if !defined(snprintf)
+# define ASMJIT_DEFINED_SNPRINTF
+# define snprintf _snprintf
+# endif // !snprintf
+#endif // _MSC_VER
+
+// ============================================================================
+// [GNUC]
+// ============================================================================
+
+#if defined(__GNUC__) && !defined(__clang__)
+# if __GNUC__ >= 4 && !defined(__MINGW32__)
+# pragma GCC visibility push(hidden)
+# endif // __GNUC__ >= 4
+#endif // __GNUC__
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/ApiEnd.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/ApiEnd.h
new file mode 100644
index 0000000..4ec7834
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/ApiEnd.h
@@ -0,0 +1,33 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// ============================================================================
+// [MSVC]
+// ============================================================================
+
+#if defined(_MSC_VER)
+// Pop disabled warnings by ApiBegin.h
+# pragma warning(pop)
+// Rename symbols back.
+# if defined(ASMJIT_DEFINED_VSNPRINTF)
+# undef ASMJIT_DEFINED_VSNPRINTF
+# undef vsnprintf
+# endif // ASMJIT_DEFINED_VSNPRINTF
+# if defined(ASMJIT_DEFINED_SNPRINTF)
+# undef ASMJIT_DEFINED_SNPRINTF
+# undef snprintf
+# endif // ASMJIT_DEFINED_SNPRINTF
+#endif // _MSC_VER
+
+// ============================================================================
+// [GNUC]
+// ============================================================================
+
+#if defined(__GNUC__) && !defined(__clang__)
+# if __GNUC__ >= 4 && !defined(__MINGW32__)
+# pragma GCC visibility pop
+# endif // __GNUC__ >= 4
+#endif // __GNUC__
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/AsmJit.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/AsmJit.h
new file mode 100644
index 0000000..9b143d4
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/AsmJit.h
@@ -0,0 +1,379 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Guard]
+#ifndef _ASMJIT_ASMJIT_H
+#define _ASMJIT_ASMJIT_H
+
+// ============================================================================
+// [asmjit_mainpage]
+// ============================================================================
+
+//! @mainpage
+//!
+//! AsmJit - Complete x86/x64 JIT and Remote Assembler for C++.
+//!
+//! AsmJit is a complete JIT and remote assembler for C++ language. It can
+//! generate native code for x86 and x64 architectures having support for
+//! a full instruction set, from legacy MMX to the newest AVX2. It has a
+//! type-safe API that allows C++ compiler to do a semantic checks at
+//! compile-time even before the assembled code is generated or run.
+//!
+//! AsmJit is not a virtual machine (VM). It doesn't have functionality to
+//! implement VM out of the box; however, it can be be used as a JIT backend
+//! for your own VM. The usage of AsmJit is not limited at all; it's suitable
+//! for multimedia, VM backends or remote code generation.
+//!
+//! @section AsmJit_Concepts Code Generation Concepts
+//!
+//! AsmJit has two completely different code generation concepts. The difference
+//! is in how the code is generated. The first concept, also referred as the low
+//! level concept, is called 'Assembler' and it's the same as writing RAW
+//! assembly by using physical registers directly. In this case AsmJit does only
+//! instruction encoding, verification and relocation.
+//!
+//! The second concept, also referred as the high level concept, is called
+//! 'Compiler'. Compiler lets you use virtually unlimited number of registers
+//! (called variables) significantly simplifying the code generation process.
+//! Compiler allocates these virtual registers to physical registers after the
+//! code generation is done. This requires some extra effort - Compiler has to
+//! generate information for each node (instruction, function declaration,
+//! function call) in the code, perform a variable liveness analysis and
+//! translate the code having variables into code having only registers.
+//!
+//! In addition, Compiler understands functions and function calling conventions.
+//! It has been designed in a way that the code generated is always a function
+//! having prototype like in a programming language. By having a function
+//! prototype the Compiler is able to insert prolog and epilog to a function
+//! being generated and it is able to call a function inside a generated one.
+//!
+//! There is no conclusion on which concept is better. Assembler brings full
+//! control on how the code is generated, while Compiler makes the generation
+//! more portable.
+//!
+//! @section AsmJit_Main_CodeGeneration Code Generation
+//!
+//! - \ref asmjit_base_general "Assembler core" - Operands, intrinsics and low-level assembler.
+//! - \ref asmjit_compiler "Compiler" - High level code generation.
+//! - \ref asmjit_cpuinfo "Cpu Information" - Get information about host processor.
+//! - \ref asmjit_logging "Logging" - Logging and error handling.
+//! - \ref AsmJit_MemoryManagement "Memory Management" - Virtual memory management.
+//!
+//! @section AsmJit_Main_HomePage AsmJit Homepage
+//!
+//! - https://github.com/kobalicek/asmjit
+
+// ============================================================================
+// [asmjit_base]
+// ============================================================================
+
+//! \defgroup asmjit_base AsmJit
+//!
+//! \brief AsmJit.
+
+// ============================================================================
+// [asmjit_base_general]
+// ============================================================================
+
+//! \defgroup asmjit_base_general AsmJit General API
+//! \ingroup asmjit_base
+//!
+//! \brief AsmJit general API.
+//!
+//! Contains all `asmjit` classes and helper functions that are architecture
+//! independent or abstract. Abstract classes are implemented by the backend,
+//! for example `Assembler` is implemented by `X86Assembler`.
+//!
+//! - See `Assembler` for low level code generation documentation.
+//! - See `Compiler` for high level code generation documentation.
+//! - See `Operand` for operand's overview.
+//!
+//! Logging and Error Handling
+//! --------------------------
+//!
+//! AsmJit contains robust interface that can be used to log the generated code
+//! and to handle possible errors. Base logging interface is defined in `Logger`
+//! class that is abstract and can be overridden. AsmJit contains two loggers
+//! that can be used out of the box - `FileLogger` that logs into a pure C
+//! `FILE*` stream and `StringLogger` that just concatenates all log messages
+//! by using a `StringBuilder` class.
+//!
+//! The following snippet shows how to setup a logger that logs to `stderr`:
+//!
+//! ~~~
+//! // `FileLogger` instance.
+//! FileLogger logger(stderr);
+//!
+//! // `Compiler` or any other `CodeGen` interface.
+//! host::Compiler c;
+//!
+//! // use `setLogger` to replace the `CodeGen` logger.
+//! c.setLogger(&logger);
+//! ~~~
+//!
+//! \sa \ref Logger, \ref FileLogger, \ref StringLogger.
+
+// ============================================================================
+// [asmjit_base_compiler]
+// ============================================================================
+
+//! \defgroup asmjit_base_compiler AsmJit Compiler
+//! \ingroup asmjit_base
+//!
+//! \brief AsmJit code-tree used by Compiler.
+//!
+//! AsmJit intermediate code-tree is a double-linked list that is made of nodes
+//! that represent assembler instructions, directives, labels and high-level
+//! constructs compiler is using to represent functions and function calls. The
+//! node list can only be used together with \ref Compiler.
+//!
+//! TODO
+
+// ============================================================================
+// [asmjit_base_util]
+// ============================================================================
+
+//! \defgroup asmjit_base_util AsmJit Utilities
+//! \ingroup asmjit_base
+//!
+//! \brief AsmJit utility classes.
+//!
+//! AsmJit contains numerous utility classes that are needed by the library
+//! itself. The most useful ones have been made public and are now exported.
+//!
+//! POD Containers
+//! --------------
+//!
+//! POD containers are used by AsmJit to manage its own data structures. The
+//! following classes can be used by AsmJit consumers:
+//!
+//! - \ref PodVector - Simple growing array-like container for POD data.
+//! - \ref StringBuilder - Simple string builder that can append string
+//! and integers.
+//!
+//! Zone Memory Allocator
+//! ---------------------
+//!
+//! Zone memory allocator is an incremental memory allocator that can be used
+//! to allocate data of short life-time. It has much better performance
+//! characteristics than all other allocators, because the only thing it can do
+//! is to increment a pointer and return its previous address. See \ref Zone
+//! for more details.
+//!
+//! CPU Ticks
+//! ---------
+//!
+//! CPU Ticks is a simple helper that can be used to do basic benchmarks. See
+//! \ref CpuTicks class for more details.
+//!
+//! Integer Utilities
+//! -----------------
+//!
+//! Integer utilities are all implemented by a static class \ref IntUtil.
+//! There are utilities for bit manipulation and bit counting, utilities to get
+//! an integer minimum / maximum and various other helpers required to perform
+//! alignment checks and binary casting from float to integer and vica versa.
+//!
+//! Vector Utilities
+//! ----------------
+//!
+//! SIMD code generation often requires to embed constants after each function
+//! or a block of functions generated. AsmJit contains classes `Vec64`,
+//! `Vec128` and `Vec256` that can be used to prepare data useful when
+//! generating SIMD code.
+//!
+//! X86/X64 code generator contains member functions `dmm`, `dxmm` and `dymm`
+//! which can be used to embed 64-bit, 128-bit and 256-bit data structures into
+//! machine code (both assembler and compiler are supported).
+//!
+//! \note Compiler contains a constant pool, which should be used instead of
+//! embedding constants manually after the function body.
+
+// ============================================================================
+// [asmjit_x86]
+// ============================================================================
+
+//! \defgroup asmjit_x86 X86/X64
+//!
+//! \brief X86/X64 module
+
+// ============================================================================
+// [asmjit_x86_general]
+// ============================================================================
+
+//! \defgroup asmjit_x86_general X86/X64 General API
+//! \ingroup asmjit_x86
+//!
+//! \brief X86/X64 general API.
+//!
+//! X86/X64 Registers
+//! -----------------
+//!
+//! There are static objects that represents X86 and X64 registers. They can
+//! be used directly (like `eax`, `mm`, `xmm`, ...) or created through
+//! these functions:
+//!
+//! - `asmjit::gpb_lo()` - Get Gpb-lo register.
+//! - `asmjit::gpb_hi()` - Get Gpb-hi register.
+//! - `asmjit::gpw()` - Get Gpw register.
+//! - `asmjit::gpd()` - Get Gpd register.
+//! - `asmjit::gpq()` - Get Gpq Gp register.
+//! - `asmjit::gpz()` - Get Gpd/Gpq register.
+//! - `asmjit::fp()` - Get Fp register.
+//! - `asmjit::mm()` - Get Mm register.
+//! - `asmjit::xmm()` - Get Xmm register.
+//! - `asmjit::ymm()` - Get Ymm register.
+//!
+//! X86/X64 Addressing
+//! ------------------
+//!
+//! X86 and x64 architectures contains several addressing modes and most ones
+//! are possible with AsmJit library. Memory represents are represented by
+//! `BaseMem` class. These functions are used to make operands that represents
+//! memory addresses:
+//!
+//! - `asmjit::ptr()` - Address size not specified.
+//! - `asmjit::byte_ptr()` - 1 byte.
+//! - `asmjit::word_ptr()` - 2 bytes (Gpw size).
+//! - `asmjit::dword_ptr()` - 4 bytes (Gpd size).
+//! - `asmjit::qword_ptr()` - 8 bytes (Gpq/Mm size).
+//! - `asmjit::tword_ptr()` - 10 bytes (FPU).
+//! - `asmjit::oword_ptr()` - 16 bytes (Xmm size).
+//! - `asmjit::yword_ptr()` - 32 bytes (Ymm size).
+//! - `asmjit::zword_ptr()` - 64 bytes (Zmm size).
+//!
+//! Most useful function to make pointer should be `asmjit::ptr()`. It creates
+//! pointer to the target with unspecified size. Unspecified size works in all
+//! intrinsics where are used registers (this means that size is specified by
+//! register operand or by instruction itself). For example `asmjit::ptr()`
+//! can't be used with `Assembler::inc()` instruction. In this case size must
+//! be specified and it's also reason to make difference between pointer sizes.
+//!
+//! Supported are simple address forms `[base + displacement]` and complex
+//! address forms `[base + index * scale + displacement]`.
+//!
+//! X86/X64 Immediates
+//! ------------------
+//!
+//! Immediate values are constants thats passed directly after instruction
+//! opcode. To create such value use `imm()` or `imm_u()` methods to create
+//! signed or unsigned immediate value.
+//!
+//! X86/X64 CPU Information
+//! -----------------------
+//!
+//! The CPUID instruction can be used to get an exhaustive information about
+//! the host X86/X64 processor. AsmJit contains utilities that can get the most
+//! important information related to the features supported by the CPU and the
+//! host operating system, in addition to host processor name and number of
+//! cores. Class `X86CpuInfo` extends `CpuInfo` and provides functionality
+//! specific to X86 and X64.
+//!
+//! By default AsmJit queries the CPU information after the library is loaded
+//! and the queried information is reused by all instances of `JitRuntime`.
+//! The global instance of `X86CpuInfo` can't be changed, because it will affect
+//! the code generation of all `Runtime`s. If there is a need to have a
+//! specific CPU information which contains modified features or processor
+//! vendor it's possible by creating a new instance of `X86CpuInfo` and setting
+//! up its members. `X86CpuUtil::detect` can be used to detect CPU features into
+//! an existing `X86CpuInfo` instance - it may become handly if only one property
+//! has to be turned on/off.
+//!
+//! If the high-level interface `X86CpuInfo` offers is not enough there is also
+//! `X86CpuUtil::callCpuId` helper that can be used to call CPUID instruction
+//! with a given parameters and to consume the output.
+//!
+//! Cpu detection is important when generating a JIT code that may or may not
+//! use certain CPU features. For example there used to be a SSE/SSE2 detection
+//! in the past and today there is often AVX/AVX2 detection.
+//!
+//! The example below shows how to detect SSE2:
+//!
+//! ~~~
+//! using namespace asmjit;
+//!
+//! // Get `X86CpuInfo` global instance.
+//! const X86CpuInfo* cpuInfo = X86CpuInfo::getHost();
+//!
+//! if (cpuInfo->hasFeature(kX86CpuFeatureSSE2)) {
+//! // Processor has SSE2.
+//! }
+//! else if (cpuInfo->hasFeature(kX86CpuFeatureMMX)) {
+//! // Processor doesn't have SSE2, but has MMX.
+//! }
+//! else {
+//! // Processor is archaic; it's a wonder AsmJit works here!
+//! }
+//! ~~~
+//!
+//! The next example shows how to call `CPUID` directly:
+//!
+//! ~~~
+//! using namespace asmjit;
+//!
+//! // Call cpuid, first two arguments are passed in Eax/Ecx.
+//! X86CpuId out;
+//! X86CpuUtil::callCpuId(0, 0, &out);
+//!
+//! // If Eax argument is 0, Ebx, Ecx and Edx registers are filled with a cpu vendor.
+//! char cpuVendor[13];
+//! ::memcpy(cpuVendor, &out.ebx, 4);
+//! ::memcpy(cpuVendor + 4, &out.edx, 4);
+//! ::memcpy(cpuVendor + 8, &out.ecx, 4);
+//! vendor[12] = '\0';
+//!
+//! // Print a CPU vendor retrieved from CPUID.
+//! ::printf("%s", cpuVendor);
+//! ~~~
+
+// ============================================================================
+// [asmjit_x86_compiler]
+// ============================================================================
+
+//! \defgroup asmjit_x86_compiler X86/X64 Code-Tree
+//! \ingroup asmjit_x86
+//!
+//! \brief X86/X64 code-tree and helpers.
+
+// ============================================================================
+// [asmjit_x86_inst]
+// ============================================================================
+
+//! \defgroup asmjit_x86_inst X86/X64 Instructions
+//! \ingroup asmjit_x86
+//!
+//! \brief X86/X64 low-level instruction definitions.
+
+// ============================================================================
+// [asmjit_x86_util]
+// ============================================================================
+
+//! \defgroup asmjit_x86_util X86/X64 Utilities
+//! \ingroup asmjit_x86
+//!
+//! \brief X86/X64 utility classes.
+
+// ============================================================================
+// [asmjit_contrib]
+// ============================================================================
+
+//! \defgroup asmjit_contrib Contributions
+//!
+//! \brief Contributions.
+
+// [Dependencies - Base]
+#include "base.h"
+
+// [Dependencies - X86/X64]
+#if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64)
+#include "x86.h"
+#endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64
+
+// [Dependencies - Host]
+#include "host.h"
+
+// [Guard]
+#endif // _ASMJIT_ASMJIT_H
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/Build.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/Build.h
new file mode 100644
index 0000000..b97a456
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/Build.h
@@ -0,0 +1,385 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Guard]
+#ifndef _ASMJIT_BUILD_H
+#define _ASMJIT_BUILD_H
+
+// [Include]
+#if defined(ASMJIT_CONFIG_FILE)
+# include ASMJIT_CONFIG_FILE
+#else
+# include "./config.h"
+#endif // ASMJIT_CONFIG_FILE
+
+// Turn off deprecation warnings when compiling AsmJit.
+#if defined(ASMJIT_EXPORTS) && defined(_MSC_VER)
+# if !defined(_CRT_SECURE_NO_DEPRECATE)
+# define _CRT_SECURE_NO_DEPRECATE
+# endif // !_CRT_SECURE_NO_DEPRECATE
+# if !defined(_CRT_SECURE_NO_WARNINGS)
+# define _CRT_SECURE_NO_WARNINGS
+# endif // !_CRT_SECURE_NO_WARNINGS
+#endif // ASMJIT_EXPORTS
+
+// [Dependencies - C]
+#include
+#include
+#include
+
+// [Dependencies - C++]
+#include
+
+// ============================================================================
+// [asmjit::build - Sanity]
+// ============================================================================
+
+#if defined(ASMJIT_DISABLE_NAMES) && !defined(ASMJIT_DISABLE_LOGGER)
+# error "ASMJIT_DISABLE_NAMES requires ASMJIT_DISABLE_LOGGER to be defined."
+#endif // ASMJIT_DISABLE_NAMES && !ASMJIT_DISABLE_LOGGER
+
+// ============================================================================
+// [asmjit::build - OS]
+// ============================================================================
+
+#if defined(_WINDOWS) || defined(__WINDOWS__) || defined(_WIN32) || defined(_WIN64)
+# define ASMJIT_OS_WINDOWS
+#elif defined(__linux) || defined(__linux__)
+# define ASMJIT_OS_POSIX
+# define ASMJIT_OS_LINUX
+#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+# define ASMJIT_OS_POSIX
+# define ASMJIT_OS_BSD
+#elif defined(__APPLE__)
+# define ASMJIT_OS_POSIX
+# define ASMJIT_OS_MAC
+#else
+# warning "AsmJit - Unable to detect host operating system, using ASMJIT_OS_POSIX"
+# define ASMJIT_OS_POSIX
+#endif
+
+// ============================================================================
+// [asmjit::build - Arch]
+// ============================================================================
+
+#if defined(_M_X64 ) || \
+ defined(_M_AMD64 ) || \
+ defined(_WIN64 ) || \
+ defined(__amd64__ ) || \
+ defined(__LP64 ) || \
+ defined(__x86_64__)
+# define ASMJIT_HOST_X64
+# define ASMJIT_HOST_LE
+# define ASMJIT_HOST_UNALIGNED_16
+# define ASMJIT_HOST_UNALIGNED_32
+# define ASMJIT_HOST_UNALIGNED_64
+#elif \
+ defined(_M_IX86 ) || \
+ defined(__INTEL__) || \
+ defined(__i386__ )
+# define ASMJIT_HOST_X86
+# define ASMJIT_HOST_LE
+# define ASMJIT_HOST_UNALIGNED_16
+# define ASMJIT_HOST_UNALIGNED_32
+# define ASMJIT_HOST_UNALIGNED_64
+#elif \
+ defined(_ARM ) || \
+ defined(_M_ARM_FP ) || \
+ defined(__ARM_NEON__ ) || \
+ defined(__arm ) || \
+ defined(__arm__ ) || \
+ defined(__TARGET_ARCH_ARM ) || \
+ defined(__TARGET_ARCH_THUMB) || \
+ defined(__thumb__ )
+# define ASMJIT_HOST_ARM
+# define ASMJIT_HOST_LE
+#else
+# warning "AsmJit - Unable to detect host architecture"
+#endif
+
+// ============================================================================
+// [asmjit::build - Build]
+// ============================================================================
+
+// Build host architecture if no architecture is selected.
+#if !defined(ASMJIT_BUILD_HOST) && \
+ !defined(ASMJIT_BUILD_X86) && \
+ !defined(ASMJIT_BUILD_X64)
+# define ASMJIT_BUILD_HOST
+#endif
+
+// Autodetect host architecture if enabled.
+#if defined(ASMJIT_BUILD_HOST)
+# if defined(ASMJIT_HOST_X86) && !defined(ASMJIT_BUILD_X86)
+# define ASMJIT_BUILD_X86
+# endif // ASMJIT_HOST_X86 && !ASMJIT_BUILD_X86
+# if defined(ASMJIT_HOST_X64) && !defined(ASMJIT_BUILD_X64)
+# define ASMJIT_BUILD_X64
+# endif // ASMJIT_HOST_X64 && !ASMJIT_BUILD_X64
+#endif // ASMJIT_BUILD_HOST
+
+// ============================================================================
+// [asmjit::build - Decorators]
+// ============================================================================
+
+#if defined(ASMJIT_EMBED) && !defined(ASMJIT_STATIC)
+# define ASMJIT_STATIC
+#endif // ASMJIT_EMBED && !ASMJIT_STATIC
+
+#if defined(ASMJIT_STATIC)
+# define ASMJIT_API
+#elif defined(ASMJIT_OS_WINDOWS)
+# if (defined(__GNUC__) || defined(__clang__)) && !defined(__MINGW32__)
+# if defined(ASMJIT_EXPORTS)
+# define ASMJIT_API __attribute__((dllexport))
+# else
+# define ASMJIT_API __attribute__((dllimport))
+# endif // ASMJIT_EXPORTS
+# else
+# if defined(ASMJIT_EXPORTS)
+# define ASMJIT_API __declspec(dllexport)
+# else
+# define ASMJIT_API __declspec(dllimport)
+# endif
+# endif
+#elif defined(__GNUC__) && (__GNUC__ >= 4)
+# define ASMJIT_API __attribute__((visibility("default")))
+#endif
+
+#if !defined(ASMJIT_API)
+# define ASMJIT_API
+#endif // ASMJIT_API
+
+// This is basically a workaround. When using MSVC and marking class as DLL
+// export everything is exported, which is unwanted since there are many
+// inlines which mimic instructions. MSVC automatically exports typeinfo and
+// vtable if at least one symbol of that class is exported. However, GCC has
+// some strange behavior that even if one or more symbol is exported it doesn't
+// export `typeinfo` unless the class itself is marked as "visibility(default)".
+#if !defined(ASMJIT_OS_WINDOWS) && (defined(__GNUC__) || defined (__clang__))
+# define ASMJIT_VCLASS ASMJIT_API
+#else
+# define ASMJIT_VCLASS
+#endif
+
+#if !defined(ASMJIT_VAR)
+# define ASMJIT_VAR extern ASMJIT_API
+#endif // !ASMJIT_VAR
+
+#if defined(_MSC_VER)
+# define ASMJIT_INLINE __forceinline
+#elif defined(__clang__)
+# define ASMJIT_INLINE inline __attribute__((always_inline)) __attribute__((visibility("hidden")))
+#elif defined(__GNUC__)
+# define ASMJIT_INLINE inline __attribute__((always_inline))
+#else
+# define ASMJIT_INLINE inline
+#endif
+
+#if defined(ASMJIT_HOST_X86)
+# if defined(__GNUC__) || defined(__clang__)
+# define ASMJIT_REGPARM_1 __attribute__((regparm(1)))
+# define ASMJIT_REGPARM_2 __attribute__((regparm(2)))
+# define ASMJIT_REGPARM_3 __attribute__((regparm(3)))
+# define ASMJIT_FASTCALL __attribute__((fastcall))
+# define ASMJIT_STDCALL __attribute__((stdcall))
+# define ASMJIT_CDECL __attribute__((cdecl))
+# else
+# define ASMJIT_FASTCALL __fastcall
+# define ASMJIT_STDCALL __stdcall
+# define ASMJIT_CDECL __cdecl
+# endif
+#else
+# define ASMJIT_FASTCALL
+# define ASMJIT_STDCALL
+# define ASMJIT_CDECL
+#endif // ASMJIT_HOST_X86
+
+// ============================================================================
+// [asmjit::build - Enum]
+// ============================================================================
+
+#if defined(_MSC_VER)
+# define ASMJIT_ENUM(_Name_) enum _Name_ : uint32_t
+#else
+# define ASMJIT_ENUM(_Name_) enum _Name_
+#endif
+
+// ============================================================================
+// [asmjit::build - Memory Management]
+// ============================================================================
+
+#if !defined(ASMJIT_ALLOC) && !defined(ASMJIT_REALLOC) && !defined(ASMJIT_FREE)
+# define ASMJIT_ALLOC(_Size_) ::malloc(_Size_)
+# define ASMJIT_REALLOC(_Ptr_, _Size_) ::realloc(_Ptr_, _Size_)
+# define ASMJIT_FREE(_Ptr_) ::free(_Ptr_)
+#else
+# if !defined(ASMJIT_ALLOC) || !defined(ASMJIT_REALLOC) || !defined(ASMJIT_FREE)
+# error "AsmJit - You must redefine ASMJIT_ALLOC, ASMJIT_REALLOC and ASMJIT_FREE."
+# endif
+#endif // !ASMJIT_ALLOC && !ASMJIT_REALLOC && !ASMJIT_FREE
+
+// ============================================================================
+// [asmjit::build - _ASMJIT_HOST_INDEX]
+// ============================================================================
+
+#if defined(ASMJIT_HOST_LE)
+# define _ASMJIT_HOST_INDEX(_Total_, _Index_) (_Index_)
+#else
+# define _ASMJIT_HOST_INDEX(_Total_, _Index_) ((_Total_) - 1 - (_Index_))
+#endif
+
+// ============================================================================
+// [asmjit::build - BLEND_OFFSET_OF]
+// ============================================================================
+
+//! Cross-platform solution to get offset of `_Field_` in `_Struct_`.
+#define ASMJIT_OFFSET_OF(_Struct_, _Field_) \
+ static_cast((intptr_t) ((const uint8_t*) &((const _Struct_*)0x1)->_Field_) - 1)
+
+// ============================================================================
+// [asmjit::build - ASMJIT_ARRAY_SIZE]
+// ============================================================================
+
+#define ASMJIT_ARRAY_SIZE(_Array_) \
+ (sizeof(_Array_) / sizeof(*_Array_))
+
+// ============================================================================
+// [asmjit::build - ASMJIT_DEBUG / ASMJIT_TRACE]
+// ============================================================================
+
+// If ASMJIT_DEBUG and ASMJIT_RELEASE is not defined ASMJIT_DEBUG will be
+// detected using the compiler specific macros. This enables to set the build
+// type using IDE.
+#if !defined(ASMJIT_DEBUG) && !defined(ASMJIT_RELEASE)
+# if defined(_DEBUG)
+# define ASMJIT_DEBUG
+# endif // _DEBUG
+#endif // !ASMJIT_DEBUG && !ASMJIT_RELEASE
+
+// ASMJIT_TRACE is only used by sources and private headers. It's safe to make
+// it unavailable outside of AsmJit.
+#if defined(ASMJIT_EXPORTS)
+namespace asmjit { static inline int disabledTrace(...) { return 0; } }
+# if defined(ASMJIT_TRACE)
+# define ASMJIT_TSEC(_Section_) _Section_
+# define ASMJIT_TLOG ::printf(__VA_ARGS__)
+# else
+# define ASMJIT_TSEC(_Section_) do {} while(0)
+# define ASMJIT_TLOG 0 && ::asmjit::disabledTrace
+# endif // ASMJIT_TRACE
+#endif // ASMJIT_EXPORTS
+
+// ============================================================================
+// [asmjit::build - ASMJIT_UNUSED]
+// ============================================================================
+
+#if !defined(ASMJIT_UNUSED)
+# define ASMJIT_UNUSED(_Var_) ((void)_Var_)
+#endif // ASMJIT_UNUSED
+
+// ============================================================================
+// [asmjit::build - ASMJIT_NOP]
+// ============================================================================
+
+#if !defined(ASMJIT_NOP)
+# define ASMJIT_NOP() ((void)0)
+#endif // ASMJIT_NOP
+
+// ============================================================================
+// [asmjit::build - ASMJIT_NO_COPY]
+// ============================================================================
+
+#define ASMJIT_NO_COPY(_Type_) \
+private: \
+ ASMJIT_INLINE _Type_(const _Type_& other); \
+ ASMJIT_INLINE _Type_& operator=(const _Type_& other); \
+public:
+
+// ============================================================================
+// [asmjit::build - StdInt]
+// ============================================================================
+
+#if defined(__MINGW32__)
+# include
+#endif // __MINGW32__
+
+#if defined(_MSC_VER) && (_MSC_VER < 1600)
+# if !defined(ASMJIT_SUPRESS_STD_TYPES)
+# if (_MSC_VER < 1300)
+typedef signed char int8_t;
+typedef signed short int16_t;
+typedef signed int int32_t;
+typedef signed __int64 int64_t;
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned __int64 uint64_t;
+# else
+typedef signed __int8 int8_t;
+typedef signed __int16 int16_t;
+typedef signed __int32 int32_t;
+typedef signed __int64 int64_t;
+typedef unsigned __int8 uint8_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
+# endif // _MSC_VER
+# endif // ASMJIT_SUPRESS_STD_TYPES
+#else
+# include
+# include
+#endif
+
+#if defined(_MSC_VER)
+# define ASMJIT_INT64_C(_Num_) _Num_##i64
+# define ASMJIT_UINT64_C(_Num_) _Num_##ui64
+#else
+# define ASMJIT_INT64_C(_Num_) _Num_##LL
+# define ASMJIT_UINT64_C(_Num_) _Num_##ULL
+#endif
+
+// ============================================================================
+// [asmjit::build - Windows]
+// ============================================================================
+
+#if defined(ASMJIT_OS_WINDOWS) && !defined(ASMJIT_SUPRESS_WINDOWS_H)
+
+# if !defined(WIN32_LEAN_AND_MEAN)
+# define WIN32_LEAN_AND_MEAN
+# define ASMJIT_UNDEF_WIN32_LEAN_AND_MEAN
+# endif // !WIN32_LEAN_AND_MEAN
+
+# if !defined(NOMINMAX)
+# define NOMINMAX
+# define ASMJIT_UNDEF_NOMINMAX
+# endif // !NOMINMAX
+
+# include
+
+# if defined(ASMJIT_UNDEF_NOMINMAX)
+# undef NOMINMAX
+# undef ASMJIT_UNDEF_NOMINMAX
+# endif
+
+# if defined(ASMJIT_UNDEF_WIN32_LEAN_AND_MEAN)
+# undef WIN32_LEAN_AND_MEAN
+# undef ASMJIT_UNDEF_WIN32_LEAN_AND_MEAN
+# endif
+
+#endif // ASMJIT_OS_WINDOWS && !ASMJIT_SUPRESS_WINDOWS_H
+
+// ============================================================================
+// [asmjit::build - Test]
+// ============================================================================
+
+// Include a unit testing package if this is a `asmjit_test` build.
+#if defined(ASMJIT_TEST)
+#include "./test/broken.h"
+#endif // ASMJIT_TEST
+
+// [Guard]
+#endif // _ASMJIT_BUILD_H
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/Config.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/Config.h
new file mode 100644
index 0000000..4041c11
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/Config.h
@@ -0,0 +1,65 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Guard]
+#ifndef _ASMJIT_CONFIG_H
+#define _ASMJIT_CONFIG_H
+
+// This file can be used to modify built-in features of AsmJit. AsmJit is by
+// default compiled only for host processor to enable JIT compilation. Both
+// Assembler and Compiler code generators are compiled by default.
+//
+// ASMJIT_BUILD_... flags can be defined to build additional backends that can
+// be used for remote code generation.
+//
+// ASMJIT_DISABLE_... flags can be defined to disable standard features. These
+// are handy especially when building asmjit statically and some features are
+// not needed or unwanted (like Compiler).
+
+#ifdef _DEBUG
+#define ASMJIT_DEBUG // Define to enable debug-mode.
+#else
+#define ASMJIT_RELEASE // Define to enable release-mode.
+#endif
+
+// ============================================================================
+// [AsmJit - Build-Type]
+// ============================================================================
+
+#ifdef BLACKBONE_STATIC
+#define ASMJIT_STATIC
+#elif BLACKBONE_EXPORTS
+#define ASMJIT_EXPORTS
+#endif
+
+// #define ASMJIT_EMBED // Asmjit is embedded (implies ASMJIT_STATIC).
+// #define ASMJIT_STATIC // Define to enable static-library build.
+
+// ============================================================================
+// [AsmJit - Build-Mode]
+// ============================================================================
+
+// #define ASMJIT_DEBUG // Define to enable debug-mode.
+// #define ASMJIT_RELEASE // Define to enable release-mode.
+// #define ASMJIT_TRACE // Define to enable tracing.
+
+// ============================================================================
+// [AsmJit - Features]
+// ============================================================================
+
+// If none of these is defined AsmJit will select host architecture by default.
+ #define ASMJIT_BUILD_X86 // Define to enable x86 instruction set (32-bit).
+ #define ASMJIT_BUILD_X64 // Define to enable x64 instruction set (64-bit).
+// #define ASMJIT_BUILD_HOST // Define to enable host instruction set.
+
+// AsmJit features are enabled by default.
+#define ASMJIT_DISABLE_COMPILER // Disable Compiler (completely).
+#define ASMJIT_DISABLE_LOGGER // Disable Logger (completely).
+#define ASMJIT_DISABLE_NAMES // Disable everything that uses strings
+ // (instruction names, error names, ...).
+
+// [Guard]
+#endif // _ASMJIT_CONFIG_H
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base.h
new file mode 100644
index 0000000..47e1bfe
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base.h
@@ -0,0 +1,34 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Guard]
+#ifndef _ASMJIT_BASE_H
+#define _ASMJIT_BASE_H
+
+// [Dependencies - AsmJit]
+#include "build.h"
+
+#include "base/assembler.h"
+#include "base/codegen.h"
+#include "base/compiler.h"
+#include "base/constpool.h"
+#include "base/containers.h"
+#include "base/cpuinfo.h"
+#include "base/cputicks.h"
+#include "base/error.h"
+#include "base/globals.h"
+#include "base/intutil.h"
+#include "base/lock.h"
+#include "base/logger.h"
+#include "base/operand.h"
+#include "base/runtime.h"
+#include "base/string.h"
+#include "base/vectypes.h"
+#include "base/vmem.h"
+#include "base/zone.h"
+
+// [Guard]
+#endif // _ASMJIT_BASE_H
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/assembler.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/assembler.h
new file mode 100644
index 0000000..bfd8c53
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/assembler.h
@@ -0,0 +1,542 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Guard]
+#ifndef _ASMJIT_BASE_ASSEMBLER_H
+#define _ASMJIT_BASE_ASSEMBLER_H
+
+// [Dependencies - AsmJit]
+#include "../base/codegen.h"
+#include "../base/containers.h"
+#include "../base/error.h"
+#include "../base/logger.h"
+#include "../base/operand.h"
+#include "../base/runtime.h"
+#include "../base/zone.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_general
+//! \{
+
+// ============================================================================
+// [asmjit::kInstId]
+// ============================================================================
+
+//! Instruction codes (stub).
+ASMJIT_ENUM(kInstId) {
+ //! No instruction.
+ kInstIdNone = 0
+};
+
+// ============================================================================
+// [asmjit::kInstOptions]
+// ============================================================================
+
+//! Instruction options (stub).
+ASMJIT_ENUM(kInstOptions) {
+ //! No instruction options.
+ kInstOptionNone = 0x00000000,
+
+ //! Emit short form of the instruction.
+ //!
+ //! X86/X64:
+ //!
+ //! Short form is mostly related to jmp and jcc instructions, but can be used
+ //! by other instructions supporting 8-bit or 32-bit immediates. This option
+ //! can be dangerous if the short jmp/jcc is required, but not encodable due
+ //! to large displacement, in such case an error happens and the whole
+ //! assembler/compiler stream is unusable.
+ kInstOptionShortForm = 0x00000001,
+
+ //! Emit long form of the instruction.
+ //!
+ //! X86/X64:
+ //!
+ //! Long form is mosrlt related to jmp and jcc instructions, but like the
+ //! `kInstOptionShortForm` option it can be used by other instructions
+ //! supporting both 8-bit and 32-bit immediates.
+ kInstOptionLongForm = 0x00000002,
+
+ //! Condition is likely to be taken.
+ kInstOptionTaken = 0x00000004,
+
+ //! Condition is unlikely to be taken.
+ kInstOptionNotTaken = 0x00000008
+};
+
+// ============================================================================
+// [asmjit::LabelLink]
+// ============================================================================
+
+//! \internal
+//!
+//! Data structure used to link linked-labels.
+struct LabelLink {
+ //! Previous link.
+ LabelLink* prev;
+ //! Offset.
+ intptr_t offset;
+ //! Inlined displacement.
+ intptr_t displacement;
+ //! RelocId if link must be absolute when relocated.
+ intptr_t relocId;
+};
+
+// ============================================================================
+// [asmjit::LabelData]
+// ============================================================================
+
+//! \internal
+//!
+//! Label data.
+struct LabelData {
+ //! Label offset.
+ intptr_t offset;
+ //! Label links chain.
+ LabelLink* links;
+};
+
+// ============================================================================
+// [asmjit::RelocData]
+// ============================================================================
+
+//! \internal
+//!
+//! Code relocation data (relative vs absolute addresses).
+//!
+//! X86/X64:
+//!
+//! X86 architecture uses 32-bit absolute addressing model by memory operands,
+//! but 64-bit mode uses relative addressing model (RIP + displacement). In
+//! code we are always using relative addressing model for referencing labels
+//! and embedded data. In 32-bit mode we must patch all references to absolute
+//! address before we can call generated function.
+struct RelocData {
+ //! Type of relocation.
+ uint32_t type;
+ //! Size of relocation (4 or 8 bytes).
+ uint32_t size;
+
+ //! Offset from code begin address.
+ Ptr from;
+
+ //! Relative displacement from code begin address (not to `offset`) or
+ //! absolute address.
+ Ptr data;
+};
+
+// ============================================================================
+// [asmjit::Assembler]
+// ============================================================================
+
+//! Base assembler.
+//!
+//! This class implements the base interface to an assembler. The architecture
+//! specific API is implemented by backends.
+//!
+//! \sa Compiler.
+struct ASMJIT_VCLASS Assembler : public CodeGen {
+ ASMJIT_NO_COPY(Assembler)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `Assembler` instance.
+ ASMJIT_API Assembler(Runtime* runtime);
+ //! Destroy the `Assembler` instance.
+ ASMJIT_API virtual ~Assembler();
+
+ // --------------------------------------------------------------------------
+ // [Reset]
+ // --------------------------------------------------------------------------
+
+ //! Reset the assembler.
+ //!
+ //! If `releaseMemory` is true all buffers will be released to the system.
+ ASMJIT_API void reset(bool releaseMemory = false);
+
+ // --------------------------------------------------------------------------
+ // [Buffer]
+ // --------------------------------------------------------------------------
+
+ //! Get capacity of the code buffer.
+ ASMJIT_INLINE size_t getCapacity() const {
+ return (size_t)(_end - _buffer);
+ }
+
+ //! Get the number of remaining bytes (space between cursor and the end of
+ //! the buffer).
+ ASMJIT_INLINE size_t getRemainingSpace() const {
+ return (size_t)(_end - _cursor);
+ }
+
+ //! Get buffer.
+ ASMJIT_INLINE uint8_t* getBuffer() const {
+ return _buffer;
+ }
+
+ //! Get the end of the buffer (points to the first byte that is outside).
+ ASMJIT_INLINE uint8_t* getEnd() const {
+ return _end;
+ }
+
+ //! Get the current position in the buffer.
+ ASMJIT_INLINE uint8_t* getCursor() const {
+ return _cursor;
+ }
+
+ //! Set the current position in the buffer.
+ ASMJIT_INLINE void setCursor(uint8_t* cursor) {
+ ASMJIT_ASSERT(cursor >= _buffer && cursor <= _end);
+ _cursor = cursor;
+ }
+
+ //! Get the current offset in the buffer.
+ ASMJIT_INLINE size_t getOffset() const {
+ return (size_t)(_cursor - _buffer);
+ }
+
+ //! Set the current offset in the buffer to `offset` and get the previous
+ //! offset value.
+ ASMJIT_INLINE size_t setOffset(size_t offset) {
+ ASMJIT_ASSERT(offset < getCapacity());
+
+ size_t oldOffset = (size_t)(_cursor - _buffer);
+ _cursor = _buffer + offset;
+ return oldOffset;
+ }
+
+ //! Grow the internal buffer.
+ //!
+ //! The internal buffer will grow at least by `n` bytes so `n` bytes can be
+ //! added to it. If `n` is zero or `getOffset() + n` is not greater than the
+ //! current capacity of the buffer this function does nothing.
+ ASMJIT_API Error _grow(size_t n);
+
+ //! Reserve the internal buffer to at least `n` bytes.
+ ASMJIT_API Error _reserve(size_t n);
+
+ //! Get BYTE at position `pos`.
+ ASMJIT_INLINE uint8_t getByteAt(size_t pos) const {
+ ASMJIT_ASSERT(pos + 1 <= (size_t)(_end - _buffer));
+ return *reinterpret_cast(_buffer + pos);
+ }
+
+ //! Get WORD at position `pos`.
+ ASMJIT_INLINE uint16_t getWordAt(size_t pos) const {
+ ASMJIT_ASSERT(pos + 2 <= (size_t)(_end - _buffer));
+ return *reinterpret_cast(_buffer + pos);
+ }
+
+ //! Get DWORD at position `pos`.
+ ASMJIT_INLINE uint32_t getDWordAt(size_t pos) const {
+ ASMJIT_ASSERT(pos + 4 <= (size_t)(_end - _buffer));
+ return *reinterpret_cast(_buffer + pos);
+ }
+
+ //! Get QWORD at position `pos`.
+ ASMJIT_INLINE uint64_t getQWordAt(size_t pos) const {
+ ASMJIT_ASSERT(pos + 8 <= (size_t)(_end - _buffer));
+ return *reinterpret_cast(_buffer + pos);
+ }
+
+ //! Get int32_t at position `pos`.
+ ASMJIT_INLINE int32_t getInt32At(size_t pos) const {
+ ASMJIT_ASSERT(pos + 4 <= (size_t)(_end - _buffer));
+ return *reinterpret_cast(_buffer + pos);
+ }
+
+ //! Get uint32_t at position `pos`.
+ ASMJIT_INLINE uint32_t getUInt32At(size_t pos) const {
+ ASMJIT_ASSERT(pos + 4 <= (size_t)(_end - _buffer));
+ return *reinterpret_cast(_buffer + pos);
+ }
+
+ //! Set BYTE at position `pos`.
+ ASMJIT_INLINE void setByteAt(size_t pos, uint8_t x) {
+ ASMJIT_ASSERT(pos + 1 <= (size_t)(_end - _buffer));
+ *reinterpret_cast(_buffer + pos) = x;
+ }
+
+ //! Set WORD at position `pos`.
+ ASMJIT_INLINE void setWordAt(size_t pos, uint16_t x) {
+ ASMJIT_ASSERT(pos + 2 <= (size_t)(_end - _buffer));
+ *reinterpret_cast(_buffer + pos) = x;
+ }
+
+ //! Set DWORD at position `pos`.
+ ASMJIT_INLINE void setDWordAt(size_t pos, uint32_t x) {
+ ASMJIT_ASSERT(pos + 4 <= (size_t)(_end - _buffer));
+ *reinterpret_cast(_buffer + pos) = x;
+ }
+
+ //! Set QWORD at position `pos`.
+ ASMJIT_INLINE void setQWordAt(size_t pos, uint64_t x) {
+ ASMJIT_ASSERT(pos + 8 <= (size_t)(_end - _buffer));
+ *reinterpret_cast(_buffer + pos) = x;
+ }
+
+ //! Set int32_t at position `pos`.
+ ASMJIT_INLINE void setInt32At(size_t pos, int32_t x) {
+ ASMJIT_ASSERT(pos + 4 <= (size_t)(_end - _buffer));
+ *reinterpret_cast(_buffer + pos) = x;
+ }
+
+ //! Set uint32_t at position `pos`.
+ ASMJIT_INLINE void setUInt32At(size_t pos, uint32_t x) {
+ ASMJIT_ASSERT(pos + 4 <= (size_t)(_end - _buffer));
+ *reinterpret_cast(_buffer + pos) = x;
+ }
+
+ // --------------------------------------------------------------------------
+ // [GetCodeSize]
+ // --------------------------------------------------------------------------
+
+ //! Get current offset in buffer, same as `getOffset() + getTramplineSize()`.
+ ASMJIT_INLINE size_t getCodeSize() const {
+ return getOffset() + getTrampolineSize();
+ }
+
+ // --------------------------------------------------------------------------
+ // [GetTrampolineSize]
+ // --------------------------------------------------------------------------
+
+ //! Get size of all possible trampolines.
+ //!
+ //! Trampolines are needed to successfuly generate relative jumps to absolute
+ //! addresses. This value is only non-zero if jmp of call instructions were
+ //! used with immediate operand (this means jumping or calling an absolute
+ //! address directly).
+ ASMJIT_INLINE size_t getTrampolineSize() const {
+ return _trampolineSize;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Label]
+ // --------------------------------------------------------------------------
+
+ //! Get number of labels created.
+ ASMJIT_INLINE size_t getLabelsCount() const {
+ return _labelList.getLength();
+ }
+
+ //! Get whether the `label` is valid (created by the assembler).
+ ASMJIT_INLINE bool isLabelValid(const Label& label) const {
+ return isLabelValid(label.getId());
+ }
+
+ //! \overload
+ ASMJIT_INLINE bool isLabelValid(uint32_t id) const {
+ return static_cast(id) < _labelList.getLength();
+ }
+
+ //! Get whether the `label` is bound.
+ //!
+ //! \note It's an error to pass label that is not valid. Check the validity
+ //! of the label by using `isLabelValid()` method before the bound check if
+ //! you are not sure about its validity, otherwise you may hit an assertion
+ //! failure in debug mode, and undefined behavior in release mode.
+ ASMJIT_INLINE bool isLabelBound(const Label& label) const {
+ return isLabelBound(label.getId());
+ }
+
+ //! \overload
+ ASMJIT_INLINE bool isLabelBound(uint32_t id) const {
+ ASMJIT_ASSERT(isLabelValid(id));
+
+ return _labelList[id].offset != -1;
+ }
+
+ //! Get `label` offset or -1 if the label is not yet bound.
+ ASMJIT_INLINE intptr_t getLabelOffset(const Label& label) const {
+ return getLabelOffset(label.getId());
+ }
+
+ //! \overload
+ ASMJIT_INLINE intptr_t getLabelOffset(uint32_t id) const {
+ ASMJIT_ASSERT(isLabelValid(id));
+ return _labelList[id].offset;
+ }
+
+ //! Get `LabelData` by `label`.
+ ASMJIT_INLINE LabelData* getLabelData(const Label& label) const {
+ return getLabelData(label.getId());
+ }
+
+ //! \overload
+ ASMJIT_INLINE LabelData* getLabelData(uint32_t id) const {
+ ASMJIT_ASSERT(isLabelValid(id));
+ return const_cast(&_labelList[id]);
+ }
+
+ //! \internal
+ //!
+ //! Register labels for other code generator, i.e. `Compiler`.
+ ASMJIT_API Error _registerIndexedLabels(size_t index);
+
+ //! \internal
+ //!
+ //! Create and initialize a new `Label`.
+ ASMJIT_API Error _newLabel(Label* dst);
+
+ //! \internal
+ //!
+ //! New LabelLink instance.
+ ASMJIT_API LabelLink* _newLabelLink();
+
+ //! Create and return a new `Label`.
+ ASMJIT_INLINE Label newLabel() {
+ Label result(NoInit);
+ _newLabel(&result);
+ return result;
+ }
+
+ //! Bind label to the current offset.
+ //!
+ //! \note Label can be bound only once!
+ ASMJIT_API virtual Error bind(const Label& label);
+
+ // --------------------------------------------------------------------------
+ // [Embed]
+ // --------------------------------------------------------------------------
+
+ //! Embed data into the code buffer.
+ ASMJIT_API virtual Error embed(const void* data, uint32_t size);
+
+ // --------------------------------------------------------------------------
+ // [Align]
+ // --------------------------------------------------------------------------
+
+ //! Align target buffer to `m` bytes.
+ //!
+ //! Typical usage of this is to align labels at start of the inner loops.
+ //!
+ //! Inserts `nop()` instructions or CPU optimized NOPs.
+ virtual Error align(uint32_t mode, uint32_t offset) = 0;
+
+ // --------------------------------------------------------------------------
+ // [Reloc]
+ // --------------------------------------------------------------------------
+
+ //! Relocate the code to `baseAddress` and copy to `dst`.
+ //!
+ //! \param dst Contains the location where the relocated code should be
+ //! copied. The pointer can be address returned by virtual memory allocator
+ //! or any other address that has sufficient space.
+ //!
+ //! \param base Base address used for relocation. The `JitRuntime` always
+ //! sets the `base` address to be the same as `dst`, but other runtimes, for
+ //! example `StaticRuntime`, do not have to follow this rule.
+ //!
+ //! \retval The number bytes actually used. If the code generator reserved
+ //! space for possible trampolines, but didn't use it, the number of bytes
+ //! used can actually be less than the expected worst case. Virtual memory
+ //! allocator can shrink the memory allocated first time.
+ //!
+ //! A given buffer will be overwritten, to get the number of bytes required,
+ //! use `getCodeSize()`.
+ ASMJIT_API size_t relocCode(void* dst, Ptr baseAddress = kNoBaseAddress) const;
+
+ //! \internal
+ //!
+ //! Reloc code.
+ virtual size_t _relocCode(void* dst, Ptr baseAddress) const = 0;
+
+ // --------------------------------------------------------------------------
+ // [Make]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API virtual void* make();
+
+ // --------------------------------------------------------------------------
+ // [Emit]
+ // --------------------------------------------------------------------------
+
+ //! Emit an instruction.
+ ASMJIT_API Error emit(uint32_t code);
+ //! \overload
+ ASMJIT_API Error emit(uint32_t code, const Operand& o0);
+ //! \overload
+ ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1);
+ //! \overload
+ ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2);
+ //! \overload
+ ASMJIT_INLINE Error emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3) {
+ return _emit(code, o0, o1, o2, o3);
+ }
+
+ //! Emit an instruction with integer immediate operand.
+ ASMJIT_API Error emit(uint32_t code, int o0);
+ //! \overload
+ ASMJIT_API Error emit(uint32_t code, uint64_t o0);
+ //! \overload
+ ASMJIT_API Error emit(uint32_t code, const Operand& o0, int o1);
+ //! \overload
+ ASMJIT_API Error emit(uint32_t code, const Operand& o0, uint64_t o1);
+ //! \overload
+ ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, int o2);
+ //! \overload
+ ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, uint64_t o2);
+ //! \overload
+ ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, int o3);
+ //! \overload
+ ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, uint64_t o3);
+
+ //! Emit an instruction (virtual).
+ virtual Error _emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3) = 0;
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Buffer where the code is emitted (either live or temporary).
+ //!
+ //! This is actually the base pointer of the buffer, to get the current
+ //! position (cursor) look at the `_cursor` member.
+ uint8_t* _buffer;
+ //! The end of the buffer (points to the first invalid byte).
+ //!
+ //! The end of the buffer is calculated as _buffer + size.
+ uint8_t* _end;
+ //! The current position in code `_buffer`.
+ uint8_t* _cursor;
+
+ //! Size of possible trampolines.
+ uint32_t _trampolineSize;
+
+ //! Inline comment that will be logged by the next instruction and set to NULL.
+ const char* _comment;
+ //! Unused `LabelLink` structures pool.
+ LabelLink* _unusedLinks;
+
+ //! LabelData list.
+ PodVector _labelList;
+ //! RelocData list.
+ PodVector _relocList;
+};
+
+//! \}
+
+// ============================================================================
+// [Defined-Later]
+// ============================================================================
+
+ASMJIT_INLINE Label::Label(Assembler& a) : Operand(NoInit) {
+ a._newLabel(this);
+}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // _ASMJIT_BASE_ASSEMBLER_H
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/codegen.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/codegen.h
new file mode 100644
index 0000000..551b84b
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/codegen.h
@@ -0,0 +1,337 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Guard]
+#ifndef _ASMJIT_BASE_CODEGEN_H
+#define _ASMJIT_BASE_CODEGEN_H
+
+// [Dependencies - AsmJit]
+#include "../base/error.h"
+#include "../base/logger.h"
+#include "../base/runtime.h"
+#include "../base/zone.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_general
+//! \{
+
+// ============================================================================
+// [asmjit::kCodeGen]
+// ============================================================================
+
+//! Features of \ref CodeGen.
+ASMJIT_ENUM(kCodeGen) {
+ //! Emit optimized code-alignment sequences (`Assembler` and `Compiler`).
+ //!
+ //! Default `true`.
+ //!
+ //! X86/X64
+ //! -------
+ //!
+ //! Default align sequence used by X86/X64 architecture is one-byte 0x90
+ //! opcode that is mostly shown by disassemblers as nop. However there are
+ //! more optimized align sequences for 2-11 bytes that may execute faster.
+ //! If this feature is enabled asmjit will generate specialized sequences
+ //! for alignment between 1 to 11 bytes. Also when `X86Compiler` is used,
+ //! it can add REX prefixes into the code to make some instructions greater
+ //! so no alignment sequence is needed.
+ kCodeGenOptimizedAlign = 0,
+
+ //! Emit jump-prediction hints (`Assembler` and `Compiler`).
+ //!
+ //! Default `false`.
+ //!
+ //! X86/X64
+ //! -------
+ //!
+ //! Jump prediction is usually based on the direction of the jump. If the
+ //! jump is backward it is usually predicted as taken; and if the jump is
+ //! forward it is usually predicted as not-taken. The reason is that loops
+ //! generally use backward jumps and conditions usually use forward jumps.
+ //! However this behavior can be overridden by using instruction prefixes.
+ //! If this option is enabled these hints will be emitted.
+ //!
+ //! This feature is disabled by default, because the only processor that
+ //! used to take into consideration prediction hints was P4. Newer processors
+ //! implement heuristics for branch prediction that ignores any static hints.
+ kCodeGenPredictedJumps = 1,
+
+ //! Schedule instructions so they can be executed faster (`Compiler` only).
+ //!
+ //! Default `false` - has to be explicitly enabled as the scheduler needs
+ //! some time to run.
+ //!
+ //! X86/X64
+ //! -------
+ //!
+ //! If scheduling is enabled AsmJit will try to reorder instructions to
+ //! minimize dependency chain. Scheduler always runs after the registers are
+ //! allocated so it doesn't change count of register allocs/spills.
+ //!
+ //! This feature is highly experimental and untested.
+ kCodeGenEnableScheduler = 2
+};
+
+// ============================================================================
+// [asmjit::kAlignMode]
+// ============================================================================
+
+//! Code aligning mode.
+ASMJIT_ENUM(kAlignMode) {
+ //! Align by emitting a sequence that can be executed (code).
+ kAlignCode = 0,
+ //! Align by emitting sequence that shouldn't be executed (data).
+ kAlignData = 1
+};
+
+// ============================================================================
+// [asmjit::kRelocMode]
+// ============================================================================
+
+//! Relocation mode.
+ASMJIT_ENUM(kRelocMode) {
+ //! Relocate an absolute address to an absolute address.
+ kRelocAbsToAbs = 0,
+ //! Relocate a relative address to an absolute address.
+ kRelocRelToAbs = 1,
+ //! Relocate an absolute address to a relative address.
+ kRelocAbsToRel = 2,
+ //! Relocate an absolute address to a relative address or use trampoline.
+ kRelocTrampoline = 3
+};
+
+// ============================================================================
+// [asmjit::CodeGen]
+// ============================================================================
+
+//! Abstract class defining basics of \ref Assembler and \ref Compiler.
+struct ASMJIT_VCLASS CodeGen {
+ ASMJIT_NO_COPY(CodeGen)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `CodeGen` instance.
+ ASMJIT_API CodeGen(Runtime* runtime);
+ //! Destroy the `CodeGen` instance.
+ ASMJIT_API virtual ~CodeGen();
+
+ // --------------------------------------------------------------------------
+ // [Runtime]
+ // --------------------------------------------------------------------------
+
+ //! Get runtime.
+ ASMJIT_INLINE Runtime* getRuntime() const {
+ return _runtime;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Logger]
+ // --------------------------------------------------------------------------
+
+#if !defined(ASMJIT_DISABLE_LOGGER)
+ //! Get whether the code generator has a logger.
+ ASMJIT_INLINE bool hasLogger() const {
+ return _logger != NULL;
+ }
+
+ //! Get logger.
+ ASMJIT_INLINE Logger* getLogger() const {
+ return _logger;
+ }
+
+ //! Set logger to `logger`.
+ ASMJIT_API Error setLogger(Logger* logger);
+#endif // !ASMJIT_DISABLE_LOGGER
+
+ // --------------------------------------------------------------------------
+ // [Arch]
+ // --------------------------------------------------------------------------
+
+ //! Get target architecture.
+ ASMJIT_INLINE uint32_t getArch() const {
+ return _arch;
+ }
+
+ //! Get default register size (4 or 8 bytes).
+ ASMJIT_INLINE uint32_t getRegSize() const {
+ return _regSize;
+ }
+
+ // --------------------------------------------------------------------------
+ // [BaseAddress]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the code-generator has a base address.
+ //!
+ //! \sa \ref getBaseAddress()
+ ASMJIT_INLINE bool hasBaseAddress() const {
+ return _baseAddress != kNoBaseAddress;
+ }
+
+ //! Get the base address.
+ ASMJIT_INLINE Ptr getBaseAddress() const {
+ return _baseAddress;
+ }
+
+ //! Set the base address to `baseAddress`.
+ ASMJIT_INLINE void setBaseAddress(Ptr baseAddress) {
+ _baseAddress = baseAddress;
+ }
+
+ //! Reset the base address.
+ ASMJIT_INLINE void resetBaseAddress() {
+ setBaseAddress(kNoBaseAddress);
+ }
+
+ // --------------------------------------------------------------------------
+ // [LastError / ErrorHandler]
+ // --------------------------------------------------------------------------
+
+ //! Get last error code.
+ ASMJIT_INLINE Error getError() const {
+ return _error;
+ }
+
+ //! Set last error code and propagate it through the error handler.
+ ASMJIT_API Error setError(Error error, const char* message = NULL);
+
+ //! Clear the last error code.
+ ASMJIT_INLINE void resetError() {
+ _error = kErrorOk;
+ }
+
+ //! Get error handler.
+ ASMJIT_INLINE ErrorHandler* getErrorHandler() const {
+ return _errorHandler;
+ }
+
+ //! Set error handler.
+ ASMJIT_API Error setErrorHandler(ErrorHandler* handler);
+
+ //! Clear error handler.
+ ASMJIT_INLINE Error resetErrorHandler() {
+ return setErrorHandler(NULL);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Code-Generation Features]
+ // --------------------------------------------------------------------------
+
+ //! Get code-generator `feature`.
+ ASMJIT_INLINE bool hasFeature(uint32_t feature) const {
+ ASMJIT_ASSERT(feature < 32);
+
+ return (_features & (1 << feature)) != 0;
+ }
+
+ //! Set code-generator `feature` to `value`.
+ ASMJIT_INLINE void setFeature(uint32_t feature, bool value) {
+ ASMJIT_ASSERT(feature < 32);
+
+ feature = static_cast(value) << feature;
+ _features = (_features & ~feature) | feature;
+ }
+
+ //! Get code-generator features.
+ ASMJIT_INLINE uint32_t getFeatures() const {
+ return _features;
+ }
+
+ //! Set code-generator features.
+ ASMJIT_INLINE void setFeatures(uint32_t features) {
+ _features = features;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Instruction Options]
+ // --------------------------------------------------------------------------
+
+ //! Get options of the next instruction.
+ ASMJIT_INLINE uint32_t getInstOptions() const {
+ return _instOptions;
+ }
+
+ //! Get options of the next instruction and reset them.
+ ASMJIT_INLINE uint32_t getInstOptionsAndReset() {
+ uint32_t instOptions = _instOptions;
+ _instOptions = 0;
+ return instOptions;
+ };
+
+ //! Set options of the next instruction.
+ ASMJIT_INLINE void setInstOptions(uint32_t instOptions) {
+ _instOptions = instOptions;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Make]
+ // --------------------------------------------------------------------------
+
+ //! Make is a convenience method to make and relocate the current code and
+ //! add it to the associated `Runtime`.
+ //!
+ //! What is needed is only to cast the returned pointer to your function type
+ //! and then use it. If there was an error during `make()` `NULL` is returned
+ //! and the last error code can be obtained by calling `getError()`.
+ virtual void* make() = 0;
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Target runtime.
+ Runtime* _runtime;
+
+#if !defined(ASMJIT_DISABLE_LOGGER)
+ //! Logger.
+ Logger* _logger;
+#else
+ //! \internal
+ //!
+ //! Makes libraries built with or without logging support binary compatible.
+ void* _logger;
+#endif // ASMJIT_DISABLE_LOGGER
+
+ //! Error handler, called by \ref setError().
+ ErrorHandler* _errorHandler;
+
+ //! Base address (-1 if unknown/not used).
+ Ptr _baseAddress;
+
+ //! Target architecture ID.
+ uint8_t _arch;
+ //! Target architecture GP register size in bytes (4 or 8).
+ uint8_t _regSize;
+ //! \internal
+ uint16_t _reserved;
+
+ //! Code-Generation features, used by \ref hasFeature() and \ref setFeature().
+ uint32_t _features;
+ //! Options affecting the next instruction.
+ uint32_t _instOptions;
+
+ //! Last error code.
+ uint32_t _error;
+
+ //! Base zone.
+ Zone _baseZone;
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // _ASMJIT_BASE_CODEGEN_H
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/compiler.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/compiler.h
new file mode 100644
index 0000000..9d3a533
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/compiler.h
@@ -0,0 +1,3159 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Guard]
+#ifndef _ASMJIT_BASE_COMPILER_H
+#define _ASMJIT_BASE_COMPILER_H
+
+#include "../build.h"
+#if !defined(ASMJIT_DISABLE_COMPILER)
+
+// [Dependencies - AsmJit]
+#include "../base/assembler.h"
+#include "../base/codegen.h"
+#include "../base/constpool.h"
+#include "../base/containers.h"
+#include "../base/error.h"
+#include "../base/intutil.h"
+#include "../base/operand.h"
+#include "../base/zone.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [Forward Declarations]
+// ============================================================================
+
+struct Compiler;
+
+struct VarAttr;
+struct VarData;
+struct VarMap;
+struct VarState;
+
+struct Node;
+struct EndNode;
+struct InstNode;
+struct JumpNode;
+
+// ============================================================================
+// [asmjit::kConstScope]
+// ============================================================================
+
+//! \addtogroup asmjit_base_compiler
+//! \{
+
+//! Scope of the constant.
+ASMJIT_ENUM(kConstScope) {
+ //! Local constant, always embedded right after the current function.
+ kConstScopeLocal = 0,
+ //! Global constant, embedded at the end of the currently compiled code.
+ kConstScopeGlobal = 1
+};
+
+// ============================================================================
+// [asmjit::kVarType]
+// ============================================================================
+
+ASMJIT_ENUM(kVarType) {
+ //! Variable is 8-bit signed integer.
+ kVarTypeInt8 = 0,
+ //! Variable is 8-bit unsigned integer.
+ kVarTypeUInt8 = 1,
+ //! Variable is 16-bit signed integer.
+ kVarTypeInt16 = 2,
+ //! Variable is 16-bit unsigned integer.
+ kVarTypeUInt16 = 3,
+ //! Variable is 32-bit signed integer.
+ kVarTypeInt32 = 4,
+ //! Variable is 32-bit unsigned integer.
+ kVarTypeUInt32 = 5,
+ //! Variable is 64-bit signed integer.
+ kVarTypeInt64 = 6,
+ //! Variable is 64-bit unsigned integer.
+ kVarTypeUInt64 = 7,
+
+ //! Variable is target `intptr_t`, not compatible with host `intptr_t`.
+ kVarTypeIntPtr = 8,
+ //! Variable is target `uintptr_t`, not compatible with host `uintptr_t`.
+ kVarTypeUIntPtr = 9,
+
+ //! Variable is 32-bit floating point (single precision).
+ kVarTypeFp32 = 10,
+ //! Variable is 64-bit floating point (double precision).
+ kVarTypeFp64 = 11,
+
+ //! \internal
+ _kVarTypeIntStart = kVarTypeInt8,
+ //! \internal
+ _kVarTypeIntEnd = kVarTypeUIntPtr,
+
+ //! \internal
+ _kVarTypeFpStart = kVarTypeFp32,
+ //! \internal
+ _kVarTypeFpEnd = kVarTypeFp64
+};
+
+// ============================================================================
+// [asmjit::kVarFlags]
+// ============================================================================
+
+//! \internal
+//!
+//! X86/X64 variable flags.
+ASMJIT_ENUM(kVarFlags) {
+ //! Variable contains single-precision floating-point(s).
+ kVarFlagSp = 0x10,
+ //! Variable contains double-precision floating-point(s).
+ kVarFlagDp = 0x20,
+ //! Variable is packed, i.e. packed floats, doubles, ...
+ kVarFlagPacked = 0x40
+};
+
+// ============================================================================
+// [asmjit::kVarAttrFlags]
+// ============================================================================
+
+//! Variable attribute flags.
+ASMJIT_ENUM(kVarAttrFlags) {
+ //! Variable is accessed through register on input.
+ kVarAttrInReg = 0x00000001,
+ //! Variable is accessed through register on output.
+ kVarAttrOutReg = 0x00000002,
+ //! Variable is accessed through register on input & output.
+ kVarAttrInOutReg = 0x00000003,
+
+ //! Variable is accessed through memory on input.
+ kVarAttrInMem = 0x00000004,
+ //! Variable is accessed through memory on output.
+ kVarAttrOutMem = 0x00000008,
+ //! Variable is accessed through memory on input & output.
+ kVarAttrInOutMem = 0x0000000C,
+
+ //! Register allocator can decide if input will be in register or memory.
+ kVarAttrInDecide = 0x00000010,
+ //! Register allocator can decide if output will be in register or memory.
+ kVarAttrOutDecide = 0x00000020,
+ //! Register allocator can decide if in/out will be in register or memory.
+ kVarAttrInOutDecide = 0x00000030,
+
+ //! Variable is converted to other type/class on the input.
+ kVarAttrInConv = 0x00000040,
+ //! Variable is converted from other type/class on the output.
+ kVarAttrOutConv = 0x00000080,
+ //! Combination of `kVarAttrInConv` and `kVarAttrOutConv`.
+ kVarAttrInOutConv = 0x000000C0,
+
+ //! Variable is a function call operand.
+ kVarAttrInCall = 0x00000100,
+ //! Variable is a function argument passed in register.
+ kVarAttrInArg = 0x00000200,
+
+ //! Variable is a function return value passed in register.
+ kVarAttrOutRet = 0x00000400,
+ //! Variable should be spilled.
+ kVarAttrSpill = 0x00000800,
+ //! Variable should be unused at the end of the instruction/node.
+ kVarAttrUnuse = 0x00001000,
+
+ //! \internal
+ //!
+ //! All in-flags.
+ kVarAttrInAll =
+ kVarAttrInReg |
+ kVarAttrInMem |
+ kVarAttrInDecide |
+ kVarAttrInCall |
+ kVarAttrInArg,
+
+ //! \internal
+ //!
+ //! All out-flags.
+ kVarAttrOutAll =
+ kVarAttrOutReg |
+ kVarAttrOutMem |
+ kVarAttrOutDecide |
+ kVarAttrOutRet,
+
+ //! Variable is already allocated on the input.
+ kVarAttrAllocInDone = 0x00400000,
+ //! Variable is already allocated on the output.
+ kVarAttrAllocOutDone = 0x00800000
+};
+
+// ============================================================================
+// [asmjit::kVarHint]
+// ============================================================================
+
+//! Variable hint (used by `Compiler)`.
+//!
+//! \sa Compiler.
+ASMJIT_ENUM(kVarHint) {
+ //! Alloc variable.
+ kVarHintAlloc = 0,
+ //! Spill variable.
+ kVarHintSpill = 1,
+ //! Save variable if modified.
+ kVarHintSave = 2,
+ //! Save variable if modified and mark it as unused.
+ kVarHintSaveAndUnuse = 3,
+ //! Mark variable as unused.
+ kVarHintUnuse = 4
+};
+
+// ============================================================================
+// [asmjit::kVarState]
+// ============================================================================
+
+//! State of variable.
+//!
+//! \note State of variable is used only during make process and it's not
+//! visible to the developer.
+ASMJIT_ENUM(kVarState) {
+ //! Variable is currently not used.
+ kVarStateUnused = 0,
+
+ //! Variable is in register.
+ //!
+ //! Variable is currently allocated in register.
+ kVarStateReg = 1,
+
+ //! Variable is in memory location or spilled.
+ //!
+ //! Variable was spilled from register to memory or variable is used for
+ //! memory only storage.
+ kVarStateMem = 2
+};
+
+// ============================================================================
+// [asmjit::kFuncConv]
+// ============================================================================
+
+//! Function calling convention.
+//!
+//! For a platform specific calling conventions, see:
+//! - `kX86FuncConv` - X86/X64 calling conventions.
+ASMJIT_ENUM(kFuncConv) {
+ //! Calling convention is invalid (can't be used).
+ kFuncConvNone = 0,
+
+#if defined(ASMJIT_DOCGEN)
+ //! Default calling convention for current platform / operating system.
+ kFuncConvHost = DependsOnHost,
+
+ //! Default C calling convention based on current compiler's settings.
+ kFuncConvHostCDecl = DependsOnHost,
+
+ //! Compatibility for `__stdcall` calling convention.
+ //!
+ //! \note This enumeration is always set to a value which is compatible with
+ //! current compilers __stdcall calling convention. In 64-bit mode the value
+ //! is compatible with `kX86FuncConvW64` or `kX86FuncConvU64`.
+ kFuncConvHostStdCall = DependsOnHost,
+
+ //! Compatibility for `__fastcall` calling convention.
+ //!
+ //! \note This enumeration is always set to a value which is compatible with
+ //! current compilers `__fastcall` calling convention. In 64-bit mode the value
+ //! is compatible with `kX86FuncConvW64` or `kX86FuncConvU64`.
+ kFuncConvHostFastCall = DependsOnHost
+#endif // ASMJIT_DOCGEN
+};
+
+// ============================================================================
+// [asmjit::kFuncHint]
+// ============================================================================
+
+//! Function hints.
+//!
+//! For a platform specific calling conventions, see:
+//! - `kX86FuncHint` - X86/X64 function hints.
+ASMJIT_ENUM(kFuncHint) {
+ //! Make a naked function (default true).
+ //!
+ //! Naked function is function without using standard prolog/epilog sequence).
+ //!
+ //! X86/X64 Specific
+ //! ----------------
+ //!
+ //! Standard prolog sequence is:
+ //!
+ //! ~~~
+ //! push zbp
+ //! mov zsp, zbp
+ //! sub zsp, StackAdjustment
+ //! ~~~
+ //!
+ //! which is an equivalent to:
+ //!
+ //! ~~~
+ //! enter StackAdjustment, 0
+ //! ~~~
+ //!
+ //! Standard epilog sequence is:
+ //!
+ //! ~~~
+ //! mov zsp, zbp
+ //! pop zbp
+ //! ~~~
+ //!
+ //! which is an equavalent to:
+ //!
+ //! ~~~
+ //! leave
+ //! ~~~
+ //!
+ //! Naked functions can omit the prolog/epilog sequence. The advantage of
+ //! doing such modification is that EBP/RBP register can be used by the
+ //! register allocator which can result in less spills/allocs.
+ kFuncHintNaked = 0,
+
+ //! Generate compact function prolog/epilog if possible.
+ //!
+ //! X86/X64 Specific
+ //! ----------------
+ //!
+ //! Use shorter, but possible slower prolog/epilog sequence to save/restore
+ //! registers.
+ kFuncHintCompact = 1
+};
+
+// ============================================================================
+// [asmjit::kFuncFlags]
+// ============================================================================
+
+//! Function flags.
+//!
+//! For a platform specific calling conventions, see:
+//! - `kX86FuncFlags` - X86/X64 function flags.
+ASMJIT_ENUM(kFuncFlags) {
+ //! Whether the function is using naked (minimal) prolog / epilog.
+ kFuncFlagIsNaked = 0x00000001,
+
+ //! Whether an another function is called from this function.
+ kFuncFlagIsCaller = 0x00000002,
+
+ //! Whether the stack is not aligned to the required stack alignment,
+ //! thus it has to be aligned manually.
+ kFuncFlagIsStackMisaligned = 0x00000004,
+
+ //! Whether the stack pointer is adjusted by the stack size needed
+ //! to save registers and function variables.
+ //!
+ //! X86/X64 Specific
+ //! ----------------
+ //!
+ //! Stack pointer (ESP/RSP) is adjusted by 'sub' instruction in prolog and by
+ //! 'add' instruction in epilog (only if function is not naked). If function
+ //! needs to perform manual stack alignment more instructions are used to
+ //! adjust the stack (like "and zsp, -Alignment").
+ kFuncFlagIsStackAdjusted = 0x00000008,
+
+ //! Whether the function is finished using `Compiler::endFunc()`.
+ kFuncFlagIsFinished = 0x80000000
+};
+
+// ============================================================================
+// [asmjit::kFuncDir]
+// ============================================================================
+
+//! Function arguments direction.
+ASMJIT_ENUM(kFuncDir) {
+ //! Arguments are passed left to right.
+ //!
+ //! This arguments direction is unusual in C, however it's used in Pascal.
+ kFuncDirLtr = 0,
+
+ //! Arguments are passed right ro left
+ //!
+ //! This is the default argument direction in C.
+ kFuncDirRtl = 1
+};
+
+// ============================================================================
+// [asmjit::kFuncArg]
+// ============================================================================
+
+//! Function argument (lo/hi) specification.
+ASMJIT_ENUM(kFuncArg) {
+ //! Maxumum number of function arguments supported by AsmJit.
+ kFuncArgCount = 16,
+ //! Extended maximum number of arguments (used internally).
+ kFuncArgCountLoHi = kFuncArgCount * 2,
+
+ //! Index to the LO part of function argument (default).
+ //!
+ //! This value is typically omitted and added only if there is HI argument
+ //! accessed.
+ kFuncArgLo = 0,
+ //! Index to the HI part of function argument.
+ //!
+ //! HI part of function argument depends on target architecture. On x86 it's
+ //! typically used to transfer 64-bit integers (they form a pair of 32-bit
+ //! integers).
+ kFuncArgHi = kFuncArgCount
+};
+
+// ============================================================================
+// [asmjit::kFuncRet]
+// ============================================================================
+
+//! Function return value (lo/hi) specification.
+ASMJIT_ENUM(kFuncRet) {
+ //! Index to the LO part of function return value.
+ kFuncRetLo = 0,
+ //! Index to the HI part of function return value.
+ kFuncRetHi = 1
+};
+
+// ============================================================================
+// [asmjit::kFuncStackInvalid]
+// ============================================================================
+
+enum kFuncMisc {
+ //! Invalid stack offset in function or function parameter.
+ kFuncStackInvalid = -1
+};
+
+// ============================================================================
+// [asmjit::kNodeType]
+// ============================================================================
+
+//! Type of node, see \ref Node.
+ASMJIT_ENUM(kNodeType) {
+ //! Invalid node (internal, can't be used).
+ kNodeTypeNone = 0,
+ //! Node is an .align directive, see \ref AlignNode.
+ kNodeTypeAlign,
+ //! Node is an embedded data, see \ref EmbedNode.
+ kNodeTypeEmbed,
+ //! Node is a comment, see \ref CommentNode.
+ kNodeTypeComment,
+ //! Node is a variable hint (alloc, spill, use, unuse), see \ref HintNode.
+ kNodeTypeHint,
+ //! Node is a label, see \ref TargetNode.
+ kNodeTypeTarget,
+ //! Node is an instruction, see \ref InstNode.
+ kNodeTypeInst,
+ //! Node is a function declaration, see \ref FuncNode.
+ kNodeTypeFunc,
+ //! Node is an end of the function, see \ref EndNode.
+ kNodeTypeEnd,
+ //! Node is a return, see \ref RetNode.
+ kNodeTypeRet,
+ //! Node is a function call, see \ref CallNode.
+ kNodeTypeCall,
+ //! Node is a function call argument moved on stack, see \ref SArgNode.
+ kNodeTypeSArg
+};
+
+// ============================================================================
+// [asmjit::kNodeFlags]
+// ============================================================================
+
+ASMJIT_ENUM(kNodeFlags) {
+ //! Whether the node has been translated, thus contains only registers.
+ kNodeFlagIsTranslated = 0x0001,
+
+ //! Whether the node was scheduled - possibly reordered, but basically this
+ //! is a mark that is set by scheduler after the node has been visited.
+ kNodeFlagIsScheduled = 0x0002,
+
+ //! Whether the node is informative only and can be safely removed.
+ kNodeFlagIsInformative = 0x0004,
+
+ //! Whether the `InstNode` is a jump.
+ kNodeFlagIsJmp = 0x0008,
+ //! Whether the `InstNode` is a conditional jump.
+ kNodeFlagIsJcc = 0x0010,
+
+ //! Whether the `InstNode` is an unconditinal jump or conditional
+ //! jump that is likely to be taken.
+ kNodeFlagIsTaken = 0x0020,
+
+ //! Whether the `Node` will return from a function.
+ //!
+ //! This flag is used by both `EndNode` and `RetNode`.
+ kNodeFlagIsRet = 0x0040,
+
+ //! Whether the instruction is special.
+ kNodeFlagIsSpecial = 0x0080,
+
+ //! Whether the instruction is an FPU instruction.
+ kNodeFlagIsFp = 0x0100
+};
+
+// ============================================================================
+// [asmjit::MemCell]
+// ============================================================================
+
+struct MemCell {
+ ASMJIT_NO_COPY(MemCell)
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get cell offset.
+ ASMJIT_INLINE int32_t getOffset() const { return _offset; }
+ //! Set cell offset.
+ ASMJIT_INLINE void setOffset(int32_t offset) { _offset = offset; }
+
+ //! Get cell size.
+ ASMJIT_INLINE uint32_t getSize() const { return _size; }
+ //! Set cell size.
+ ASMJIT_INLINE void setSize(uint32_t size) { _size = size; }
+
+ //! Get cell alignment.
+ ASMJIT_INLINE uint32_t getAlignment() const { return _alignment; }
+ //! Set cell alignment.
+ ASMJIT_INLINE void setAlignment(uint32_t alignment) { _alignment = alignment; }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Next active cell.
+ MemCell* _next;
+
+ //! Offset, relative to base-offset.
+ int32_t _offset;
+ //! Size.
+ uint32_t _size;
+ //! Alignment.
+ uint32_t _alignment;
+};
+
+// ============================================================================
+// [asmjit::Var]
+// ============================================================================
+
+//! Base class for all variables.
+struct Var : public Operand {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE Var() : Operand(NoInit) {
+ _init_packed_op_sz_b0_b1_id(kOperandTypeVar, 0, 0, 0, kInvalidValue);
+ _init_packed_d2_d3(kInvalidValue, kInvalidValue);
+ }
+
+ ASMJIT_INLINE Var(const Var& other) : Operand(other) {}
+
+ explicit ASMJIT_INLINE Var(const _NoInit&) : Operand(NoInit) {}
+
+ // --------------------------------------------------------------------------
+ // [Var Specific]
+ // --------------------------------------------------------------------------
+
+ //! Clone `Var` operand.
+ ASMJIT_INLINE Var clone() const {
+ return Var(*this);
+ }
+
+ //! Reset Var operand.
+ ASMJIT_INLINE void reset() {
+ _init_packed_op_sz_b0_b1_id(kOperandTypeVar, 0, kInvalidReg, kInvalidReg, kInvalidValue);
+ _init_packed_d2_d3(kInvalidValue, kInvalidValue);
+ }
+
+ //! Get whether the variable has been initialized by `Compiler`.
+ ASMJIT_INLINE bool isInitialized() const {
+ return _vreg.id != kInvalidValue;
+ }
+
+ //! Get variable type.
+ ASMJIT_INLINE uint32_t getVarType() const {
+ return _vreg.vType;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Operator Overload]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE Var& operator=(const Var& other) { _copy(other); return *this; }
+
+ ASMJIT_INLINE bool operator==(const Var& other) const { return _packed[0] == other._packed[0]; }
+ ASMJIT_INLINE bool operator!=(const Var& other) const { return !operator==(other); }
+};
+
+// ============================================================================
+// [asmjit::VarBits]
+// ============================================================================
+
+//! Bit-array used by variable-liveness analysis.
+struct VarBits {
+ // --------------------------------------------------------------------------
+ // [Enums]
+ // --------------------------------------------------------------------------
+
+ enum {
+ kEntitySize = static_cast(sizeof(uintptr_t)),
+ kEntityBits = kEntitySize * 8
+ };
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE uintptr_t getBit(uint32_t index) const {
+ return (data[index / kEntityBits] >> (index % kEntityBits)) & 1;
+ }
+
+ ASMJIT_INLINE void setBit(uint32_t index) {
+ data[index / kEntityBits] |= static_cast(1) << (index % kEntityBits);
+ }
+
+ ASMJIT_INLINE void delBit(uint32_t index) {
+ data[index / kEntityBits] &= ~(static_cast(1) << (index % kEntityBits));
+ }
+
+ // --------------------------------------------------------------------------
+ // [Ops]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE bool copyBits(const VarBits* s0, uint32_t len) {
+ uintptr_t r = 0;
+ for (uint32_t i = 0; i < len; i++) {
+ uintptr_t t = s0->data[i];
+ data[i] = t;
+ r |= t;
+ }
+ return r != 0;
+ }
+
+ ASMJIT_INLINE bool addBits(const VarBits* s0, uint32_t len) {
+ return addBits(this, s0, len);
+ }
+
+ ASMJIT_INLINE bool addBits(const VarBits* s0, const VarBits* s1, uint32_t len) {
+ uintptr_t r = 0;
+ for (uint32_t i = 0; i < len; i++) {
+ uintptr_t t = s0->data[i] | s1->data[i];
+ data[i] = t;
+ r |= t;
+ }
+ return r != 0;
+ }
+
+ ASMJIT_INLINE bool andBits(const VarBits* s1, uint32_t len) {
+ return andBits(this, s1, len);
+ }
+
+ ASMJIT_INLINE bool andBits(const VarBits* s0, const VarBits* s1, uint32_t len) {
+ uintptr_t r = 0;
+ for (uint32_t i = 0; i < len; i++) {
+ uintptr_t t = s0->data[i] & s1->data[i];
+ data[i] = t;
+ r |= t;
+ }
+ return r != 0;
+ }
+
+ ASMJIT_INLINE bool delBits(const VarBits* s1, uint32_t len) {
+ return delBits(this, s1, len);
+ }
+
+ ASMJIT_INLINE bool delBits(const VarBits* s0, const VarBits* s1, uint32_t len) {
+ uintptr_t r = 0;
+ for (uint32_t i = 0; i < len; i++) {
+ uintptr_t t = s0->data[i] & ~s1->data[i];
+ data[i] = t;
+ r |= t;
+ }
+ return r != 0;
+ }
+
+ ASMJIT_INLINE bool _addBitsDelSource(VarBits* s1, uint32_t len) {
+ return _addBitsDelSource(this, s1, len);
+ }
+
+ ASMJIT_INLINE bool _addBitsDelSource(const VarBits* s0, VarBits* s1, uint32_t len) {
+ uintptr_t r = 0;
+ for (uint32_t i = 0; i < len; i++) {
+ uintptr_t a = s0->data[i];
+ uintptr_t b = s1->data[i];
+
+ this->data[i] = a | b;
+ b &= ~a;
+
+ s1->data[i] = b;
+ r |= b;
+ }
+ return r != 0;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ uintptr_t data[1];
+};
+
+// ============================================================================
+// [asmjit::VarData]
+// ============================================================================
+
+//! Base variable data.
+struct VarData {
+ // --------------------------------------------------------------------------
+ // [Accessors - Base]
+ // --------------------------------------------------------------------------
+
+ //! Get variable name.
+ ASMJIT_INLINE const char* getName() const {
+ return _name;
+ }
+
+ //! Get variable id.
+ ASMJIT_INLINE uint32_t getId() const {
+ return _id;
+ }
+
+ //! Get variable type.
+ ASMJIT_INLINE uint32_t getType() const {
+ return _type;
+ }
+
+ //! Get variable class.
+ ASMJIT_INLINE uint32_t getClass() const {
+ return _class;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - ContextId]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the variable has context id.
+ ASMJIT_INLINE bool hasContextId() const {
+ return _contextId != kInvalidValue;
+ }
+
+ //! Get context variable id (used only by `Context)`.
+ ASMJIT_INLINE uint32_t getContextId() const {
+ return _contextId;
+ }
+
+ //! Set context variable id (used only by `Context)`.
+ ASMJIT_INLINE void setContextId(uint32_t contextId) {
+ _contextId = contextId;
+ }
+
+ //! Reset context variable id (used only by `Context)`.
+ ASMJIT_INLINE void resetContextId() {
+ _contextId = kInvalidValue;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - Priority]
+ // --------------------------------------------------------------------------
+
+ //! Get variable priority, used by compiler to decide which variable to spill.
+ ASMJIT_INLINE uint32_t getPriority() const {
+ return _priority;
+ }
+
+ //! Set variable priority.
+ ASMJIT_INLINE void setPriority(uint32_t priority) {
+ ASMJIT_ASSERT(priority <= 0xFF);
+ _priority = static_cast(priority);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - State]
+ // --------------------------------------------------------------------------
+
+ //! Get variable state, only used by `Context`.
+ ASMJIT_INLINE uint32_t getState() const {
+ return _state;
+ }
+
+ //! Set variable state, only used by `Context`.
+ ASMJIT_INLINE void setState(uint32_t state) {
+ ASMJIT_ASSERT(state <= 0xFF);
+ _state = static_cast(state);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - RegIndex]
+ // --------------------------------------------------------------------------
+
+ //! Get register index.
+ ASMJIT_INLINE uint32_t getRegIndex() const {
+ return _regIndex;
+ }
+
+ //! Set register index.
+ ASMJIT_INLINE void setRegIndex(uint32_t regIndex) {
+ ASMJIT_ASSERT(regIndex <= 0xFF);
+ _regIndex = static_cast(regIndex);
+ }
+
+ //! Reset register index.
+ ASMJIT_INLINE void resetRegIndex() {
+ _regIndex = static_cast(kInvalidReg);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - HomeIndex/Mask]
+ // --------------------------------------------------------------------------
+
+ //! Get home registers mask.
+ ASMJIT_INLINE uint32_t getHomeMask() const {
+ return _homeMask;
+ }
+
+ //! Add a home register index to the home registers mask.
+ ASMJIT_INLINE void addHomeIndex(uint32_t regIndex) {
+ _homeMask |= IntUtil::mask(regIndex);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - Flags]
+ // --------------------------------------------------------------------------
+
+ //! Get variable flags.
+ ASMJIT_INLINE uint32_t getFlags() const {
+ return _flags;
+ }
+
+ //! Get whether the VarData is only memory allocated on the stack.
+ ASMJIT_INLINE bool isStack() const { return static_cast(_isStack); }
+
+ //! Get whether the variable is a function argument passed through memory.
+ ASMJIT_INLINE bool isMemArg() const { return static_cast(_isMemArg); }
+
+ //! Get variable content can be calculated by a simple instruction.
+ ASMJIT_INLINE bool isCalculated() const { return static_cast(_isCalculated); }
+ //! Get whether to save variable when it's unused (spill).
+ ASMJIT_INLINE bool saveOnUnuse() const { return static_cast(_saveOnUnuse); }
+
+ //! Get whether the variable was changed.
+ ASMJIT_INLINE bool isModified() const { return static_cast(_modified); }
+ //! Set whether the variable was changed.
+ ASMJIT_INLINE void setModified(bool modified) { _modified = modified; }
+
+ //! Get variable alignment.
+ ASMJIT_INLINE uint32_t getAlignment() const { return _alignment; }
+ //! Get variable size.
+ ASMJIT_INLINE uint32_t getSize() const { return _size; }
+
+ //! Get home memory offset.
+ ASMJIT_INLINE int32_t getMemOffset() const { return _memOffset; }
+ //! Set home memory offset.
+ ASMJIT_INLINE void setMemOffset(int32_t offset) { _memOffset = offset; }
+
+ //! Get home memory cell.
+ ASMJIT_INLINE MemCell* getMemCell() const { return _memCell; }
+ //! Set home memory cell.
+ ASMJIT_INLINE void setMemCell(MemCell* cell) { _memCell = cell; }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - Temporary Usage]
+ // --------------------------------------------------------------------------
+
+ //! Get temporary VarAttr.
+ ASMJIT_INLINE VarAttr* getVa() const { return _va; }
+ //! Set temporary VarAttr.
+ ASMJIT_INLINE void setVa(VarAttr* va) { _va = va; }
+ //! Reset temporary VarAttr.
+ ASMJIT_INLINE void resetVa() { _va = NULL; }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Variable name.
+ const char* _name;
+
+ //! Variable id.
+ uint32_t _id;
+ //! Context variable id, used by `Context` only, initially `kInvalidValue`.
+ uint32_t _contextId;
+
+ //! Variable type.
+ uint8_t _type;
+ //! Variable class.
+ uint8_t _class;
+ //! Variable flags.
+ uint8_t _flags;
+ //! Variable priority.
+ uint8_t _priority;
+
+ //! Variable state (connected with actual `VarState)`.
+ uint8_t _state;
+ //! Actual register index (only used by `Context)`, during translate.
+ uint8_t _regIndex;
+
+ //! Whether the variable is only used as memory allocated on the stack.
+ uint8_t _isStack : 1;
+ //! Whether the variable is a function argument passed through memory.
+ uint8_t _isMemArg : 1;
+ //! Whether variable content can be calculated by a simple instruction.
+ //!
+ //! This is used mainly by MMX and SSE2 code. This flag indicates that
+ //! register allocator should never reserve memory for this variable, because
+ //! the content can be generated by a single instruction (for example PXOR).
+ uint8_t _isCalculated : 1;
+ //! Save on unuse (at end of the variable scope).
+ uint8_t _saveOnUnuse : 1;
+ //! Whether variable was changed (connected with actual `VarState)`.
+ uint8_t _modified : 1;
+ //! \internal
+ uint8_t _reserved0 : 3;
+ //! Variable natural alignment.
+ uint8_t _alignment;
+
+ //! Variable size.
+ uint32_t _size;
+
+ //! Mask of all registers variable has been allocated to.
+ uint32_t _homeMask;
+
+ //! Home memory offset.
+ int32_t _memOffset;
+ //! Home memory cell, used by `Context` (initially NULL).
+ MemCell* _memCell;
+
+ //! Register read access statistics.
+ uint32_t rReadCount;
+ //! Register write access statistics.
+ uint32_t rWriteCount;
+
+ //! Memory read statistics.
+ uint32_t mReadCount;
+ //! Memory write statistics.
+ uint32_t mWriteCount;
+
+ // --------------------------------------------------------------------------
+ // [Members - Temporary Usage]
+ // --------------------------------------------------------------------------
+
+ // These variables are only used during register allocation. They are
+ // initialized by init() phase and reset by cleanup() phase.
+
+ union {
+ //! Temporary link to VarAttr* used by the `Context` used in
+ //! various phases, but always set back to NULL when finished.
+ //!
+ //! This temporary data is designed to be used by algorithms that need to
+ //! store some data into variables themselves during compilation. But it's
+ //! expected that after variable is compiled & translated the data is set
+ //! back to zero/null. Initial value is NULL.
+ VarAttr* _va;
+
+ //! \internal
+ //!
+ //! Same as `_va` just provided as `uintptr_t`.
+ uintptr_t _vaUInt;
+ };
+};
+
+// ============================================================================
+// [asmjit::VarAttr]
+// ============================================================================
+
+struct VarAttr {
+ // --------------------------------------------------------------------------
+ // [Setup]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void setup(VarData* vd, uint32_t flags = 0, uint32_t inRegs = 0, uint32_t allocableRegs = 0) {
+ _vd = vd;
+ _flags = flags;
+ _varCount = 0;
+ _inRegIndex = kInvalidReg;
+ _outRegIndex = kInvalidReg;
+ _reserved = 0;
+ _inRegs = inRegs;
+ _allocableRegs = allocableRegs;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get VarData.
+ ASMJIT_INLINE VarData* getVd() const { return _vd; }
+ //! Set VarData.
+ ASMJIT_INLINE void setVd(VarData* vd) { _vd = vd; }
+
+ //! Get flags.
+ ASMJIT_INLINE uint32_t getFlags() const { return _flags; }
+ //! Set flags.
+ ASMJIT_INLINE void setFlags(uint32_t flags) { _flags = flags; }
+
+ //! Get whether `flag` is on.
+ ASMJIT_INLINE bool hasFlag(uint32_t flag) { return (_flags & flag) != 0; }
+ //! Add `flags`.
+ ASMJIT_INLINE void orFlags(uint32_t flags) { _flags |= flags; }
+ //! Mask `flags`.
+ ASMJIT_INLINE void andFlags(uint32_t flags) { _flags &= flags; }
+ //! Clear `flags`.
+ ASMJIT_INLINE void andNotFlags(uint32_t flags) { _flags &= ~flags; }
+
+ //! Get how many times the variable is used by the instruction/node.
+ ASMJIT_INLINE uint32_t getVarCount() const { return _varCount; }
+ //! Set how many times the variable is used by the instruction/node.
+ ASMJIT_INLINE void setVarCount(uint32_t count) { _varCount = static_cast(count); }
+ //! Add how many times the variable is used by the instruction/node.
+ ASMJIT_INLINE void addVarCount(uint32_t count = 1) { _varCount += static_cast(count); }
+
+ //! Get whether the variable has to be allocated in a specific input register.
+ ASMJIT_INLINE uint32_t hasInRegIndex() const { return _inRegIndex != kInvalidReg; }
+ //! Get the input register index or `kInvalidReg`.
+ ASMJIT_INLINE uint32_t getInRegIndex() const { return _inRegIndex; }
+ //! Set the input register index.
+ ASMJIT_INLINE void setInRegIndex(uint32_t index) { _inRegIndex = static_cast(index); }
+ //! Reset the input register index.
+ ASMJIT_INLINE void resetInRegIndex() { _inRegIndex = kInvalidReg; }
+
+ //! Get whether the variable has to be allocated in a specific output register.
+ ASMJIT_INLINE uint32_t hasOutRegIndex() const { return _outRegIndex != kInvalidReg; }
+ //! Get the output register index or `kInvalidReg`.
+ ASMJIT_INLINE uint32_t getOutRegIndex() const { return _outRegIndex; }
+ //! Set the output register index.
+ ASMJIT_INLINE void setOutRegIndex(uint32_t index) { _outRegIndex = static_cast(index); }
+ //! Reset the output register index.
+ ASMJIT_INLINE void resetOutRegIndex() { _outRegIndex = kInvalidReg; }
+
+ //! Get whether the mandatory input registers are in used.
+ ASMJIT_INLINE bool hasInRegs() const { return _inRegs != 0; }
+ //! Get mandatory input registers (mask).
+ ASMJIT_INLINE uint32_t getInRegs() const { return _inRegs; }
+ //! Set mandatory input registers (mask).
+ ASMJIT_INLINE void setInRegs(uint32_t mask) { _inRegs = mask; }
+ //! Add mandatory input registers (mask).
+ ASMJIT_INLINE void addInRegs(uint32_t mask) { _inRegs |= mask; }
+ //! And mandatory input registers (mask).
+ ASMJIT_INLINE void andInRegs(uint32_t mask) { _inRegs &= mask; }
+ //! Clear mandatory input registers (mask).
+ ASMJIT_INLINE void delInRegs(uint32_t mask) { _inRegs &= ~mask; }
+
+ //! Get allocable input registers (mask).
+ ASMJIT_INLINE uint32_t getAllocableRegs() const { return _allocableRegs; }
+ //! Set allocable input registers (mask).
+ ASMJIT_INLINE void setAllocableRegs(uint32_t mask) { _allocableRegs = mask; }
+ //! Add allocable input registers (mask).
+ ASMJIT_INLINE void addAllocableRegs(uint32_t mask) { _allocableRegs |= mask; }
+ //! And allocable input registers (mask).
+ ASMJIT_INLINE void andAllocableRegs(uint32_t mask) { _allocableRegs &= mask; }
+ //! Clear allocable input registers (mask).
+ ASMJIT_INLINE void delAllocableRegs(uint32_t mask) { _allocableRegs &= ~mask; }
+
+ // --------------------------------------------------------------------------
+ // [Operator Overload]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE VarAttr& operator=(const VarAttr& other) {
+ ::memcpy(this, &other, sizeof(VarAttr));
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ VarData* _vd;
+ //! Flags.
+ uint32_t _flags;
+
+ union {
+ struct {
+ //! How many times the variable is used by the instruction/node.
+ uint8_t _varCount;
+ //! Input register index or `kInvalidReg` if it's not given.
+ //!
+ //! Even if the input register index is not given (i.e. it may by any
+ //! register), register allocator should assign an index that will be
+ //! used to persist a variable into this specific index. It's helpful
+ //! in situations where one variable has to be allocated in multiple
+ //! registers to determine the register which will be persistent.
+ uint8_t _inRegIndex;
+ //! Output register index or `kInvalidReg` if it's not given.
+ //!
+ //! Typically `kInvalidReg` if variable is only used on input.
+ uint8_t _outRegIndex;
+ //! \internal
+ uint8_t _reserved;
+ };
+
+ //! \internal
+ //!
+ //! Packed data #0.
+ uint32_t _packed;
+ };
+
+ //! Mandatory input registers.
+ //!
+ //! Mandatory input registers are required by the instruction even if
+ //! there are duplicates. This schema allows us to allocate one variable
+ //! in one or more register when needed. Required mostly by instructions
+ //! that have implicit register operands (imul, cpuid, ...) and function
+ //! call.
+ uint32_t _inRegs;
+
+ //! Allocable input registers.
+ //!
+ //! Optional input registers is a mask of all allocable registers for a given
+ //! variable where we have to pick one of them. This mask is usually not used
+ //! when _inRegs is set. If both masks are used then the register
+ //! allocator tries first to find an intersection between these and allocates
+ //! an extra slot if not found.
+ uint32_t _allocableRegs;
+};
+
+// ============================================================================
+// [asmjit::VarMap]
+// ============================================================================
+
+//! Variables' map related to a single node (instruction / other node).
+struct VarMap {
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get count of variables (all).
+ ASMJIT_INLINE uint32_t getVaCount() const {
+ return _vaCount;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Variables count.
+ uint32_t _vaCount;
+};
+
+// ============================================================================
+// [asmjit::VarState]
+// ============================================================================
+
+//! Variables' state.
+struct VarState {};
+
+// ============================================================================
+// [asmjit::TypeId / VarMapping]
+// ============================================================================
+
+//! Function builder 'void' type.
+struct Void {};
+
+//! Function builder 'int8_t' type.
+struct Int8Type {};
+//! Function builder 'uint8_t' type.
+struct UInt8Type {};
+
+//! Function builder 'int16_t' type.
+struct Int16Type {};
+//! Function builder 'uint16_t' type.
+struct UInt16Type {};
+
+//! Function builder 'int32_t' type.
+struct Int32Type {};
+//! Function builder 'uint32_t' type.
+struct UInt32Type {};
+
+//! Function builder 'int64_t' type.
+struct Int64Type {};
+//! Function builder 'uint64_t' type.
+struct UInt64Type {};
+
+//! Function builder 'intptr_t' type.
+struct IntPtrType {};
+//! Function builder 'uintptr_t' type.
+struct UIntPtrType {};
+
+//! Function builder 'float' type.
+struct FloatType {};
+//! Function builder 'double' type.
+struct DoubleType {};
+
+#if !defined(ASMJIT_DOCGEN)
+template
+struct TypeId {
+ enum { kId = static_cast(::asmjit::kInvalidVar) };
+};
+
+template
+struct TypeId {
+ enum { kId = kVarTypeIntPtr };
+};
+
+#define ASMJIT_TYPE_ID(_T_, _Id_) \
+ template<> \
+ struct TypeId<_T_> { enum { kId = _Id_ }; }
+
+ASMJIT_TYPE_ID(void, kInvalidVar);
+ASMJIT_TYPE_ID(Void, kInvalidVar);
+
+ASMJIT_TYPE_ID(int8_t, kVarTypeInt8);
+ASMJIT_TYPE_ID(Int8Type, kVarTypeInt8);
+
+ASMJIT_TYPE_ID(uint8_t, kVarTypeUInt8);
+ASMJIT_TYPE_ID(UInt8Type, kVarTypeUInt8);
+
+ASMJIT_TYPE_ID(int16_t, kVarTypeInt16);
+ASMJIT_TYPE_ID(Int16Type, kVarTypeInt16);
+
+ASMJIT_TYPE_ID(uint16_t, kVarTypeUInt8);
+ASMJIT_TYPE_ID(UInt16Type, kVarTypeUInt8);
+
+ASMJIT_TYPE_ID(int32_t, kVarTypeInt32);
+ASMJIT_TYPE_ID(Int32Type, kVarTypeUInt8);
+
+ASMJIT_TYPE_ID(uint32_t, kVarTypeUInt32);
+ASMJIT_TYPE_ID(UInt32Type, kVarTypeUInt8);
+
+ASMJIT_TYPE_ID(int64_t, kVarTypeInt64);
+ASMJIT_TYPE_ID(Int64Type, kVarTypeUInt8);
+
+ASMJIT_TYPE_ID(uint64_t, kVarTypeUInt64);
+ASMJIT_TYPE_ID(UInt64Type, kVarTypeUInt8);
+
+ASMJIT_TYPE_ID(float, kVarTypeFp32);
+ASMJIT_TYPE_ID(FloatType, kVarTypeFp32);
+
+ASMJIT_TYPE_ID(double, kVarTypeFp64);
+ASMJIT_TYPE_ID(DoubleType, kVarTypeFp64);
+#endif // !ASMJIT_DOCGEN
+
+// ============================================================================
+// [asmjit::FuncInOut]
+// ============================================================================
+
+//! Function in/out - argument or return value translated from `FuncPrototype`.
+struct FuncInOut {
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE uint32_t getVarType() const { return _varType; }
+
+ ASMJIT_INLINE bool hasRegIndex() const { return _regIndex != kInvalidReg; }
+ ASMJIT_INLINE uint32_t getRegIndex() const { return _regIndex; }
+
+ ASMJIT_INLINE bool hasStackOffset() const { return _stackOffset != kFuncStackInvalid; }
+ ASMJIT_INLINE int32_t getStackOffset() const { return static_cast(_stackOffset); }
+
+ //! Get whether the argument / return value is assigned.
+ ASMJIT_INLINE bool isSet() const {
+ return (_regIndex != kInvalidReg) | (_stackOffset != kFuncStackInvalid);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Reset]
+ // --------------------------------------------------------------------------
+
+ //! Reset the function argument to "unassigned state".
+ ASMJIT_INLINE void reset() { _packed = 0xFFFFFFFF; }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ union {
+ struct {
+ //! Variable type, see `kVarType`.
+ uint8_t _varType;
+ //! Register index if argument / return value is a register.
+ uint8_t _regIndex;
+ //! Stack offset if argument / return value is on the stack.
+ int16_t _stackOffset;
+ };
+
+ //! All members packed into single 32-bit integer.
+ uint32_t _packed;
+ };
+};
+
+// ============================================================================
+// [asmjit::FuncPrototype]
+// ============================================================================
+
+//! Function prototype.
+//!
+//! Function prototype contains information about function return type, count
+//! of arguments and their types. Function prototype is a low level structure
+//! which doesn't contain platform specific or calling convention specific
+//! information. Function prototype is used to create a `FuncDecl`.
+struct FuncPrototype {
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get function return value.
+ ASMJIT_INLINE uint32_t getRet() const { return _ret; }
+
+ //! Get function arguments' IDs.
+ ASMJIT_INLINE const uint32_t* getArgList() const { return _argList; }
+ //! Get count of function arguments.
+ ASMJIT_INLINE uint32_t getArgCount() const { return _argCount; }
+
+ //! Get argument at index `id`.
+ ASMJIT_INLINE uint32_t getArg(uint32_t id) const {
+ ASMJIT_ASSERT(id < _argCount);
+ return _argList[id];
+ }
+
+ //! Set function definition - return type and arguments.
+ ASMJIT_INLINE void _setPrototype(uint32_t ret, const uint32_t* argList, uint32_t argCount) {
+ _ret = ret;
+ _argList = argList;
+ _argCount = argCount;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ uint32_t _ret;
+ uint32_t _argCount;
+ const uint32_t* _argList;
+};
+
+// ============================================================================
+// [asmjit::FuncBuilderX]
+// ============================================================================
+
+//! Custom function builder for up to 32 function arguments.
+struct FuncBuilderX : public FuncPrototype {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE FuncBuilderX() {
+ _setPrototype(kInvalidVar, _builderArgList, 0);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Set return type to `retType`.
+ ASMJIT_INLINE void setRet(uint32_t retType) {
+ _ret = retType;
+ }
+
+ ASMJIT_INLINE void setArg(uint32_t id, uint32_t type) {
+ ASMJIT_ASSERT(id < _argCount);
+ _builderArgList[id] = type;
+ }
+
+ ASMJIT_INLINE void addArg(uint32_t type) {
+ ASMJIT_ASSERT(_argCount < kFuncArgCount);
+ _builderArgList[_argCount++] = type;
+ }
+
+ template
+ ASMJIT_INLINE void setRetT() {
+ setRet(TypeId::kId);
+ }
+
+ template
+ ASMJIT_INLINE void setArgT(uint32_t id) {
+ setArg(id, TypeId::kId);
+ }
+
+ template
+ ASMJIT_INLINE void addArgT() {
+ addArg(TypeId::kId);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ uint32_t _builderArgList[kFuncArgCount];
+};
+
+//! \internal
+#define T(_Type_) TypeId<_Type_>::kId
+
+//! Function prototype (no args).
+template
+struct FuncBuilder0 : public FuncPrototype {
+ ASMJIT_INLINE FuncBuilder0() {
+ _setPrototype(T(RET), NULL, 0);
+ }
+};
+
+//! Function prototype (1 argument).
+template
+struct FuncBuilder1 : public FuncPrototype {
+ ASMJIT_INLINE FuncBuilder1() {
+ static const uint32_t args[] = { T(P0) };
+ _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args));
+ }
+};
+
+//! Function prototype (2 arguments).
+template
+struct FuncBuilder2 : public FuncPrototype {
+ ASMJIT_INLINE FuncBuilder2() {
+ static const uint32_t args[] = { T(P0), T(P1) };
+ _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args));
+ }
+};
+
+//! Function prototype (3 arguments).
+template
+struct FuncBuilder3 : public FuncPrototype {
+ ASMJIT_INLINE FuncBuilder3() {
+ static const uint32_t args[] = { T(P0), T(P1), T(P2) };
+ _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args));
+ }
+};
+
+//! Function prototype (4 arguments).
+template
+struct FuncBuilder4 : public FuncPrototype {
+ ASMJIT_INLINE FuncBuilder4() {
+ static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3) };
+ _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args));
+ }
+};
+
+//! Function prototype (5 arguments).
+template
+struct FuncBuilder5 : public FuncPrototype {
+ ASMJIT_INLINE FuncBuilder5() {
+ static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3), T(P4) };
+ _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args));
+ }
+};
+
+//! Function prototype (6 arguments).
+template
+struct FuncBuilder6 : public FuncPrototype {
+ ASMJIT_INLINE FuncBuilder6() {
+ static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3), T(P4), T(P5) };
+ _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args));
+ }
+};
+
+//! Function prototype (7 arguments).
+template
+struct FuncBuilder7 : public FuncPrototype {
+ ASMJIT_INLINE FuncBuilder7() {
+ static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3), T(P4), T(P5), T(P6) };
+ _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args));
+ }
+};
+
+//! Function prototype (8 arguments).
+template
+struct FuncBuilder8 : public FuncPrototype {
+ ASMJIT_INLINE FuncBuilder8() {
+ static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3), T(P4), T(P5), T(P6), T(P7) };
+ _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args));
+ }
+};
+
+//! Function prototype (9 arguments).
+template
+struct FuncBuilder9 : public FuncPrototype {
+ ASMJIT_INLINE FuncBuilder9() {
+ static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3), T(P4), T(P5), T(P6), T(P7), T(P8) };
+ _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args));
+ }
+};
+
+//! Function prototype (10 arguments).
+template
+struct FuncBuilder10 : public FuncPrototype {
+ ASMJIT_INLINE FuncBuilder10() {
+ static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3), T(P4), T(P5), T(P6), T(P7), T(P8), T(P9) };
+ _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args));
+ }
+};
+
+#undef T
+
+// ============================================================================
+// [asmjit::FuncDecl]
+// ============================================================================
+
+//! Function declaration.
+struct FuncDecl {
+ // --------------------------------------------------------------------------
+ // [Accessors - Calling Convention]
+ // --------------------------------------------------------------------------
+
+ //! Get function calling convention, see `kFuncConv`.
+ ASMJIT_INLINE uint32_t getConvention() const { return _convention; }
+
+ //! Get whether the callee pops the stack.
+ ASMJIT_INLINE uint32_t getCalleePopsStack() const { return _calleePopsStack; }
+
+ //! Get direction of arguments passed on the stack.
+ //!
+ //! Direction should be always `kFuncDirRtl`.
+ //!
+ //! \note This is related to used calling convention, it's not affected by
+ //! number of function arguments or their types.
+ ASMJIT_INLINE uint32_t getDirection() const { return _direction; }
+
+ //! Get stack size needed for function arguments passed on the stack.
+ ASMJIT_INLINE uint32_t getArgStackSize() const { return _argStackSize; }
+ //! Get size of "Red Zone".
+ ASMJIT_INLINE uint32_t getRedZoneSize() const { return _redZoneSize; }
+ //! Get size of "Spill Zone".
+ ASMJIT_INLINE uint32_t getSpillZoneSize() const { return _spillZoneSize; }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - Arguments and Return]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the function has a return value.
+ ASMJIT_INLINE bool hasRet() const { return _retCount != 0; }
+ //! Get count of function return values.
+ ASMJIT_INLINE uint32_t getRetCount() const { return _retCount; }
+
+ //! Get function return value.
+ ASMJIT_INLINE FuncInOut& getRet(uint32_t index = kFuncRetLo) { return _retList[index]; }
+ //! Get function return value.
+ ASMJIT_INLINE const FuncInOut& getRet(uint32_t index = kFuncRetLo) const { return _retList[index]; }
+
+ //! Get count of function arguments.
+ ASMJIT_INLINE uint32_t getArgCount() const { return _argCount; }
+
+ //! Get function arguments array.
+ ASMJIT_INLINE FuncInOut* getArgList() { return _argList; }
+ //! Get function arguments array (const).
+ ASMJIT_INLINE const FuncInOut* getArgList() const { return _argList; }
+
+ //! Get function argument at index `index`.
+ ASMJIT_INLINE FuncInOut& getArg(size_t index) {
+ ASMJIT_ASSERT(index < kFuncArgCountLoHi);
+ return _argList[index];
+ }
+
+ //! Get function argument at index `index`.
+ ASMJIT_INLINE const FuncInOut& getArg(size_t index) const {
+ ASMJIT_ASSERT(index < kFuncArgCountLoHi);
+ return _argList[index];
+ }
+
+ ASMJIT_INLINE void resetArg(size_t index) {
+ ASMJIT_ASSERT(index < kFuncArgCountLoHi);
+ _argList[index].reset();
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Calling convention.
+ uint8_t _convention;
+ //! Whether a callee pops stack.
+ uint8_t _calleePopsStack : 1;
+ //! Direction for arguments passed on the stack, see `kFuncDir`.
+ uint8_t _direction : 1;
+ //! Reserved #0 (alignment).
+ uint8_t _reserved0 : 6;
+
+ //! Count of arguments in `_argList`.
+ uint8_t _argCount;
+ //! Count of return value(s).
+ uint8_t _retCount;
+
+ //! Count of bytes consumed by arguments on the stack (aligned).
+ uint32_t _argStackSize;
+
+ //! Size of "Red Zone".
+ //!
+ //! \note Used by AMD64-ABI (128 bytes).
+ uint16_t _redZoneSize;
+
+ //! Size of "Spill Zone".
+ //!
+ //! \note Used by WIN64-ABI (32 bytes).
+ uint16_t _spillZoneSize;
+
+ //! Function arguments (including HI arguments) mapped to physical
+ //! registers and stack offset.
+ FuncInOut _argList[kFuncArgCountLoHi];
+
+ //! Function return value(s).
+ FuncInOut _retList[2];
+};
+
+// ============================================================================
+// [asmjit::Node]
+// ============================================================================
+
+//! Base node.
+//!
+//! `Every` node represents an abstract instruction, directive, label, or
+//! macro-instruction generated by compiler.
+struct Node {
+ ASMJIT_NO_COPY(Node)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create new `Node`.
+ //!
+ //! \note Always use compiler to create nodes.
+ ASMJIT_INLINE Node(Compiler* compiler, uint32_t type); // Defined-Later.
+
+ //! Destroy `Node`.
+ ASMJIT_INLINE ~Node() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors - List]
+ // --------------------------------------------------------------------------
+
+ //! Get previous node in the compiler stream.
+ ASMJIT_INLINE Node* getPrev() const {
+ return _prev;
+ }
+
+ //! Get next node in the compiler stream.
+ ASMJIT_INLINE Node* getNext() const {
+ return _next;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - Comment]
+ // --------------------------------------------------------------------------
+
+ //! Get comment string.
+ ASMJIT_INLINE const char* getComment() const {
+ return _comment;
+ }
+
+ //! Set comment string to `str`.
+ ASMJIT_INLINE void setComment(const char* comment) {
+ _comment = comment;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - Type and Flags]
+ // --------------------------------------------------------------------------
+
+ //! Get node type, see `kNodeType`.
+ ASMJIT_INLINE uint32_t getType() const {
+ return _type;
+ }
+
+ //! Get node flags.
+ ASMJIT_INLINE uint32_t getFlags() const {
+ return _flags;
+ }
+
+ //! Get whether the instruction has flag `flag`.
+ ASMJIT_INLINE bool hasFlag(uint32_t flag) const {
+ return (static_cast(_flags) & flag) != 0;
+ }
+
+ //! Set node flags to `flags`.
+ ASMJIT_INLINE void setFlags(uint32_t flags) {
+ _flags = static_cast(flags);
+ }
+
+ //! Add instruction `flags`.
+ ASMJIT_INLINE void orFlags(uint32_t flags) {
+ _flags |= static_cast(flags);
+ }
+
+ //! And instruction `flags`.
+ ASMJIT_INLINE void andFlags(uint32_t flags) {
+ _flags &= static_cast(flags);
+ }
+
+ //! Clear instruction `flags`.
+ ASMJIT_INLINE void andNotFlags(uint32_t flags) {
+ _flags &= ~static_cast(flags);
+ }
+
+ //! Get whether the node has beed fetched.
+ ASMJIT_INLINE bool isFetched() const {
+ return _flowId != 0;
+ }
+
+ //! Get whether the node has been translated.
+ ASMJIT_INLINE bool isTranslated() const {
+ return hasFlag(kNodeFlagIsTranslated);
+ }
+
+ //! Get whether the node has been translated.
+ ASMJIT_INLINE bool isScheduled() const {
+ return hasFlag(kNodeFlagIsScheduled);
+ }
+
+ //! Get whether the node is informative only and can be safely removed after
+ //! translation.
+ //!
+ //! Informative nodes are comments and hints.
+ ASMJIT_INLINE bool isInformative() const {
+ return hasFlag(kNodeFlagIsInformative);
+ }
+
+ //! Whether the node is `InstNode` and unconditional jump.
+ ASMJIT_INLINE bool isJmp() const { return hasFlag(kNodeFlagIsJmp); }
+ //! Whether the node is `InstNode` and conditional jump.
+ ASMJIT_INLINE bool isJcc() const { return hasFlag(kNodeFlagIsJcc); }
+ //! Whether the node is `InstNode` and conditional/unconditional jump.
+ ASMJIT_INLINE bool isJmpOrJcc() const { return hasFlag(kNodeFlagIsJmp | kNodeFlagIsJcc); }
+ //! Whether the node is `InstNode` and return.
+ ASMJIT_INLINE bool isRet() const { return hasFlag(kNodeFlagIsRet); }
+
+ //! Get whether the node is `InstNode` and the instruction is special.
+ ASMJIT_INLINE bool isSpecial() const { return hasFlag(kNodeFlagIsSpecial); }
+ //! Get whether the node is `InstNode` and the instruction uses x87-FPU.
+ ASMJIT_INLINE bool isFp() const { return hasFlag(kNodeFlagIsFp); }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - FlowId]
+ // --------------------------------------------------------------------------
+
+ //! Get flow index.
+ ASMJIT_INLINE uint32_t getFlowId() const { return _flowId; }
+ //! Set flow index.
+ ASMJIT_INLINE void setFlowId(uint32_t flowId) { _flowId = flowId; }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - VarMap]
+ // --------------------------------------------------------------------------
+
+ //! Get whether node contains variable allocation instructions.
+ ASMJIT_INLINE bool hasMap() const {
+ return _map != NULL;
+ }
+
+ //! Get variable allocation instructions.
+ ASMJIT_INLINE VarMap* getMap() const {
+ return _map;
+ }
+
+ //! Get variable allocation instructions casted to `T*`.
+ template
+ ASMJIT_INLINE T* getMap() const {
+ return static_cast(_map);
+ }
+
+ //! Set variable allocation instructions.
+ ASMJIT_INLINE void setMap(VarMap* map) {
+ _map = map;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - VarState]
+ // --------------------------------------------------------------------------
+
+ //! Get node state.
+ ASMJIT_INLINE VarState* getState() const {
+ return _state;
+ }
+
+ //! Get node state casted to `T*`.
+ template
+ ASMJIT_INLINE T* getState() const {
+ return static_cast(_state);
+ }
+
+ //! Set node state.
+ ASMJIT_INLINE void setState(VarState* state) {
+ _state = state;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors - Liveness]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the node has variable liveness bits.
+ ASMJIT_INLINE bool hasLiveness() const {
+ return _liveness != NULL;
+ }
+
+ //! Get variable liveness bits.
+ ASMJIT_INLINE VarBits* getLiveness() const {
+ return _liveness;
+ }
+
+ //! Set variable liveness bits.
+ ASMJIT_INLINE void setLiveness(VarBits* liveness) {
+ _liveness = liveness;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Previous node.
+ Node* _prev;
+ //! Next node.
+ Node* _next;
+
+ //! Node type, see `kNodeType`.
+ uint8_t _type;
+ //! Operands count (if the node has operands, otherwise zero).
+ uint8_t _opCount;
+ //! Node flags, different meaning for every node type.
+ uint16_t _flags;
+
+ //! Flow index.
+ uint32_t _flowId;
+
+ //! Inline comment string, initially set to NULL.
+ const char* _comment;
+
+ //! Variable mapping (VarAttr to VarData), initially NULL, filled during
+ //! fetch phase.
+ VarMap* _map;
+
+ //! Variable liveness bits (initially NULL, filled by analysis phase).
+ VarBits* _liveness;
+
+ //! Saved state.
+ //!
+ //! Initially NULL, not all nodes have saved state, only branch/flow control
+ //! nodes.
+ VarState* _state;
+};
+
+// ============================================================================
+// [asmjit::AlignNode]
+// ============================================================================
+
+//! Align node.
+struct AlignNode : public Node {
+ ASMJIT_NO_COPY(AlignNode)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `AlignNode` instance.
+ ASMJIT_INLINE AlignNode(Compiler* compiler, uint32_t mode, uint32_t offset) :
+ Node(compiler, kNodeTypeAlign) {
+
+ _mode = mode;
+ _offset = offset;
+ }
+
+ //! Destroy the `AlignNode` instance.
+ ASMJIT_INLINE ~AlignNode() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get alignment mode.
+ ASMJIT_INLINE uint32_t getMode() const {
+ return _mode;
+ }
+
+ //! Set alignment mode.
+ ASMJIT_INLINE void setMode(uint32_t mode) {
+ _mode = mode;
+ }
+
+ //! Get align offset in bytes.
+ ASMJIT_INLINE uint32_t getOffset() const {
+ return _offset;
+ }
+
+ //! Set align offset in bytes to `offset`.
+ ASMJIT_INLINE void setOffset(uint32_t offset) {
+ _offset = offset;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Alignment mode, see \ref kAlignMode.
+ uint32_t _mode;
+ //! Alignment offset in bytes.
+ uint32_t _offset;
+};
+
+// ============================================================================
+// [asmjit::EmbedNode]
+// ============================================================================
+
+//! Embed node.
+//!
+//! Embed node is used to embed data into final assembler stream. The data is
+//! considered to be RAW; No analysis is performed on RAW data.
+struct EmbedNode : public Node {
+ ASMJIT_NO_COPY(EmbedNode)
+
+ // --------------------------------------------------------------------------
+ // [Enums]
+ // --------------------------------------------------------------------------
+
+ enum { kInlineBufferSize = 8 };
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `EmbedNode` instance.
+ ASMJIT_INLINE EmbedNode(Compiler* compiler, void* data, uint32_t size) :
+ Node(compiler, kNodeTypeEmbed) {
+
+ _size = size;
+ if (size <= kInlineBufferSize) {
+ if (data != NULL)
+ ::memcpy(_data.buf, data, size);
+ }
+ else {
+ _data.ptr = static_cast(data);
+ }
+ }
+
+ //! Destroy the `EmbedNode` instance.
+ ASMJIT_INLINE ~EmbedNode() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get pointer to data.
+ uint8_t* getData() { return getSize() <= kInlineBufferSize ? const_cast(_data.buf) : _data.ptr; }
+ //! Get size of data.
+ uint32_t getSize() const { return _size; }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Size of the embedded data.
+ uint32_t _size;
+
+ union {
+ //! data buffer.
+ uint8_t buf[kInlineBufferSize];
+ //! Data buffer.
+ uint8_t* ptr;
+ } _data;
+};
+
+// ============================================================================
+// [asmjit::CommentNode]
+// ============================================================================
+
+//! Comment node.
+//!
+//! Comments allows to comment your assembler stream for better debugging
+//! and visualization. Comments are usually ignored in release builds unless
+//! the logger is present.
+struct CommentNode : public Node {
+ ASMJIT_NO_COPY(CommentNode)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `CommentNode` instance.
+ ASMJIT_INLINE CommentNode(Compiler* compiler, const char* comment) : Node(compiler, kNodeTypeComment) {
+ orFlags(kNodeFlagIsInformative);
+ _comment = comment;
+ }
+
+ //! Destroy the `CommentNode` instance.
+ ASMJIT_INLINE ~CommentNode() {}
+};
+
+// ============================================================================
+// [asmjit::HintNode]
+// ============================================================================
+
+//! Hint node.
+struct HintNode : public Node {
+ ASMJIT_NO_COPY(HintNode)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `HintNode` instance.
+ ASMJIT_INLINE HintNode(Compiler* compiler, VarData* vd, uint32_t hint, uint32_t value) :
+ Node(compiler, kNodeTypeHint) {
+
+ orFlags(kNodeFlagIsInformative);
+ _vd = vd;
+ _hint = hint;
+ _value = value;
+ }
+
+ //! Destroy the `HintNode` instance.
+ ASMJIT_INLINE ~HintNode() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get variable.
+ ASMJIT_INLINE VarData* getVd() const { return _vd; }
+
+ //! Get hint it (see `kVarHint)`.
+ ASMJIT_INLINE uint32_t getHint() const{ return _hint; }
+ //! Set hint it (see `kVarHint)`.
+ ASMJIT_INLINE void setHint(uint32_t hint) { _hint = hint; }
+
+ //! Get hint value.
+ ASMJIT_INLINE uint32_t getValue() const { return _value; }
+ //! Set hint value.
+ ASMJIT_INLINE void setValue(uint32_t value) { _value = value; }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Variable.
+ VarData* _vd;
+ //! Hint id.
+ uint32_t _hint;
+ //! Value.
+ uint32_t _value;
+};
+
+// ============================================================================
+// [asmjit::TargetNode]
+// ============================================================================
+
+//! label node.
+struct TargetNode : public Node {
+ ASMJIT_NO_COPY(TargetNode)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `TargetNode` instance.
+ ASMJIT_INLINE TargetNode(Compiler* compiler, uint32_t labelId) : Node(compiler, kNodeTypeTarget) {
+ _id = labelId;
+ _numRefs = 0;
+ _offset = -1;
+ _from = NULL;
+ }
+
+ //! Destroy the `TargetNode` instance.
+ ASMJIT_INLINE ~TargetNode() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get target label.
+ ASMJIT_INLINE Label getLabel() const { return Label(_id); }
+ //! Get target label id.
+ ASMJIT_INLINE uint32_t getLabelId() const { return _id; }
+
+ //! Get first jmp instruction.
+ ASMJIT_INLINE JumpNode* getFrom() const { return _from; }
+
+ //! Get whether the node has assigned state.
+ ASMJIT_INLINE bool hasState() const { return _state != NULL; }
+ //! Get state for this target.
+ ASMJIT_INLINE VarState* getState() const { return _state; }
+ //! Set state for this target.
+ ASMJIT_INLINE void setState(VarState* state) { _state = state; }
+
+ //! Get number of jumps to this target.
+ ASMJIT_INLINE uint32_t getNumRefs() const { return _numRefs; }
+ //! Set number of jumps to this target.
+ ASMJIT_INLINE void setNumRefs(uint32_t i) { _numRefs = i; }
+
+ //! Add number of jumps to this target.
+ ASMJIT_INLINE void addNumRefs(uint32_t i = 1) { _numRefs += i; }
+ //! Subtract number of jumps to this target.
+ ASMJIT_INLINE void subNumRefs(uint32_t i = 1) { _numRefs -= i; }
+
+ //! Get the label offset.
+ //!
+ //! \note Only valid after the content has been serialized to the `Assembler`.
+ ASMJIT_INLINE intptr_t getOffset() const { return _offset; }
+
+ //! Set the label offset.
+ ASMJIT_INLINE void setOffset(intptr_t offset) { _offset = offset; }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Label id.
+ uint32_t _id;
+ //! Count of jumps here.
+ uint32_t _numRefs;
+
+ //! Label offset, after serialization.
+ intptr_t _offset;
+ //! First jump instruction that points to this target (label).
+ JumpNode* _from;
+};
+
+// ============================================================================
+// [asmjit::InstNode]
+// ============================================================================
+
+//! Instruction node.
+struct InstNode : public Node {
+ ASMJIT_NO_COPY(InstNode)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `InstNode` instance.
+ ASMJIT_INLINE InstNode(Compiler* compiler, uint32_t instId, uint32_t instOptions, Operand* opList, uint32_t opCount) :
+ Node(compiler, kNodeTypeInst) {
+
+ _instId = static_cast(instId);
+ _reserved = 0;
+ _instOptions = instOptions;
+
+ _opCount = static_cast(opCount);
+ _opList = opList;
+
+ _updateMemOp();
+ }
+
+ //! Destroy the `InstNode` instance.
+ ASMJIT_INLINE ~InstNode() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get instruction ID, see `kX86InstId`.
+ ASMJIT_INLINE uint32_t getInstId() const {
+ return _instId;
+ }
+
+ //! Set instruction ID to `instId`.
+ //!
+ //! Please do not modify instruction code if you don't know what are you
+ //! doing. Incorrect instruction code or operands can cause assertion failure.
+ ASMJIT_INLINE void setInstId(uint32_t instId) {
+ _instId = static_cast(instId);
+ }
+
+ //! Whether the instruction is an unconditional jump or whether the
+ //! instruction is a conditional jump which is likely to be taken.
+ ASMJIT_INLINE bool isTaken() const {
+ return hasFlag(kNodeFlagIsTaken);
+ }
+
+ //! Get emit options.
+ ASMJIT_INLINE uint32_t getOptions() const {
+ return _instOptions;
+ }
+ //! Set emit options.
+ ASMJIT_INLINE void setOptions(uint32_t options) {
+ _instOptions = options;
+ }
+ //! Add emit options.
+ ASMJIT_INLINE void addOptions(uint32_t options) {
+ _instOptions |= options;
+ }
+ //! Mask emit options.
+ ASMJIT_INLINE void andOptions(uint32_t options) {
+ _instOptions &= options;
+ }
+ //! Clear emit options.
+ ASMJIT_INLINE void delOptions(uint32_t options) {
+ _instOptions &= ~options;
+ }
+
+ //! Get operands list.
+ ASMJIT_INLINE Operand* getOpList() {
+ return _opList;
+ }
+ //! \overload
+ ASMJIT_INLINE const Operand* getOpList() const {
+ return _opList;
+ }
+
+ //! Get operands count.
+ ASMJIT_INLINE uint32_t getOpCount() const {
+ return _opCount;
+ }
+
+ //! Get whether the instruction contains a memory operand.
+ ASMJIT_INLINE bool hasMemOp() const {
+ return _memOpIndex != 0xFF;
+ }
+
+ //! Set memory operand index (in opList), 0xFF means that instruction
+ //! doesn't have a memory operand.
+ ASMJIT_INLINE void setMemOpIndex(uint32_t index) {
+ _memOpIndex = static_cast(index);
+ }
+ //! Reset memory operand index, setting it to 0xFF.
+ ASMJIT_INLINE void resetMemOpIndex() {
+ _memOpIndex = 0xFF;
+ }
+
+ //! Get memory operand.
+ //!
+ //! Can only be called if the instruction has such operand, see `hasMemOp()`.
+ ASMJIT_INLINE BaseMem* getMemOp() const {
+ ASMJIT_ASSERT(hasMemOp());
+ return static_cast(&_opList[_memOpIndex]);
+ }
+
+ //! \overload
+ template
+ ASMJIT_INLINE T* getMemOp() const {
+ ASMJIT_ASSERT(hasMemOp());
+ return static_cast(&_opList[_memOpIndex]);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Utils]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void _updateMemOp() {
+ Operand* opList = getOpList();
+ uint32_t opCount = getOpCount();
+
+ uint32_t i;
+ for (i = 0; i < opCount; i++)
+ if (opList[i].isMem())
+ goto _Update;
+ i = 0xFF;
+
+_Update:
+ setMemOpIndex(i);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Instruction ID, see `kInstId`.
+ uint16_t _instId;
+ //! \internal
+ uint8_t _memOpIndex;
+ //! \internal
+ uint8_t _reserved;
+ //! Instruction options, see `kInstOptions`.
+ uint32_t _instOptions;
+
+ //! Operands list.
+ Operand* _opList;
+};
+
+// ============================================================================
+// [asmjit::JumpNode]
+// ============================================================================
+
+//! Jump node.
+struct JumpNode : public InstNode {
+ ASMJIT_NO_COPY(JumpNode)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE JumpNode(Compiler* compiler, uint32_t code, uint32_t options, Operand* opList, uint32_t opCount) :
+ InstNode(compiler, code, options, opList, opCount) {}
+ ASMJIT_INLINE ~JumpNode() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE TargetNode* getTarget() const { return _target; }
+ ASMJIT_INLINE JumpNode* getJumpNext() const { return _jumpNext; }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Target node.
+ TargetNode* _target;
+ //! Next jump to the same target in a single linked-list.
+ JumpNode *_jumpNext;
+};
+
+// ============================================================================
+// [asmjit::FuncNode]
+// ============================================================================
+
+//! Function declaration node.
+//!
+//! Functions are base blocks for generating assembler output. Each generated
+//! assembler stream needs standard entry and leave sequences which are compatible
+//! with the operating system ABI.
+//!
+//! `FuncNode` can be used to generate function prolog and epilog which are
+//! compatible with a given function calling convention and to allocate and
+//! manage variables that can be allocated/spilled during compilation phase.
+struct FuncNode : public Node {
+ ASMJIT_NO_COPY(FuncNode)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `FuncNode` instance.
+ //!
+ //! Always use `Compiler::addFunc()` to create a `FuncNode` instance.
+ ASMJIT_INLINE FuncNode(Compiler* compiler) :
+ Node(compiler, kNodeTypeFunc),
+ _entryNode(NULL),
+ _exitNode(NULL),
+ _decl(NULL),
+ _end(NULL),
+ _argList(NULL),
+ _funcHints(IntUtil::mask(kFuncHintNaked)),
+ _funcFlags(0),
+ _expectedStackAlignment(0),
+ _requiredStackAlignment(0),
+ _redZoneSize(0),
+ _spillZoneSize(0),
+ _argStackSize(0),
+ _memStackSize(0),
+ _callStackSize(0) {}
+
+ //! Destroy the `FuncNode` instance.
+ ASMJIT_INLINE ~FuncNode() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get function entry `TargetNode`.
+ ASMJIT_INLINE TargetNode* getEntryNode() const { return _entryNode; }
+ //! Get function exit `TargetNode`.
+ ASMJIT_INLINE TargetNode* getExitNode() const { return _exitNode; }
+
+ //! Get function entry label.
+ ASMJIT_INLINE Label getEntryLabel() const { return _entryNode->getLabel(); }
+ //! Get function exit label.
+ ASMJIT_INLINE Label getExitLabel() const { return _exitNode->getLabel(); }
+
+ //! Get function `EndNode`.
+ ASMJIT_INLINE EndNode* getEnd() const { return _end; }
+ //! Get function declaration.
+ ASMJIT_INLINE FuncDecl* getDecl() const { return _decl; }
+
+ //! Get arguments list.
+ ASMJIT_INLINE VarData** getArgList() const { return _argList; }
+ //! Get arguments count.
+ ASMJIT_INLINE uint32_t getArgCount() const { return _decl->getArgCount(); }
+
+ //! Get argument at `i`.
+ ASMJIT_INLINE VarData* getArg(uint32_t i) const {
+ ASMJIT_ASSERT(i < getArgCount());
+ return _argList[i];
+ }
+
+ //! Set argument at `i`.
+ ASMJIT_INLINE void setArg(uint32_t i, VarData* vd) {
+ ASMJIT_ASSERT(i < getArgCount());
+ _argList[i] = vd;
+ }
+
+ //! Reset argument at `i`.
+ ASMJIT_INLINE void resetArg(uint32_t i) {
+ ASMJIT_ASSERT(i < getArgCount());
+ _argList[i] = NULL;
+ }
+
+ //! Get function hints.
+ ASMJIT_INLINE uint32_t getFuncHints() const { return _funcHints; }
+ //! Get function flags.
+ ASMJIT_INLINE uint32_t getFuncFlags() const { return _funcFlags; }
+
+ //! Get whether the _funcFlags has `flag`
+ ASMJIT_INLINE bool hasFuncFlag(uint32_t flag) const { return (_funcFlags & flag) != 0; }
+ //! Set function `flag`.
+ ASMJIT_INLINE void addFuncFlags(uint32_t flags) { _funcFlags |= flags; }
+ //! Clear function `flag`.
+ ASMJIT_INLINE void clearFuncFlags(uint32_t flags) { _funcFlags &= ~flags; }
+
+ //! Get whether the function is naked.
+ ASMJIT_INLINE bool isNaked() const { return hasFuncFlag(kFuncFlagIsNaked); }
+ //! Get whether the function is also a caller.
+ ASMJIT_INLINE bool isCaller() const { return hasFuncFlag(kFuncFlagIsCaller); }
+ //! Get whether the required stack alignment is lower than expected one,
+ //! thus it has to be aligned manually.
+ ASMJIT_INLINE bool isStackMisaligned() const { return hasFuncFlag(kFuncFlagIsStackMisaligned); }
+ //! Get whether the stack pointer is adjusted inside function prolog/epilog.
+ ASMJIT_INLINE bool isStackAdjusted() const { return hasFuncFlag(kFuncFlagIsStackAdjusted); }
+
+ //! Get whether the function is finished.
+ ASMJIT_INLINE bool isFinished() const { return hasFuncFlag(kFuncFlagIsFinished); }
+
+ //! Get expected stack alignment.
+ ASMJIT_INLINE uint32_t getExpectedStackAlignment() const { return _expectedStackAlignment; }
+ //! Set expected stack alignment.
+ ASMJIT_INLINE void setExpectedStackAlignment(uint32_t alignment) { _expectedStackAlignment = alignment; }
+
+ //! Get required stack alignment.
+ ASMJIT_INLINE uint32_t getRequiredStackAlignment() const { return _requiredStackAlignment; }
+ //! Set required stack alignment.
+ ASMJIT_INLINE void setRequiredStackAlignment(uint32_t alignment) { _requiredStackAlignment = alignment; }
+
+ //! Update required stack alignment so it's not lower than expected
+ //! stack alignment.
+ ASMJIT_INLINE void updateRequiredStackAlignment() {
+ if (_requiredStackAlignment <= _expectedStackAlignment) {
+ _requiredStackAlignment = _expectedStackAlignment;
+ clearFuncFlags(kFuncFlagIsStackMisaligned);
+ }
+ else {
+ addFuncFlags(kFuncFlagIsStackMisaligned);
+ }
+ }
+
+ //! Set stack "Red Zone" size.
+ ASMJIT_INLINE uint32_t getRedZoneSize() const { return _redZoneSize; }
+ //! Get stack "Red Zone" size.
+ ASMJIT_INLINE void setRedZoneSize(uint32_t s) { _redZoneSize = static_cast(s); }
+
+ //! Set stack "Spill Zone" size.
+ ASMJIT_INLINE uint32_t getSpillZoneSize() const { return _spillZoneSize; }
+ //! Get stack "Spill Zone" size.
+ ASMJIT_INLINE void setSpillZoneSize(uint32_t s) { _spillZoneSize = static_cast(s); }
+
+ //! Get stack size used by function arguments.
+ ASMJIT_INLINE uint32_t getArgStackSize() const { return _argStackSize; }
+
+ //! Get stack size used by variables and memory allocated on the stack.
+ ASMJIT_INLINE uint32_t getMemStackSize() const { return _memStackSize; }
+
+ //! Get stack size used by function calls.
+ ASMJIT_INLINE uint32_t getCallStackSize() const { return _callStackSize; }
+ //! Merge stack size used by function call with `s`.
+ ASMJIT_INLINE void mergeCallStackSize(uint32_t s) { if (_callStackSize < s) _callStackSize = s; }
+
+ // --------------------------------------------------------------------------
+ // [Hints]
+ // --------------------------------------------------------------------------
+
+ //! Set function hint.
+ ASMJIT_INLINE void setHint(uint32_t hint, uint32_t value) {
+ ASMJIT_ASSERT(hint <= 31);
+ ASMJIT_ASSERT(value <= 1);
+
+ _funcHints &= ~(1 << hint);
+ _funcHints |= (value << hint);
+ }
+
+ //! Get function hint.
+ ASMJIT_INLINE uint32_t getHint(uint32_t hint) const {
+ ASMJIT_ASSERT(hint <= 31);
+ return (_funcHints >> hint) & 0x1;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Function entry.
+ TargetNode* _entryNode;
+ //! Function exit.
+ TargetNode* _exitNode;
+
+ //! Function declaration.
+ FuncDecl* _decl;
+ //! Function end.
+ EndNode* _end;
+
+ //! Arguments list as `VarData`.
+ VarData** _argList;
+
+ //! Function hints;
+ uint32_t _funcHints;
+ //! Function flags.
+ uint32_t _funcFlags;
+
+ //! Expected stack alignment (we depend on this value).
+ //!
+ //! \note It can be global alignment given by the OS or described by an
+ //! target platform ABI.
+ uint32_t _expectedStackAlignment;
+ //! Required stack alignment (usually for multimedia instructions).
+ uint32_t _requiredStackAlignment;
+
+ //! The "Red Zone" size - count of bytes which might be accessed without
+ //! adjusting the stack pointer.
+ uint16_t _redZoneSize;
+ //! Spill zone size (used by WIN64 ABI).
+ uint16_t _spillZoneSize;
+
+ //! Stack size needed for function arguments.
+ uint32_t _argStackSize;
+ //! Stack size needed for all variables and memory allocated on the stack.
+ uint32_t _memStackSize;
+ //! Stack size needed to call other functions.
+ uint32_t _callStackSize;
+};
+
+// ============================================================================
+// [asmjit::EndNode]
+// ============================================================================
+
+//! End of function/block node.
+struct EndNode : public Node {
+ ASMJIT_NO_COPY(EndNode)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `EndNode` instance.
+ ASMJIT_INLINE EndNode(Compiler* compiler) : Node(compiler, kNodeTypeEnd) {
+ _flags |= kNodeFlagIsRet;
+ }
+
+ //! Destroy the `EndNode` instance.
+ ASMJIT_INLINE ~EndNode() {}
+};
+
+// ============================================================================
+// [asmjit::RetNode]
+// ============================================================================
+
+//! Function return node.
+struct RetNode : public Node {
+ ASMJIT_NO_COPY(RetNode)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `RetNode` instance.
+ ASMJIT_INLINE RetNode(Compiler* compiler, const Operand& o0, const Operand& o1) : Node(compiler, kNodeTypeRet) {
+ _flags |= kNodeFlagIsRet;
+ _ret[0] = o0;
+ _ret[1] = o1;
+ }
+
+ //! Destroy the `RetNode` instance.
+ ASMJIT_INLINE ~RetNode() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get the first return operand.
+ ASMJIT_INLINE Operand& getFirst() { return _ret[0]; }
+ //! \overload
+ ASMJIT_INLINE const Operand& getFirst() const { return _ret[0]; }
+
+ //! Get the second return operand.
+ ASMJIT_INLINE Operand& getSecond() { return _ret[1]; }
+ //! \overload
+ ASMJIT_INLINE const Operand& getSecond() const { return _ret[1]; }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Ret operand(s).
+ Operand _ret[2];
+};
+
+// ============================================================================
+// [asmjit::CallNode]
+// ============================================================================
+
+//! Function-call node.
+struct CallNode : public Node {
+ ASMJIT_NO_COPY(CallNode)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `CallNode` instance.
+ ASMJIT_INLINE CallNode(Compiler* compiler, const Operand& target) :
+ Node(compiler, kNodeTypeCall),
+ _decl(NULL),
+ _target(target),
+ _args(NULL) {}
+
+ //! Destroy the `CallNode` instance.
+ ASMJIT_INLINE ~CallNode() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get function declaration.
+ ASMJIT_INLINE FuncDecl* getDecl() const { return _decl; }
+
+ //! Get target operand.
+ ASMJIT_INLINE Operand& getTarget() { return _target; }
+ //! \overload
+ ASMJIT_INLINE const Operand& getTarget() const { return _target; }
+
+ //! Get return at `i`.
+ ASMJIT_INLINE Operand& getRet(uint32_t i = 0) {
+ ASMJIT_ASSERT(i < 2);
+ return _ret[i];
+ }
+ //! \overload
+ ASMJIT_INLINE const Operand& getRet(uint32_t i = 0) const {
+ ASMJIT_ASSERT(i < 2);
+ return _ret[i];
+ }
+
+ //! Get argument at `i`.
+ ASMJIT_INLINE Operand& getArg(uint32_t i) {
+ ASMJIT_ASSERT(i < kFuncArgCountLoHi);
+ return _args[i];
+ }
+ //! \overload
+ ASMJIT_INLINE const Operand& getArg(uint32_t i) const {
+ ASMJIT_ASSERT(i < kFuncArgCountLoHi);
+ return _args[i];
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Function declaration.
+ FuncDecl* _decl;
+
+ //! Target (address of function, register, label, ...).
+ Operand _target;
+ //! Return.
+ Operand _ret[2];
+ //! Arguments.
+ Operand* _args;
+};
+
+// ============================================================================
+// [asmjit::SArgNode]
+// ============================================================================
+
+//! Function-call 'argument on the stack' node.
+struct SArgNode : public Node {
+ ASMJIT_NO_COPY(SArgNode)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `SArgNode` instance.
+ ASMJIT_INLINE SArgNode(Compiler* compiler, CallNode* call, VarData* sVd, VarData* cVd) :
+ Node(compiler, kNodeTypeSArg),
+ _call(call),
+ _sVd(sVd),
+ _cVd(cVd),
+ _args(0) {}
+
+ //! Destroy the `SArgNode` instance.
+ ASMJIT_INLINE ~SArgNode() {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get the associated function-call.
+ ASMJIT_INLINE CallNode* getCall() const { return _call; }
+ //! Get source variable.
+ ASMJIT_INLINE VarData* getSVd() const { return _sVd; }
+ //! Get conversion variable.
+ ASMJIT_INLINE VarData* getCVd() const { return _cVd; }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Associated `CallNode`.
+ CallNode* _call;
+ //! Source variable.
+ VarData* _sVd;
+ //! Temporary variable used for conversion (or NULL).
+ VarData* _cVd;
+
+ //! Affected arguments bit-array.
+ uint32_t _args;
+};
+
+//! \}
+
+// ============================================================================
+// [asmjit::Compiler]
+// ============================================================================
+
+//! \addtogroup asmjit_base_general
+//! \{
+
+//! Base compiler.
+//!
+//! \sa Assembler.
+struct ASMJIT_VCLASS Compiler : public CodeGen {
+ ASMJIT_NO_COPY(Compiler)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `Compiler` instance.
+ ASMJIT_API Compiler(Runtime* runtime);
+ //! Destroy the `Compiler` instance.
+ ASMJIT_API virtual ~Compiler();
+
+ // --------------------------------------------------------------------------
+ // [LookAhead]
+ // --------------------------------------------------------------------------
+
+ //! Get maximum look ahead.
+ ASMJIT_INLINE uint32_t getMaxLookAhead() const {
+ return _maxLookAhead;
+ }
+
+ //! Set maximum look ahead to `val`.
+ ASMJIT_INLINE void setMaxLookAhead(uint32_t val) {
+ _maxLookAhead = val;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Clear / Reset]
+ // --------------------------------------------------------------------------
+
+ //! Reset the compiler.
+ //!
+ //! If `releaseMemory` is true all buffers will be released to the system.
+ ASMJIT_API void reset(bool releaseMemory = false);
+
+ // --------------------------------------------------------------------------
+ // [Nodes]
+ // --------------------------------------------------------------------------
+
+ template
+ ASMJIT_INLINE T* newNode() {
+ void* p = _baseZone.alloc(sizeof(T));
+ return new(p) T(this);
+ }
+
+ template
+ ASMJIT_INLINE T* newNode(P0 p0) {
+ void* p = _baseZone.alloc(sizeof(T));
+ return new(p) T(this, p0);
+ }
+
+ template
+ ASMJIT_INLINE T* newNode(P0 p0, P1 p1) {
+ void* p = _baseZone.alloc(sizeof(T));
+ return new(p) T(this, p0, p1);
+ }
+
+ template
+ ASMJIT_INLINE T* newNode(P0 p0, P1 p1, P2 p2) {
+ void* p = _baseZone.alloc(sizeof(T));
+ return new(p) T(this, p0, p1, p2);
+ }
+
+ //! Get first node.
+ ASMJIT_INLINE Node* getFirstNode() const { return _firstNode; }
+ //! Get last node.
+ ASMJIT_INLINE Node* getLastNode() const { return _lastNode; }
+
+ //! Get current node.
+ //!
+ //! \note If this method returns `NULL` it means that nothing has been emitted
+ //! yet.
+ ASMJIT_INLINE Node* getCursor() const { return _cursor; }
+ //! Set the current node without returning the previous node (private).
+ ASMJIT_INLINE void _setCursor(Node* node) { _cursor = node; }
+ //! Set the current node to `node` and return the previous one.
+ ASMJIT_API Node* setCursor(Node* node);
+
+ //! Add node `node` after current and set current to `node`.
+ ASMJIT_API Node* addNode(Node* node);
+ //! Add node before `ref`.
+ ASMJIT_API Node* addNodeBefore(Node* node, Node* ref);
+ //! Add node after `ref`.
+ ASMJIT_API Node* addNodeAfter(Node* node, Node* ref);
+ //! Remove node `node`.
+ ASMJIT_API Node* removeNode(Node* node);
+ //! Remove multiple nodes.
+ ASMJIT_API void removeNodes(Node* first, Node* last);
+
+ // --------------------------------------------------------------------------
+ // [Func]
+ // --------------------------------------------------------------------------
+
+ //! Get current function.
+ ASMJIT_INLINE FuncNode* getFunc() const { return _func; }
+
+ // --------------------------------------------------------------------------
+ // [Align]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `AlignNode`.
+ ASMJIT_API AlignNode* newAlign(uint32_t mode, uint32_t offset);
+ //! Add a new `AlignNode`.
+ ASMJIT_API AlignNode* addAlign(uint32_t mode, uint32_t offset);
+
+ //! Align target buffer to `m` bytes.
+ //!
+ //! Typical usage of this is to align labels at start of the inner loops.
+ //!
+ //! Inserts `nop()` instructions or CPU optimized NOPs.
+ ASMJIT_INLINE AlignNode* align(uint32_t mode, uint32_t offset) {
+ return addAlign(mode, offset);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Target]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `TargetNode`.
+ ASMJIT_API TargetNode* newTarget();
+ //! Add a new `TargetNode`.
+ ASMJIT_API TargetNode* addTarget();
+
+ //! Get `TargetNode` by `id`.
+ ASMJIT_INLINE TargetNode* getTargetById(uint32_t id) {
+ ASMJIT_ASSERT(OperandUtil::isLabelId(id));
+ ASMJIT_ASSERT(id < _targetList.getLength());
+
+ return _targetList[id];
+ }
+
+ //! Get `TargetNode` by `label`.
+ ASMJIT_INLINE TargetNode* getTarget(const Label& label) {
+ return getTargetById(label.getId());
+ }
+
+ // --------------------------------------------------------------------------
+ // [Label]
+ // --------------------------------------------------------------------------
+
+ //! Get count of created labels.
+ ASMJIT_INLINE size_t getLabelsCount() const {
+ return _targetList.getLength();
+ }
+
+ //! Get whether `label` is created.
+ ASMJIT_INLINE bool isLabelValid(const Label& label) const {
+ return isLabelValid(label.getId());
+ }
+
+ //! \overload
+ ASMJIT_INLINE bool isLabelValid(uint32_t id) const {
+ return static_cast(id) < _targetList.getLength();
+ }
+
+ //! Get `TargetNode` by `label`.
+ ASMJIT_INLINE TargetNode* getTargetByLabel(const Label& label) {
+ return getTargetByLabel(label.getId());
+ }
+
+ //! \overload
+ ASMJIT_INLINE TargetNode* getTargetByLabel(uint32_t id) {
+ ASMJIT_ASSERT(isLabelValid(id));
+ return _targetList[id];
+ }
+
+ //! Get `label` offset or -1 if the label is not bound.
+ //!
+ //! This method can be only called after the code has been serialized to the
+ //! `Assembler`, otherwise the offset returned will be -1 (even if the label
+ //! has been bound).
+ ASMJIT_INLINE intptr_t getLabelOffset(const Label& label) const {
+ return getLabelOffset(label.getId());
+ }
+
+ //! \overload
+ ASMJIT_INLINE intptr_t getLabelOffset(uint32_t id) const {
+ ASMJIT_ASSERT(isLabelValid(id));
+ return _targetList[id]->getOffset();
+ }
+
+ //! \internal
+ //!
+ //! Create and initialize a new `Label`.
+ ASMJIT_API Error _newLabel(Label* dst);
+
+ //! Create and return a new `Label`.
+ ASMJIT_INLINE Label newLabel() {
+ Label result(NoInit);
+ _newLabel(&result);
+ return result;
+ }
+
+ //! Bind label to the current offset.
+ //!
+ //! \note Label can be bound only once!
+ ASMJIT_API Error bind(const Label& label);
+
+ // --------------------------------------------------------------------------
+ // [Embed]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `EmbedNode`.
+ ASMJIT_API EmbedNode* newEmbed(const void* data, uint32_t size);
+ //! Add a new `EmbedNode`.
+ ASMJIT_API EmbedNode* addEmbed(const void* data, uint32_t size);
+
+ //! Embed data.
+ ASMJIT_INLINE EmbedNode* embed(const void* data, uint32_t size) {
+ return addEmbed(data, size);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Comment]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `CommentNode`.
+ ASMJIT_API CommentNode* newComment(const char* str);
+ //! Add a new `CommentNode`.
+ ASMJIT_API CommentNode* addComment(const char* str);
+
+ //! Emit a single comment line.
+ ASMJIT_API CommentNode* comment(const char* fmt, ...);
+
+ // --------------------------------------------------------------------------
+ // [Hint]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `HintNode`.
+ ASMJIT_API HintNode* newHint(Var& var, uint32_t hint, uint32_t value);
+ //! Add a new `HintNode`.
+ ASMJIT_API HintNode* addHint(Var& var, uint32_t hint, uint32_t value);
+
+ // --------------------------------------------------------------------------
+ // [Vars]
+ // --------------------------------------------------------------------------
+
+ //! Get whether variable `var` is created.
+ ASMJIT_INLINE bool isVarValid(const Var& var) const {
+ return static_cast(var.getId() & kOperandIdNum) < _varList.getLength();
+ }
+
+ //! \internal
+ //!
+ //! Get `VarData` by `var`.
+ ASMJIT_INLINE VarData* getVd(const Var& var) const {
+ return getVdById(var.getId());
+ }
+
+ //! \internal
+ //!
+ //! Get `VarData` by `id`.
+ ASMJIT_INLINE VarData* getVdById(uint32_t id) const {
+ ASMJIT_ASSERT(id != kInvalidValue);
+ ASMJIT_ASSERT(static_cast(id & kOperandIdNum) < _varList.getLength());
+
+ return _varList[id & kOperandIdNum];
+ }
+
+ //! \internal
+ //!
+ //! Get an array of 'VarData*'.
+ ASMJIT_INLINE VarData** _getVdArray() const {
+ return const_cast(_varList.getData());
+ }
+
+ //! \internal
+ //!
+ //! Create a new `VarData`.
+ ASMJIT_API VarData* _newVd(uint32_t type, uint32_t size, uint32_t c, const char* name);
+
+ //! Create a new `Var`.
+ virtual Error _newVar(Var* var, uint32_t type, const char* name) = 0;
+
+ //! Alloc variable `var`.
+ ASMJIT_API void alloc(Var& var);
+ //! Alloc variable `var` using `regIndex` as a register index.
+ ASMJIT_API void alloc(Var& var, uint32_t regIndex);
+ //! Alloc variable `var` using `reg` as a register operand.
+ ASMJIT_API void alloc(Var& var, const Reg& reg);
+ //! Spill variable `var`.
+ ASMJIT_API void spill(Var& var);
+ //! Save variable `var` if the status is `modified` at this point.
+ ASMJIT_API void save(Var& var);
+ //! Unuse variable `var`.
+ ASMJIT_API void unuse(Var& var);
+
+ //! Alloc variable `var` (if initialized), but only if it's initialized.
+ ASMJIT_INLINE void allocUnsafe(Var& var) {
+ if (var.isInitialized())
+ alloc(var);
+ }
+
+ //! Alloc variable `var` (if initialized) using `regIndex` as a register index
+ ASMJIT_INLINE void allocUnsafe(Var& var, uint32_t regIndex) {
+ if (var.isInitialized())
+ alloc(var, regIndex);
+ }
+
+ //! Alloc variable `var` (if initialized) using `reg` as a register operand.
+ ASMJIT_INLINE void allocUnsafe(Var& var, const Reg& reg) {
+ if (var.isInitialized())
+ alloc(var, reg);
+ }
+
+ //! Spill variable `var` (if initialized).
+ ASMJIT_INLINE void spillUnsafe(Var& var) {
+ if (var.isInitialized())
+ spill(var);
+ }
+
+ //! Save variable `var` (if initialized) if the status is `modified` at this point.
+ ASMJIT_INLINE void saveUnsafe(Var& var) {
+ if (var.isInitialized())
+ save(var);
+ }
+
+ //! Unuse variable `var` (if initialized).
+ ASMJIT_INLINE void unuseUnsafe(Var& var) {
+ if (var.isInitialized())
+ unuse(var);
+ }
+
+ //! Get priority of variable `var`.
+ ASMJIT_API uint32_t getPriority(Var& var) const;
+ //! Set priority of variable `var` to `priority`.
+ ASMJIT_API void setPriority(Var& var, uint32_t priority);
+
+ //! Get save-on-unuse `var` property.
+ ASMJIT_API bool getSaveOnUnuse(Var& var) const;
+ //! Set save-on-unuse `var` property to `value`.
+ ASMJIT_API void setSaveOnUnuse(Var& var, bool value);
+
+ //! Rename variable `var` to `name`.
+ //!
+ //! \note Only new name will appear in the logger.
+ ASMJIT_API void rename(Var& var, const char* name);
+
+ // --------------------------------------------------------------------------
+ // [Stack]
+ // --------------------------------------------------------------------------
+
+ //! \internal
+ //!
+ //! Create a new memory chunk allocated on the current function's stack.
+ virtual Error _newStack(BaseMem* mem, uint32_t size, uint32_t alignment, const char* name) = 0;
+
+ // --------------------------------------------------------------------------
+ // [Const]
+ // --------------------------------------------------------------------------
+
+ //! \internal
+ //!
+ //! Put data to a constant-pool and get a memory reference to it.
+ virtual Error _newConst(BaseMem* mem, uint32_t scope, const void* data, size_t size) = 0;
+
+ // --------------------------------------------------------------------------
+ // [Assembler]
+ // --------------------------------------------------------------------------
+
+ //! Get an assembler instance that is associated with the compiler.
+ //!
+ //! \note One instance of `Assembler` is shared and has lifetime same as the
+ //! compiler, however, each call to `getAssembler()` resets the assembler so
+ //! new code can be serialized into it.
+ ASMJIT_API Assembler* getAssembler();
+
+ //! \internal
+ //!
+ //! Create a new `Assembler` instance associated with the compiler.
+ virtual Assembler* _newAssembler() = 0;
+
+ // --------------------------------------------------------------------------
+ // [Serialize]
+ // --------------------------------------------------------------------------
+
+ //! Serialize a compiled code to `assembler`.
+ virtual Error serialize(Assembler* assembler) = 0;
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Internal assembler.
+ Assembler* _assembler;
+
+ //! Flow id added to each node created (used only by `Context)`.
+ uint32_t _nodeFlowId;
+ //! Flags added to each node created (used only by `Context)`.
+ uint32_t _nodeFlags;
+
+ //! Maximum count of nodes to look ahead when allocating/spilling
+ //! registers.
+ uint32_t _maxLookAhead;
+
+ //! Variable mapping (translates incoming kVarType into target).
+ const uint8_t* _targetVarMapping;
+
+ //! First node.
+ Node* _firstNode;
+ //! Last node.
+ Node* _lastNode;
+
+ //! Current node.
+ Node* _cursor;
+ //! Current function.
+ FuncNode* _func;
+
+ //! Variable zone.
+ Zone _varZone;
+ //! String/data zone.
+ Zone _stringZone;
+ //! Local constant pool zone.
+ Zone _localConstZone;
+
+ //! TargetNode list.
+ PodVector _targetList;
+ //! VarData list.
+ PodVector _varList;
+
+ //! Local constant pool, flushed at the end of each function.
+ ConstPool _localConstPool;
+ //! Global constant pool, flushed at the end of the compilation.
+ ConstPool _globalConstPool;
+
+ //! Label to start of the local constant pool.
+ Label _localConstPoolLabel;
+ //! Label to start of the global constant pool.
+ Label _globalConstPoolLabel;
+};
+
+//! \}
+
+// ============================================================================
+// [Defined-Later]
+// ============================================================================
+
+ASMJIT_INLINE Label::Label(Compiler& c) : Operand(NoInit) {
+ c._newLabel(this);
+}
+
+ASMJIT_INLINE Node::Node(Compiler* compiler, uint32_t type) {
+ _prev = NULL;
+ _next = NULL;
+ _type = static_cast(type);
+ _opCount = 0;
+ _flags = static_cast(compiler->_nodeFlags);
+ _flowId = compiler->_nodeFlowId;
+ _comment = NULL;
+ _map = NULL;
+ _liveness = NULL;
+ _state = NULL;
+}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // !ASMJIT_DISABLE_COMPILER
+#endif // _ASMJIT_BASE_COMPILER_H
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/constpool.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/constpool.h
new file mode 100644
index 0000000..8f66b8b
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/constpool.h
@@ -0,0 +1,303 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Guard]
+#ifndef _ASMJIT_BASE_CONSTPOOL_H
+#define _ASMJIT_BASE_CONSTPOOL_H
+
+// [Dependencies - AsmJit]
+#include "../base/error.h"
+#include "../base/zone.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_util
+//! \{
+
+// ============================================================================
+// [asmjit::ConstPoolNode]
+// ============================================================================
+
+//! \internal
+//!
+//! Zone-allocated constant-pool node.
+struct ConstPoolNode {
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void* getData() const {
+ return static_cast(const_cast(this) + 1);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Left/Right nodes.
+ ConstPoolNode* _link[2];
+ //! Horizontal level for balance.
+ uint32_t _level : 31;
+ //! Whether this constant is shared with another.
+ uint32_t _shared : 1;
+ //! Data offset from the beginning of the pool.
+ uint32_t _offset;
+};
+
+// ============================================================================
+// [asmjit::ConstPoolTree]
+// ============================================================================
+
+//! \internal
+//!
+//! Zone-allocated constant-pool tree.
+struct ConstPoolTree {
+ enum {
+ //! Maximum tree height == log2(1 << 64).
+ kHeightLimit = 64
+ };
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE ConstPoolTree(size_t dataSize = 0) :
+ _root(NULL),
+ _length(0),
+ _dataSize(dataSize) {}
+ ASMJIT_INLINE ~ConstPoolTree() {}
+
+ // --------------------------------------------------------------------------
+ // [Reset]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void reset() {
+ _root = NULL;
+ _length = 0;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE bool isEmpty() const {
+ return _length == 0;
+ }
+
+ ASMJIT_INLINE size_t getLength() const {
+ return _length;
+ }
+
+ ASMJIT_INLINE void setDataSize(size_t dataSize) {
+ ASMJIT_ASSERT(isEmpty());
+ _dataSize = dataSize;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Ops]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API ConstPoolNode* get(const void* data);
+ ASMJIT_API void put(ConstPoolNode* node);
+
+ // --------------------------------------------------------------------------
+ // [Iterate]
+ // --------------------------------------------------------------------------
+
+ template
+ ASMJIT_INLINE void iterate(Visitor& visitor) const {
+ ConstPoolNode* node = const_cast(_root);
+ ConstPoolNode* link;
+
+ ConstPoolNode* stack[kHeightLimit];
+
+ if (node == NULL)
+ return;
+
+ size_t top = 0;
+
+ for (;;) {
+ link = node->_link[0];
+
+ if (link != NULL) {
+ ASMJIT_ASSERT(top != kHeightLimit);
+ stack[top++] = node;
+
+ node = link;
+ continue;
+ }
+
+_Visit:
+ visitor.visit(node);
+ link = node->_link[1];
+
+ if (link != NULL) {
+ node = link;
+ continue;
+ }
+
+ if (top == 0)
+ break;
+
+ node = stack[--top];
+ goto _Visit;
+ }
+ }
+
+ // --------------------------------------------------------------------------
+ // [Helpers]
+ // --------------------------------------------------------------------------
+
+ static ASMJIT_INLINE ConstPoolNode* _newNode(Zone* zone, const void* data, size_t size, size_t offset, bool shared) {
+ ConstPoolNode* node = zone->allocT(sizeof(ConstPoolNode) + size);
+ if (node == NULL)
+ return NULL;
+
+ node->_link[0] = NULL;
+ node->_link[1] = NULL;
+ node->_level = 1;
+ node->_shared = shared;
+ node->_offset = static_cast(offset);
+
+ ::memcpy(node->getData(), data, size);
+ return node;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Root of the tree
+ ConstPoolNode* _root;
+ //! Length of the tree (count of nodes).
+ size_t _length;
+ //! Size of the data.
+ size_t _dataSize;
+};
+
+// ============================================================================
+// [asmjit::ConstPoolGap]
+// ============================================================================
+
+//! \internal
+//!
+//! Zone-allocated constant-pool gap.
+struct ConstPoolGap {
+ //! Link to the next gap
+ ConstPoolGap* _next;
+ //! Offset of the gap.
+ size_t _offset;
+ //! Remaining bytes of the gap (basically a gap size).
+ size_t _length;
+};
+
+// ============================================================================
+// [asmjit::ConstPool]
+// ============================================================================
+
+//! Constant pool.
+struct ConstPool {
+ ASMJIT_NO_COPY(ConstPool)
+
+ enum {
+ kIndex1 = 0,
+ kIndex2 = 1,
+ kIndex4 = 2,
+ kIndex8 = 3,
+ kIndex16 = 4,
+ kIndex32 = 5,
+ kIndexCount = 6
+ };
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API ConstPool(Zone* zone);
+ ASMJIT_API ~ConstPool();
+
+ // --------------------------------------------------------------------------
+ // [Reset]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API void reset();
+
+ // --------------------------------------------------------------------------
+ // [Ops]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the constant-pool is empty.
+ ASMJIT_INLINE bool isEmpty() const {
+ return _size == 0;
+ }
+
+ //! Get the size of the constant-pool in bytes.
+ ASMJIT_INLINE size_t getSize() const {
+ return _size;
+ }
+
+ //! Get minimum alignment.
+ ASMJIT_INLINE size_t getAlignment() const {
+ return _alignment;
+ }
+
+ //! Add a constant to the constant pool.
+ //!
+ //! The constant must have known size, which is 1, 2, 4, 8, 16 or 32 bytes.
+ //! The constant is added to the pool only if it doesn't not exist, otherwise
+ //! cached value is returned.
+ //!
+ //! AsmJit is able to subdivide added constants, so for example if you add
+ //! 8-byte constant 0x1122334455667788 it will create the following slots:
+ //!
+ //! 8-byte: 0x1122334455667788
+ //! 4-byte: 0x11223344, 0x55667788
+ //!
+ //! The reason is that when combining MMX/SSE/AVX code some patterns are used
+ //! frequently. However, AsmJit is not able to reallocate a constant that has
+ //! been already added. For example if you try to add 4-byte constant and then
+ //! 8-byte constant having the same 4-byte pattern as the previous one, two
+ //! independent slots will be generated by the pool.
+ ASMJIT_API Error add(const void* data, size_t size, size_t& dstOffset);
+
+ // --------------------------------------------------------------------------
+ // [Fill]
+ // --------------------------------------------------------------------------
+
+ //! Fill the destination with the constants from the pool.
+ ASMJIT_API void fill(void* dst);
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Zone allocator.
+ Zone* _zone;
+ //! Tree per size.
+ ConstPoolTree _tree[kIndexCount];
+ //! Gaps per size.
+ ConstPoolGap* _gaps[kIndexCount];
+ //! Gaps pool
+ ConstPoolGap* _gapPool;
+
+ //! Size of the pool (in bytes).
+ size_t _size;
+ //! Alignemnt.
+ size_t _alignment;
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // _ASMJIT_BASE_CONSTPOOL_H
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/containers.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/containers.h
new file mode 100644
index 0000000..c6dc70d
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/containers.h
@@ -0,0 +1,350 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Guard]
+#ifndef _ASMJIT_BASE_CONTAINERS_H
+#define _ASMJIT_BASE_CONTAINERS_H
+
+// [Dependencies - AsmJit]
+#include "../base/error.h"
+#include "../base/globals.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_util
+//! \{
+
+// ============================================================================
+// [asmjit::PodVectorData]
+// ============================================================================
+
+//! \internal
+struct PodVectorData {
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get data.
+ ASMJIT_INLINE void* getData() const {
+ return (void*)(this + 1);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Capacity of the vector.
+ size_t capacity;
+ //! Length of the vector.
+ size_t length;
+};
+
+// ============================================================================
+// [asmjit::PodVectorBase]
+// ============================================================================
+
+//! \internal
+struct PodVectorBase {
+ static ASMJIT_API const PodVectorData _nullData;
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new instance of `PodVectorBase`.
+ ASMJIT_INLINE PodVectorBase() :
+ _d(const_cast(&_nullData)) {}
+
+ //! Destroy the `PodVectorBase` and data.
+ ASMJIT_INLINE ~PodVectorBase() {
+ reset(true);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Reset]
+ // --------------------------------------------------------------------------
+
+ //! Reset the vector data and set its `length` to zero.
+ //!
+ //! If `releaseMemory` is true the vector buffer will be released to the
+ //! system.
+ ASMJIT_API void reset(bool releaseMemory = false);
+
+ // --------------------------------------------------------------------------
+ // [Grow / Reserve]
+ // --------------------------------------------------------------------------
+
+protected:
+ ASMJIT_API Error _grow(size_t n, size_t sizeOfT);
+ ASMJIT_API Error _reserve(size_t n, size_t sizeOfT);
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+public:
+ PodVectorData* _d;
+};
+
+// ============================================================================
+// [asmjit::PodVector]
+// ============================================================================
+
+//! Template used to store and manage array of POD data.
+//!
+//! This template has these adventages over other vector<> templates:
+//! - Non-copyable (designed to be non-copyable, we want it)
+//! - No copy-on-write (some implementations of stl can use it)
+//! - Optimized for working only with POD types
+//! - Uses ASMJIT_... memory management macros
+template
+struct PodVector : PodVectorBase {
+ ASMJIT_NO_COPY(PodVector)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new instance of `PodVector`.
+ ASMJIT_INLINE PodVector() {}
+ //! Destroy the `PodVector<>` and data.
+ ASMJIT_INLINE ~PodVector() {}
+
+ // --------------------------------------------------------------------------
+ // [Data]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the vector is empty.
+ ASMJIT_INLINE bool isEmpty() const {
+ return _d->length == 0;
+ }
+
+ //! Get length.
+ ASMJIT_INLINE size_t getLength() const {
+ return _d->length;
+ }
+
+ //! Get capacity.
+ ASMJIT_INLINE size_t getCapacity() const {
+ return _d->capacity;
+ }
+
+ //! Get data.
+ ASMJIT_INLINE T* getData() {
+ return static_cast(_d->getData());
+ }
+
+ //! \overload
+ ASMJIT_INLINE const T* getData() const {
+ return static_cast(_d->getData());
+ }
+
+ // --------------------------------------------------------------------------
+ // [Grow / Reserve]
+ // --------------------------------------------------------------------------
+
+ //! Called to grow the buffer to fit at least `n` elements more.
+ ASMJIT_INLINE Error _grow(size_t n) {
+ return PodVectorBase::_grow(n, sizeof(T));
+ }
+
+ //! Realloc internal array to fit at least `n` items.
+ ASMJIT_INLINE Error _reserve(size_t n) {
+ return PodVectorBase::_reserve(n, sizeof(T));
+ }
+
+ // --------------------------------------------------------------------------
+ // [Ops]
+ // --------------------------------------------------------------------------
+
+ //! Prepend `item` to vector.
+ Error prepend(const T& item) {
+ PodVectorData* d = _d;
+
+ if (d->length == d->capacity) {
+ ASMJIT_PROPAGATE_ERROR(_grow(1));
+ _d = d;
+ }
+
+ ::memmove(static_cast(d->getData()) + 1, d->getData(), d->length * sizeof(T));
+ ::memcpy(d->getData(), &item, sizeof(T));
+
+ d->length++;
+ return kErrorOk;
+ }
+
+ //! Insert an `item` at the `index`.
+ Error insert(size_t index, const T& item) {
+ PodVectorData* d = _d;
+ ASMJIT_ASSERT(index <= d->length);
+
+ if (d->length == d->capacity) {
+ ASMJIT_PROPAGATE_ERROR(_grow(1));
+ d = _d;
+ }
+
+ T* dst = static_cast(d->getData()) + index;
+ ::memmove(dst + 1, dst, d->length - index);
+ ::memcpy(dst, &item, sizeof(T));
+
+ d->length++;
+ return kErrorOk;
+ }
+
+ //! Append `item` to vector.
+ Error append(const T& item) {
+ PodVectorData* d = _d;
+
+ if (d->length == d->capacity) {
+ ASMJIT_PROPAGATE_ERROR(_grow(1));
+ d = _d;
+ }
+
+ ::memcpy(static_cast(d->getData()) + d->length, &item, sizeof(T));
+
+ d->length++;
+ return kErrorOk;
+ }
+
+ //! Get index of `val` or `kInvalidIndex` if not found.
+ size_t indexOf(const T& val) const {
+ PodVectorData* d = _d;
+
+ const T* data = static_cast(d->getData());
+ size_t len = d->length;
+
+ for (size_t i = 0; i < len; i++)
+ if (data[i] == val)
+ return i;
+
+ return kInvalidIndex;
+ }
+
+ //! Remove item at index `i`.
+ void removeAt(size_t i) {
+ PodVectorData* d = _d;
+ ASMJIT_ASSERT(i < d->length);
+
+ T* data = static_cast(d->getData()) + i;
+ d->length--;
+ ::memmove(data, data + 1, d->length - i);
+ }
+
+ //! Swap this pod-vector with `other`.
+ void swap(PodVector& other) {
+ T* otherData = other._d;
+ other._d = _d;
+ _d = otherData;
+ }
+
+ //! Get item at index `i`.
+ ASMJIT_INLINE T& operator[](size_t i) {
+ ASMJIT_ASSERT(i < getLength());
+ return getData()[i];
+ }
+
+ //! Get item at index `i`.
+ ASMJIT_INLINE const T& operator[](size_t i) const {
+ ASMJIT_ASSERT(i < getLength());
+ return getData()[i];
+ }
+};
+
+// ============================================================================
+// [asmjit::PodList]
+// ============================================================================
+
+//! \internal
+template
+struct PodList {
+ ASMJIT_NO_COPY(PodList)
+
+ // --------------------------------------------------------------------------
+ // [Link]
+ // --------------------------------------------------------------------------
+
+ struct Link {
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get next node.
+ ASMJIT_INLINE Link* getNext() const { return _next; }
+
+ //! Get value.
+ ASMJIT_INLINE T getValue() const { return _value; }
+ //! Set value to `value`.
+ ASMJIT_INLINE void setValue(const T& value) { _value = value; }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ Link* _next;
+ T _value;
+ };
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE PodList() : _first(NULL), _last(NULL) {}
+ ASMJIT_INLINE ~PodList() {}
+
+ // --------------------------------------------------------------------------
+ // [Data]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE bool isEmpty() const { return _first != NULL; }
+
+ ASMJIT_INLINE Link* getFirst() const { return _first; }
+ ASMJIT_INLINE Link* getLast() const { return _last; }
+
+ // --------------------------------------------------------------------------
+ // [Ops]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void reset() {
+ _first = NULL;
+ _last = NULL;
+ }
+
+ ASMJIT_INLINE void prepend(Link* link) {
+ link->_next = _first;
+ if (_first == NULL)
+ _last = link;
+ _first = link;
+ }
+
+ ASMJIT_INLINE void append(Link* link) {
+ link->_next = NULL;
+ if (_first == NULL)
+ _first = link;
+ else
+ _last->_next = link;
+ _last = link;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ Link* _first;
+ Link* _last;
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // _ASMJIT_BASE_CONTAINERS_H
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/context_p.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/context_p.h
new file mode 100644
index 0000000..bd23501
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/context_p.h
@@ -0,0 +1,307 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Guard]
+#ifndef _ASMJIT_BASE_CONTEXT_P_H
+#define _ASMJIT_BASE_CONTEXT_P_H
+
+#include "../build.h"
+#if !defined(ASMJIT_DISABLE_COMPILER)
+
+// [Dependencies - AsmJit]
+#include "../base/compiler.h"
+#include "../base/zone.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_compiler
+//! \{
+
+// ============================================================================
+// [asmjit::Context]
+// ============================================================================
+
+//! \internal
+//!
+//! Code generation context is the logic behind `Compiler`. The context is
+//! used to compile the code stored in `Compiler`.
+struct Context {
+ ASMJIT_NO_COPY(Context)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ Context(Compiler* compiler);
+ virtual ~Context();
+
+ // --------------------------------------------------------------------------
+ // [Reset]
+ // --------------------------------------------------------------------------
+
+ //! Reset the whole context.
+ virtual void reset(bool releaseMemory = false);
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get compiler.
+ ASMJIT_INLINE Compiler* getCompiler() const { return _compiler; }
+
+ //! Get function.
+ ASMJIT_INLINE FuncNode* getFunc() const { return _func; }
+ //! Get stop node.
+ ASMJIT_INLINE Node* getStop() const { return _stop; }
+
+ //! Get start of the current scope.
+ ASMJIT_INLINE Node* getStart() const { return _start; }
+ //! Get end of the current scope.
+ ASMJIT_INLINE Node* getEnd() const { return _end; }
+
+ //! Get extra block.
+ ASMJIT_INLINE Node* getExtraBlock() const { return _extraBlock; }
+ //! Set extra block.
+ ASMJIT_INLINE void setExtraBlock(Node* node) { _extraBlock = node; }
+
+ // --------------------------------------------------------------------------
+ // [Error]
+ // --------------------------------------------------------------------------
+
+ //! Get the last error code.
+ ASMJIT_INLINE Error getError() const {
+ return getCompiler()->getError();
+ }
+
+ //! Set the last error code and propagate it through the error handler.
+ ASMJIT_INLINE Error setError(Error error, const char* message = NULL) {
+ return getCompiler()->setError(error, message);
+ }
+
+ // --------------------------------------------------------------------------
+ // [State]
+ // --------------------------------------------------------------------------
+
+ //! Get current state.
+ ASMJIT_INLINE VarState* getState() const {
+ return _state;
+ }
+
+ //! Load current state from `target` state.
+ virtual void loadState(VarState* src) = 0;
+
+ //! Save current state, returning new `VarState` instance.
+ virtual VarState* saveState() = 0;
+
+ //! Change the current state to `target` state.
+ virtual void switchState(VarState* src) = 0;
+
+ //! Change the current state to the intersection of two states `a` and `b`.
+ virtual void intersectStates(VarState* a, VarState* b) = 0;
+
+ // --------------------------------------------------------------------------
+ // [Context]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE Error _registerContextVar(VarData* vd) {
+ if (vd->hasContextId())
+ return kErrorOk;
+
+ uint32_t cid = static_cast(_contextVd.getLength());
+ ASMJIT_PROPAGATE_ERROR(_contextVd.append(vd));
+
+ vd->setContextId(cid);
+ return kErrorOk;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Mem]
+ // --------------------------------------------------------------------------
+
+ MemCell* _newVarCell(VarData* vd);
+ MemCell* _newStackCell(uint32_t size, uint32_t alignment);
+
+ ASMJIT_INLINE MemCell* getVarCell(VarData* vd) {
+ MemCell* cell = vd->getMemCell();
+ return cell ? cell : _newVarCell(vd);
+ }
+
+ virtual Error resolveCellOffsets();
+
+ // --------------------------------------------------------------------------
+ // [Bits]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE VarBits* newBits(uint32_t len) {
+ return static_cast(
+ _baseZone.allocZeroed(static_cast(len) * VarBits::kEntitySize));
+ }
+
+ ASMJIT_INLINE VarBits* copyBits(const VarBits* src, uint32_t len) {
+ return static_cast(
+ _baseZone.dup(src, static_cast(len) * VarBits::kEntitySize));
+ }
+
+ // --------------------------------------------------------------------------
+ // [Fetch]
+ // --------------------------------------------------------------------------
+
+ //! Fetch.
+ //!
+ //! Fetch iterates over all nodes and gathers information about all variables
+ //! used. The process generates information required by register allocator,
+ //! variable liveness analysis and translator.
+ virtual Error fetch() = 0;
+
+ // --------------------------------------------------------------------------
+ // [RemoveUnreachableCode]
+ // --------------------------------------------------------------------------
+
+ //! Remove unreachable code.
+ virtual Error removeUnreachableCode();
+
+ // --------------------------------------------------------------------------
+ // [Analyze]
+ // --------------------------------------------------------------------------
+
+ //! Perform variable liveness analysis.
+ //!
+ //! Analysis phase iterates over nodes in reverse order and generates a bit
+ //! array describing variables that are alive at every node in the function.
+ //! When the analysis start all variables are assumed dead. When a read or
+ //! read/write operations of a variable is detected the variable becomes
+ //! alive; when only write operation is detected the variable becomes dead.
+ //!
+ //! When a label is found all jumps to that label are followed and analysis
+ //! repeats until all variables are resolved.
+ virtual Error livenessAnalysis();
+
+ // --------------------------------------------------------------------------
+ // [Annotate]
+ // --------------------------------------------------------------------------
+
+ virtual Error annotate() = 0;
+
+ // --------------------------------------------------------------------------
+ // [Translate]
+ // --------------------------------------------------------------------------
+
+ //! Translate code by allocating registers and handling state changes.
+ virtual Error translate() = 0;
+
+ // --------------------------------------------------------------------------
+ // [Schedule]
+ // --------------------------------------------------------------------------
+
+ virtual Error schedule();
+
+ // --------------------------------------------------------------------------
+ // [Cleanup]
+ // --------------------------------------------------------------------------
+
+ virtual void cleanup();
+
+ // --------------------------------------------------------------------------
+ // [Compile]
+ // --------------------------------------------------------------------------
+
+ virtual Error compile(FuncNode* func);
+
+ // --------------------------------------------------------------------------
+ // [Serialize]
+ // --------------------------------------------------------------------------
+
+ virtual Error serialize(Assembler* assembler, Node* start, Node* stop) = 0;
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Compiler.
+ Compiler* _compiler;
+ //! Function.
+ FuncNode* _func;
+
+ //! Zone allocator.
+ Zone _baseZone;
+
+ //! \internal
+ //!
+ //! Offset (how many bytes to add) to `VarMap` to get `VarAttr` array. Used
+ //! by liveness analysis shared across all backends. This is needed because
+ //! `VarMap` is a base class for a specialized version that liveness analysis
+ //! doesn't use, it just needs `VarAttr` array.
+ uint32_t _varMapToVaListOffset;
+
+ //! Start of the current active scope.
+ Node* _start;
+ //! End of the current active scope.
+ Node* _end;
+
+ //! Node that is used to insert extra code after the function body.
+ Node* _extraBlock;
+ //! Stop node.
+ Node* _stop;
+
+ //! Unreachable nodes.
+ PodList _unreachableList;
+ //! Jump nodes.
+ PodList _jccList;
+
+ //! All variables used by the current function.
+ PodVector _contextVd;
+
+ //! Memory used to spill variables.
+ MemCell* _memVarCells;
+ //! Memory used to alloc memory on the stack.
+ MemCell* _memStackCells;
+
+ //! Count of 1-byte cells.
+ uint32_t _mem1ByteVarsUsed;
+ //! Count of 2-byte cells.
+ uint32_t _mem2ByteVarsUsed;
+ //! Count of 4-byte cells.
+ uint32_t _mem4ByteVarsUsed;
+ //! Count of 8-byte cells.
+ uint32_t _mem8ByteVarsUsed;
+ //! Count of 16-byte cells.
+ uint32_t _mem16ByteVarsUsed;
+ //! Count of 32-byte cells.
+ uint32_t _mem32ByteVarsUsed;
+ //! Count of 64-byte cells.
+ uint32_t _mem64ByteVarsUsed;
+ //! Count of stack memory cells.
+ uint32_t _memStackCellsUsed;
+
+ //! Maximum memory alignment used by the function.
+ uint32_t _memMaxAlign;
+ //! Count of bytes used by variables.
+ uint32_t _memVarTotal;
+ //! Count of bytes used by stack.
+ uint32_t _memStackTotal;
+ //! Count of bytes used by variables and stack after alignment.
+ uint32_t _memAllTotal;
+
+ //! Default lenght of annotated instruction.
+ uint32_t _annotationLength;
+
+ //! Current state (used by register allocator).
+ VarState* _state;
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // !ASMJIT_DISABLE_COMPILER
+#endif // _ASMJIT_BASE_CONTEXT_P_H
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/cpuinfo.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/cpuinfo.h
new file mode 100644
index 0000000..06ff636
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/cpuinfo.h
@@ -0,0 +1,147 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Guard]
+#ifndef _ASMJIT_BASE_CPUINFO_H
+#define _ASMJIT_BASE_CPUINFO_H
+
+// [Dependencies - AsmJit]
+#include "../base/globals.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_general
+//! \{
+
+// ============================================================================
+// [asmjit::kCpuVendor]
+// ============================================================================
+
+//! Cpu vendor ID.
+//!
+//! Vendor IDs are specific to AsmJit library. During the library initialization
+//! AsmJit checks host CPU and tries to identify the vendor based on the CPUID
+//! calls. Some manufacturers changed their vendor strings and AsmJit is aware
+//! of that - it checks multiple combinations and decides which vendor ID should
+//! be used.
+ASMJIT_ENUM(kCpuVendor) {
+ //! No/Unknown vendor.
+ kCpuVendorNone = 0,
+
+ //! Intel vendor.
+ kCpuVendorIntel = 1,
+ //! AMD vendor.
+ kCpuVendorAmd = 2,
+ //! VIA vendor.
+ kCpuVendorVia = 3
+};
+
+// ============================================================================
+// [asmjit::CpuInfo]
+// ============================================================================
+
+//! Base cpu information.
+struct CpuInfo {
+ ASMJIT_NO_COPY(CpuInfo)
+
+ //! \internal
+ enum {
+ kFeaturesPerUInt32 = static_cast(sizeof(uint32_t)) * 8
+ };
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE CpuInfo(uint32_t size = sizeof(CpuInfo)) : _size(size) {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get CPU vendor string.
+ ASMJIT_INLINE const char* getVendorString() const { return _vendorString; }
+ //! Get CPU brand string.
+ ASMJIT_INLINE const char* getBrandString() const { return _brandString; }
+
+ //! Get CPU vendor ID.
+ ASMJIT_INLINE uint32_t getVendorId() const { return _vendorId; }
+ //! Get CPU family ID.
+ ASMJIT_INLINE uint32_t getFamily() const { return _family; }
+ //! Get CPU model ID.
+ ASMJIT_INLINE uint32_t getModel() const { return _model; }
+ //! Get CPU stepping.
+ ASMJIT_INLINE uint32_t getStepping() const { return _stepping; }
+
+ //! Get number of hardware threads available.
+ ASMJIT_INLINE uint32_t getHwThreadsCount() const { return _hwThreadsCount; }
+
+ //! Get whether CPU has a `feature`.
+ ASMJIT_INLINE bool hasFeature(uint32_t feature) const {
+ ASMJIT_ASSERT(feature < sizeof(_features) * 8);
+
+ return static_cast(
+ (_features[feature / kFeaturesPerUInt32] >> (feature % kFeaturesPerUInt32)) & 0x1);
+ }
+
+ //! Add a CPU `feature`.
+ ASMJIT_INLINE CpuInfo& addFeature(uint32_t feature) {
+ ASMJIT_ASSERT(feature < sizeof(_features) * 8);
+
+ _features[feature / kFeaturesPerUInt32] |= (1U << (feature % kFeaturesPerUInt32));
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Statics]
+ // --------------------------------------------------------------------------
+
+ //! Detect the number of hardware threads.
+ static ASMJIT_API uint32_t detectHwThreadsCount();
+
+ //! Get host cpu.
+ static ASMJIT_API const CpuInfo* getHost();
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Size of the structure in bytes.
+ uint32_t _size;
+
+ //! Cpu short vendor string.
+ char _vendorString[16];
+ //! Cpu long vendor string (brand).
+ char _brandString[64];
+
+ //! Cpu vendor id, see `asmjit::kCpuVendor`.
+ uint32_t _vendorId;
+ //! Cpu family ID.
+ uint32_t _family;
+ //! Cpu model ID.
+ uint32_t _model;
+ //! Cpu stepping.
+ uint32_t _stepping;
+
+ //! Number of hardware threads.
+ uint32_t _hwThreadsCount;
+
+ //! Cpu features bitfield.
+ uint32_t _features[4];
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // _ASMJIT_BASE_CPUINFO_H
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/cputicks.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/cputicks.h
new file mode 100644
index 0000000..1732c2e
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/cputicks.h
@@ -0,0 +1,40 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Guard]
+#ifndef _ASMJIT_BASE_CPUTICKS_H
+#define _ASMJIT_BASE_CPUTICKS_H
+
+// [Dependencies - AsmJit]
+#include "../base/globals.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_util
+//! \{
+
+// ============================================================================
+// [asmjit::CpuTicks]
+// ============================================================================
+
+//! CPU ticks utilities.
+struct CpuTicks {
+ //! Get the current CPU ticks for benchmarking (1ms resolution).
+ static ASMJIT_API uint32_t now();
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // _ASMJIT_BASE_CPUTICKS_H
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/error.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/error.h
new file mode 100644
index 0000000..46b4089
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/error.h
@@ -0,0 +1,218 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Guard]
+#ifndef _ASMJIT_BASE_ERROR_H
+#define _ASMJIT_BASE_ERROR_H
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+// [Dependencies - AsmJit]
+#include "../base/globals.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_general
+//! \{
+
+// ============================================================================
+// [asmjit::kError]
+// ============================================================================
+
+//! AsmJit error codes.
+ASMJIT_ENUM(kError) {
+ //! No error (success).
+ //!
+ //! This is default state and state you want.
+ kErrorOk = 0,
+
+ //! Heap memory allocation failed.
+ kErrorNoHeapMemory = 1,
+
+ //! Virtual memory allocation failed.
+ kErrorNoVirtualMemory = 2,
+
+ //! Invalid argument.
+ kErrorInvalidArgument = 3,
+
+ //! Invalid state.
+ kErrorInvalidState = 4,
+
+ //! No code generated.
+ //!
+ //! Returned by runtime if the code-generator contains no code.
+ kErrorNoCodeGenerated = 5,
+
+ //! Code generated is too large to fit in memory reserved.
+ //!
+ //! Returned by `StaticRuntime` in case that the code generated is too large
+ //! to fit in the memory already reserved for it.
+ kErrorCodeTooLarge = 6,
+
+ //! Label is already bound.
+ kErrorLabelAlreadyBound = 7,
+
+ //! Unknown instruction (an instruction ID is out of bounds or instruction
+ //! name is invalid).
+ kErrorUnknownInst = 8,
+
+ //! Illegal instruction.
+ //!
+ //! This status code can also be returned in X64 mode if AH, BH, CH or DH
+ //! registers have been used together with a REX prefix. The instruction
+ //! is not encodable in such case.
+ //!
+ //! Example of raising `kErrorIllegalInst` error.
+ //!
+ //! ~~~
+ //! // Invalid address size.
+ //! a.mov(dword_ptr(eax), al);
+ //!
+ //! // Undecodable instruction - AH used with R10, however R10 can only be
+ //! // encoded by using REX prefix, which conflicts with AH.
+ //! a.mov(byte_ptr(r10), ah);
+ //! ~~~
+ //!
+ //! \note In debug mode assertion is raised instead of returning an error.
+ kErrorIllegalInst = 9,
+
+ //! Illegal (unencodable) addressing used.
+ kErrorIllegalAddresing = 10,
+
+ //! Illegal (unencodable) displacement used.
+ //!
+ //! X86/X64
+ //! -------
+ //!
+ //! Short form of jump instruction has been used, but the displacement is out
+ //! of bounds.
+ kErrorIllegalDisplacement = 11,
+
+ //! A variable has been assigned more than once to a function argument (Compiler).
+ kErrorOverlappedArgs = 12,
+
+ //! Count of AsmJit error codes.
+ kErrorCount = 13
+};
+
+// ============================================================================
+// [asmjit::Error]
+// ============================================================================
+
+//! AsmJit error type (unsigned integer).
+typedef uint32_t Error;
+
+// ============================================================================
+// [asmjit::ErrorHandler]
+// ============================================================================
+
+//! Error handler.
+//!
+//! Error handler can be used to override the default behavior of `CodeGen`
+//! error handling and propagation. See `handleError` on how to override it.
+//!
+//! Please note that `addRef` and `release` functions are used, but there is
+//! no reference counting implemented by default, reimplement to change the
+//! default behavior.
+struct ASMJIT_VCLASS ErrorHandler {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `ErrorHandler` instance.
+ ASMJIT_API ErrorHandler();
+ //! Destroy the `ErrorHandler` instance.
+ ASMJIT_API virtual ~ErrorHandler();
+
+ // --------------------------------------------------------------------------
+ // [Interface]
+ // --------------------------------------------------------------------------
+
+ //! Reference this error handler.
+ //!
+ //! \note This member function is provided for convenience. The default
+ //! implementation does nothing. If you are working in environment where
+ //! multiple `ErrorHandler` instances are used by a different code generators
+ //! you may provide your own functionality for reference counting. In that
+ //! case `addRef()` and `release()` functions should be overridden.
+ ASMJIT_API virtual ErrorHandler* addRef() const;
+
+ //! Release this error handler.
+ //!
+ //! \note This member function is provided for convenience. See `addRef()`
+ //! for more detailed information related to reference counting.
+ ASMJIT_API virtual void release();
+
+ //! Error handler (pure).
+ //!
+ //! Error handler is called when an error happened. An error can happen in
+ //! many places, but error handler is mostly used by `Assembler` and
+ //! `Compiler` classes to report anything that may cause incorrect code
+ //! generation. There are multiple ways how the error handler can be used
+ //! and each has it's pros/cons.
+ //!
+ //! AsmJit library doesn't use exceptions and can be compiled with or without
+ //! exception handling support. Even if the AsmJit library is compiled without
+ //! exceptions it is exception-safe and handleError() can report an incoming
+ //! error by throwing an exception of any type. It's guaranteed that the
+ //! exception won't be catched by AsmJit and will be propagated to the code
+ //! calling AsmJit `Assembler` or `Compiler` methods. Alternative to
+ //! throwing an exception is using `setjmp()` and `longjmp()` pair available
+ //! in the standard C library.
+ //!
+ //! If the exception or setjmp() / longjmp() mechanism is used, the state of
+ //! the `BaseAssember` or `Compiler` is unchanged and if it's possible the
+ //! execution (instruction serialization) can continue. However if the error
+ //! happened during any phase that translates or modifies the stored code
+ //! (for example relocation done by `Assembler` or analysis/translation
+ //! done by `Compiler`) the execution can't continue and the error will
+ //! be also stored in `Assembler` or `Compiler`.
+ //!
+ //! Finally, if no exceptions nor setjmp() / longjmp() mechanisms were used,
+ //! you can still implement a compatible handling by returning from your
+ //! error handler. Returning `true` means that error was reported and AsmJit
+ //! should continue execution, but `false` sets the rror immediately to the
+ //! `Assembler` or `Compiler` and execution shouldn't continue (this
+ //! is the default behavior in case no error handler is used).
+ virtual bool handleError(Error code, const char* message) = 0;
+};
+
+// ============================================================================
+// [asmjit::ErrorUtil]
+// ============================================================================
+
+//! Error utilities.
+struct ErrorUtil {
+#if !defined(ASMJIT_DISABLE_NAMES)
+ //! Get printable version of AsmJit `kError` code.
+ static ASMJIT_API const char* asString(Error code);
+#endif // ASMJIT_DISABLE_NAMES
+};
+
+//! \}
+
+// ============================================================================
+// [ASMJIT_PROPAGATE_ERROR]
+// ============================================================================
+
+//! \internal
+//!
+//! Used by AsmJit to return the `_Exp_` result if it's an error.
+#define ASMJIT_PROPAGATE_ERROR(_Exp_) \
+ do { \
+ ::asmjit::Error errval_ = (_Exp_); \
+ if (errval_ != ::asmjit::kErrorOk) \
+ return errval_; \
+ } while (0)
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // _ASMJIT_BASE_ERROR_H
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/globals.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/globals.h
new file mode 100644
index 0000000..0364578
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/globals.h
@@ -0,0 +1,177 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Guard]
+#ifndef _ASMJIT_BASE_GLOBALS_H
+#define _ASMJIT_BASE_GLOBALS_H
+
+// [Dependencies - AsmJit]
+#include "../build.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_general
+//! \{
+
+// ============================================================================
+// [asmjit::Ptr / SignedPtr]
+// ============================================================================
+
+//! 64-bit unsigned pointer, compatible with JIT and non-JIT generators.
+//!
+//! This is the preferred pointer type to use with AsmJit library. It has a
+//! capability to hold any pointer for any architecture making it an ideal
+//! candidate for cross-platform code generation.
+typedef uint64_t Ptr;
+
+//! 64-bit signed pointer, like \ref Ptr, but made signed.
+typedef int64_t SignedPtr;
+
+// ============================================================================
+// [asmjit::kGlobals]
+// ============================================================================
+
+//! Invalid index
+//!
+//! Invalid index is the last possible index that is never used in practice. In
+//! AsmJit it is used exclusively with strings to indicate the the length of the
+//! string is not known and has to be determined.
+static const size_t kInvalidIndex = ~static_cast(0);
+
+//! Invalid base address.
+static const Ptr kNoBaseAddress = static_cast(static_cast(-1));
+
+//! Global constants.
+ASMJIT_ENUM(kGlobals) {
+ //! Invalid value or operand id.
+ kInvalidValue = 0xFFFFFFFF,
+
+ //! Invalid register index.
+ kInvalidReg = 0xFF,
+ //! Invalid variable type.
+ kInvalidVar = 0xFF,
+
+ //! Host memory allocator overhead.
+ //!
+ //! The overhead is decremented from all zone allocators so the operating
+ //! system doesn't have allocate extra virtual page to keep tract of the
+ //! requested memory block.
+ //!
+ //! The number is actually a guess.
+ kMemAllocOverhead = sizeof(intptr_t) * 4,
+
+ //! Memory grow threshold.
+ //!
+ //! After the grow threshold is reached the capacity won't be doubled
+ //! anymore.
+ kMemAllocGrowMax = 8192 * 1024
+};
+
+// ============================================================================
+// [asmjit::kArch]
+// ============================================================================
+
+//! Architecture.
+ASMJIT_ENUM(kArch) {
+ //! No/Unknown architecture.
+ kArchNone = 0,
+
+ //! X86 architecture.
+ kArchX86 = 1,
+ //! X64 architecture, also called AMD64.
+ kArchX64 = 2,
+
+ //! Arm architecture.
+ kArchArm = 4,
+
+#if defined(ASMJIT_HOST_X86)
+ kArchHost = kArchX86,
+#endif // ASMJIT_HOST_X86
+
+#if defined(ASMJIT_HOST_X64)
+ kArchHost = kArchX64,
+#endif // ASMJIT_HOST_X64
+
+#if defined(ASMJIT_HOST_ARM)
+ kArchHost = kArchArm,
+#endif // ASMJIT_HOST_ARM
+
+ //! Whether the host is 64-bit.
+ kArchHost64Bit = sizeof(intptr_t) >= 8
+};
+
+//! \}
+
+// ============================================================================
+// [asmjit::Init / NoInit]
+// ============================================================================
+
+#if !defined(ASMJIT_DOCGEN)
+struct _Init {};
+static const _Init Init = {};
+
+struct _NoInit {};
+static const _NoInit NoInit = {};
+#endif // !ASMJIT_DOCGEN
+
+// ============================================================================
+// [asmjit::Assert]
+// ============================================================================
+
+//! \addtogroup asmjit_base_general
+//! \{
+
+//! Called in debug build on assertion failure.
+//!
+//! \param exp Expression that failed.
+//! \param file Source file name where it happened.
+//! \param line Line in the source file.
+//!
+//! If you have problems with assertions put a breakpoint at assertionFailed()
+//! function (asmjit/base/globals.cpp) and check the call stack to locate the
+//! failing code.
+ASMJIT_API void assertionFailed(const char* exp, const char* file, int line);
+
+#if defined(ASMJIT_DEBUG)
+#define ASMJIT_ASSERT(_Exp_) \
+ do { \
+ if (!(_Exp_)) ::asmjit::assertionFailed(#_Exp_, __FILE__, __LINE__); \
+ } while (0)
+#else
+#define ASMJIT_ASSERT(_Exp_) ASMJIT_NOP()
+#endif // DEBUG
+
+//! \}
+
+} // asmjit namespace
+
+// ============================================================================
+// [asmjit_cast<>]
+// ============================================================================
+
+//! \addtogroup asmjit_base_util
+//! \{
+
+//! Cast used to cast pointer to function. It's like reinterpret_cast<>,
+//! but uses internally C style cast to work with MinGW.
+//!
+//! If you are using single compiler and `reinterpret_cast<>` works for you,
+//! there is no reason to use `asmjit_cast<>`. If you are writing
+//! cross-platform software with various compiler support, consider using
+//! `asmjit_cast<>` instead of `reinterpret_cast<>`.
+template
+static ASMJIT_INLINE T asmjit_cast(Z* p) { return (T)p; }
+
+//! \}
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // _ASMJIT_BASE_GLOBALS_H
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/intutil.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/intutil.h
new file mode 100644
index 0000000..c58d957
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/intutil.h
@@ -0,0 +1,713 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Guard]
+#ifndef _ASMJIT_BASE_INTUTIL_H
+#define _ASMJIT_BASE_INTUTIL_H
+
+// [Dependencies - AsmJit]
+#include "../base/globals.h"
+
+#if defined(_MSC_VER)
+#pragma intrinsic(_BitScanForward)
+#endif // ASMJIT_OS_WINDOWS
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_util
+//! \{
+
+// ============================================================================
+// [asmjit::IntTraits]
+// ============================================================================
+
+//! \internal
+template
+struct IntTraits {
+ enum {
+ kIsSigned = static_cast(~static_cast(0)) < static_cast(0),
+ kIsUnsigned = !kIsSigned,
+
+ kIs8Bit = sizeof(T) == 1,
+ kIs16Bit = sizeof(T) == 2,
+ kIs32Bit = sizeof(T) == 4,
+ kIs64Bit = sizeof(T) == 8,
+
+ kIsIntPtr = sizeof(T) == sizeof(intptr_t)
+ };
+};
+
+// ============================================================================
+// [asmjit::IntUtil]
+// ============================================================================
+
+//! Integer utilities.
+struct IntUtil {
+ // --------------------------------------------------------------------------
+ // [Float <-> Int]
+ // --------------------------------------------------------------------------
+
+ //! \internal
+ union Float {
+ int32_t i;
+ float f;
+ };
+
+ //! \internal
+ union Double {
+ int64_t i;
+ double d;
+ };
+
+ //! Bit-cast `float` to 32-bit integer.
+ static ASMJIT_INLINE int32_t floatAsInt(float f) { Float m; m.f = f; return m.i; }
+ //! Bit-cast 32-bit integer to `float`.
+ static ASMJIT_INLINE float intAsFloat(int32_t i) { Float m; m.i = i; return m.f; }
+
+ //! Bit-cast `double` to 64-bit integer.
+ static ASMJIT_INLINE int64_t doubleAsInt(double d) { Double m; m.d = d; return m.i; }
+ //! Bit-cast 64-bit integer to `double`.
+ static ASMJIT_INLINE double intAsDouble(int64_t i) { Double m; m.i = i; return m.d; }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - Pack / Unpack]
+ // --------------------------------------------------------------------------
+
+ //! Pack two 8-bit integer and one 16-bit integer into a 32-bit integer as it
+ //! is an array of `{u0,u1,w2}`.
+ static ASMJIT_INLINE uint32_t pack32_2x8_1x16(uint32_t u0, uint32_t u1, uint32_t w2) {
+#if defined(ASMJIT_HOST_LE)
+ return u0 + (u1 << 8) + (w2 << 16);
+#else
+ return (u0 << 24) + (u1 << 16) + (w2);
+#endif // ASMJIT_HOST
+ }
+
+ //! Pack four 8-bit integer into a 32-bit integer as it is an array of `{u0,u1,u2,u3}`.
+ static ASMJIT_INLINE uint32_t pack32_4x8(uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3) {
+#if defined(ASMJIT_HOST_LE)
+ return u0 + (u1 << 8) + (u2 << 16) + (u3 << 24);
+#else
+ return (u0 << 24) + (u1 << 16) + (u2 << 8) + u3;
+#endif // ASMJIT_HOST
+ }
+
+ //! Pack two 32-bit integer into a 64-bit integer as it is an array of `{u0,u1}`.
+ static ASMJIT_INLINE uint64_t pack64_2x32(uint32_t u0, uint32_t u1) {
+#if defined(ASMJIT_HOST_LE)
+ return (static_cast(u1) << 32) + u0;
+#else
+ return (static_cast(u0) << 32) + u1;
+#endif // ASMJIT_HOST
+ }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - Min/Max]
+ // --------------------------------------------------------------------------
+
+ // NOTE: Because some environments declare min() and max() as macros, it has
+ // been decided to use different name so we never collide with them.
+
+ //! Get minimum value of `a` and `b`.
+ template
+ static ASMJIT_INLINE T iMin(const T& a, const T& b) { return a < b ? a : b; }
+
+ //! Get maximum value of `a` and `b`.
+ template
+ static ASMJIT_INLINE T iMax(const T& a, const T& b) { return a > b ? a : b; }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - MaxUInt]
+ // --------------------------------------------------------------------------
+
+ //! Get maximum unsigned value of `T`.
+ template
+ static ASMJIT_INLINE T maxUInt() { return ~T(0); }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - InInterval]
+ // --------------------------------------------------------------------------
+
+ //! Get whether `x` is greater or equal than `start` and less or equal than `end`.
+ template
+ static ASMJIT_INLINE bool inInterval(const T& x, const T& start, const T& end) {
+ return x >= start && x <= end;
+ }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - IsInt/IsUInt]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the given integer `x` can be casted to 8-bit signed integer.
+ template
+ static ASMJIT_INLINE bool isInt8(T x) {
+ if (IntTraits::kIsSigned)
+ return sizeof(T) <= sizeof(int8_t) ? true : x >= T(-128) && x <= T(127);
+ else
+ return x <= T(127);
+ }
+
+ //! Get whether the given integer `x` can be casted to 8-bit unsigned integer.
+ template
+ static ASMJIT_INLINE bool isUInt8(T x) {
+ if (IntTraits::kIsSigned)
+ return x >= T(0) && (sizeof(T) <= sizeof(uint8_t) ? true : x <= T(255));
+ else
+ return sizeof(T) <= sizeof(uint8_t) ? true : x <= T(255);
+ }
+
+ //! Get whether the given integer `x` can be casted to 16-bit signed integer.
+ template
+ static ASMJIT_INLINE bool isInt16(T x) {
+ if (IntTraits::kIsSigned)
+ return sizeof(T) <= sizeof(int16_t) ? true : x >= T(-32768) && x <= T(32767);
+ else
+ return x >= T(0) && (sizeof(T) <= sizeof(int16_t) ? true : x <= T(32767));
+ }
+
+ //! Get whether the given integer `x` can be casted to 16-bit unsigned integer.
+ template
+ static ASMJIT_INLINE bool isUInt16(T x) {
+ if (IntTraits::kIsSigned)
+ return x >= T(0) && (sizeof(T) <= sizeof(uint16_t) ? true : x <= T(65535));
+ else
+ return sizeof(T) <= sizeof(uint16_t) ? true : x <= T(65535);
+ }
+
+ //! Get whether the given integer `x` can be casted to 32-bit signed integer.
+ template
+ static ASMJIT_INLINE bool isInt32(T x) {
+ if (IntTraits::kIsSigned)
+ return sizeof(T) <= sizeof(int32_t) ? true : x >= T(-2147483647) - 1 && x <= T(2147483647);
+ else
+ return x >= T(0) && (sizeof(T) <= sizeof(int32_t) ? true : x <= T(2147483647));
+ }
+
+ //! Get whether the given integer `x` can be casted to 32-bit unsigned integer.
+ template
+ static ASMJIT_INLINE bool isUInt32(T x) {
+ if (IntTraits::kIsSigned)
+ return x >= T(0) && (sizeof(T) <= sizeof(uint32_t) ? true : x <= T(4294967295U));
+ else
+ return sizeof(T) <= sizeof(uint32_t) ? true : x <= T(4294967295U);
+ }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - IsPowerOf2]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the `n` value is a power of two (only one bit is set).
+ template
+ static ASMJIT_INLINE bool isPowerOf2(T n) {
+ return n != 0 && (n & (n - 1)) == 0;
+ }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - Mask]
+ // --------------------------------------------------------------------------
+
+ //! Generate a bit-mask that has `x` bit set.
+ static ASMJIT_INLINE uint32_t mask(uint32_t x) {
+ ASMJIT_ASSERT(x < 32);
+ return (1U << x);
+ }
+
+ //! Generate a bit-mask that has `x0` and `x1` bits set.
+ static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1) {
+ return mask(x0) | mask(x1);
+ }
+
+ //! Generate a bit-mask that has `x0`, `x1` and `x2` bits set.
+ static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2) {
+ return mask(x0) | mask(x1) | mask(x2);
+ }
+
+ //! Generate a bit-mask that has `x0`, `x1`, `x2` and `x3` bits set.
+ static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3) {
+ return mask(x0) | mask(x1) | mask(x2) | mask(x3);
+ }
+
+ //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3` and `x4` bits set.
+ static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4) {
+ return mask(x0) | mask(x1) | mask(x2) | mask(x3) |
+ mask(x4) ;
+ }
+
+ //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4` and `x5` bits set.
+ static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5) {
+ return mask(x0) | mask(x1) | mask(x2) | mask(x3) |
+ mask(x4) | mask(x5) ;
+ }
+
+ //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4`, `x5` and `x6` bits set.
+ static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5, uint32_t x6) {
+ return mask(x0) | mask(x1) | mask(x2) | mask(x3) |
+ mask(x4) | mask(x5) | mask(x6) ;
+ }
+
+ //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4`, `x5`, `x6` and `x7` bits set.
+ static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7) {
+ return mask(x0) | mask(x1) | mask(x2) | mask(x3) |
+ mask(x4) | mask(x5) | mask(x6) | mask(x7) ;
+ }
+
+ //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4`, `x5`, `x6`, `x7` and `x8` bits set.
+ static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7, uint32_t x8) {
+ return mask(x0) | mask(x1) | mask(x2) | mask(x3) |
+ mask(x4) | mask(x5) | mask(x6) | mask(x7) |
+ mask(x8) ;
+ }
+
+ //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4`, `x5`, `x6`, `x7`, `x8` and `x9` bits set.
+ static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7, uint32_t x8, uint32_t x9) {
+ return mask(x0) | mask(x1) | mask(x2) | mask(x3) |
+ mask(x4) | mask(x5) | mask(x6) | mask(x7) |
+ mask(x8) | mask(x9) ;
+ }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - Bits]
+ // --------------------------------------------------------------------------
+
+ //! Generate a bit-mask that has `x` most significant bits set.
+ static ASMJIT_INLINE uint32_t bits(uint32_t x) {
+ // Shifting more bits that the type has has undefined behavior. Everything
+ // we need is that application shouldn't crash because of that, but the
+ // content of register after shift is not defined. So in case that the
+ // requested shift is too large for the type we correct this undefined
+ // behavior by setting all bits to ones (this is why we generate an overflow
+ // mask).
+ uint32_t overflow = static_cast(
+ -static_cast(x >= sizeof(uint32_t) * 8));
+
+ return ((static_cast(1) << x) - 1U) | overflow;
+ }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - HasBit]
+ // --------------------------------------------------------------------------
+
+ //! Get whether `x` has bit `n` set.
+ static ASMJIT_INLINE bool hasBit(uint32_t x, uint32_t n) {
+ return static_cast((x >> n) & 0x1);
+ }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - BitCount]
+ // --------------------------------------------------------------------------
+
+ //! Get count of bits in `x`.
+ //!
+ //! Taken from http://graphics.stanford.edu/~seander/bithacks.html .
+ static ASMJIT_INLINE uint32_t bitCount(uint32_t x) {
+ x = x - ((x >> 1) & 0x55555555U);
+ x = (x & 0x33333333U) + ((x >> 2) & 0x33333333U);
+ return (((x + (x >> 4)) & 0x0F0F0F0FU) * 0x01010101U) >> 24;
+ }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - FindFirstBit]
+ // --------------------------------------------------------------------------
+
+ //! \internal
+ static ASMJIT_INLINE uint32_t findFirstBitSlow(uint32_t mask) {
+ // This is a reference (slow) implementation of findFirstBit(), used when
+ // we don't have compiler support for this task. The implementation speed
+ // has been improved to check for 2 bits per iteration.
+ uint32_t i = 1;
+
+ while (mask != 0) {
+ uint32_t two = mask & 0x3;
+ if (two != 0x0)
+ return i - (two & 0x1);
+
+ i += 2;
+ mask >>= 2;
+ }
+
+ return 0xFFFFFFFFU;
+ }
+
+ //! Find a first bit in `mask`.
+ static ASMJIT_INLINE uint32_t findFirstBit(uint32_t mask) {
+#if defined(_MSC_VER)
+ DWORD i;
+ if (_BitScanForward(&i, mask)) {
+ ASMJIT_ASSERT(findFirstBitSlow(mask) == i);
+ return static_cast(i);
+ }
+ return 0xFFFFFFFFU;
+#else
+ return findFirstBitSlow(mask);
+#endif
+ }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - Misc]
+ // --------------------------------------------------------------------------
+
+ static ASMJIT_INLINE uint32_t keepNOnesFromRight(uint32_t mask, uint32_t nBits) {
+ uint32_t m = 0x1;
+
+ do {
+ nBits -= (mask & m) == 0;
+ m <<= 1;
+ if (nBits == 0) {
+ m -= 1;
+ mask &= m;
+ break;
+ }
+ } while (m);
+
+ return mask;
+ }
+
+ static ASMJIT_INLINE uint32_t indexNOnesFromRight(uint8_t* dst, uint32_t mask, uint32_t nBits) {
+ uint32_t totalBits = nBits;
+ uint8_t i = 0;
+ uint32_t m = 0x1;
+
+ do {
+ if (mask & m) {
+ *dst++ = i;
+ if (--nBits == 0)
+ break;
+ }
+
+ m <<= 1;
+ i++;
+ } while (m);
+
+ return totalBits - nBits;
+ }
+
+ // --------------------------------------------------------------------------
+ // [AsmJit - Alignment]
+ // --------------------------------------------------------------------------
+
+ template
+ static ASMJIT_INLINE bool isAligned(T base, T alignment) {
+ return (base % alignment) == 0;
+ }
+
+ //! Align `base` to `alignment`.
+ template
+ static ASMJIT_INLINE T alignTo(T base, T alignment) {
+ return (base + (alignment - 1)) & ~(alignment - 1);
+ }
+
+ template
+ static ASMJIT_INLINE T alignToPowerOf2(T base) {
+ // Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.
+ base -= 1;
+
+#if defined(_MSC_VER)
+# pragma warning(push)
+# pragma warning(disable: 4293)
+#endif // _MSC_VER
+
+ base = base | (base >> 1);
+ base = base | (base >> 2);
+ base = base | (base >> 4);
+
+ // 8/16/32 constants are multiplied by the condition to prevent a compiler
+ // complaining about the 'shift count >= type width' (GCC).
+ if (sizeof(T) >= 2) base = base | (base >> ( 8 * (sizeof(T) >= 2))); // Base >> 8.
+ if (sizeof(T) >= 4) base = base | (base >> (16 * (sizeof(T) >= 4))); // Base >> 16.
+ if (sizeof(T) >= 8) base = base | (base >> (32 * (sizeof(T) >= 8))); // Base >> 32.
+
+#if defined(_MSC_VER)
+# pragma warning(pop)
+#endif // _MSC_VER
+
+ return base + 1;
+ }
+
+ //! Get delta required to align `base` to `alignment`.
+ template
+ static ASMJIT_INLINE T deltaTo(T base, T alignment) {
+ return alignTo(base, alignment) - base;
+ }
+};
+
+// ============================================================================
+// [asmjit::UInt64]
+// ============================================================================
+
+union UInt64 {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE UInt64 fromUInt64(uint64_t val) {
+ UInt64 data;
+ data.setUInt64(val);
+ return data;
+ }
+
+ ASMJIT_INLINE UInt64 fromUInt64(const UInt64& val) {
+ UInt64 data;
+ data.setUInt64(val);
+ return data;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Reset]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void reset() {
+ if (kArchHost64Bit) {
+ u64 = 0;
+ }
+ else {
+ u32[0] = 0;
+ u32[1] = 0;
+ }
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE uint64_t getUInt64() const {
+ return u64;
+ }
+
+ ASMJIT_INLINE UInt64& setUInt64(uint64_t val) {
+ u64 = val;
+ return *this;
+ }
+
+ ASMJIT_INLINE UInt64& setUInt64(const UInt64& val) {
+ if (kArchHost64Bit) {
+ u64 = val.u64;
+ }
+ else {
+ u32[0] = val.u32[0];
+ u32[1] = val.u32[1];
+ }
+ return *this;
+ }
+
+ ASMJIT_INLINE UInt64& setPacked_2x32(uint32_t u0, uint32_t u1) {
+ if (kArchHost64Bit) {
+ u64 = IntUtil::pack64_2x32(u0, u1);
+ }
+ else {
+ u32[0] = u0;
+ u32[1] = u1;
+ }
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Add]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE UInt64& add(uint64_t val) {
+ u64 += val;
+ return *this;
+ }
+
+ ASMJIT_INLINE UInt64& add(const UInt64& val) {
+ if (kArchHost64Bit) {
+ u64 += val.u64;
+ }
+ else {
+ u32[0] += val.u32[0];
+ u32[1] += val.u32[1];
+ }
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Sub]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE UInt64& sub(uint64_t val) {
+ u64 -= val;
+ return *this;
+ }
+
+ ASMJIT_INLINE UInt64& sub(const UInt64& val) {
+ if (kArchHost64Bit) {
+ u64 -= val.u64;
+ }
+ else {
+ u32[0] -= val.u32[0];
+ u32[1] -= val.u32[1];
+ }
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [And]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE UInt64& and_(uint64_t val) {
+ u64 &= val;
+ return *this;
+ }
+
+ ASMJIT_INLINE UInt64& and_(const UInt64& val) {
+ if (kArchHost64Bit) {
+ u64 &= val.u64;
+ }
+ else {
+ u32[0] &= val.u32[0];
+ u32[1] &= val.u32[1];
+ }
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [AndNot]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE UInt64& andNot(uint64_t val) {
+ u64 &= ~val;
+ return *this;
+ }
+
+ ASMJIT_INLINE UInt64& andNot(const UInt64& val) {
+ if (kArchHost64Bit) {
+ u64 &= ~val.u64;
+ }
+ else {
+ u32[0] &= ~val.u32[0];
+ u32[1] &= ~val.u32[1];
+ }
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Or]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE UInt64& or_(uint64_t val) {
+ u64 |= val;
+ return *this;
+ }
+
+ ASMJIT_INLINE UInt64& or_(const UInt64& val) {
+ if (kArchHost64Bit) {
+ u64 |= val.u64;
+ }
+ else {
+ u32[0] |= val.u32[0];
+ u32[1] |= val.u32[1];
+ }
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Xor]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE UInt64& xor_(uint64_t val) {
+ u64 ^= val;
+ return *this;
+ }
+
+ ASMJIT_INLINE UInt64& xor_(const UInt64& val) {
+ if (kArchHost64Bit) {
+ u64 ^= val.u64;
+ }
+ else {
+ u32[0] ^= val.u32[0];
+ u32[1] ^= val.u32[1];
+ }
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Eq]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE bool isZero() const {
+ return kArchHost64Bit ? u64 == 0 : (u32[0] | u32[1]) == 0;
+ }
+
+ ASMJIT_INLINE bool isNonZero() const {
+ return kArchHost64Bit ? u64 != 0 : (u32[0] | u32[1]) != 0;
+ }
+
+ ASMJIT_INLINE bool eq(uint64_t val) const {
+ return u64 == val;
+ }
+
+ ASMJIT_INLINE bool eq(const UInt64& val) const {
+ return kArchHost64Bit ? u64 == val.u64 : (u32[0] == val.u32[0]) & (u32[1] == val.u32[1]);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Operator Overload]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE UInt64& operator+=(uint64_t val) { return add(val); }
+ ASMJIT_INLINE UInt64& operator+=(const UInt64& val) { return add(val); }
+
+ ASMJIT_INLINE UInt64& operator-=(uint64_t val) { return sub(val); }
+ ASMJIT_INLINE UInt64& operator-=(const UInt64& val) { return sub(val); }
+
+ ASMJIT_INLINE UInt64& operator&=(uint64_t val) { return and_(val); }
+ ASMJIT_INLINE UInt64& operator&=(const UInt64& val) { return and_(val); }
+
+ ASMJIT_INLINE UInt64& operator|=(uint64_t val) { return or_(val); }
+ ASMJIT_INLINE UInt64& operator|=(const UInt64& val) { return or_(val); }
+
+ ASMJIT_INLINE UInt64& operator^=(uint64_t val) { return xor_(val); }
+ ASMJIT_INLINE UInt64& operator^=(const UInt64& val) { return xor_(val); }
+
+ ASMJIT_INLINE bool operator==(uint64_t val) const { return eq(val); }
+ ASMJIT_INLINE bool operator==(const UInt64& val) const { return eq(val); }
+
+ ASMJIT_INLINE bool operator!=(uint64_t val) const { return !eq(val); }
+ ASMJIT_INLINE bool operator!=(const UInt64& val) const { return !eq(val); }
+
+ ASMJIT_INLINE bool operator<(uint64_t val) const { return u64 < val; }
+ ASMJIT_INLINE bool operator<(const UInt64& val) const { return u64 < val.u64; }
+
+ ASMJIT_INLINE bool operator<=(uint64_t val) const { return u64 <= val; }
+ ASMJIT_INLINE bool operator<=(const UInt64& val) const { return u64 <= val.u64; }
+
+ ASMJIT_INLINE bool operator>(uint64_t val) const { return u64 > val; }
+ ASMJIT_INLINE bool operator>(const UInt64& val) const { return u64 > val.u64; }
+
+ ASMJIT_INLINE bool operator>=(uint64_t val) const { return u64 >= val; }
+ ASMJIT_INLINE bool operator>=(const UInt64& val) const { return u64 >= val.u64; }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ uint64_t u64;
+
+ uint32_t u32[2];
+ uint16_t u16[4];
+ uint8_t u8[8];
+
+ struct {
+#if defined(ASMJIT_HOST_LE)
+ uint32_t lo, hi;
+#else
+ uint32_t hi, lo;
+#endif // ASMJIT_HOST_LE
+ };
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // _ASMJIT_BASE_INTUTIL_H
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/lock.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/lock.h
new file mode 100644
index 0000000..f2e2042
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/lock.h
@@ -0,0 +1,131 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Guard]
+#ifndef _ASMJIT_BASE_LOCK_H
+#define _ASMJIT_BASE_LOCK_H
+
+// [Dependencies - AsmJit]
+#include "../build.h"
+
+// [Dependencies - Posix]
+#if defined(ASMJIT_OS_POSIX)
+# include
+#endif // ASMJIT_OS_POSIX
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_util
+//! \{
+
+// ============================================================================
+// [asmjit::Lock]
+// ============================================================================
+
+//! Lock - used in thread-safe code for locking.
+struct Lock {
+ ASMJIT_NO_COPY(Lock)
+
+ // --------------------------------------------------------------------------
+ // [Windows]
+ // --------------------------------------------------------------------------
+
+#if defined(ASMJIT_OS_WINDOWS)
+ typedef CRITICAL_SECTION Handle;
+
+ //! Create a new `Lock` instance.
+ ASMJIT_INLINE Lock() { InitializeCriticalSection(&_handle); }
+ //! Destroy the `Lock` instance.
+ ASMJIT_INLINE ~Lock() { DeleteCriticalSection(&_handle); }
+
+ //! Lock.
+ ASMJIT_INLINE void lock() { EnterCriticalSection(&_handle); }
+ //! Unlock.
+ ASMJIT_INLINE void unlock() { LeaveCriticalSection(&_handle); }
+
+#endif // ASMJIT_OS_WINDOWS
+
+ // --------------------------------------------------------------------------
+ // [Posix]
+ // --------------------------------------------------------------------------
+
+#if defined(ASMJIT_OS_POSIX)
+ typedef pthread_mutex_t Handle;
+
+ //! Create a new `Lock` instance.
+ ASMJIT_INLINE Lock() { pthread_mutex_init(&_handle, NULL); }
+ //! Destroy the `Lock` instance.
+ ASMJIT_INLINE ~Lock() { pthread_mutex_destroy(&_handle); }
+
+ //! Lock.
+ ASMJIT_INLINE void lock() { pthread_mutex_lock(&_handle); }
+ //! Unlock.
+ ASMJIT_INLINE void unlock() { pthread_mutex_unlock(&_handle); }
+#endif // ASMJIT_OS_POSIX
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get handle.
+ ASMJIT_INLINE Handle& getHandle() {
+ return _handle;
+ }
+ //! \overload
+ ASMJIT_INLINE const Handle& getHandle() const {
+ return _handle;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Handle.
+ Handle _handle;
+};
+
+// ============================================================================
+// [asmjit::AutoLock]
+// ============================================================================
+
+//! Scoped lock.
+struct AutoLock {
+ ASMJIT_NO_COPY(AutoLock)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Autolock `target`, scoped.
+ ASMJIT_INLINE AutoLock(Lock& target) : _target(target) {
+ _target.lock();
+ }
+
+ //! Autounlock `target`.
+ ASMJIT_INLINE ~AutoLock() {
+ _target.unlock();
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Pointer to target (lock).
+ Lock& _target;
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // _ASMJIT_BASE_LOCK_H
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/logger.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/logger.h
new file mode 100644
index 0000000..b3adc40
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/logger.h
@@ -0,0 +1,249 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Guard]
+#ifndef _ASMJIT_BASE_LOGGER_H
+#define _ASMJIT_BASE_LOGGER_H
+
+#include "../build.h"
+#if !defined(ASMJIT_DISABLE_LOGGER)
+
+// [Dependencies - AsmJit]
+#include "../base/string.h"
+
+// [Dependencies - C]
+#include
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_util
+//! \{
+
+// ============================================================================
+// [asmjit::kLoggerOption]
+// ============================================================================
+
+//! Logger options.
+ASMJIT_ENUM(kLoggerOption) {
+ //! Whether to output instructions also in binary form.
+ kLoggerOptionBinaryForm = 0,
+
+ //! Whether to output immediates as hexadecimal numbers.
+ kLoggerOptionHexImmediate = 1,
+ //! Whether to output displacements as hexadecimal numbers.
+ kLoggerOptionHexDisplacement = 2,
+
+ //! Count of logger options.
+ kLoggerOptionCount = 3
+};
+
+// ============================================================================
+// [asmjit::kLoggerStyle]
+// ============================================================================
+
+//! Logger style.
+ASMJIT_ENUM(kLoggerStyle) {
+ kLoggerStyleDefault = 0,
+ kLoggerStyleDirective = 1,
+ kLoggerStyleLabel = 2,
+ kLoggerStyleData = 3,
+ kLoggerStyleComment = 4,
+
+ kLoggerStyleCount = 5
+};
+
+// ============================================================================
+// [asmjit::Logger]
+// ============================================================================
+
+//! Abstract logging class.
+//!
+//! This class can be inherited and reimplemented to fit into your logging
+//! subsystem. When reimplementing use `Logger::log()` method to log into
+//! a custom stream.
+//!
+//! This class also contain `_enabled` member that can be used to enable
+//! or disable logging.
+struct ASMJIT_VCLASS Logger {
+ ASMJIT_NO_COPY(Logger)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a `Logger` instance.
+ ASMJIT_API Logger();
+ //! Destroy the `Logger` instance.
+ ASMJIT_API virtual ~Logger();
+
+ // --------------------------------------------------------------------------
+ // [Logging]
+ // --------------------------------------------------------------------------
+
+ //! Log output.
+ virtual void logString(uint32_t style, const char* buf, size_t len = kInvalidIndex) = 0;
+
+ //! Log formatter message (like sprintf) sending output to `logString()` method.
+ ASMJIT_API void logFormat(uint32_t style, const char* fmt, ...);
+ //! Log binary data.
+ ASMJIT_API void logBinary(uint32_t style, const void* data, size_t size);
+
+ // --------------------------------------------------------------------------
+ // [Options]
+ // --------------------------------------------------------------------------
+
+ //! Get all logger options as a single integer.
+ ASMJIT_INLINE uint32_t getOptions() const {
+ return _options;
+ }
+
+ //! Get the given logger option.
+ ASMJIT_INLINE bool getOption(uint32_t id) const {
+ ASMJIT_ASSERT(id < kLoggerOptionCount);
+ return static_cast((_options >> id) & 0x1);
+ }
+
+ //! Set the given logger option.
+ ASMJIT_API void setOption(uint32_t id, bool value);
+
+ // --------------------------------------------------------------------------
+ // [Indentation]
+ // --------------------------------------------------------------------------
+
+ //! Get indentation.
+ ASMJIT_INLINE const char* getIndentation() const {
+ return _indentation;
+ }
+
+ //! Set indentation.
+ ASMJIT_API void setIndentation(const char* indentation);
+
+ //! Reset indentation.
+ ASMJIT_INLINE void resetIndentation() {
+ setIndentation(NULL);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Options, see `kLoggerOption`.
+ uint32_t _options;
+
+ //! Indentation.
+ char _indentation[12];
+};
+
+// ============================================================================
+// [asmjit::FileLogger]
+// ============================================================================
+
+//! Logger that can log to standard C `FILE*` stream.
+struct ASMJIT_VCLASS FileLogger : public Logger {
+ ASMJIT_NO_COPY(FileLogger)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new `FileLogger` that logs to a `FILE` stream.
+ ASMJIT_API FileLogger(FILE* stream = NULL);
+
+ //! Destroy the `FileLogger`.
+ ASMJIT_API virtual ~FileLogger();
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get `FILE*` stream.
+ //!
+ //! \note Return value can be `NULL`.
+ ASMJIT_INLINE FILE* getStream() const {
+ return _stream;
+ }
+
+ //! Set `FILE*` stream, can be set to `NULL` to disable logging, although
+ //! the `CodeGen` will still call `logString` even if there is no stream.
+ ASMJIT_INLINE void setStream(FILE* stream) {
+ _stream = stream;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Logging]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API virtual void logString(uint32_t style, const char* buf, size_t len = kInvalidIndex);
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! C file stream.
+ FILE* _stream;
+};
+
+// ============================================================================
+// [asmjit::StringLogger]
+// ============================================================================
+
+//! String logger.
+struct ASMJIT_VCLASS StringLogger : public Logger {
+ ASMJIT_NO_COPY(StringLogger)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create new `StringLogger`.
+ ASMJIT_API StringLogger();
+
+ //! Destroy the `StringLogger`.
+ ASMJIT_API virtual ~StringLogger();
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get `char*` pointer which represents the resulting string.
+ //!
+ //! The pointer is owned by `StringLogger`, it can't be modified or freed.
+ ASMJIT_INLINE const char* getString() const {
+ return _stringBuilder.getData();
+ }
+
+ //! Clear the resulting string.
+ ASMJIT_INLINE void clearString() {
+ _stringBuilder.clear();
+ }
+
+ // --------------------------------------------------------------------------
+ // [Logging]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API virtual void logString(uint32_t style, const char* buf, size_t len = kInvalidIndex);
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Output.
+ StringBuilder _stringBuilder;
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // !ASMJIT_DISABLE_LOGGER
+#endif // _ASMJIT_BASE_LOGGER_H
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/operand.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/operand.h
new file mode 100644
index 0000000..4553e33
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/operand.h
@@ -0,0 +1,1090 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Guard]
+#ifndef _ASMJIT_BASE_OPERAND_H
+#define _ASMJIT_BASE_OPERAND_H
+
+// [Dependencies - AsmJit]
+#include "../base/intutil.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [Forward Declarations]
+// ============================================================================
+
+struct Assembler;
+struct Compiler;
+
+//! \addtogroup asmjit_base_general
+//! \{
+
+// ============================================================================
+// [asmjit::kOperandType]
+// ============================================================================
+
+//! Operand types that can be encoded in `Operand`.
+ASMJIT_ENUM(kOperandType) {
+ //! Invalid operand, used only internally (not initialized Operand).
+ kOperandTypeNone = 0,
+ //! Operand is a register.
+ kOperandTypeReg = 1,
+ //! Operand is a variable.
+ kOperandTypeVar = 2,
+ //! Operand is a memory.
+ kOperandTypeMem = 3,
+ //! Operand is an immediate value.
+ kOperandTypeImm = 4,
+ //! Operand is a label.
+ kOperandTypeLabel = 5
+};
+
+// ============================================================================
+// [asmjit::kOperandId]
+// ============================================================================
+
+//! Operand id masks used to determine the operand type.
+ASMJIT_ENUM(kOperandId) {
+ //! Operand id refers to `Var`.
+ kOperandIdVar = 0x80000000U,
+ //! Operand id to real index mask.
+ kOperandIdNum = 0x7FFFFFFFU
+};
+
+// ============================================================================
+// [asmjit::kRegClass]
+// ============================================================================
+
+//! Register class.
+ASMJIT_ENUM(kRegClass) {
+ //! Gp register class, compatible with all architectures.
+ kRegClassGp = 0
+};
+
+// ============================================================================
+// [asmjit::kSize]
+// ============================================================================
+
+//! Common size of registers and pointers.
+ASMJIT_ENUM(kSize) {
+ //! 1 byte size (BYTE).
+ kSizeByte = 1,
+ //! 2 bytes size (WORD).
+ kSizeWord = 2,
+ //! 4 bytes size (DWORD).
+ kSizeDWord = 4,
+ //! 8 bytes size (QWORD).
+ kSizeQWord = 8,
+ //! 10 bytes size (TWORD).
+ kSizeTWord = 10,
+ //! 16 bytes size (OWORD / DQWORD).
+ kSizeOWord = 16,
+ //! 32 bytes size (YWORD / QQWORD).
+ kSizeYWord = 32
+};
+
+// ============================================================================
+// [asmjit::kMemType]
+// ============================================================================
+
+//! Type of memory operand.
+ASMJIT_ENUM(kMemType) {
+ //! Memory operand is a combination of base register and optional index register
+ //! and displacement.
+ //!
+ //! The `Assembler` interprets `kMemTypeBaseIndex` and `kMemTypeStackIndex`
+ //! types the same way, but `Compiler` interprets `kMemTypeBaseIndex` as
+ //! `[base + index]` and `kMemTypeStackIndex` as `[stack(base) + index]`.
+ kMemTypeBaseIndex = 0,
+
+ //! Memory operand is a combination of variable's memory location,
+ //! optional index register and displacement.
+ //!
+ //! The `Assembler` interprets `kMemTypeBaseIndex` and `kMemTypeStackIndex`
+ //! types in the same way, but `Compiler` interprets `kMemTypeBaseIndex` as
+ //! `[base + index]` and `kMemTypeStackIndex` as `[stack(base) + index]`.
+ kMemTypeStackIndex = 1,
+
+ //! Memory operand refers to the memory location specified by a label.
+ kMemTypeLabel = 2,
+ //! Memory operand is an absolute memory location.
+ //!
+ //! Supported mostly by x86, truncated to a 32-bit value when running in
+ //! 64-bit mode (x64).
+ kMemTypeAbsolute = 3
+};
+
+// ============================================================================
+// [asmjit::Operand]
+// ============================================================================
+
+//! Operand can contain register, memory location, immediate, or label.
+struct Operand {
+ // --------------------------------------------------------------------------
+ // [Structs]
+ // --------------------------------------------------------------------------
+
+ //! \internal
+ //!
+ //! Base operand data.
+ struct BaseOp {
+ //! Type of operand, see `kOperandType`.
+ uint8_t op;
+ //! Size of operand (register, address, immediate, or variable).
+ uint8_t size;
+ //! \internal
+ uint8_t reserved_2_1;
+ //! \internal
+ uint8_t reserved_3_1;
+
+ //! Operand id, identifier used by `Assembler` and `Compiler`.
+ //!
+ //! \note Uninitialized operand has always set id to `kInvalidValue`.
+ uint32_t id;
+
+ //! \internal
+ uint32_t reserved_8_4;
+ //! \internal
+ uint32_t reserved_12_4;
+ };
+
+ //! \internal
+ //!
+ //! Register or Variable operand data.
+ struct VRegOp {
+ //! Type of operand, `kOperandTypeReg`.
+ uint8_t op;
+ //! Size of register or variable.
+ uint8_t size;
+
+ union {
+ //! Register code = (type << 8) | index.
+ uint16_t code;
+
+ //! Register type and index access.
+ struct {
+#if defined(ASMJIT_HOST_LE)
+ //! Register index.
+ uint8_t index;
+ //! Register type.
+ uint8_t type;
+#else
+ //! Register type.
+ uint8_t type;
+ //! Register index.
+ uint8_t index;
+#endif // ASMJIT_HOST
+ };
+ };
+
+ //! Variable id, used by `Compiler` to identify variables.
+ uint32_t id;
+
+ union {
+ struct {
+ //! Variable type.
+ uint32_t vType;
+ //! \internal
+ uint32_t reserved_12_4;
+ };
+
+ //! \internal
+ //!
+ //! This is not needed or used, it's just to force compiler to always
+ //! align this struct to 8-bytes (so the struct is compatible to others
+ //! when it comes to alignment). It should fix VS linker warning as well.
+ uint64_t reserved8_8;
+ };
+ };
+
+ //! \internal
+ //!
+ //! Memory or Variable operand data.
+ struct VMemOp {
+ //! Type of operand, `kOperandTypeMem`.
+ uint8_t op;
+ //! Size of the pointer in bytes.
+ uint8_t size;
+ //! Type of the memory operand, see `kMemType`.
+ uint8_t type;
+ //! X86/X64 layout:
+ //! - segment [3 bits], see `kX86Seg`.
+ //! - shift [2 bits], index register shift (0 to 3).
+ uint8_t flags;
+
+ //! Base register, variable or label id.
+ uint32_t base;
+ //! Index register or variable.
+ uint32_t index;
+ //! 32-bit displacement or absolute address.
+ int32_t displacement;
+ };
+
+ //! \internal
+ //!
+ //! Immediate operand data.
+ struct ImmOp {
+ //! Type of operand, `kOperandTypeImm`.
+ uint8_t op;
+ //! Size of immediate (or 0 to autodetect).
+ uint8_t size;
+ //! \internal
+ uint8_t reserved_2_1;
+ //! \internal
+ uint8_t reserved_3_1;
+
+ //! Operand id, always set to `kInvalidValue` (immediates don't have IDs).
+ uint32_t id;
+
+ union {
+ //! 8x8-bit signed immediate values.
+ int8_t _i8[8];
+ //! 8x8-bit unsigned immediate values.
+ uint8_t _u8[8];
+
+ //! 4x16-bit signed immediate values.
+ int16_t _i16[4];
+ //! 4x16-bit unsigned immediate values.
+ uint16_t _u16[4];
+
+ //! 2x32-bit signed immediate values.
+ int32_t _i32[2];
+ //! 2x32-bit unsigned immediate values.
+ uint32_t _u32[2];
+
+ //! 1x64-bit signed immediate value.
+ int64_t _i64[1];
+ //! 1x64-bit unsigned immediate value.
+ uint64_t _u64[1];
+
+ //! 2x SP-FP values.
+ float _f32[2];
+ //! 1x DP-FP value.
+ double _f64[1];
+ } value;
+ };
+
+ //! \internal
+ //!
+ //! Label operand data.
+ struct LabelOp {
+ //! Type of operand, `kOperandTypeLabel`.
+ uint8_t op;
+ //! Always zero, labels don't have size.
+ uint8_t size;
+ //! \internal
+ uint8_t reserved_2_1;
+ //! \internal
+ uint8_t reserved_3_1;
+
+ //! Operand id (`kInvalidValue` if the label is not initialized by code
+ //! generator).
+ uint32_t id;
+
+ //! \internal
+ uint32_t reserved_8_4;
+ //! \internal
+ uint32_t reserved_12_4;
+ };
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create an uninitialized operand.
+ ASMJIT_INLINE Operand() {
+ _init_packed_op_sz_b0_b1_id(kOperandTypeNone, 0, 0, 0, kInvalidValue);
+ _init_packed_d2_d3(0, 0);
+ }
+
+ //! Create a reference to `other` operand.
+ ASMJIT_INLINE Operand(const Operand& other) {
+ _init(other);
+ }
+
+ explicit ASMJIT_INLINE Operand(const _NoInit&) {}
+
+ // --------------------------------------------------------------------------
+ // [Operand]
+ // --------------------------------------------------------------------------
+
+ //! Clone `Operand`.
+ ASMJIT_INLINE Operand clone() const {
+ return Operand(*this);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Init & Copy]
+ // --------------------------------------------------------------------------
+
+ //! \internal
+ //!
+ //! Initialize operand to `other` (used by constructors).
+ ASMJIT_INLINE void _init(const Operand& other) {
+ ::memcpy(this, &other, sizeof(Operand));
+ }
+
+ ASMJIT_INLINE void _init_packed_op_sz_b0_b1_id(uint32_t op, uint32_t sz, uint32_t r0, uint32_t r1, uint32_t id) {
+ // This hack is not for performance, but to decrease the size of the binary
+ // generated when constructing AsmJit operands (mostly for third parties).
+ // Some compilers are not able to join four BYTE writes to a single DWORD
+ // write. Because the 'a', 'b', 'c' and 'd' variables are usually compile
+ // time constants the compiler can do a really nice job if they are joined
+ // by using bitwise operations.
+ _packed[0].setPacked_2x32(IntUtil::pack32_4x8(op, sz, r0, r1), id);
+ }
+
+ ASMJIT_INLINE void _init_packed_op_sz_w0_id(uint32_t op, uint32_t sz, uint32_t w0, uint32_t id) {
+ _packed[0].setPacked_2x32(IntUtil::pack32_2x8_1x16(op, sz, w0), id);
+ }
+
+ ASMJIT_INLINE void _init_packed_d0_d1(uint32_t u0, uint32_t u1) {
+ _packed[0].setPacked_2x32(u0, u1);
+ }
+
+ ASMJIT_INLINE void _init_packed_d2_d3(uint32_t u2, uint32_t u3) {
+ _packed[1].setPacked_2x32(u2, u3);
+ }
+
+ //! \internal
+ //!
+ //! Initialize operand to `other` (used by assign operators).
+ ASMJIT_INLINE void _copy(const Operand& other) {
+ ::memcpy(this, &other, sizeof(Operand));
+ }
+
+ // --------------------------------------------------------------------------
+ // [Data]
+ // --------------------------------------------------------------------------
+
+ template
+ ASMJIT_INLINE T& getData() {
+ return reinterpret_cast(_base);
+ }
+
+ template
+ ASMJIT_INLINE const T& getData() const {
+ return reinterpret_cast(_base);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Type]
+ // --------------------------------------------------------------------------
+
+ //! Get type of the operand, see `kOperandType`.
+ ASMJIT_INLINE uint32_t getOp() const { return _base.op; }
+
+ //! Get whether the operand is none - `kOperandTypeNone`.
+ ASMJIT_INLINE bool isNone() const { return (_base.op == kOperandTypeNone); }
+ //! Get whether the operand is a register - `kOperandTypeReg`.
+ ASMJIT_INLINE bool isReg() const { return (_base.op == kOperandTypeReg); }
+ //! Get whether the operand is a variable - `kOperandTypeVar`.
+ ASMJIT_INLINE bool isVar() const { return (_base.op == kOperandTypeVar); }
+ //! Get whether the operand is a memory address - `kOperandTypeMem`.
+ ASMJIT_INLINE bool isMem() const { return (_base.op == kOperandTypeMem); }
+ //! Get whether the operand is an immediate value - `kOperandTypeImm`.
+ ASMJIT_INLINE bool isImm() const { return (_base.op == kOperandTypeImm); }
+ //! Get whether the operand is a label - `kOperandTypeLabel`.
+ ASMJIT_INLINE bool isLabel() const { return (_base.op == kOperandTypeLabel); }
+
+ // --------------------------------------------------------------------------
+ // [Type - Combined]
+ // --------------------------------------------------------------------------
+
+ //! Get register type.
+ ASMJIT_INLINE uint32_t getRegType() const {
+ return _vreg.type;
+ }
+
+ //! Get register index.
+ ASMJIT_INLINE uint32_t getRegIndex() const {
+ return _vreg.index;
+ }
+
+ //! Get whether the operand is register of `type`.
+ ASMJIT_INLINE bool isRegType(uint32_t type) const {
+ return (_packed[0].u32[0] & IntUtil::pack32_2x8_1x16(0xFF, 0, 0xFF00)) == IntUtil::pack32_2x8_1x16(kOperandTypeReg, 0, (type << 8));
+ }
+
+ //! Get whether the operand is register and of `type` and `index`.
+ ASMJIT_INLINE bool isRegCode(uint32_t type, uint32_t index) const {
+ return (_packed[0].u32[0] & IntUtil::pack32_2x8_1x16(0xFF, 0, 0xFFFF)) == IntUtil::pack32_2x8_1x16(kOperandTypeReg, 0, (type << 8) + index);
+ }
+
+ //! Get whether the operand is a register or memory.
+ ASMJIT_INLINE bool isRegOrMem() const {
+ ASMJIT_ASSERT(kOperandTypeReg == 1);
+ ASMJIT_ASSERT(kOperandTypeMem == 3);
+ return (static_cast(_base.op) | 0x2U) == 0x3U;
+ }
+
+ //! Get whether the operand is variable or memory.
+ ASMJIT_INLINE bool isVarOrMem() const {
+ ASMJIT_ASSERT(kOperandTypeVar == 2);
+ ASMJIT_ASSERT(kOperandTypeMem == 3);
+ return (static_cast(_base.op) - 2U) <= 1;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Size]
+ // --------------------------------------------------------------------------
+
+ //! Get size of the operand in bytes.
+ ASMJIT_INLINE uint32_t getSize() const {
+ return _base.size;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Id]
+ // --------------------------------------------------------------------------
+
+ //! Get operand id.
+ //!
+ //! Operand id's are used internally by `Assembler` and `Compiler`.
+ //!
+ //! There is no way to change or remove operand id. Unneeded operands can be
+ //! simply reassigned by `operator=`.
+ ASMJIT_INLINE uint32_t getId() const {
+ return _base.id;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ union {
+ //! Base data.
+ BaseOp _base;
+ //! Register or variable data.
+ VRegOp _vreg;
+ //! Memory data.
+ VMemOp _vmem;
+ //! Immediate data.
+ ImmOp _imm;
+ //! Label data.
+ LabelOp _label;
+
+ //! Packed operand as two 64-bit integers.
+ UInt64 _packed[2];
+ };
+};
+
+// ============================================================================
+// [asmjit::OperandUtil]
+// ============================================================================
+
+//! Operand utilities.
+struct OperandUtil {
+ //! Make variable id.
+ static ASMJIT_INLINE uint32_t makeVarId(uint32_t id) {
+ return id | kOperandIdVar;
+ }
+
+ //! Make label id.
+ static ASMJIT_INLINE uint32_t makeLabelId(uint32_t id) {
+ return id;
+ }
+
+ //! Strip variable id bit so it becomes a pure index to `VarData[]` array.
+ static ASMJIT_INLINE uint32_t stripVarId(uint32_t id) {
+ return id & 0x7FFFFFFFU;
+ }
+
+ //! Get whether the id refers to `Var`.
+ //!
+ //! \note The function will never return `true` if the id is `kInvalidValue`.
+ //! The trick is to compare a given id to -1 (kInvalidValue) so we check both
+ //! using only one comparison.
+ static ASMJIT_INLINE bool isVarId(uint32_t id) {
+ return static_cast(id) < -1;
+ }
+
+ //! Get whether the id refers to `Label`.
+ //!
+ //! \note The function will never return `true` if the id is `kInvalidValue`.
+ static ASMJIT_INLINE bool isLabelId(uint32_t id) {
+ return static_cast(id) >= 0;
+ }
+};
+
+// ============================================================================
+// [asmjit::Reg]
+// ============================================================================
+
+//! Base class for all register operands.
+struct Reg : public Operand {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a dummy base register.
+ ASMJIT_INLINE Reg() : Operand(NoInit) {
+ _init_packed_op_sz_w0_id(kOperandTypeReg, 0, (kInvalidReg << 8) + kInvalidReg, kInvalidValue);
+ _init_packed_d2_d3(kInvalidVar, 0);
+ }
+
+ //! Create a new base register.
+ ASMJIT_INLINE Reg(uint32_t type, uint32_t index, uint32_t size) : Operand(NoInit) {
+ _init_packed_op_sz_w0_id(kOperandTypeReg, size, (type << 8) + index, kInvalidValue);
+ _init_packed_d2_d3(kInvalidVar, 0);
+ }
+
+ //! Create a new reference to `other`.
+ ASMJIT_INLINE Reg(const Reg& other) : Operand(other) {}
+
+ //! Create a new reference to `other` and change the index to `index`.
+ ASMJIT_INLINE Reg(const Reg& other, uint32_t index) : Operand(other) {
+ _vreg.index = static_cast(index);
+ }
+
+ explicit ASMJIT_INLINE Reg(const _NoInit&) : Operand(NoInit) {}
+
+ // --------------------------------------------------------------------------
+ // [Reg Specific]
+ // --------------------------------------------------------------------------
+
+ //! Clone `Reg` operand.
+ ASMJIT_INLINE Reg clone() const {
+ return Reg(*this);
+ }
+
+ //! Get whether register code is equal to `type`.
+ ASMJIT_INLINE bool isRegType(uint32_t type) const {
+ return _vreg.type == type;
+ }
+
+ //! Get whether register code is equal to `type`.
+ ASMJIT_INLINE bool isRegCode(uint32_t code) const {
+ return _vreg.code == code;
+ }
+
+ //! Get whether register code is equal to `type`.
+ ASMJIT_INLINE bool isRegCode(uint32_t type, uint32_t index) const {
+ return _vreg.code == (type << 8) + index;
+ }
+
+ //! Get register code that equals to '(type << 8) + index'.
+ ASMJIT_INLINE uint32_t getRegCode() const {
+ return _vreg.code;
+ }
+
+ //! Get register type.
+ ASMJIT_INLINE uint32_t getRegType() const {
+ return _vreg.type;
+ }
+
+ //! Get register index.
+ ASMJIT_INLINE uint32_t getRegIndex() const {
+ return _vreg.index;
+ }
+
+#define ASMJIT_REG_OP(_Type_) \
+ ASMJIT_INLINE _Type_ clone() const { \
+ return _Type_(*this); \
+ } \
+ \
+ /*! Set register `size`. */ \
+ ASMJIT_INLINE _Type_& setSize(uint32_t size) { \
+ _vreg.size = static_cast(size); \
+ return *this; \
+ } \
+ \
+ /*! Set register `code`. */ \
+ ASMJIT_INLINE _Type_& setCode(uint32_t code) { \
+ _vreg.code = static_cast(code); \
+ return *this; \
+ } \
+ \
+ /*! Set register `type` and `index`. */ \
+ ASMJIT_INLINE _Type_& setCode(uint32_t type, uint32_t index) { \
+ _vreg.type = static_cast(type); \
+ _vreg.index = static_cast(index); \
+ return *this; \
+ } \
+ \
+ /*! Set register `type`. */ \
+ ASMJIT_INLINE _Type_& setType(uint32_t type) { \
+ _vreg.type = static_cast(type); \
+ return *this; \
+ } \
+ \
+ /*! Set register `index`. */ \
+ ASMJIT_INLINE _Type_& setIndex(uint32_t index) { \
+ _vreg.index = static_cast(index); \
+ return *this; \
+ } \
+ \
+ ASMJIT_INLINE _Type_& operator=(const _Type_& other) { _copy(other); return *this; } \
+ \
+ ASMJIT_INLINE bool operator==(const _Type_& other) const { return _packed[0].u32[0] == other._packed[0].u32[0]; } \
+ ASMJIT_INLINE bool operator!=(const _Type_& other) const { return !operator==(other); }
+};
+
+// ============================================================================
+// [asmjit::BaseMem]
+// ============================================================================
+
+//! Base class for all memory operands.
+struct BaseMem : public Operand {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE BaseMem() : Operand(NoInit) {
+ reset();
+ }
+
+ ASMJIT_INLINE BaseMem(const BaseMem& other) : Operand(other) {}
+ explicit ASMJIT_INLINE BaseMem(const _NoInit&) : Operand(NoInit) {}
+
+ // --------------------------------------------------------------------------
+ // [BaseMem Specific]
+ // --------------------------------------------------------------------------
+
+ //! Clone `BaseMem` operand.
+ ASMJIT_INLINE BaseMem clone() const {
+ return BaseMem(*this);
+ }
+
+ //! Reset `BaseMem` operand.
+ ASMJIT_INLINE void reset() {
+ _init_packed_op_sz_b0_b1_id(kOperandTypeMem, 0, kMemTypeBaseIndex, 0, kInvalidValue);
+ _init_packed_d2_d3(kInvalidValue, 0);
+ }
+
+ //! Get the type of the memory operand, see `kMemType`.
+ ASMJIT_INLINE uint32_t getMemType() const {
+ return _vmem.type;
+ }
+
+ //! Get whether the type of the memory operand is either `kMemTypeBaseIndex`
+ //! or `kMemTypeStackIndex`.
+ ASMJIT_INLINE bool isBaseIndexType() const {
+ return _vmem.type <= kMemTypeStackIndex;
+ }
+
+ //! Get whether the memory operand has base register.
+ ASMJIT_INLINE bool hasBase() const {
+ return _vmem.base != kInvalidValue;
+ }
+
+ //! Get memory operand base id, or `kInvalidValue`.
+ ASMJIT_INLINE uint32_t getBase() const {
+ return _vmem.base;
+ }
+
+ //! Set memory operand size.
+ ASMJIT_INLINE BaseMem& setSize(uint32_t size) {
+ _vmem.size = static_cast(size);
+ return *this;
+ }
+
+ //! Get memory operand relative displacement.
+ ASMJIT_INLINE int32_t getDisplacement() const {
+ return _vmem.displacement;
+ }
+
+ //! Set memory operand relative displacement.
+ ASMJIT_INLINE BaseMem& setDisplacement(int32_t disp) {
+ _vmem.displacement = disp;
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Operator Overload]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE BaseMem& operator=(const BaseMem& other) {
+ _copy(other);
+ return *this;
+ }
+
+ ASMJIT_INLINE bool operator==(const BaseMem& other) const {
+ return (_packed[0] == other._packed[0]) & (_packed[1] == other._packed[1]);
+ }
+
+ ASMJIT_INLINE bool operator!=(const BaseMem& other) const {
+ return !(*this == other);
+ }
+};
+
+// ============================================================================
+// [asmjit::Imm]
+// ============================================================================
+
+//! Immediate operand.
+//!
+//! Immediate operand is usually part of instruction itself. It's inlined after
+//! or before the instruction opcode. Immediates can be only signed or unsigned
+//! integers.
+//!
+//! To create immediate operand use `imm()` or `imm_u()` non-members or `Imm`
+//! constructors.
+struct Imm : public Operand {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new immediate value (initial value is 0).
+ Imm() : Operand(NoInit) {
+ _init_packed_op_sz_b0_b1_id(kOperandTypeImm, 0, 0, 0, kInvalidValue);
+ _imm.value._i64[0] = 0;
+ }
+
+ //! Create a new signed immediate value, assigning the value to `val`.
+ explicit Imm(int64_t val) : Operand(NoInit) {
+ _init_packed_op_sz_b0_b1_id(kOperandTypeImm, 0, 0, 0, kInvalidValue);
+ _imm.value._i64[0] = val;
+ }
+
+ //! Create a new immediate value from `other`.
+ ASMJIT_INLINE Imm(const Imm& other) : Operand(other) {}
+
+ explicit ASMJIT_INLINE Imm(const _NoInit&) : Operand(NoInit) {}
+
+ // --------------------------------------------------------------------------
+ // [Immediate Specific]
+ // --------------------------------------------------------------------------
+
+ //! Clone `Imm` operand.
+ ASMJIT_INLINE Imm clone() const {
+ return Imm(*this);
+ }
+
+ //! Get whether the immediate can be casted to 8-bit signed integer.
+ ASMJIT_INLINE bool isInt8() const { return IntUtil::isInt8(_imm.value._i64[0]); }
+ //! Get whether the immediate can be casted to 8-bit unsigned integer.
+ ASMJIT_INLINE bool isUInt8() const { return IntUtil::isUInt8(_imm.value._i64[0]); }
+
+ //! Get whether the immediate can be casted to 16-bit signed integer.
+ ASMJIT_INLINE bool isInt16() const { return IntUtil::isInt16(_imm.value._i64[0]); }
+ //! Get whether the immediate can be casted to 16-bit unsigned integer.
+ ASMJIT_INLINE bool isUInt16() const { return IntUtil::isUInt16(_imm.value._i64[0]); }
+
+ //! Get whether the immediate can be casted to 32-bit signed integer.
+ ASMJIT_INLINE bool isInt32() const { return IntUtil::isInt32(_imm.value._i64[0]); }
+ //! Get whether the immediate can be casted to 32-bit unsigned integer.
+ ASMJIT_INLINE bool isUInt32() const { return IntUtil::isUInt32(_imm.value._i64[0]); }
+
+ //! Get immediate value as 8-bit signed integer.
+ ASMJIT_INLINE int8_t getInt8() const { return _imm.value._i8[_ASMJIT_HOST_INDEX(8, 0)]; }
+ //! Get immediate value as 8-bit unsigned integer.
+ ASMJIT_INLINE uint8_t getUInt8() const { return _imm.value._u8[_ASMJIT_HOST_INDEX(8, 0)]; }
+ //! Get immediate value as 16-bit signed integer.
+ ASMJIT_INLINE int16_t getInt16() const { return _imm.value._i16[_ASMJIT_HOST_INDEX(4, 0)]; }
+ //! Get immediate value as 16-bit unsigned integer.
+ ASMJIT_INLINE uint16_t getUInt16() const { return _imm.value._u16[_ASMJIT_HOST_INDEX(4, 0)]; }
+ //! Get immediate value as 32-bit signed integer.
+ ASMJIT_INLINE int32_t getInt32() const { return _imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)]; }
+ //! Get immediate value as 32-bit unsigned integer.
+ ASMJIT_INLINE uint32_t getUInt32() const { return _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)]; }
+ //! Get immediate value as 64-bit signed integer.
+ ASMJIT_INLINE int64_t getInt64() const { return _imm.value._i64[0]; }
+ //! Get immediate value as 64-bit unsigned integer.
+ ASMJIT_INLINE uint64_t getUInt64() const { return _imm.value._u64[0]; }
+
+ //! Get immediate value as `intptr_t`.
+ ASMJIT_INLINE intptr_t getIntPtr() const {
+ if (sizeof(intptr_t) == sizeof(int64_t))
+ return static_cast(getInt64());
+ else
+ return static_cast(getInt32());
+ }
+
+ //! Get immediate value as `uintptr_t`.
+ ASMJIT_INLINE uintptr_t getUIntPtr() const {
+ if (sizeof(uintptr_t) == sizeof(uint64_t))
+ return static_cast(getUInt64());
+ else
+ return static_cast(getUInt32());
+ }
+
+ //! Get low 32-bit signed integer.
+ ASMJIT_INLINE int32_t getInt32Lo() const { return _imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)]; }
+ //! Get low 32-bit signed integer.
+ ASMJIT_INLINE uint32_t getUInt32Lo() const { return _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)]; }
+ //! Get high 32-bit signed integer.
+ ASMJIT_INLINE int32_t getInt32Hi() const { return _imm.value._i32[_ASMJIT_HOST_INDEX(2, 1)]; }
+ //! Get high 32-bit signed integer.
+ ASMJIT_INLINE uint32_t getUInt32Hi() const { return _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)]; }
+
+ //! Set immediate value to 8-bit signed integer `val`.
+ ASMJIT_INLINE Imm& setInt8(int8_t val) {
+ if (kArchHost64Bit) {
+ _imm.value._i64[0] = static_cast(val);
+ }
+ else {
+ int32_t val32 = static_cast(val);
+ _imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)] = val32;
+ _imm.value._i32[_ASMJIT_HOST_INDEX(2, 1)] = val32 >> 31;
+ }
+ return *this;
+ }
+
+ //! Set immediate value to 8-bit unsigned integer `val`.
+ ASMJIT_INLINE Imm& setUInt8(uint8_t val) {
+ if (kArchHost64Bit) {
+ _imm.value._u64[0] = static_cast(val);
+ }
+ else {
+ _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] = static_cast(val);
+ _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0;
+ }
+ return *this;
+ }
+
+ //! Set immediate value to 16-bit signed integer `val`.
+ ASMJIT_INLINE Imm& setInt16(int16_t val) {
+ if (kArchHost64Bit) {
+ _imm.value._i64[0] = static_cast(val);
+ }
+ else {
+ int32_t val32 = static_cast(val);
+ _imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)] = val32;
+ _imm.value._i32[_ASMJIT_HOST_INDEX(2, 1)] = val32 >> 31;
+ }
+ return *this;
+ }
+
+ //! Set immediate value to 16-bit unsigned integer `val`.
+ ASMJIT_INLINE Imm& setUInt16(uint16_t val) {
+ if (kArchHost64Bit) {
+ _imm.value._u64[0] = static_cast(val);
+ }
+ else {
+ _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] = static_cast(val);
+ _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0;
+ }
+ return *this;
+ }
+
+ //! Set immediate value to 32-bit signed integer `val`.
+ ASMJIT_INLINE Imm& setInt32(int32_t val) {
+ if (kArchHost64Bit) {
+ _imm.value._i64[0] = static_cast(val);
+ }
+ else {
+ _imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)] = val;
+ _imm.value._i32[_ASMJIT_HOST_INDEX(2, 1)] = val >> 31;
+ }
+ return *this;
+ }
+
+ //! Set immediate value to 32-bit unsigned integer `val`.
+ ASMJIT_INLINE Imm& setUInt32(uint32_t val) {
+ if (kArchHost64Bit) {
+ _imm.value._u64[0] = static_cast(val);
+ }
+ else {
+ _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] = val;
+ _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0;
+ }
+ return *this;
+ }
+
+ //! Set immediate value to 64-bit signed integer `val`.
+ ASMJIT_INLINE Imm& setInt64(int64_t val) {
+ _imm.value._i64[0] = val;
+ return *this;
+ }
+
+ //! Set immediate value to 64-bit unsigned integer `val`.
+ ASMJIT_INLINE Imm& setUInt64(uint64_t val) {
+ _imm.value._u64[0] = val;
+ return *this;
+ }
+
+ //! Set immediate value to intptr_t `val`.
+ ASMJIT_INLINE Imm& setIntPtr(intptr_t val) {
+ _imm.value._i64[0] = static_cast(val);
+ return *this;
+ }
+
+ //! Set immediate value to uintptr_t `val`.
+ ASMJIT_INLINE Imm& setUIntPtr(uintptr_t val) {
+ _imm.value._u64[0] = static_cast(val);
+ return *this;
+ }
+
+ //! Set immediate value as unsigned type to `val`.
+ ASMJIT_INLINE Imm& setPtr(void* p) { return setIntPtr((intptr_t)p); }
+
+ // --------------------------------------------------------------------------
+ // [Float]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE Imm& setFloat(float f) {
+ _imm.value._f32[_ASMJIT_HOST_INDEX(2, 0)] = f;
+ _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0;
+ return *this;
+ }
+
+ ASMJIT_INLINE Imm& setDouble(double d) {
+ _imm.value._f64[0] = d;
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Truncate]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE Imm& truncateTo8Bits() {
+ if (kArchHost64Bit) {
+ _imm.value._u64[0] &= static_cast(0x000000FFU);
+ }
+ else {
+ _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] &= 0x000000FFU;
+ _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0;
+ }
+ return *this;
+ }
+
+ ASMJIT_INLINE Imm& truncateTo16Bits() {
+ if (kArchHost64Bit) {
+ _imm.value._u64[0] &= static_cast(0x0000FFFFU);
+ }
+ else {
+ _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] &= 0x0000FFFFU;
+ _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0;
+ }
+ return *this;
+ }
+
+ ASMJIT_INLINE Imm& truncateTo32Bits() {
+ _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0;
+ return *this;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Operator Overload]
+ // --------------------------------------------------------------------------
+
+ //! Assign `other` to the immediate operand.
+ ASMJIT_INLINE Imm& operator=(const Imm& other) {
+ _copy(other);
+ return *this;
+ }
+};
+
+// ============================================================================
+// [asmjit::Label]
+// ============================================================================
+
+//! Label (jump target or data location).
+//!
+//! Label represents a location in code typically used as jump targets, but may
+//! be also reference data or static variables. Label has to be explicitly
+//! created by a code-generator by calling `CodeGen::newLabel()` where `CodeGen`
+//! is your code generator, which derives from `Assembler` or `Compiler`.
+//!
+//! Example of using labels:
+//!
+//! ~~~
+//! // Create Assembler/Compiler.
+//! host::Assembler a;
+//!
+//! // Create Label instance.
+//! Label L_1(a);
+//!
+//! // ... your code ...
+//!
+//! // Using label.
+//! a.jump(L_1);
+//!
+//! // ... your code ...
+//!
+//! // Bind label to the current position, see `CodeGen::bind()`.
+//! a.bind(L_1);
+//! ~~~
+struct Label : public Operand {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create new, unassociated label.
+ ASMJIT_INLINE Label() : Operand(NoInit) {
+ reset();
+ }
+
+ explicit ASMJIT_INLINE Label(uint32_t id) : Operand(NoInit) {
+ _init_packed_op_sz_b0_b1_id(kOperandTypeLabel, 0, 0, 0, id);
+ _init_packed_d2_d3(0, 0);
+ }
+
+ //! Create new initialized label.
+ explicit ASMJIT_INLINE Label(Assembler& a);
+ //! Create new initialized label.
+ explicit ASMJIT_INLINE Label(Compiler& c);
+
+ //! Create reference to another label.
+ ASMJIT_INLINE Label(const Label& other) : Operand(other) {}
+
+ explicit ASMJIT_INLINE Label(const _NoInit&) : Operand(NoInit) {}
+
+ // --------------------------------------------------------------------------
+ // [Reset]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE void reset() {
+ _init_packed_op_sz_b0_b1_id(kOperandTypeLabel, 0, 0, 0, kInvalidValue);
+ _init_packed_d2_d3(0, 0);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Label Specific]
+ // --------------------------------------------------------------------------
+
+ //! Get whether the label has been initialized by `Assembler` or `Compiler`.
+ ASMJIT_INLINE bool isInitialized() const {
+ return _label.id != kInvalidValue;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Operator Overload]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE Label& operator=(const Label& other) { _copy(other); return *this; }
+
+ ASMJIT_INLINE bool operator==(const Label& other) const { return _base.id == other._base.id; }
+ ASMJIT_INLINE bool operator!=(const Label& other) const { return _base.id != other._base.id; }
+};
+
+// ============================================================================
+// [asmjit::Operand - Globals]
+// ============================================================================
+
+//! No operand, can be used to reset an operand by assignment or to refer to an
+//! operand that doesn't exist.
+ASMJIT_VAR const Operand noOperand;
+
+//! Create signed immediate value operand.
+static ASMJIT_INLINE Imm imm(int64_t val) {
+ return Imm(val);
+}
+
+//! Create unsigned immediate value operand.
+static ASMJIT_INLINE Imm imm_u(uint64_t val) {
+ return Imm(static_cast(val));
+}
+
+//! Create void* pointer immediate value operand.
+static ASMJIT_INLINE Imm imm_ptr(void* p) {
+ return Imm(static_cast((intptr_t)p));
+}
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // _ASMJIT_BASE_OPERAND_H
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/runtime.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/runtime.h
new file mode 100644
index 0000000..b355fc4
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/runtime.h
@@ -0,0 +1,262 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Guard]
+#ifndef _ASMJIT_BASE_RUNTIME_H
+#define _ASMJIT_BASE_RUNTIME_H
+
+// [Dependencies - AsmJit]
+#include "../base/error.h"
+#include "../base/vmem.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+// ============================================================================
+// [Forward Declarations]
+// ============================================================================
+
+struct Assembler;
+struct CpuInfo;
+
+//! \addtogroup asmjit_base_general
+//! \{
+
+// ============================================================================
+// [asmjit::kRuntimeType]
+// ============================================================================
+
+ASMJIT_ENUM(kRuntimeType) {
+ kRuntimeTypeNone = 0,
+
+ kRuntimeTypeJit = 1,
+ kRuntimeTypeRemote = 2
+};
+
+// ============================================================================
+// [asmjit::Runtime]
+// ============================================================================
+
+//! Base runtime.
+struct ASMJIT_VCLASS Runtime {
+ ASMJIT_NO_COPY(Runtime)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a `Runtime` instance.
+ ASMJIT_API Runtime();
+ //! Destroy the `Runtime` instance.
+ ASMJIT_API virtual ~Runtime();
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get runtime type.
+ ASMJIT_INLINE uint32_t getRuntimeType() const {
+ return _runtimeType;
+ }
+
+ //! Get whether the runtime has a base address.
+ //!
+ //! \sa \ref getBaseAddress()
+ ASMJIT_INLINE bool hasBaseAddress() const {
+ return _baseAddress == kNoBaseAddress;
+ }
+
+ //! Get the base address.
+ ASMJIT_INLINE Ptr getBaseAddress() const {
+ return _baseAddress;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Interface]
+ // --------------------------------------------------------------------------
+
+ //! Get CPU information.
+ virtual const CpuInfo* getCpuInfo() = 0;
+
+ //! Get stack alignment of target runtime.
+ virtual uint32_t getStackAlignment() = 0;
+
+ //! Allocate a memory needed for a code generated by `assembler` and
+ //! relocate it to the target location.
+ //!
+ //! The beginning of the memory allocated for the function is returned in
+ //! `dst`. Returns Status code as \ref kError, on failure `dst` is set to
+ //! `NULL`.
+ virtual Error add(void** dst, Assembler* assembler) = 0;
+
+ //! Release memory allocated by `add`.
+ virtual Error release(void* p) = 0;
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Maximum size of the code that can be added to the runtime (0=unlimited).
+ size_t _sizeLimit;
+ //! Base address (-1 means no base address).
+ Ptr _baseAddress;
+
+ //! Type of the runtime.
+ uint8_t _runtimeType;
+ //! Type of the allocation.
+ uint8_t _allocType;
+ //! \internal
+ uint8_t _reserved[sizeof(intptr_t) - 2];
+};
+
+// ============================================================================
+// [asmjit::HostRuntime]
+// ============================================================================
+
+//! Base runtime for JIT code generation.
+struct ASMJIT_VCLASS HostRuntime : public Runtime {
+ ASMJIT_NO_COPY(HostRuntime)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a `HostRuntime` instance.
+ ASMJIT_API HostRuntime();
+ //! Destroy the `HostRuntime` instance.
+ ASMJIT_API virtual ~HostRuntime();
+
+ // --------------------------------------------------------------------------
+ // [Interface]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API virtual const CpuInfo* getCpuInfo();
+ ASMJIT_API virtual uint32_t getStackAlignment();
+
+ //! Flush an instruction cache.
+ //!
+ //! This member function is called after the code has been copied to the
+ //! destination buffer. It is only useful for JIT code generation as it
+ //! causes a flush of the processor cache.
+ //!
+ //! Flushing is basically a NOP under X86/X64, but is needed by architectures
+ //! that do not have a transparent instruction cache.
+ //!
+ //! This function can also be overridden to improve compatibility with tools
+ //! such as Valgrind, however, it's not an official part of AsmJit.
+ ASMJIT_API virtual void flush(void* p, size_t size);
+};
+
+// ============================================================================
+// [asmjit::StaticRuntime]
+// ============================================================================
+
+//! JIT static runtime.
+//!
+//! JIT static runtime can be used to generate code to a memory location that
+//! is known.
+struct ASMJIT_VCLASS StaticRuntime : public HostRuntime {
+ ASMJIT_NO_COPY(StaticRuntime)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a `StaticRuntime` instance.
+ //!
+ //! The `address` specifies a fixed target address, which will be used as a
+ //! base address for relocation, and `sizeLimit` specified the maximum size
+ //! of a code that can be copied to it. If there is no limit `sizeLimit`
+ //! should be zero.
+ ASMJIT_API StaticRuntime(void* baseAddress, size_t sizeLimit = 0);
+ //! Destroy the `StaticRuntime` instance.
+ ASMJIT_API virtual ~StaticRuntime();
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get the base address.
+ ASMJIT_INLINE Ptr getBaseAddress() const {
+ return _baseAddress;
+ }
+
+ //! Get the maximum size of the code that can be relocated to the target
+ //! address or zero if unlimited.
+ ASMJIT_INLINE size_t getSizeLimit() const {
+ return _sizeLimit;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Interface]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API virtual Error add(void** dst, Assembler* assembler);
+ ASMJIT_API virtual Error release(void* p);
+};
+
+// ============================================================================
+// [asmjit::JitRuntime]
+// ============================================================================
+
+//! JIT runtime.
+struct ASMJIT_VCLASS JitRuntime : public HostRuntime {
+ ASMJIT_NO_COPY(JitRuntime)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a `JitRuntime` instance.
+ ASMJIT_API JitRuntime();
+ //! Destroy the `JitRuntime` instance.
+ ASMJIT_API virtual ~JitRuntime();
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get the type of allocation.
+ ASMJIT_INLINE uint32_t getAllocType() const {
+ return _allocType;
+ }
+
+ //! Set the type of allocation.
+ ASMJIT_INLINE void setAllocType(uint32_t allocType) {
+ _allocType = allocType;
+ }
+
+ //! Get the virtual memory manager.
+ ASMJIT_INLINE VMemMgr* getMemMgr() const {
+ return const_cast(&_memMgr);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Interface]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API virtual Error add(void** dst, Assembler* assembler);
+ ASMJIT_API virtual Error release(void* p);
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Virtual memory manager.
+ VMemMgr _memMgr;
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // _ASMJIT_BASE_RUNTIME_H
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/string.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/string.h
new file mode 100644
index 0000000..145a689
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/string.h
@@ -0,0 +1,372 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Guard]
+#ifndef _ASMJIT_BASE_STRING_H
+#define _ASMJIT_BASE_STRING_H
+
+// [Dependencies - AsmJit]
+#include "../base/globals.h"
+
+// [Dependencies - C]
+#include
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_util
+//! \{
+
+// ============================================================================
+// [asmjit::kStringOp]
+// ============================================================================
+
+//! \internal
+//!
+//! String operation.
+ASMJIT_ENUM(kStringOp) {
+ //! Replace the current string by a given content.
+ kStringOpSet = 0,
+ //! Append a given content to the current string.
+ kStringOpAppend = 1
+};
+
+// ============================================================================
+// [asmjit::kStringFormat]
+// ============================================================================
+
+//! \internal
+//!
+//! String format flags.
+ASMJIT_ENUM(kStringFormat) {
+ kStringFormatShowSign = 0x00000001,
+ kStringFormatShowSpace = 0x00000002,
+ kStringFormatAlternate = 0x00000004,
+ kStringFormatSigned = 0x80000000
+};
+
+// ============================================================================
+// [asmjit::StringUtil]
+// ============================================================================
+
+//! String utilities.
+struct StringUtil {
+ static ASMJIT_INLINE size_t nlen(const char* s, size_t maxlen) {
+ size_t i;
+ for (i = 0; i < maxlen; i++)
+ if (!s[i])
+ break;
+ return i;
+ }
+};
+
+// ============================================================================
+// [asmjit::StringBuilder]
+// ============================================================================
+
+//! String builder.
+//!
+//! String builder was designed to be able to build a string using append like
+//! operation to append numbers, other strings, or signle characters. It can
+//! allocate it's own buffer or use a buffer created on the stack.
+//!
+//! String builder contains method specific to AsmJit functionality, used for
+//! logging or HTML output.
+struct StringBuilder {
+ ASMJIT_NO_COPY(StringBuilder)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API StringBuilder();
+ ASMJIT_API ~StringBuilder();
+
+ ASMJIT_INLINE StringBuilder(const _NoInit&) {}
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get string builder capacity.
+ ASMJIT_INLINE size_t getCapacity() const { return _capacity; }
+ //! Get length.
+ ASMJIT_INLINE size_t getLength() const { return _length; }
+
+ //! Get null-terminated string data.
+ ASMJIT_INLINE char* getData() { return _data; }
+ //! Get null-terminated string data (const).
+ ASMJIT_INLINE const char* getData() const { return _data; }
+
+ // --------------------------------------------------------------------------
+ // [Prepare / Reserve]
+ // --------------------------------------------------------------------------
+
+ //! Prepare to set/append.
+ ASMJIT_API char* prepare(uint32_t op, size_t len);
+
+ //! Reserve `to` bytes in string builder.
+ ASMJIT_API bool reserve(size_t to);
+
+ // --------------------------------------------------------------------------
+ // [Clear]
+ // --------------------------------------------------------------------------
+
+ //! Clear the content in String builder.
+ ASMJIT_API void clear();
+
+ // --------------------------------------------------------------------------
+ // [Op]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_API bool _opString(uint32_t op, const char* str, size_t len = kInvalidIndex);
+ ASMJIT_API bool _opVFormat(uint32_t op, const char* fmt, va_list ap);
+ ASMJIT_API bool _opChar(uint32_t op, char c);
+ ASMJIT_API bool _opChars(uint32_t op, char c, size_t len);
+ ASMJIT_API bool _opNumber(uint32_t op, uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0);
+ ASMJIT_API bool _opHex(uint32_t op, const void* data, size_t len);
+
+ // --------------------------------------------------------------------------
+ // [Set]
+ // --------------------------------------------------------------------------
+
+ //! Replace the current content by `str` of `len`.
+ ASMJIT_INLINE bool setString(const char* str, size_t len = kInvalidIndex) {
+ return _opString(kStringOpSet, str, len);
+ }
+
+ //! Replace the current content by formatted string `fmt`.
+ ASMJIT_INLINE bool setVFormat(const char* fmt, va_list ap) {
+ return _opVFormat(kStringOpSet, fmt, ap);
+ }
+
+ //! Replace the current content by formatted string `fmt`.
+ ASMJIT_API bool setFormat(const char* fmt, ...);
+
+ //! Replace the current content by `c` character.
+ ASMJIT_INLINE bool setChar(char c) {
+ return _opChar(kStringOpSet, c);
+ }
+
+ //! Replace the current content by `c` of `len`.
+ ASMJIT_INLINE bool setChars(char c, size_t len) {
+ return _opChars(kStringOpSet, c, len);
+ }
+
+ //! Replace the current content by formatted integer `i`.
+ ASMJIT_INLINE bool setInt(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) {
+ return _opNumber(kStringOpSet, i, base, width, flags | kStringFormatSigned);
+ }
+
+ //! Replace the current content by formatted integer `i`.
+ ASMJIT_INLINE bool setUInt(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) {
+ return _opNumber(kStringOpSet, i, base, width, flags);
+ }
+
+ //! Replace the current content by the given `data` converted to a HEX string.
+ ASMJIT_INLINE bool setHex(const void* data, size_t len) {
+ return _opHex(kStringOpSet, data, len);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Append]
+ // --------------------------------------------------------------------------
+
+ //! Append `str` of `len`.
+ ASMJIT_INLINE bool appendString(const char* str, size_t len = kInvalidIndex) {
+ return _opString(kStringOpAppend, str, len);
+ }
+
+ //! Append a formatted string `fmt` to the current content.
+ ASMJIT_INLINE bool appendVFormat(const char* fmt, va_list ap) {
+ return _opVFormat(kStringOpAppend, fmt, ap);
+ }
+
+ //! Append a formatted string `fmt` to the current content.
+ ASMJIT_API bool appendFormat(const char* fmt, ...);
+
+ //! Append `c` character.
+ ASMJIT_INLINE bool appendChar(char c) {
+ return _opChar(kStringOpAppend, c);
+ }
+
+ //! Append `c` of `len`.
+ ASMJIT_INLINE bool appendChars(char c, size_t len) {
+ return _opChars(kStringOpAppend, c, len);
+ }
+
+ //! Append `i`.
+ ASMJIT_INLINE bool appendInt(int64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) {
+ return _opNumber(kStringOpAppend, static_cast(i), base, width, flags | kStringFormatSigned);
+ }
+
+ //! Append `i`.
+ ASMJIT_INLINE bool appendUInt(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) {
+ return _opNumber(kStringOpAppend, i, base, width, flags);
+ }
+
+ //! Append the given `data` converted to a HEX string.
+ ASMJIT_INLINE bool appendHex(const void* data, size_t len) {
+ return _opHex(kStringOpAppend, data, len);
+ }
+
+ // --------------------------------------------------------------------------
+ // [_Append]
+ // --------------------------------------------------------------------------
+
+ //! Append `str` of `len`, inlined, without buffer overflow check.
+ ASMJIT_INLINE void _appendString(const char* str, size_t len = kInvalidIndex) {
+ // len should be a constant if we are inlining.
+ if (len == kInvalidIndex) {
+ char* p = &_data[_length];
+
+ while (*str) {
+ ASMJIT_ASSERT(p < _data + _capacity);
+ *p++ = *str++;
+ }
+
+ *p = '\0';
+ _length = (size_t)(p - _data);
+ }
+ else {
+ ASMJIT_ASSERT(_capacity - _length >= len);
+
+ char* p = &_data[_length];
+ char* pEnd = p + len;
+
+ while (p < pEnd)
+ *p++ = *str++;
+
+ *p = '\0';
+ _length += len;
+ }
+ }
+
+ //! Append `c` character, inlined, without buffer overflow check.
+ ASMJIT_INLINE void _appendChar(char c) {
+ ASMJIT_ASSERT(_capacity - _length >= 1);
+
+ _data[_length] = c;
+ _length++;
+ _data[_length] = '\0';
+ }
+
+ //! Append `c` of `len`, inlined, without buffer overflow check.
+ ASMJIT_INLINE void _appendChars(char c, size_t len) {
+ ASMJIT_ASSERT(_capacity - _length >= len);
+
+ char* p = &_data[_length];
+ char* pEnd = p + len;
+
+ while (p < pEnd)
+ *p++ = c;
+
+ *p = '\0';
+ _length += len;
+ }
+
+ ASMJIT_INLINE void _appendUInt32(uint32_t i) {
+ char buf_[32];
+
+ char* pEnd = buf_ + ASMJIT_ARRAY_SIZE(buf_);
+ char* pBuf = pEnd;
+
+ do {
+ uint32_t d = i / 10;
+ uint32_t r = i % 10;
+
+ *--pBuf = static_cast(r + '0');
+ i = d;
+ } while (i);
+
+ ASMJIT_ASSERT(_capacity - _length >= (size_t)(pEnd - pBuf));
+ char* p = &_data[_length];
+
+ do {
+ *p++ = *pBuf;
+ } while (++pBuf != pEnd);
+
+ *p = '\0';
+ _length = (size_t)(p - _data);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Eq]
+ // --------------------------------------------------------------------------
+
+ //! Check for equality with other `str` of `len`.
+ ASMJIT_API bool eq(const char* str, size_t len = kInvalidIndex) const;
+ //! Check for equality with `other`.
+ ASMJIT_INLINE bool eq(const StringBuilder& other) const {
+ return eq(other._data);
+ }
+
+ // --------------------------------------------------------------------------
+ // [Operator Overload]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE bool operator==(const StringBuilder& other) const { return eq(other); }
+ ASMJIT_INLINE bool operator!=(const StringBuilder& other) const { return !eq(other); }
+
+ ASMJIT_INLINE bool operator==(const char* str) const { return eq(str); }
+ ASMJIT_INLINE bool operator!=(const char* str) const { return !eq(str); }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! String data.
+ char* _data;
+ //! Length.
+ size_t _length;
+ //! Capacity.
+ size_t _capacity;
+ //! Whether the string can be freed.
+ size_t _canFree;
+};
+
+// ============================================================================
+// [asmjit::StringBuilderT]
+// ============================================================================
+
+//! \internal
+template
+struct StringBuilderT : public StringBuilder {
+ ASMJIT_NO_COPY(StringBuilderT)
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ ASMJIT_INLINE StringBuilderT() : StringBuilder(NoInit) {
+ _data = _embeddedData;
+ _data[0] = 0;
+
+ _length = 0;
+ _capacity = N;
+ _canFree = false;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Embedded data.
+ char _embeddedData[static_cast(
+ N + 1 + sizeof(intptr_t)) & ~static_cast(sizeof(intptr_t) - 1)];
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // _ASMJIT_BASE_STRING_H
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/vectypes.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/vectypes.h
new file mode 100644
index 0000000..d675ec2
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/vectypes.h
@@ -0,0 +1,1251 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Guard]
+#ifndef _ASMJIT_BASE_VECTYPES_H
+#define _ASMJIT_BASE_VECTYPES_H
+
+// [Dependencies - AsmJit]
+#include "../base/globals.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_util
+//! \{
+
+// ============================================================================
+// [asmjit::Vec64]
+// ============================================================================
+
+//! 64-bit vector register data.
+union Vec64 {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Set all eight 8-bit signed integers.
+ static ASMJIT_INLINE Vec64 fromSb(
+ int8_t x0, int8_t x1, int8_t x2, int8_t x3, int8_t x4, int8_t x5, int8_t x6, int8_t x7)
+ {
+ Vec64 self;
+ self.setSb(x0, x1, x2, x3, x4, x5, x6, x7);
+ return self;
+ }
+
+ //! Set all eight 8-bit signed integers.
+ static ASMJIT_INLINE Vec64 fromSb(
+ int8_t x0)
+ {
+ Vec64 self;
+ self.setSb(x0);
+ return self;
+ }
+
+ //! Set all eight 8-bit unsigned integers.
+ static ASMJIT_INLINE Vec64 fromUb(
+ uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7)
+ {
+ Vec64 self;
+ self.setUb(x0, x1, x2, x3, x4, x5, x6, x7);
+ return self;
+ }
+
+ //! Set all eight 8-bit unsigned integers.
+ static ASMJIT_INLINE Vec64 fromUb(
+ uint8_t x0)
+ {
+ Vec64 self;
+ self.setUb(x0);
+ return self;
+ }
+
+ //! Set all four 16-bit signed integers.
+ static ASMJIT_INLINE Vec64 fromSw(
+ int16_t x0, int16_t x1, int16_t x2, int16_t x3)
+ {
+ Vec64 self;
+ self.setSw(x0, x1, x2, x3);
+ return self;
+ }
+
+ //! Set all four 16-bit signed integers.
+ static ASMJIT_INLINE Vec64 fromSw(
+ int16_t x0)
+ {
+ Vec64 self;
+ self.setSw(x0);
+ return self;
+ }
+
+ //! Set all four 16-bit unsigned integers.
+ static ASMJIT_INLINE Vec64 fromUw(
+ uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3)
+ {
+ Vec64 self;
+ self.setUw(x0, x1, x2, x3);
+ return self;
+ }
+
+ //! Set all four 16-bit unsigned integers.
+ static ASMJIT_INLINE Vec64 fromUw(
+ uint16_t x0)
+ {
+ Vec64 self;
+ self.setUw(x0);
+ return self;
+ }
+
+ //! Set all two 32-bit signed integers.
+ static ASMJIT_INLINE Vec64 fromSd(
+ int32_t x0, int32_t x1)
+ {
+ Vec64 self;
+ self.setSd(x0, x1);
+ return self;
+ }
+
+ //! Set all two 32-bit signed integers.
+ static ASMJIT_INLINE Vec64 fromSd(
+ int32_t x0)
+ {
+ Vec64 self;
+ self.setSd(x0);
+ return self;
+ }
+
+ //! Set all two 32-bit unsigned integers.
+ static ASMJIT_INLINE Vec64 fromUd(
+ uint32_t x0, uint32_t x1)
+ {
+ Vec64 self;
+ self.setUd(x0, x1);
+ return self;
+ }
+
+ //! Set all two 32-bit unsigned integers.
+ static ASMJIT_INLINE Vec64 fromUd(
+ uint32_t x0)
+ {
+ Vec64 self;
+ self.setUd(x0);
+ return self;
+ }
+
+ //! Set 64-bit signed integer.
+ static ASMJIT_INLINE Vec64 fromSq(
+ int64_t x0)
+ {
+ Vec64 self;
+ self.setSq(x0);
+ return self;
+ }
+
+ //! Set 64-bit unsigned integer.
+ static ASMJIT_INLINE Vec64 fromUq(
+ uint64_t x0)
+ {
+ Vec64 self;
+ self.setUq(x0);
+ return self;
+ }
+
+ //! Set all two SP-FP values.
+ static ASMJIT_INLINE Vec64 fromSf(
+ float x0, float x1)
+ {
+ Vec64 self;
+ self.setSf(x0, x1);
+ return self;
+ }
+
+ //! Set all two SP-FP values.
+ static ASMJIT_INLINE Vec64 fromSf(
+ float x0)
+ {
+ Vec64 self;
+ self.setSf(x0);
+ return self;
+ }
+
+ //! Set all two SP-FP values.
+ static ASMJIT_INLINE Vec64 fromDf(
+ double x0)
+ {
+ Vec64 self;
+ self.setDf(x0);
+ return self;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Set all eight 8-bit signed integers.
+ ASMJIT_INLINE void setSb(
+ int8_t x0, int8_t x1, int8_t x2, int8_t x3, int8_t x4, int8_t x5, int8_t x6, int8_t x7)
+ {
+ sb[0] = x0; sb[1] = x1; sb[2] = x2; sb[3] = x3;
+ sb[4] = x4; sb[5] = x5; sb[6] = x6; sb[7] = x7;
+ }
+
+ //! Set all eight 8-bit signed integers.
+ ASMJIT_INLINE void setSb(
+ int8_t x0)
+ {
+ setUb(static_cast(x0));
+ }
+
+ //! Set all eight 8-bit unsigned integers.
+ ASMJIT_INLINE void setUb(
+ uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7)
+ {
+ ub[0] = x0; ub[1] = x1; ub[2] = x2; ub[3] = x3;
+ ub[4] = x4; ub[5] = x5; ub[6] = x6; ub[7] = x7;
+ }
+
+ //! Set all eight 8-bit unsigned integers.
+ ASMJIT_INLINE void setUb(
+ uint8_t x0)
+ {
+ if (kArchHost64Bit) {
+ uint64_t t = static_cast(x0) * ASMJIT_UINT64_C(0x0101010101010101);
+ uq[0] = t;
+ }
+ else {
+ uint32_t t = static_cast(x0) * static_cast(0x01010101U);
+ ud[0] = t;
+ ud[1] = t;
+ }
+ }
+
+ //! Set all four 16-bit signed integers.
+ ASMJIT_INLINE void setSw(
+ int16_t x0, int16_t x1, int16_t x2, int16_t x3)
+ {
+ sw[0] = x0; sw[1] = x1; sw[2] = x2; sw[3] = x3;
+ }
+
+ //! Set all four 16-bit signed integers.
+ ASMJIT_INLINE void setSw(
+ int16_t x0)
+ {
+ setUw(static_cast(x0));
+ }
+
+ //! Set all four 16-bit unsigned integers.
+ ASMJIT_INLINE void setUw(
+ uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3)
+ {
+ uw[0] = x0; uw[1] = x1; uw[2] = x2; uw[3] = x3;
+ }
+
+ //! Set all four 16-bit unsigned integers.
+ ASMJIT_INLINE void setUw(
+ uint16_t x0)
+ {
+ if (kArchHost64Bit) {
+ uint64_t t = static_cast(x0) * ASMJIT_UINT64_C(0x0001000100010001);
+ uq[0] = t;
+ }
+ else {
+ uint32_t t = static_cast(x0) * static_cast(0x00010001U);
+ ud[0] = t;
+ ud[1] = t;
+ }
+ }
+
+ //! Set all two 32-bit signed integers.
+ ASMJIT_INLINE void setSd(
+ int32_t x0, int32_t x1)
+ {
+ sd[0] = x0; sd[1] = x1;
+ }
+
+ //! Set all two 32-bit signed integers.
+ ASMJIT_INLINE void setSd(
+ int32_t x0)
+ {
+ sd[0] = x0; sd[1] = x0;
+ }
+
+ //! Set all two 32-bit unsigned integers.
+ ASMJIT_INLINE void setUd(
+ uint32_t x0, uint32_t x1)
+ {
+ ud[0] = x0; ud[1] = x1;
+ }
+
+ //! Set all two 32-bit unsigned integers.
+ ASMJIT_INLINE void setUd(
+ uint32_t x0)
+ {
+ ud[0] = x0; ud[1] = x0;
+ }
+
+ //! Set 64-bit signed integer.
+ ASMJIT_INLINE void setSq(
+ int64_t x0)
+ {
+ sq[0] = x0;
+ }
+
+ //! Set 64-bit unsigned integer.
+ ASMJIT_INLINE void setUq(
+ uint64_t x0)
+ {
+ uq[0] = x0;
+ }
+
+ //! Set all two SP-FP values.
+ ASMJIT_INLINE void setSf(
+ float x0, float x1)
+ {
+ sf[0] = x0; sf[1] = x1;
+ }
+
+ //! Set all two SP-FP values.
+ ASMJIT_INLINE void setSf(
+ float x0)
+ {
+ sf[0] = x0; sf[1] = x0;
+ }
+
+ //! Set all two SP-FP values.
+ ASMJIT_INLINE void setDf(
+ double x0)
+ {
+ df[0] = x0;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Array of eight 8-bit signed integers.
+ int8_t sb[8];
+ //! Array of eight 8-bit unsigned integers.
+ uint8_t ub[8];
+ //! Array of four 16-bit signed integers.
+ int16_t sw[4];
+ //! Array of four 16-bit unsigned integers.
+ uint16_t uw[4];
+ //! Array of two 32-bit signed integers.
+ int32_t sd[2];
+ //! Array of two 32-bit unsigned integers.
+ uint32_t ud[2];
+ //! Array of one 64-bit signed integer.
+ int64_t sq[1];
+ //! Array of one 64-bit unsigned integer.
+ uint64_t uq[1];
+
+ //! Array of two SP-FP values.
+ float sf[2];
+ //! Array of one DP-FP value.
+ double df[1];
+};
+
+// ============================================================================
+// [asmjit::Vec128]
+// ============================================================================
+
+//! 128-bit vector register data.
+union Vec128 {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Set all sixteen 8-bit signed integers.
+ static ASMJIT_INLINE Vec128 fromSb(
+ int8_t x0 , int8_t x1 , int8_t x2 , int8_t x3 ,
+ int8_t x4 , int8_t x5 , int8_t x6 , int8_t x7 ,
+ int8_t x8 , int8_t x9 , int8_t x10, int8_t x11,
+ int8_t x12, int8_t x13, int8_t x14, int8_t x15)
+ {
+ Vec128 self;
+ self.setSb(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15);
+ return self;
+ }
+
+ //! Set all sixteen 8-bit signed integers.
+ static ASMJIT_INLINE Vec128 fromSb(
+ int8_t x0)
+ {
+ Vec128 self;
+ self.setSb(x0);
+ return self;
+ }
+
+ //! Set all sixteen 8-bit unsigned integers.
+ static ASMJIT_INLINE Vec128 fromUb(
+ uint8_t x0 , uint8_t x1 , uint8_t x2 , uint8_t x3 ,
+ uint8_t x4 , uint8_t x5 , uint8_t x6 , uint8_t x7 ,
+ uint8_t x8 , uint8_t x9 , uint8_t x10, uint8_t x11,
+ uint8_t x12, uint8_t x13, uint8_t x14, uint8_t x15)
+ {
+ Vec128 self;
+ self.setUb(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15);
+ return self;
+ }
+
+ //! Set all sixteen 8-bit unsigned integers.
+ static ASMJIT_INLINE Vec128 fromUb(
+ uint8_t x0)
+ {
+ Vec128 self;
+ self.setUb(x0);
+ return self;
+ }
+
+ //! Set all eight 16-bit signed integers.
+ static ASMJIT_INLINE Vec128 fromSw(
+ int16_t x0, int16_t x1, int16_t x2, int16_t x3, int16_t x4, int16_t x5, int16_t x6, int16_t x7)
+ {
+ Vec128 self;
+ self.setSw(x0, x1, x2, x3, x4, x5, x6, x7);
+ return self;
+ }
+
+ //! Set all eight 16-bit signed integers.
+ static ASMJIT_INLINE Vec128 fromSw(
+ int16_t x0)
+ {
+ Vec128 self;
+ self.setSw(x0);
+ return self;
+ }
+
+ //! Set all eight 16-bit unsigned integers.
+ static ASMJIT_INLINE Vec128 fromUw(
+ uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3, uint16_t x4, uint16_t x5, uint16_t x6, uint16_t x7)
+ {
+ Vec128 self;
+ self.setUw(x0, x1, x2, x3, x4, x5, x6, x7);
+ return self;
+ }
+
+ //! Set all eight 16-bit unsigned integers.
+ static ASMJIT_INLINE Vec128 fromUw(
+ uint16_t x0)
+ {
+ Vec128 self;
+ self.setUw(x0);
+ return self;
+ }
+
+ //! Set all four 32-bit signed integers.
+ static ASMJIT_INLINE Vec128 fromSd(
+ int32_t x0, int32_t x1, int32_t x2, int32_t x3)
+ {
+ Vec128 self;
+ self.setSd(x0, x1, x2, x3);
+ return self;
+ }
+
+ //! Set all four 32-bit signed integers.
+ static ASMJIT_INLINE Vec128 fromSd(
+ int32_t x0)
+ {
+ Vec128 self;
+ self.setSd(x0);
+ return self;
+ }
+
+ //! Set all four 32-bit unsigned integers.
+ static ASMJIT_INLINE Vec128 fromUd(
+ uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3)
+ {
+ Vec128 self;
+ self.setUd(x0, x1, x2, x3);
+ return self;
+ }
+
+ //! Set all four 32-bit unsigned integers.
+ static ASMJIT_INLINE Vec128 fromUd(
+ uint32_t x0)
+ {
+ Vec128 self;
+ self.setUd(x0);
+ return self;
+ }
+
+ //! Set all two 64-bit signed integers.
+ static ASMJIT_INLINE Vec128 fromSq(
+ int64_t x0, int64_t x1)
+ {
+ Vec128 self;
+ self.setSq(x0, x1);
+ return self;
+ }
+
+ //! Set all two 64-bit signed integers.
+ static ASMJIT_INLINE Vec128 fromSq(
+ int64_t x0)
+ {
+ Vec128 self;
+ self.setSq(x0);
+ return self;
+ }
+
+ //! Set all two 64-bit unsigned integers.
+ static ASMJIT_INLINE Vec128 fromUq(
+ uint64_t x0, uint64_t x1)
+ {
+ Vec128 self;
+ self.setUq(x0, x1);
+ return self;
+ }
+
+ //! Set all two 64-bit unsigned integers.
+ static ASMJIT_INLINE Vec128 fromUq(
+ uint64_t x0)
+ {
+ Vec128 self;
+ self.setUq(x0);
+ return self;
+ }
+
+ //! Set all four SP-FP floats.
+ static ASMJIT_INLINE Vec128 fromSf(
+ float x0, float x1, float x2, float x3)
+ {
+ Vec128 self;
+ self.setSf(x0, x1, x2, x3);
+ return self;
+ }
+
+ //! Set all four SP-FP floats.
+ static ASMJIT_INLINE Vec128 fromSf(
+ float x0)
+ {
+ Vec128 self;
+ self.setSf(x0);
+ return self;
+ }
+
+ //! Set all two DP-FP floats.
+ static ASMJIT_INLINE Vec128 fromDf(
+ double x0, double x1)
+ {
+ Vec128 self;
+ self.setDf(x0, x1);
+ return self;
+ }
+
+ //! Set all two DP-FP floats.
+ static ASMJIT_INLINE Vec128 fromDf(
+ double x0)
+ {
+ Vec128 self;
+ self.setDf(x0);
+ return self;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Set all sixteen 8-bit signed integers.
+ ASMJIT_INLINE void setSb(
+ int8_t x0 , int8_t x1 , int8_t x2 , int8_t x3 ,
+ int8_t x4 , int8_t x5 , int8_t x6 , int8_t x7 ,
+ int8_t x8 , int8_t x9 , int8_t x10, int8_t x11,
+ int8_t x12, int8_t x13, int8_t x14, int8_t x15)
+ {
+ sb[0 ] = x0 ; sb[1 ] = x1 ; sb[2 ] = x2 ; sb[3 ] = x3 ;
+ sb[4 ] = x4 ; sb[5 ] = x5 ; sb[6 ] = x6 ; sb[7 ] = x7 ;
+ sb[8 ] = x8 ; sb[9 ] = x9 ; sb[10] = x10; sb[11] = x11;
+ sb[12] = x12; sb[13] = x13; sb[14] = x14; sb[15] = x15;
+ }
+
+ //! Set all sixteen 8-bit signed integers.
+ ASMJIT_INLINE void setSb(
+ int8_t x0)
+ {
+ setUb(static_cast(x0));
+ }
+
+ //! Set all sixteen 8-bit unsigned integers.
+ ASMJIT_INLINE void setUb(
+ uint8_t x0 , uint8_t x1 , uint8_t x2 , uint8_t x3 ,
+ uint8_t x4 , uint8_t x5 , uint8_t x6 , uint8_t x7 ,
+ uint8_t x8 , uint8_t x9 , uint8_t x10, uint8_t x11,
+ uint8_t x12, uint8_t x13, uint8_t x14, uint8_t x15)
+ {
+ ub[0 ] = x0 ; ub[1 ] = x1 ; ub[2 ] = x2 ; ub[3 ] = x3 ;
+ ub[4 ] = x4 ; ub[5 ] = x5 ; ub[6 ] = x6 ; ub[7 ] = x7 ;
+ ub[8 ] = x8 ; ub[9 ] = x9 ; ub[10] = x10; ub[11] = x11;
+ ub[12] = x12; ub[13] = x13; ub[14] = x14; ub[15] = x15;
+ }
+
+ //! Set all sixteen 8-bit unsigned integers.
+ ASMJIT_INLINE void setUb(
+ uint8_t x0)
+ {
+ if (kArchHost64Bit) {
+ uint64_t t = static_cast(x0) * ASMJIT_UINT64_C(0x0101010101010101);
+ uq[0] = t;
+ uq[1] = t;
+ }
+ else {
+ uint32_t t = static_cast(x0) * static_cast(0x01010101U);
+ ud[0] = t;
+ ud[1] = t;
+ ud[2] = t;
+ ud[3] = t;
+ }
+ }
+
+ //! Set all eight 16-bit signed integers.
+ ASMJIT_INLINE void setSw(
+ int16_t x0, int16_t x1, int16_t x2, int16_t x3, int16_t x4, int16_t x5, int16_t x6, int16_t x7)
+ {
+ sw[0] = x0; sw[1] = x1; sw[2] = x2; sw[3] = x3;
+ sw[4] = x4; sw[5] = x5; sw[6] = x6; sw[7] = x7;
+ }
+
+ //! Set all eight 16-bit signed integers.
+ ASMJIT_INLINE void setSw(
+ int16_t x0)
+ {
+ setUw(static_cast(x0));
+ }
+
+ //! Set all eight 16-bit unsigned integers.
+ ASMJIT_INLINE void setUw(
+ uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3, uint16_t x4, uint16_t x5, uint16_t x6, uint16_t x7)
+ {
+ uw[0] = x0; uw[1] = x1; uw[2] = x2; uw[3] = x3;
+ uw[4] = x4; uw[5] = x5; uw[6] = x6; uw[7] = x7;
+ }
+
+ //! Set all eight 16-bit unsigned integers.
+ ASMJIT_INLINE void setUw(
+ uint16_t x0)
+ {
+ if (kArchHost64Bit) {
+ uint64_t t = static_cast(x0) * ASMJIT_UINT64_C(0x0001000100010001);
+ uq[0] = t;
+ uq[1] = t;
+ }
+ else {
+ uint32_t t = static_cast(x0) * static_cast(0x00010001U);
+ ud[0] = t;
+ ud[1] = t;
+ ud[2] = t;
+ ud[3] = t;
+ }
+ }
+
+ //! Set all four 32-bit signed integers.
+ ASMJIT_INLINE void setSd(
+ int32_t x0, int32_t x1, int32_t x2, int32_t x3)
+ {
+ sd[0] = x0; sd[1] = x1; sd[2] = x2; sd[3] = x3;
+ }
+
+ //! Set all four 32-bit signed integers.
+ ASMJIT_INLINE void setSd(
+ int32_t x0)
+ {
+ setUd(static_cast(x0));
+ }
+
+ //! Set all four 32-bit unsigned integers.
+ ASMJIT_INLINE void setUd(
+ uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3)
+ {
+ ud[0] = x0; ud[1] = x1; ud[2] = x2; ud[3] = x3;
+ }
+
+ //! Set all four 32-bit unsigned integers.
+ ASMJIT_INLINE void setUd(
+ uint32_t x0)
+ {
+ if (kArchHost64Bit) {
+ uint64_t t = (static_cast(x0) << 32) + x0;
+ uq[0] = t;
+ uq[1] = t;
+ }
+ else {
+ ud[0] = x0;
+ ud[1] = x0;
+ ud[2] = x0;
+ ud[3] = x0;
+ }
+ }
+
+ //! Set all two 64-bit signed integers.
+ ASMJIT_INLINE void setSq(
+ int64_t x0, int64_t x1)
+ {
+ sq[0] = x0; sq[1] = x1;
+ }
+
+ //! Set all two 64-bit signed integers.
+ ASMJIT_INLINE void setSq(
+ int64_t x0)
+ {
+ sq[0] = x0; sq[1] = x0;
+ }
+
+ //! Set all two 64-bit unsigned integers.
+ ASMJIT_INLINE void setUq(
+ uint64_t x0, uint64_t x1)
+ {
+ uq[0] = x0; uq[1] = x1;
+ }
+
+ //! Set all two 64-bit unsigned integers.
+ ASMJIT_INLINE void setUq(
+ uint64_t x0)
+ {
+ uq[0] = x0; uq[1] = x0;
+ }
+
+ //! Set all four SP-FP floats.
+ ASMJIT_INLINE void setSf(
+ float x0, float x1, float x2, float x3)
+ {
+ sf[0] = x0; sf[1] = x1; sf[2] = x2; sf[3] = x3;
+ }
+
+ //! Set all four SP-FP floats.
+ ASMJIT_INLINE void setSf(
+ float x0)
+ {
+ sf[0] = x0; sf[1] = x0; sf[2] = x0; sf[3] = x0;
+ }
+
+ //! Set all two DP-FP floats.
+ ASMJIT_INLINE void setDf(
+ double x0, double x1)
+ {
+ df[0] = x0; df[1] = x1;
+ }
+
+ //! Set all two DP-FP floats.
+ ASMJIT_INLINE void setDf(
+ double x0)
+ {
+ df[0] = x0; df[1] = x0;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Array of sixteen 8-bit signed integers.
+ int8_t sb[16];
+ //! Array of sixteen 8-bit unsigned integers.
+ uint8_t ub[16];
+ //! Array of eight 16-bit signed integers.
+ int16_t sw[8];
+ //! Array of eight 16-bit unsigned integers.
+ uint16_t uw[8];
+ //! Array of four 32-bit signed integers.
+ int32_t sd[4];
+ //! Array of four 32-bit unsigned integers.
+ uint32_t ud[4];
+ //! Array of two 64-bit signed integers.
+ int64_t sq[2];
+ //! Array of two 64-bit unsigned integers.
+ uint64_t uq[2];
+
+ //! Array of four 32-bit single precision floating points.
+ float sf[4];
+ //! Array of two 64-bit double precision floating points.
+ double df[2];
+};
+
+// ============================================================================
+// [asmjit::Vec256]
+// ============================================================================
+
+//! 256-bit vector register data.
+union Vec256 {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Set all thirty two 8-bit signed integers.
+ static ASMJIT_INLINE Vec256 fromSb(
+ int8_t x0 , int8_t x1 , int8_t x2 , int8_t x3 ,
+ int8_t x4 , int8_t x5 , int8_t x6 , int8_t x7 ,
+ int8_t x8 , int8_t x9 , int8_t x10, int8_t x11,
+ int8_t x12, int8_t x13, int8_t x14, int8_t x15,
+ int8_t x16, int8_t x17, int8_t x18, int8_t x19,
+ int8_t x20, int8_t x21, int8_t x22, int8_t x23,
+ int8_t x24, int8_t x25, int8_t x26, int8_t x27,
+ int8_t x28, int8_t x29, int8_t x30, int8_t x31)
+ {
+ Vec256 self;
+ self.setSb(
+ x0, x1 , x2 , x3 , x4 , x5 , x6 , x7 , x8 , x9 , x10, x11, x12, x13, x14, x15,
+ x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31);
+ return self;
+ }
+
+ //! Set all thirty two 8-bit signed integers.
+ static ASMJIT_INLINE Vec256 fromSb(
+ int8_t x0)
+ {
+ Vec256 self;
+ self.setSb(x0);
+ return self;
+ }
+
+ //! Set all thirty two 8-bit unsigned integers.
+ static ASMJIT_INLINE Vec256 fromUb(
+ uint8_t x0 , uint8_t x1 , uint8_t x2 , uint8_t x3 ,
+ uint8_t x4 , uint8_t x5 , uint8_t x6 , uint8_t x7 ,
+ uint8_t x8 , uint8_t x9 , uint8_t x10, uint8_t x11,
+ uint8_t x12, uint8_t x13, uint8_t x14, uint8_t x15,
+ uint8_t x16, uint8_t x17, uint8_t x18, uint8_t x19,
+ uint8_t x20, uint8_t x21, uint8_t x22, uint8_t x23,
+ uint8_t x24, uint8_t x25, uint8_t x26, uint8_t x27,
+ uint8_t x28, uint8_t x29, uint8_t x30, uint8_t x31)
+ {
+ Vec256 self;
+ self.setUb(
+ x0, x1 , x2 , x3 , x4 , x5 , x6 , x7 , x8 , x9 , x10, x11, x12, x13, x14, x15,
+ x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31);
+ return self;
+ }
+
+ //! Set all thirty two 8-bit unsigned integers.
+ static ASMJIT_INLINE Vec256 fromUb(
+ uint8_t x0)
+ {
+ Vec256 self;
+ self.setUb(x0);
+ return self;
+ }
+
+ //! Set all sixteen 16-bit signed integers.
+ static ASMJIT_INLINE Vec256 fromSw(
+ int16_t x0, int16_t x1, int16_t x2 , int16_t x3 , int16_t x4 , int16_t x5 , int16_t x6 , int16_t x7 ,
+ int16_t x8, int16_t x9, int16_t x10, int16_t x11, int16_t x12, int16_t x13, int16_t x14, int16_t x15)
+ {
+ Vec256 self;
+ self.setSw(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15);
+ return self;
+ }
+
+ //! Set all sixteen 16-bit signed integers.
+ static ASMJIT_INLINE Vec256 fromSw(
+ int16_t x0)
+ {
+ Vec256 self;
+ self.setSw(x0);
+ return self;
+ }
+
+ //! Set all sixteen 16-bit unsigned integers.
+ static ASMJIT_INLINE Vec256 fromUw(
+ uint16_t x0, uint16_t x1, uint16_t x2 , uint16_t x3 , uint16_t x4 , uint16_t x5 , uint16_t x6 , uint16_t x7 ,
+ uint16_t x8, uint16_t x9, uint16_t x10, uint16_t x11, uint16_t x12, uint16_t x13, uint16_t x14, uint16_t x15)
+ {
+ Vec256 self;
+ self.setUw(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15);
+ return self;
+ }
+
+ //! Set all sixteen 16-bit unsigned integers.
+ static ASMJIT_INLINE Vec256 fromUw(
+ uint16_t x0)
+ {
+ Vec256 self;
+ self.setUw(x0);
+ return self;
+ }
+
+ //! Set all eight 32-bit signed integers.
+ static ASMJIT_INLINE Vec256 fromSd(
+ int32_t x0, int32_t x1, int32_t x2, int32_t x3,
+ int32_t x4, int32_t x5, int32_t x6, int32_t x7)
+ {
+ Vec256 self;
+ self.setSd(x0, x1, x2, x3, x4, x5, x6, x7);
+ return self;
+ }
+
+ //! Set all eight 32-bit signed integers.
+ static ASMJIT_INLINE Vec256 fromSd(
+ int32_t x0)
+ {
+ Vec256 self;
+ self.setSd(x0);
+ return self;
+ }
+
+ //! Set all eight 32-bit unsigned integers.
+ static ASMJIT_INLINE Vec256 fromUd(
+ uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3,
+ uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7)
+ {
+ Vec256 self;
+ self.setUd(x0, x1, x2, x3, x4, x5, x6, x7);
+ return self;
+ }
+
+ //! Set all eight 32-bit unsigned integers.
+ static ASMJIT_INLINE Vec256 fromUd(
+ uint32_t x0)
+ {
+ Vec256 self;
+ self.setUd(x0);
+ return self;
+ }
+
+ //! Set all four 64-bit signed integers.
+ static ASMJIT_INLINE Vec256 fromSq(
+ int64_t x0, int64_t x1, int64_t x2, int64_t x3)
+ {
+ Vec256 self;
+ self.setSq(x0, x1, x2, x3);
+ return self;
+ }
+
+ //! Set all four 64-bit signed integers.
+ static ASMJIT_INLINE Vec256 fromSq(
+ int64_t x0)
+ {
+ Vec256 self;
+ self.setSq(x0);
+ return self;
+ }
+
+ //! Set all four 64-bit unsigned integers.
+ static ASMJIT_INLINE Vec256 fromUq(
+ uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3)
+ {
+ Vec256 self;
+ self.setUq(x0, x1, x2, x3);
+ return self;
+ }
+
+ //! Set all four 64-bit unsigned integers.
+ static ASMJIT_INLINE Vec256 fromUq(
+ uint64_t x0)
+ {
+ Vec256 self;
+ self.setUq(x0);
+ return self;
+ }
+
+ //! Set all eight SP-FP floats.
+ static ASMJIT_INLINE Vec256 fromSf(
+ float x0, float x1, float x2, float x3,
+ float x4, float x5, float x6, float x7)
+ {
+ Vec256 self;
+ self.setSf(x0, x1, x2, x3, x4, x5, x6, x7);
+ return self;
+ }
+
+ //! Set all eight SP-FP floats.
+ static ASMJIT_INLINE Vec256 fromSf(
+ float x0)
+ {
+ Vec256 self;
+ self.setSf(x0);
+ return self;
+ }
+
+ //! Set all four DP-FP floats.
+ static ASMJIT_INLINE Vec256 fromDf(
+ double x0, double x1, double x2, double x3)
+ {
+ Vec256 self;
+ self.setDf(x0, x1, x2, x3);
+ return self;
+ }
+
+ //! Set all four DP-FP floats.
+ static ASMJIT_INLINE Vec256 fromDf(
+ double x0)
+ {
+ Vec256 self;
+ self.setDf(x0);
+ return self;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Set all thirty two 8-bit signed integers.
+ ASMJIT_INLINE void setSb(
+ int8_t x0 , int8_t x1 , int8_t x2 , int8_t x3 ,
+ int8_t x4 , int8_t x5 , int8_t x6 , int8_t x7 ,
+ int8_t x8 , int8_t x9 , int8_t x10, int8_t x11,
+ int8_t x12, int8_t x13, int8_t x14, int8_t x15,
+ int8_t x16, int8_t x17, int8_t x18, int8_t x19,
+ int8_t x20, int8_t x21, int8_t x22, int8_t x23,
+ int8_t x24, int8_t x25, int8_t x26, int8_t x27,
+ int8_t x28, int8_t x29, int8_t x30, int8_t x31)
+ {
+ sb[0 ] = x0 ; sb[1 ] = x1 ; sb[2 ] = x2 ; sb[3 ] = x3 ;
+ sb[4 ] = x4 ; sb[5 ] = x5 ; sb[6 ] = x6 ; sb[7 ] = x7 ;
+ sb[8 ] = x8 ; sb[9 ] = x9 ; sb[10] = x10; sb[11] = x11;
+ sb[12] = x12; sb[13] = x13; sb[14] = x14; sb[15] = x15;
+ sb[16] = x16; sb[17] = x17; sb[18] = x18; sb[19] = x19;
+ sb[20] = x20; sb[21] = x21; sb[22] = x22; sb[23] = x23;
+ sb[24] = x24; sb[25] = x25; sb[26] = x26; sb[27] = x27;
+ sb[28] = x28; sb[29] = x29; sb[30] = x30; sb[31] = x31;
+ }
+
+ //! Set all thirty two 8-bit signed integers.
+ ASMJIT_INLINE void setSb(
+ int8_t x0)
+ {
+ setUb(static_cast(x0));
+ }
+
+ //! Set all thirty two 8-bit unsigned integers.
+ ASMJIT_INLINE void setUb(
+ uint8_t x0 , uint8_t x1 , uint8_t x2 , uint8_t x3 ,
+ uint8_t x4 , uint8_t x5 , uint8_t x6 , uint8_t x7 ,
+ uint8_t x8 , uint8_t x9 , uint8_t x10, uint8_t x11,
+ uint8_t x12, uint8_t x13, uint8_t x14, uint8_t x15,
+ uint8_t x16, uint8_t x17, uint8_t x18, uint8_t x19,
+ uint8_t x20, uint8_t x21, uint8_t x22, uint8_t x23,
+ uint8_t x24, uint8_t x25, uint8_t x26, uint8_t x27,
+ uint8_t x28, uint8_t x29, uint8_t x30, uint8_t x31)
+ {
+ ub[0 ] = x0 ; ub[1 ] = x1 ; ub[2 ] = x2 ; ub[3 ] = x3 ;
+ ub[4 ] = x4 ; ub[5 ] = x5 ; ub[6 ] = x6 ; ub[7 ] = x7 ;
+ ub[8 ] = x8 ; ub[9 ] = x9 ; ub[10] = x10; ub[11] = x11;
+ ub[12] = x12; ub[13] = x13; ub[14] = x14; ub[15] = x15;
+ ub[16] = x16; ub[17] = x17; ub[18] = x18; ub[19] = x19;
+ ub[20] = x20; ub[21] = x21; ub[22] = x22; ub[23] = x23;
+ ub[24] = x24; ub[25] = x25; ub[26] = x26; ub[27] = x27;
+ ub[28] = x28; ub[29] = x29; ub[30] = x30; ub[31] = x31;
+ }
+
+ //! Set all thirty two 8-bit unsigned integers.
+ ASMJIT_INLINE void setUb(
+ uint8_t x0)
+ {
+ if (kArchHost64Bit) {
+ uint64_t t = static_cast(x0)* ASMJIT_UINT64_C(0x0101010101010101);
+ uq[0] = t;
+ uq[1] = t;
+ uq[2] = t;
+ uq[3] = t;
+ }
+ else {
+ uint32_t t = static_cast(x0)* static_cast(0x01010101U);
+ ud[0] = t;
+ ud[1] = t;
+ ud[2] = t;
+ ud[3] = t;
+ ud[4] = t;
+ ud[5] = t;
+ ud[6] = t;
+ ud[7] = t;
+ }
+ }
+
+ //! Set all sixteen 16-bit signed integers.
+ ASMJIT_INLINE void setSw(
+ int16_t x0, int16_t x1, int16_t x2, int16_t x3, int16_t x4, int16_t x5, int16_t x6, int16_t x7,
+ int16_t x8, int16_t x9, int16_t x10, int16_t x11, int16_t x12, int16_t x13, int16_t x14, int16_t x15)
+ {
+ sw[0 ] = x0 ; sw[1 ] = x1 ; sw[2 ] = x2 ; sw[3 ] = x3 ;
+ sw[4 ] = x4 ; sw[5 ] = x5 ; sw[6 ] = x6 ; sw[7 ] = x7 ;
+ sw[8 ] = x8 ; sw[9 ] = x9 ; sw[10] = x10; sw[11] = x11;
+ sw[12] = x12; sw[13] = x13; sw[14] = x14; sw[15] = x15;
+ }
+
+ //! Set all sixteen 16-bit signed integers.
+ ASMJIT_INLINE void setSw(
+ int16_t x0)
+ {
+ setUw(static_cast(x0));
+ }
+
+ //! Set all sixteen 16-bit unsigned integers.
+ ASMJIT_INLINE void setUw(
+ uint16_t x0, uint16_t x1, uint16_t x2 , uint16_t x3 , uint16_t x4 , uint16_t x5 , uint16_t x6 , uint16_t x7 ,
+ uint16_t x8, uint16_t x9, uint16_t x10, uint16_t x11, uint16_t x12, uint16_t x13, uint16_t x14, uint16_t x15)
+ {
+ uw[0 ] = x0 ; uw[1 ] = x1 ; uw[2 ] = x2 ; uw[3 ] = x3 ;
+ uw[4 ] = x4 ; uw[5 ] = x5 ; uw[6 ] = x6 ; uw[7 ] = x7 ;
+ uw[8 ] = x8 ; uw[9 ] = x9 ; uw[10] = x10; uw[11] = x11;
+ uw[12] = x12; uw[13] = x13; uw[14] = x14; uw[15] = x15;
+ }
+
+ //! Set all eight 16-bit unsigned integers.
+ ASMJIT_INLINE void setUw(
+ uint16_t x0)
+ {
+ if (kArchHost64Bit) {
+ uint64_t t = static_cast(x0)* ASMJIT_UINT64_C(0x0001000100010001);
+ uq[0] = t;
+ uq[1] = t;
+ uq[2] = t;
+ uq[3] = t;
+ }
+ else {
+ uint32_t t = static_cast(x0)* static_cast(0x00010001U);
+ ud[0] = t;
+ ud[1] = t;
+ ud[2] = t;
+ ud[3] = t;
+ ud[4] = t;
+ ud[5] = t;
+ ud[6] = t;
+ ud[7] = t;
+ }
+ }
+
+ //! Set all eight 32-bit signed integers.
+ ASMJIT_INLINE void setSd(
+ int32_t x0, int32_t x1, int32_t x2, int32_t x3,
+ int32_t x4, int32_t x5, int32_t x6, int32_t x7)
+ {
+ sd[0] = x0; sd[1] = x1; sd[2] = x2; sd[3] = x3;
+ sd[4] = x4; sd[5] = x5; sd[6] = x6; sd[7] = x7;
+ }
+
+ //! Set all eight 32-bit signed integers.
+ ASMJIT_INLINE void setSd(
+ int32_t x0)
+ {
+ setUd(static_cast(x0));
+ }
+
+ //! Set all eight 32-bit unsigned integers.
+ ASMJIT_INLINE void setUd(
+ uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3,
+ uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7)
+ {
+ ud[0] = x0; ud[1] = x1; ud[2] = x2; ud[3] = x3;
+ ud[4] = x4; ud[5] = x5; ud[6] = x6; ud[7] = x7;
+ }
+
+ //! Set all eight 32-bit unsigned integers.
+ ASMJIT_INLINE void setUd(
+ uint32_t x0)
+ {
+ if (kArchHost64Bit) {
+ uint64_t t = (static_cast(x0) << 32) + x0;
+ uq[0] = t;
+ uq[1] = t;
+ uq[2] = t;
+ uq[3] = t;
+ }
+ else {
+ ud[0] = x0;
+ ud[1] = x0;
+ ud[2] = x0;
+ ud[3] = x0;
+ ud[4] = x0;
+ ud[5] = x0;
+ ud[6] = x0;
+ ud[7] = x0;
+ }
+ }
+
+ //! Set all four 64-bit signed integers.
+ ASMJIT_INLINE void setSq(
+ int64_t x0, int64_t x1, int64_t x2, int64_t x3)
+ {
+ sq[0] = x0; sq[1] = x1; sq[2] = x2; sq[3] = x3;
+ }
+
+ //! Set all four 64-bit signed integers.
+ ASMJIT_INLINE void setSq(
+ int64_t x0)
+ {
+ sq[0] = x0; sq[1] = x0; sq[2] = x0; sq[3] = x0;
+ }
+
+ //! Set all four 64-bit unsigned integers.
+ ASMJIT_INLINE void setUq(
+ uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3)
+ {
+ uq[0] = x0; uq[1] = x1; uq[2] = x2; uq[3] = x3;
+ }
+
+ //! Set all four 64-bit unsigned integers.
+ ASMJIT_INLINE void setUq(
+ uint64_t x0)
+ {
+ uq[0] = x0; uq[1] = x0; uq[2] = x0; uq[3] = x0;
+ }
+
+ //! Set all eight SP-FP floats.
+ ASMJIT_INLINE void setSf(
+ float x0, float x1, float x2, float x3,
+ float x4, float x5, float x6, float x7)
+ {
+ sf[0] = x0; sf[1] = x1; sf[2] = x2; sf[3] = x3;
+ sf[4] = x4; sf[5] = x5; sf[6] = x6; sf[7] = x7;
+ }
+
+ //! Set all eight SP-FP floats.
+ ASMJIT_INLINE void setSf(
+ float x0)
+ {
+ sf[0] = x0; sf[1] = x0; sf[2] = x0; sf[3] = x0;
+ sf[4] = x0; sf[5] = x0; sf[6] = x0; sf[7] = x0;
+ }
+
+ //! Set all four DP-FP floats.
+ ASMJIT_INLINE void setDf(
+ double x0, double x1, double x2, double x3)
+ {
+ df[0] = x0; df[1] = x1; df[2] = x2; df[3] = x3;
+ }
+
+ //! Set all four DP-FP floats.
+ ASMJIT_INLINE void setDf(
+ double x0)
+ {
+ df[0] = x0; df[1] = x0; df[2] = x0; df[3] = x0;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+ //! Array of thirty two 8-bit signed integers.
+ int8_t sb[32];
+ //! Array of thirty two 8-bit unsigned integers.
+ uint8_t ub[32];
+ //! Array of sixteen 16-bit signed integers.
+ int16_t sw[16];
+ //! Array of sixteen 16-bit unsigned integers.
+ uint16_t uw[16];
+ //! Array of eight 32-bit signed integers.
+ int32_t sd[8];
+ //! Array of eight 32-bit unsigned integers.
+ uint32_t ud[8];
+ //! Array of four 64-bit signed integers.
+ int64_t sq[4];
+ //! Array of four 64-bit unsigned integers.
+ uint64_t uq[4];
+
+ //! Array of eight 32-bit single precision floating points.
+ float sf[8];
+ //! Array of four 64-bit double precision floating points.
+ double df[4];
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // _ASMJIT_BASE_VECTYPES_H
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/vmem.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/vmem.h
new file mode 100644
index 0000000..998a49b
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/vmem.h
@@ -0,0 +1,240 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Guard]
+#ifndef _ASMJIT_BASE_VMEM_H
+#define _ASMJIT_BASE_VMEM_H
+
+// [Dependencies]
+#include "../base/error.h"
+#include "../base/lock.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_util
+//! \{
+
+// ============================================================================
+// [asmjit::kVMemAlloc]
+// ============================================================================
+
+//! Type of virtual memory allocation, see `VMemMgr::alloc()`.
+ASMJIT_ENUM(kVMemAlloc) {
+ //! Normal memory allocation, has to be freed by `VMemMgr::release()`.
+ kVMemAllocFreeable = 0,
+ //! Allocate permanent memory, can't be freed.
+ kVMemAllocPermanent = 1
+};
+
+// ============================================================================
+// [asmjit::kVMemFlags]
+// ============================================================================
+
+//! Type of virtual memory allocation, see `VMemMgr::alloc()`.
+ASMJIT_ENUM(kVMemFlags) {
+ //! Memory is writable.
+ kVMemFlagWritable = 0x00000001,
+ //! Memory is executable.
+ kVMemFlagExecutable = 0x00000002
+};
+
+// ============================================================================
+// [asmjit::VMemUtil]
+// ============================================================================
+
+//! Virtual memory utilities.
+//!
+//! Defines functions that provide facility to allocate and free memory that is
+//! executable in a platform independent manner. If both the processor and host
+//! operating system support data-execution-prevention then the only way how to
+//! run machine code is to allocate it to a memory that has marked as executable.
+//! VMemUtil is just unified interface to platform dependent APIs.
+//!
+//! `VirtualAlloc()` function is used on Windows operating system and `mmap()`
+//! on POSIX. `VirtualAlloc()` and `mmap()` documentation provide a detailed
+//! overview on how to use a platform specific APIs.
+struct VMemUtil {
+ //! Get a size/alignment of a single virtual memory page.
+ static ASMJIT_API size_t getPageSize();
+
+ //! Get a recommended granularity for a single `alloc` call.
+ static ASMJIT_API size_t getPageGranularity();
+
+ //! Allocate virtual memory.
+ //!
+ //! Pages are readable/writeable, but they are not guaranteed to be
+ //! executable unless 'canExecute' is true. Returns the address of
+ //! allocated memory, or NULL on failure.
+ static ASMJIT_API void* alloc(size_t length, size_t* allocated, uint32_t flags);
+
+#if defined(ASMJIT_OS_WINDOWS)
+ //! Allocate virtual memory of `hProcess`.
+ //!
+ //! \note This function is Windows specific.
+ static ASMJIT_API void* allocProcessMemory(HANDLE hProcess, size_t length, size_t* allocated, uint32_t flags);
+#endif // ASMJIT_OS_WINDOWS
+
+ //! Free memory allocated by `alloc()`.
+ static ASMJIT_API Error release(void* addr, size_t length);
+
+#if defined(ASMJIT_OS_WINDOWS)
+ //! Release virtual memory of `hProcess`.
+ //!
+ //! \note This function is Windows specific.
+ static ASMJIT_API Error releaseProcessMemory(HANDLE hProcess, void* addr, size_t length);
+#endif // ASMJIT_OS_WINDOWS
+};
+
+// ============================================================================
+// [asmjit::VMemMgr]
+// ============================================================================
+
+//! Reference implementation of memory manager that uses `VMemUtil` to allocate
+//! chunks of virtual memory and bit arrays to manage it.
+struct VMemMgr {
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+#if !defined(ASMJIT_OS_WINDOWS)
+ //! Create a `VMemMgr` instance.
+ ASMJIT_API VMemMgr();
+#else
+ //! Create a `VMemMgr` instance.
+ //!
+ //! \note When running on Windows it's possible to specify a `hProcess` to
+ //! be used for memory allocation. This allows to allocate memory of remote
+ //! process.
+ ASMJIT_API VMemMgr(HANDLE hProcess = static_cast(0));
+#endif // ASMJIT_OS_WINDOWS
+
+ //! Destroy the `VMemMgr` instance and free all blocks.
+ ASMJIT_API ~VMemMgr();
+
+ // --------------------------------------------------------------------------
+ // [Reset]
+ // --------------------------------------------------------------------------
+
+ //! Free all allocated memory.
+ ASMJIT_API void reset();
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+#if defined(ASMJIT_OS_WINDOWS)
+ //! Get the handle of the process memory manager is bound to.
+ ASMJIT_INLINE HANDLE getProcessHandle() const {
+ return _hProcess;
+ }
+#endif // ASMJIT_OS_WINDOWS
+
+ //! Get how many bytes are currently allocated.
+ ASMJIT_INLINE size_t getAllocatedBytes() const {
+ return _allocatedBytes;
+ }
+
+ //! Get how many bytes are currently used.
+ ASMJIT_INLINE size_t getUsedBytes() const {
+ return _usedBytes;
+ }
+
+ //! Get whether to keep allocated memory after the `VMemMgr` is destroyed.
+ //!
+ //! \sa \ref setKeepVirtualMemory.
+ ASMJIT_INLINE bool getKeepVirtualMemory() const {
+ return _keepVirtualMemory;
+ }
+
+ //! Set whether to keep allocated memory after memory manager is
+ //! destroyed.
+ //!
+ //! This method is usable when patching code of remote process. You need to
+ //! allocate process memory, store generated assembler into it and patch the
+ //! method you want to redirect (into your code). This method affects only
+ //! VMemMgr destructor. After destruction all internal
+ //! structures are freed, only the process virtual memory remains.
+ //!
+ //! \note Memory allocated with kVMemAllocPermanent is always kept.
+ //!
+ //! \sa \ref getKeepVirtualMemory.
+ ASMJIT_INLINE void setKeepVirtualMemory(bool keepVirtualMemory) {
+ _keepVirtualMemory = keepVirtualMemory;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Alloc / Release]
+ // --------------------------------------------------------------------------
+
+ //! Allocate a `size` bytes of virtual memory.
+ //!
+ //! Note that if you are implementing your own virtual memory manager then you
+ //! can quitly ignore type of allocation. This is mainly for AsmJit to memory
+ //! manager that allocated memory will be never freed.
+ ASMJIT_API void* alloc(size_t size, uint32_t type = kVMemAllocFreeable);
+
+ //! Free previously allocated memory at a given `address`.
+ ASMJIT_API Error release(void* p);
+
+ //! Free extra memory allocated with `p`.
+ ASMJIT_API Error shrink(void* p, size_t used);
+
+ // --------------------------------------------------------------------------
+ // [Members]
+ // --------------------------------------------------------------------------
+
+#if defined(ASMJIT_OS_WINDOWS)
+ //! Process passed to `VirtualAllocEx` and `VirtualFree`.
+ HANDLE _hProcess;
+#endif // ASMJIT_OS_WINDOWS
+
+ //! Lock to enable thread-safe functionality.
+ Lock _lock;
+
+ //! Default block size.
+ size_t _blockSize;
+ //! Default block density.
+ size_t _blockDensity;
+
+ // Whether to keep virtual memory after destroy.
+ bool _keepVirtualMemory;
+
+ //! How many bytes are currently allocated.
+ size_t _allocatedBytes;
+ //! How many bytes are currently used.
+ size_t _usedBytes;
+
+ //! \internal
+ //! \{
+
+ struct RbNode;
+ struct MemNode;
+ struct PermanentNode;
+
+ // Memory nodes root.
+ MemNode* _root;
+ // Memory nodes list.
+ MemNode* _first;
+ MemNode* _last;
+ MemNode* _optimal;
+ // Permanent memory.
+ PermanentNode* _permanent;
+
+ //! \}
+};
+
+//! \}
+
+} // asmjit namespace
+
+// [Api-End]
+#include "../apiend.h"
+
+// [Guard]
+#endif // _ASMJIT_BASE_VMEM_H
diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/zone.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/zone.h
new file mode 100644
index 0000000..3578902
--- /dev/null
+++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/base/zone.h
@@ -0,0 +1,221 @@
+// [AsmJit]
+// Complete x86/x64 JIT and Remote Assembler for C++.
+//
+// [License]
+// Zlib - See LICENSE.md file in the package.
+
+// [Guard]
+#ifndef _ASMJIT_BASE_ZONE_H
+#define _ASMJIT_BASE_ZONE_H
+
+// [Dependencies]
+#include "../base/globals.h"
+
+// [Api-Begin]
+#include "../apibegin.h"
+
+namespace asmjit {
+
+//! \addtogroup asmjit_base_util
+//! \{
+
+// ============================================================================
+// [asmjit::Zone]
+// ============================================================================
+
+//! Zone memory allocator.
+//!
+//! Zone is an incremental memory allocator that allocates memory by simply
+//! incrementing a pointer. It allocates blocks of memory by using standard
+//! C library `malloc/free`, but divides these blocks into smaller segments
+//! requirested by calling `Zone::alloc()` and friends.
+//!
+//! Zone memory allocators are designed to allocate data of short lifetime. The
+//! data used by `Assembler` and `Compiler` has a very short lifetime, thus, is
+//! allocated by `Zone`. The advantage is that `Zone` can free all of the data
+//! allocated at once by calling `reset()` or by `Zone` destructor.
+struct Zone {
+ // --------------------------------------------------------------------------
+ // [Block]
+ // --------------------------------------------------------------------------
+
+ //! \internal
+ //!
+ //! A single block of memory.
+ struct Block {
+ // ------------------------------------------------------------------------
+ // [Accessors]
+ // ------------------------------------------------------------------------
+
+ //! Get the size of the block.
+ ASMJIT_INLINE size_t getBlockSize() const {
+ return (size_t)(end - data);
+ }
+
+ //! Get count of remaining bytes in the block.
+ ASMJIT_INLINE size_t getRemainingSize() const {
+ return (size_t)(end - pos);
+ }
+
+ // ------------------------------------------------------------------------
+ // [Members]
+ // ------------------------------------------------------------------------
+
+ //! Current data pointer (pointer to the first available byte).
+ uint8_t* pos;
+ //! End data pointer (pointer to the first invalid byte).
+ uint8_t* end;
+
+ //! Link to the previous block.
+ Block* prev;
+ //! Link to the next block.
+ Block* next;
+
+ //! Data.
+ uint8_t data[sizeof(void*)];
+ };
+
+ // --------------------------------------------------------------------------
+ // [Construction / Destruction]
+ // --------------------------------------------------------------------------
+
+ //! Create a new instance of `Zone` allocator.
+ //!
+ //! The `blockSize` parameter describes the default size of the block. If the
+ //! `size` parameter passed to `alloc()` is greater than the default size
+ //! `Zone` will allocate and use a larger block, but it will not change the
+ //! default `blockSize`.
+ //!
+ //! It's not required, but it's good practice to set `blockSize` to a
+ //! reasonable value that depends on the usage of `Zone`. Greater block sizes
+ //! are generally safer and performs better than unreasonably low values.
+ ASMJIT_API Zone(size_t blockSize);
+
+ //! Destroy the `Zone` instance.
+ //!
+ //! This will destroy the `Zone` instance and release all blocks of memory
+ //! allocated by it. It performs implicit `reset(true)`.
+ ASMJIT_API ~Zone();
+
+ // --------------------------------------------------------------------------
+ // [Reset]
+ // --------------------------------------------------------------------------
+
+ //! Reset the `Zone` invalidating all blocks allocated.
+ //!
+ //! If `releaseMemory` is true all buffers will be released to the system.
+ ASMJIT_API void reset(bool releaseMemory = false);
+
+ // --------------------------------------------------------------------------
+ // [Accessors]
+ // --------------------------------------------------------------------------
+
+ //! Get the default block size.
+ ASMJIT_INLINE size_t getBlockSize() const {
+ return _blockSize;
+ }
+
+ // --------------------------------------------------------------------------
+ // [Alloc]
+ // --------------------------------------------------------------------------
+
+ //! Allocate `size` bytes of memory.
+ //!
+ //! Pointer returned is valid until the `Zone` instance is destroyed or reset
+ //! by calling `reset()`. If you plan to make an instance of C++ from the
+ //! given pointer use placement `new` and `delete` operators:
+ //!
+ //! ~~~
+ //! using namespace asmjit;
+ //!
+ //! class SomeObject { ... };
+ //!
+ //! // Create Zone with default block size of 65536 bytes.
+ //! Zone zone(65536);
+ //!
+ //! // Create your objects using zone object allocating, for example:
+ //! Object* obj = static_cast