- Minor reorganization of source code (split defs to operand and instruction info).

- Added JECXZ instruction.
- Doxyfile is now in project root.
- Documentation updates.
This commit is contained in:
kobalicek
2014-05-10 21:19:50 +02:00
parent bd1a5facb8
commit 1a73e65534
69 changed files with 9451 additions and 5174 deletions

View File

@@ -222,8 +222,6 @@ AsmJit_AddSource(ASMJIT_SRC asmjit/base
cpuinfo.h cpuinfo.h
cputicks.cpp cputicks.cpp
cputicks.h cputicks.h
defs.cpp
defs.h
error.cpp error.cpp
error.h error.h
func.cpp func.cpp
@@ -234,6 +232,8 @@ AsmJit_AddSource(ASMJIT_SRC asmjit/base
lock.h lock.h
logger.cpp logger.cpp
logger.h logger.h
operand.cpp
operand.h
podlist.h podlist.h
podvector.cpp podvector.cpp
podvector.h podvector.h
@@ -257,10 +257,14 @@ AsmJit_AddSource(ASMJIT_SRC asmjit/x86
x86context_p.h x86context_p.h
x86cpuinfo.cpp x86cpuinfo.cpp
x86cpuinfo.h x86cpuinfo.h
x86defs.cpp
x86defs.h
x86func.cpp x86func.cpp
x86func.h x86func.h
x86inst.cpp
x86inst.h
x86operand.cpp
x86operand.h
x86util.cpp
x86util.h
) )
AsmJit_AddSource(ASMJIT_SRC asmjit/contrib AsmJit_AddSource(ASMJIT_SRC asmjit/contrib

236
Doxyfile Normal file
View File

@@ -0,0 +1,236 @@
# Doxyfile 1.8.7
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "AsmJit"
PROJECT_NUMBER = "1.1"
PROJECT_BRIEF = "Complete Remote and JIT Assembler for x86/x64"
OUTPUT_DIRECTORY = .
CREATE_SUBDIRS = NO
ALLOW_UNICODE_NAMES = NO
OUTPUT_LANGUAGE = English
FULL_PATH_NAMES = YES
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
QT_AUTOBRIEF = NO
JAVADOC_AUTOBRIEF = YES
MULTILINE_CPP_IS_BRIEF = YES
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
INHERIT_DOCS = YES
TAB_SIZE = 2
MARKDOWN_SUPPORT = YES
AUTOLINK_SUPPORT = NO
IDL_PROPERTY_SUPPORT = NO
SEPARATE_MEMBER_PAGES = NO
DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
INLINE_GROUPED_CLASSES = NO
INLINE_SIMPLE_STRUCTS = NO
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_PACKAGE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = NO
HIDE_UNDOC_CLASSES = YES
HIDE_UNDOC_MEMBERS = NO
HIDE_FRIEND_COMPOUNDS = YES
HIDE_IN_BODY_DOCS = YES
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = NO
# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
# their full class and namespace scopes in the documentation. If set to YES the
# scope will be hidden.
# The default value is: NO.
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = NO
SHOW_GROUPED_MEMB_INC = NO
INLINE_INFO = YES
SORT_MEMBER_DOCS = NO
SORT_BRIEF_DOCS = NO
SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = YES
STRICT_PROTO_MATCHING = NO
GENERATE_TODOLIST = NO
GENERATE_TESTLIST = NO
GENERATE_BUGLIST = NO
GENERATE_DEPRECATEDLIST= NO
MAX_INITIALIZER_LINES = 0
SHOW_USED_FILES = NO
SHOW_FILES = NO
SHOW_NAMESPACES = NO
#---------------------------------------------------------------------------
# Configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = YES
WARNINGS = YES
WARN_IF_UNDOCUMENTED = NO
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# Configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = src/asmjit
INPUT_ENCODING = UTF-8
RECURSIVE = YES
EXCLUDE =
USE_MDFILE_AS_MAINPAGE = README.md
#---------------------------------------------------------------------------
# Configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
SOURCE_TOOLTIPS = YES
VERBATIM_HEADERS = NO
#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = NO
#---------------------------------------------------------------------------
# Configuration options related to outputs
#---------------------------------------------------------------------------
GENERATE_HTML = YES
GENERATE_LATEX = NO
GENERATE_RTF = NO
GENERATE_MAN = NO
GENERATE_XML = YES
XML_OUTPUT = build_xml
XML_PROGRAMLISTING = NO
HTML_OUTPUT = build_doc
HTML_FILE_EXTENSION = .html
LAYOUT_FILE = tools/doc-layout.xml
HTML_HEADER = tools/doc-header.html
HTML_FOOTER = tools/doc-footer.html
HTML_STYLESHEET = tools/doc-style.css
HTML_EXTRA_STYLESHEET =
HTML_EXTRA_FILES =
HTML_COLORSTYLE_HUE = 220
HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80
HTML_TIMESTAMP = NO
HTML_DYNAMIC_SECTIONS = NO
HTML_INDEX_NUM_ENTRIES = 0
SEARCHENGINE = NO
#---------------------------------------------------------------------------
# Configuration options related to the CHM output
#---------------------------------------------------------------------------
# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
# Windows.
#
# The HTML Help Workshop contains a compiler that can convert all HTML output
# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
# files are now used as the Windows 98 help format, and will replace the old
# Windows help format (.hlp) on all Windows platforms in the future. Compressed
# HTML files also contain an index, a table of contents, and you can search for
# words in the documentation. The HTML workshop also contains a viewer for
# compressed HTML files.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
GENERATE_HTMLHELP = NO
# The CHM_FILE tag can be used to specify the file name of the resulting .chm
# file. You can add a path in front of the file if the result should not be
# written to the html output directory.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
CHM_FILE =
# The HHC_LOCATION tag can be used to specify the location (absolute path
# including file name) of the HTML help compiler ( hhc.exe). If non-empty
# doxygen will try to run the HTML help compiler on the generated index.hhp.
# The file has to be specified with full path.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
HHC_LOCATION =
# The BINARY_TOC flag controls whether a binary table of contents is generated (
# YES) or a normal table of contents ( NO) in the .chm file. Furthermore it
# enables the Previous and Next buttons.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
BINARY_TOC = NO
# The TOC_EXPAND flag can be set to YES to add extra items for group members to
# the table of contents of the HTML help documentation and to the tree view.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
TOC_EXPAND = NO
DISABLE_INDEX = NO
GENERATE_TREEVIEW = NO
ENUM_VALUES_PER_LINE = 0
TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = NO
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
PREDEFINED = ASMJIT_DOCGEN \
ASMJIT_BUILD_X86 \
ASMJIT_BUILD_X64 \
ASMJIT_API
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = NO
CLASS_GRAPH = NO

View File

@@ -29,7 +29,7 @@ Features
* Built-in CPU detection, * Built-in CPU detection,
* Virtual Memory management, * Virtual Memory management,
* Pretty logging and error handling, * Pretty logging and error handling,
* Small and embeddable, around 150kB compiled, * Small and embeddable, around 150-200kB compiled,
* Zero dependencies, not even STL or RTTI. * Zero dependencies, not even STL or RTTI.
Supported Environments Supported Environments
@@ -46,7 +46,7 @@ Supported Environments
* BorlandC++ * BorlandC++
* GNU (3.4.X+, 4.0+, MinGW) * GNU (3.4.X+, 4.0+, MinGW)
* MSVC (VS2005, VS2008, VS2010) * MSVC (VS2005+)
* Other compilers require testing * Other compilers require testing
### Backends ### Backends

View File

@@ -88,7 +88,7 @@ static void blend(asmjit::host::Compiler& c) {
c.psrlw(a0, 8); c.psrlw(a0, 8);
c.punpcklbw(x0, cZero); c.punpcklbw(x0, cZero);
c.pshuflw(a0, a0, mm_shuffle(1, 1, 1, 1)); c.pshuflw(a0, a0, X86Util::mmShuffle(1, 1, 1, 1));
c.punpcklbw(y0, cZero); c.punpcklbw(y0, cZero);
c.pmullw(x0, a0); c.pmullw(x0, a0);
@@ -136,8 +136,8 @@ static void blend(asmjit::host::Compiler& c) {
c.punpckhbw(x1, cZero); c.punpckhbw(x1, cZero);
c.punpckhwd(a1, a1); c.punpckhwd(a1, a1);
c.pshufd(a0, a0, mm_shuffle(3, 3, 1, 1)); c.pshufd(a0, a0, X86Util::mmShuffle(3, 3, 1, 1));
c.pshufd(a1, a1, mm_shuffle(3, 3, 1, 1)); c.pshufd(a1, a1, X86Util::mmShuffle(3, 3, 1, 1));
c.pmullw(x0, a0); c.pmullw(x0, a0);
c.pmullw(x1, a1); c.pmullw(x1, a1);
@@ -166,7 +166,7 @@ static void blend(asmjit::host::Compiler& c) {
c.endFunc(); c.endFunc();
// Data. // Data.
c.align(16); c.align(kAlignData, 16);
c.bind(L_Data); c.bind(L_Data);
c.dxmm(XmmData::fromSw(0x0080)); c.dxmm(XmmData::fromSw(0x0080));
c.dxmm(XmmData::fromSw(0x0101)); c.dxmm(XmmData::fromSw(0x0101));

View File

@@ -268,6 +268,87 @@ static void opcode(asmjit::host::Assembler& a) {
a.xor_(intptr_gp0, gp1); a.xor_(intptr_gp0, gp1);
a.xor_(intptr_gp0, 0); a.xor_(intptr_gp0, 0);
// Label...Jcc/Jecxz/Jmp.
{
a.nop();
Label L(a);
a.bind(L);
a.ja(L);
a.jae(L);
a.jb(L);
a.jbe(L);
a.jc(L);
a.je(L);
a.jg(L);
a.jge(L);
a.jl(L);
a.jle(L);
a.jna(L);
a.jnae(L);
a.jnb(L);
a.jnbe(L);
a.jnc(L);
a.jne(L);
a.jng(L);
a.jnge(L);
a.jnl(L);
a.jnle(L);
a.jno(L);
a.jnp(L);
a.jns(L);
a.jnz(L);
a.jo(L);
a.jp(L);
a.jpe(L);
a.jpo(L);
a.js(L);
a.jz(L);
a.jecxz(ecx, L);
a.jmp(L);
}
// Jcc/Jecxz/Jmp...Label.
{
a.nop();
Label L(a);
a.ja(L);
a.jae(L);
a.jb(L);
a.jbe(L);
a.jc(L);
a.je(L);
a.jg(L);
a.jge(L);
a.jl(L);
a.jle(L);
a.jna(L);
a.jnae(L);
a.jnb(L);
a.jnbe(L);
a.jnc(L);
a.jne(L);
a.jng(L);
a.jnge(L);
a.jnl(L);
a.jnle(L);
a.jno(L);
a.jnp(L);
a.jns(L);
a.jnz(L);
a.jo(L);
a.jp(L);
a.jpe(L);
a.jpo(L);
a.js(L);
a.jz(L);
a.jecxz(ecx, L);
a.jmp(L);
a.bind(L);
}
// Fpu. // Fpu.
a.nop(); a.nop();

View File

@@ -59,7 +59,7 @@ int main(int argc, char* argv[]) {
printf(" asmjit::LabelData : %u\n", static_cast<uint32_t>(sizeof(LabelData))); printf(" asmjit::LabelData : %u\n", static_cast<uint32_t>(sizeof(LabelData)));
printf(" asmjit::RelocData : %u\n", static_cast<uint32_t>(sizeof(RelocData))); printf(" asmjit::RelocData : %u\n", static_cast<uint32_t>(sizeof(RelocData)));
printf("\n"); printf("\n");
printf(" asmjit::BaseNode : %u\n", static_cast<uint32_t>(sizeof(BaseNode))); printf(" asmjit::Node : %u\n", static_cast<uint32_t>(sizeof(Node)));
printf(" asmjit::AlignNode : %u\n", static_cast<uint32_t>(sizeof(AlignNode))); printf(" asmjit::AlignNode : %u\n", static_cast<uint32_t>(sizeof(AlignNode)));
printf(" asmjit::CallNode : %u\n", static_cast<uint32_t>(sizeof(CallNode))); printf(" asmjit::CallNode : %u\n", static_cast<uint32_t>(sizeof(CallNode)));
printf(" asmjit::CommentNode : %u\n", static_cast<uint32_t>(sizeof(CommentNode))); printf(" asmjit::CommentNode : %u\n", static_cast<uint32_t>(sizeof(CommentNode)));

View File

@@ -56,19 +56,315 @@
//! //!
//! @section AsmJit_Main_CodeGeneration Code Generation //! @section AsmJit_Main_CodeGeneration Code Generation
//! //!
//! - @ref asmjit_base "Assembler core" - Operands, intrinsics and low-level assembler. //! - @ref asmjit_base_general "Assembler core" - Operands, intrinsics and low-level assembler.
//! - @ref asmjit_compiler "Compiler" - High level code generation. //! - @ref asmjit_compiler "Compiler" - High level code generation.
//! - @ref asmjit_cpuinfo "Cpu Information" - Get information about host processor. //! - @ref asmjit_cpuinfo "Cpu Information" - Get information about host processor.
//! - @ref asmjit_logging "Logging" - Logging and error handling. //! - @ref asmjit_logging "Logging" - Logging and error handling.
//! - @ref AsmJit_MemoryManagement "Memory Management" - Virtual memory management. //! - @ref AsmJit_MemoryManagement "Memory Management" - Virtual memory management.
//! //!
//! @section AsmJit_Main_Configuration Configuration, Definitions and Utilities
//!
//! - @ref asmjit_config "Configuration" - Macros used to configure AsmJit.
//!
//! @section AsmJit_Main_HomePage AsmJit Homepage //! @section AsmJit_Main_HomePage AsmJit Homepage
//! //!
//! - http://code.google.com/p/asmjit/ //! - https://github.com/kobalicekp/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 `BaseAssembler` is implemented by `x86x64::X86X64Assembler`.
//!
//! - See `BaseAssembler` for low level code generation documentation.
//! - See `BaseCompiler` 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_tree]
// ============================================================================
//! \defgroup asmjit_base_tree AsmJit Code-Tree
//! \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 BaseCompiler.
//!
//! 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 `Vec64Data`,
//! `Vec128Data` and `Vec256Data` 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_x86x64]
// ============================================================================
//! \defgroup asmjit_x86x64 X86/X64
//!
//! \brief X86/X64 module
// ============================================================================
// [asmjit_x86x64_general]
// ============================================================================
//! \defgroup asmjit_x86x64_general X86/X64 General API
//! \ingroup asmjit_x86x64
//!
//! \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()`
//! - `asmjit::byte_ptr()`
//! - `asmjit::word_ptr()`
//! - `asmjit::dword_ptr()`
//! - `asmjit::qword_ptr()`
//! - `asmjit::tword_ptr()`
//! - `asmjit::oword_ptr()`
//! - `asmjit::yword_ptr()`
//! - `asmjit::intptr_ptr()`
//!
//! 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 @c asmjit::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 @c asmjit::imm() or @c asmjit::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 `CpuInfo` extends `BaseCpuInfo` 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 `CpuInfo` 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 `CpuInfo` and setting
//! up its members. `CpuUtil::detect` can be used to detect CPU features into
//! an existing `CpuInfo` instance - it may become handly if only one property
//! has to be turned on/off.
//!
//! If the high-level interface `CpuInfo` offers is not enough there is also
//! `CpuUtil::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;
//! using namespace asmjit::host;
//!
//! // Get `CpuInfo` global instance.
//! const CpuInfo* cpuInfo = CpuInfo::getHost();
//!
//! if (cpuInfo->hasFeature(kCpuFeatureSse2)) {
//! // Processor has SSE2.
//! }
//! else if (cpuInfo->hasFeature(kCpuFeatureMmx)) {
//! // 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.
//! CpuId out;
//! CpuUtil::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_x86x64_tree]
// ============================================================================
//! \defgroup asmjit_x86x64_tree X86/X64 Code-Tree
//! \ingroup asmjit_x86x64
//!
//! \brief X86/X64 code-tree and helpers.
// ============================================================================
// [asmjit_x86x64_inst]
// ============================================================================
//! \defgroup asmjit_x86x64_inst X86/X64 Instructions
//! \ingroup asmjit_x86x64
//!
//! \brief X86/X64 low-level instruction definitions.
// ============================================================================
// [asmjit_x86x64_util]
// ============================================================================
//! \defgroup asmjit_x86x64_util X86/X64 Utilities
//! \ingroup asmjit_x86x64
//!
//! \brief X86/X64 utility classes.
// ============================================================================
// [asmjit_contrib]
// ============================================================================
//! \defgroup asmjit_contrib Contributions
//!
//! \brief Contributions.
// [Dependencies - Base] // [Dependencies - Base]
#include "base.h" #include "base.h"

View File

@@ -8,193 +8,7 @@
#ifndef _ASMJIT_BASE_H #ifndef _ASMJIT_BASE_H
#define _ASMJIT_BASE_H #define _ASMJIT_BASE_H
// ============================================================================
// [asmjit_base]
// ============================================================================
//! @defgroup asmjit_base Base
//!
//! @brief AsmJit Base API.
//!
//! Contains all `asmjit` classes and helper functions that are architecture
//! independent or abstract. Abstract classes are implemented by the backend,
//! for example `BaseAssembler` is implemented by `x86x64::X86X64Assembler`.
//!
//! - See `BaseAssembler` for low level code generation documentation.
//! - See `BaseCompiler` for high level code generation documentation.
//! - See `Operand` for operand's overview.
//!
//! @section AsmJit_Core_Registers 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.
//!
//! @section AsmJit_Core_Addressing 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()`
//! - `asmjit::byte_ptr()`
//! - `asmjit::word_ptr()`
//! - `asmjit::dword_ptr()`
//! - `asmjit::qword_ptr()`
//! - `asmjit::tword_ptr()`
//! - `asmjit::oword_ptr()`
//! - `asmjit::yword_ptr()`
//! - `asmjit::intptr_ptr()`
//!
//! 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 @c asmjit::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 (register + displacement) and complex
//! address forms (register + (register << shift) + displacement).
//!
//! @section AsmJit_Core_Immediates Immediates
//!
//! Immediate values are constants thats passed directly after instruction
//! opcode. To create such value use @c asmjit::imm() or @c asmjit::imm_u()
//! methods to create signed or unsigned immediate value.
//!
//! @sa @c asmjit::BaseCompiler.
// ============================================================================
// [asmjit_base_globals]
// ============================================================================
//! @defgroup asmjit_base_globals Globals
//! @ingroup asmjit_base
//!
//! @brief Global definitions, macros and functions.
// ============================================================================
// [asmjit_base_codegen]
// ============================================================================
//! @defgroup asmjit_base_codegen Code Generation (Base)
//! @ingroup asmjit_base
//!
//! @brief Low-level and high-level code generation.
// ============================================================================
// [asmjit_base_cpu_info]
// ============================================================================
//! @defgroup asmjit_base_cpu_info CPU Information (Base)
//! @ingroup asmjit_base
//!
//! @brief CPU Information Interface, platform neutral.
// ============================================================================
// [asmjit_base_logging_and_errors]
// ============================================================================
//! @defgroup asmjit_base_logging_and_errors Logging and Error Handling
//! @ingroup asmjit_base
//!
//! @brief 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 `FILE*`
//! and `StringLogger` that just concatenates all log messages without sending
//! them to a stream.
//!
//! 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_util]
// ============================================================================
//! @defgroup asmjit_base_util Utilities
//! @ingroup asmjit_base
//!
//! @brief Utilities inside AsmJit made public.
//!
//! 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
//! --------------
//!
//! TODO: Documentation
//!
//! String Builder
//! --------------
//!
//! TODO: Documentation
//!
//! Integer Utilities
//! -----------------
//!
//! TODO: Documentation
//!
//! Zone Memory Allocator
//! ---------------------
//!
//! TODO: Documentation
//!
//! CPU Ticks
//! ---------
//!
//! TODO: Documentation
// ============================================================================
// [asmjit_base_vectypes]
// ============================================================================
//! @defgroup asmjit_base_vectypes Vector Types
//! @ingroup asmjit_base
//!
//! @brief Vector types can be used to create a data which is stored in the
//! machine code.
// ============================================================================
// [asmjit::]
// ============================================================================
//! @namespace asmjit
//! Main AsmJit library namespace.
//!
//! There are not other namespaces used in AsmJit library.
// ============================================================================
// [Dependencies - AsmJit] // [Dependencies - AsmJit]
// ============================================================================
#include "build.h" #include "build.h"
#include "base/assembler.h" #include "base/assembler.h"
@@ -203,15 +17,16 @@
#include "base/constpool.h" #include "base/constpool.h"
#include "base/cpuinfo.h" #include "base/cpuinfo.h"
#include "base/cputicks.h" #include "base/cputicks.h"
#include "base/defs.h"
#include "base/error.h" #include "base/error.h"
#include "base/func.h" #include "base/func.h"
#include "base/globals.h" #include "base/globals.h"
#include "base/intutil.h" #include "base/intutil.h"
#include "base/lock.h" #include "base/lock.h"
#include "base/logger.h" #include "base/logger.h"
#include "base/operand.h"
#include "base/podlist.h" #include "base/podlist.h"
#include "base/podvector.h" #include "base/podvector.h"
#include "base/runtime.h"
#include "base/string.h" #include "base/string.h"
#include "base/vectypes.h" #include "base/vectypes.h"
#include "base/vmem.h" #include "base/vmem.h"

View File

@@ -10,9 +10,9 @@
// [Dependencies - AsmJit] // [Dependencies - AsmJit]
#include "../base/codegen.h" #include "../base/codegen.h"
#include "../base/defs.h"
#include "../base/error.h" #include "../base/error.h"
#include "../base/logger.h" #include "../base/logger.h"
#include "../base/operand.h"
#include "../base/podlist.h" #include "../base/podlist.h"
#include "../base/podvector.h" #include "../base/podvector.h"
#include "../base/runtime.h" #include "../base/runtime.h"
@@ -23,14 +23,59 @@
namespace asmjit { namespace asmjit {
//! @addtogroup asmjit_base_codegen //! \addtogroup asmjit_base_general
//! @{ //! \{
// ============================================================================
// [asmjit::kInstCode]
// ============================================================================
//! Instruction codes (stub).
ASMJIT_ENUM(kInstCode) {
//! No instruction.
kInstNone = 0
};
// ============================================================================
// [asmjit::kInstOptions]
// ============================================================================
//! Instruction options (stub).
ASMJIT_ENUM(kInstOptions) {
//! No instruction options.
kInstOptionNone = 0x00,
//! 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 = 0x01,
//! 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 = 0x02,
//! Condition is likely to be taken (instruction).
kInstOptionTaken = 0x04,
//! Condition is unlikely to be taken (instruction).
kInstOptionNotTaken = 0x08
};
// ============================================================================ // ============================================================================
// [asmjit::LabelLink] // [asmjit::LabelLink]
// ============================================================================ // ============================================================================
//! @internal //! \internal
//! //!
//! Data structure used to link linked-labels. //! Data structure used to link linked-labels.
struct LabelLink { struct LabelLink {
@@ -48,7 +93,7 @@ struct LabelLink {
// [asmjit::LabelData] // [asmjit::LabelData]
// ============================================================================ // ============================================================================
//! @internal //! \internal
//! //!
//! Label data. //! Label data.
struct LabelData { struct LabelData {
@@ -62,7 +107,7 @@ struct LabelData {
// [asmjit::RelocData] // [asmjit::RelocData]
// ============================================================================ // ============================================================================
//! @internal //! \internal
//! //!
//! Code relocation data (relative vs absolute addresses). //! Code relocation data (relative vs absolute addresses).
//! //!
@@ -182,61 +227,61 @@ struct BaseAssembler : public CodeGen {
//! Reserve the internal buffer to at least `n` bytes. //! Reserve the internal buffer to at least `n` bytes.
ASMJIT_API Error _reserve(size_t n); ASMJIT_API Error _reserve(size_t n);
//! Set byte at position `pos`. //! Get BYTE at position `pos`.
ASMJIT_INLINE uint8_t getByteAt(size_t pos) const { ASMJIT_INLINE uint8_t getByteAt(size_t pos) const {
ASMJIT_ASSERT(pos + 1 <= (size_t)(_end - _buffer)); ASMJIT_ASSERT(pos + 1 <= (size_t)(_end - _buffer));
return *reinterpret_cast<const uint8_t*>(_buffer + pos); return *reinterpret_cast<const uint8_t*>(_buffer + pos);
} }
//! Set word at position `pos`. //! Get WORD at position `pos`.
ASMJIT_INLINE uint16_t getWordAt(size_t pos) const { ASMJIT_INLINE uint16_t getWordAt(size_t pos) const {
ASMJIT_ASSERT(pos + 2 <= (size_t)(_end - _buffer)); ASMJIT_ASSERT(pos + 2 <= (size_t)(_end - _buffer));
return *reinterpret_cast<const uint16_t*>(_buffer + pos); return *reinterpret_cast<const uint16_t*>(_buffer + pos);
} }
//! Set dword at position `pos`. //! Get DWORD at position `pos`.
ASMJIT_INLINE uint32_t getDWordAt(size_t pos) const { ASMJIT_INLINE uint32_t getDWordAt(size_t pos) const {
ASMJIT_ASSERT(pos + 4 <= (size_t)(_end - _buffer)); ASMJIT_ASSERT(pos + 4 <= (size_t)(_end - _buffer));
return *reinterpret_cast<const uint32_t*>(_buffer + pos); return *reinterpret_cast<const uint32_t*>(_buffer + pos);
} }
//! Set qword at position `pos`. //! Get QWORD at position `pos`.
ASMJIT_INLINE uint64_t getQWordAt(size_t pos) const { ASMJIT_INLINE uint64_t getQWordAt(size_t pos) const {
ASMJIT_ASSERT(pos + 8 <= (size_t)(_end - _buffer)); ASMJIT_ASSERT(pos + 8 <= (size_t)(_end - _buffer));
return *reinterpret_cast<const uint64_t*>(_buffer + pos); return *reinterpret_cast<const uint64_t*>(_buffer + pos);
} }
//! Set int32_t at position `pos`. //! Get int32_t at position `pos`.
ASMJIT_INLINE int32_t getInt32At(size_t pos) const { ASMJIT_INLINE int32_t getInt32At(size_t pos) const {
ASMJIT_ASSERT(pos + 4 <= (size_t)(_end - _buffer)); ASMJIT_ASSERT(pos + 4 <= (size_t)(_end - _buffer));
return *reinterpret_cast<const int32_t*>(_buffer + pos); return *reinterpret_cast<const int32_t*>(_buffer + pos);
} }
//! Set uint32_t at position `pos`. //! Get uint32_t at position `pos`.
ASMJIT_INLINE uint32_t getUInt32At(size_t pos) const { ASMJIT_INLINE uint32_t getUInt32At(size_t pos) const {
ASMJIT_ASSERT(pos + 4 <= (size_t)(_end - _buffer)); ASMJIT_ASSERT(pos + 4 <= (size_t)(_end - _buffer));
return *reinterpret_cast<const uint32_t*>(_buffer + pos); return *reinterpret_cast<const uint32_t*>(_buffer + pos);
} }
//! Set byte at position `pos`. //! Set BYTE at position `pos`.
ASMJIT_INLINE void setByteAt(size_t pos, uint8_t x) { ASMJIT_INLINE void setByteAt(size_t pos, uint8_t x) {
ASMJIT_ASSERT(pos + 1 <= (size_t)(_end - _buffer)); ASMJIT_ASSERT(pos + 1 <= (size_t)(_end - _buffer));
*reinterpret_cast<uint8_t*>(_buffer + pos) = x; *reinterpret_cast<uint8_t*>(_buffer + pos) = x;
} }
//! Set word at position `pos`. //! Set WORD at position `pos`.
ASMJIT_INLINE void setWordAt(size_t pos, uint16_t x) { ASMJIT_INLINE void setWordAt(size_t pos, uint16_t x) {
ASMJIT_ASSERT(pos + 2 <= (size_t)(_end - _buffer)); ASMJIT_ASSERT(pos + 2 <= (size_t)(_end - _buffer));
*reinterpret_cast<uint16_t*>(_buffer + pos) = x; *reinterpret_cast<uint16_t*>(_buffer + pos) = x;
} }
//! Set dword at position `pos`. //! Set DWORD at position `pos`.
ASMJIT_INLINE void setDWordAt(size_t pos, uint32_t x) { ASMJIT_INLINE void setDWordAt(size_t pos, uint32_t x) {
ASMJIT_ASSERT(pos + 4 <= (size_t)(_end - _buffer)); ASMJIT_ASSERT(pos + 4 <= (size_t)(_end - _buffer));
*reinterpret_cast<uint32_t*>(_buffer + pos) = x; *reinterpret_cast<uint32_t*>(_buffer + pos) = x;
} }
//! Set qword at position `pos`. //! Set QWORD at position `pos`.
ASMJIT_INLINE void setQWordAt(size_t pos, uint64_t x) { ASMJIT_INLINE void setQWordAt(size_t pos, uint64_t x) {
ASMJIT_ASSERT(pos + 8 <= (size_t)(_end - _buffer)); ASMJIT_ASSERT(pos + 8 <= (size_t)(_end - _buffer));
*reinterpret_cast<uint64_t*>(_buffer + pos) = x; *reinterpret_cast<uint64_t*>(_buffer + pos) = x;
@@ -291,14 +336,14 @@ struct BaseAssembler : public CodeGen {
return static_cast<size_t>(label.getId()) < _labels.getLength(); return static_cast<size_t>(label.getId()) < _labels.getLength();
} }
//! @internal //! \internal
//! //!
//! Get `LabelData` by `label`. //! Get `LabelData` by `label`.
ASMJIT_INLINE LabelData* getLabelData(const Label& label) const { ASMJIT_INLINE LabelData* getLabelData(const Label& label) const {
return getLabelDataById(label.getId()); return getLabelDataById(label.getId());
} }
//! @internal //! \internal
//! //!
//! Get `LabelData` by `id`. //! Get `LabelData` by `id`.
ASMJIT_INLINE LabelData* getLabelDataById(uint32_t id) const { ASMJIT_INLINE LabelData* getLabelDataById(uint32_t id) const {
@@ -308,17 +353,17 @@ struct BaseAssembler : public CodeGen {
return const_cast<LabelData*>(&_labels[id]); return const_cast<LabelData*>(&_labels[id]);
} }
//! @internal //! \internal
//! //!
//! Register labels for other code generator, i.e. `Compiler`. //! Register labels for other code generator, i.e. `Compiler`.
ASMJIT_API Error _registerIndexedLabels(size_t index); ASMJIT_API Error _registerIndexedLabels(size_t index);
//! @internal //! \internal
//! //!
//! Create and initialize a new `Label`. //! Create and initialize a new `Label`.
ASMJIT_API Error _newLabel(Label* dst); ASMJIT_API Error _newLabel(Label* dst);
//! @internal //! \internal
//! //!
//! New LabelLink instance. //! New LabelLink instance.
ASMJIT_API LabelLink* _newLabelLink(); ASMJIT_API LabelLink* _newLabelLink();
@@ -335,7 +380,7 @@ struct BaseAssembler : public CodeGen {
//! Bind label to the current offset. //! Bind label to the current offset.
//! //!
//! @note Label can be bound only once! //! \note Label can be bound only once!
ASMJIT_INLINE void bind(const Label& label) { ASMJIT_INLINE void bind(const Label& label) {
_bind(label); _bind(label);
} }
@@ -356,12 +401,14 @@ struct BaseAssembler : public CodeGen {
//! Typical usage of this is to align labels at start of the inner loops. //! Typical usage of this is to align labels at start of the inner loops.
//! //!
//! Inserts `nop()` instructions or CPU optimized NOPs. //! Inserts `nop()` instructions or CPU optimized NOPs.
ASMJIT_INLINE Error align(uint32_t m) { ASMJIT_INLINE Error align(uint32_t mode, uint32_t offset) {
return _align(m); return _align(mode, offset);
} }
//! Align target buffer to `m` bytes (virtual). //! \internal
virtual Error _align(uint32_t m) = 0; //!
//! Align target buffer to `m` bytes.
virtual Error _align(uint32_t mode, uint32_t offset) = 0;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [Reloc] // [Reloc]
@@ -369,25 +416,25 @@ struct BaseAssembler : public CodeGen {
//! Simplifed version of `relocCode()` method designed for JIT. //! Simplifed version of `relocCode()` method designed for JIT.
//! //!
//! @overload //! \overload
ASMJIT_INLINE size_t relocCode(void* dst) const { ASMJIT_INLINE size_t relocCode(void* dst) const {
return _relocCode(dst, static_cast<Ptr>((uintptr_t)dst)); return _relocCode(dst, static_cast<Ptr>((uintptr_t)dst));
} }
//! Relocate code to a given address `dst`. //! Relocate code to a given address `dst`.
//! //!
//! @param dst Where the relocated code should me stored. The pointer can be //! \param dst Refers the location where the relocated code should be copied.
//! address returned by virtual memory allocator or your own address if you //! The pointer can be address returned by virtual memory allocator or any
//! want only to store the code for later reuse (or load, etc...). //! custom address.
//! @param addressBase Base address used for relocation. When using JIT code
//! generation, this will be the same as `dst`, only casted to system
//! integer type. But when generating code for remote process then the value
//! can be different.
//! //!
//! @retval The bytes used. Code-generator can create trampolines which are //! \param base Base address used for relocation. `JitRuntime` always sets
//! used when calling other functions inside the JIT code. However, these //! `base` address to be the same as `dst`, but other runtimes do not have
//! trampolines can be unused so the relocCode() returns the exact size needed //! to follow this rule.
//! for the function. //!
//! \retval The number bytes used. If the code generator reserved space for
//! possible trampolines, but these weren't generated, the number of bytes
//! used can be actually less than the expected worst case. Virtual memory
//! allocator can in such case return some memory back to the pool.
//! //!
//! A given buffer will be overwritten, to get number of bytes required use //! A given buffer will be overwritten, to get number of bytes required use
//! `getCodeSize()`. //! `getCodeSize()`.
@@ -395,7 +442,9 @@ struct BaseAssembler : public CodeGen {
return _relocCode(dst, base); return _relocCode(dst, base);
} }
//! Reloc code (virtual). //! \internal
//!
//! Reloc code.
virtual size_t _relocCode(void* dst, Ptr base) const = 0; virtual size_t _relocCode(void* dst, Ptr base) const = 0;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -410,24 +459,24 @@ struct BaseAssembler : public CodeGen {
//! Emit an instruction. //! Emit an instruction.
ASMJIT_API Error emit(uint32_t code); ASMJIT_API Error emit(uint32_t code);
//! @overload //! \overload
ASMJIT_API Error emit(uint32_t code, const Operand& o0); ASMJIT_API Error emit(uint32_t code, const Operand& o0);
//! @overload //! \overload
ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1); ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1);
//! @overload //! \overload
ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2); ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2);
//! @overload //! \overload
ASMJIT_INLINE Error emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3) { 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); return _emit(code, o0, o1, o2, o3);
} }
//! Emit an instruction with integer immediate operand. //! Emit an instruction with integer immediate operand.
ASMJIT_API Error emit(uint32_t code, int o0); ASMJIT_API Error emit(uint32_t code, int o0);
//! @overload //! \overload
ASMJIT_API Error emit(uint32_t code, const Operand& o0, int o1); ASMJIT_API Error emit(uint32_t code, const Operand& o0, int o1);
//! @overload //! \overload
ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, int o2); ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, int o2);
//! @overload //! \overload
ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, int o3); ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, int o3);
//! Emit an instruction (virtual). //! Emit an instruction (virtual).
@@ -464,7 +513,7 @@ struct BaseAssembler : public CodeGen {
PodVector<RelocData> _relocData; PodVector<RelocData> _relocData;
}; };
//! @} //! \}
// ============================================================================ // ============================================================================
// [Defined-Later] // [Defined-Later]

View File

@@ -26,8 +26,8 @@ CodeGen::CodeGen(Runtime* runtime) :
_errorHandler(NULL), _errorHandler(NULL),
_arch(kArchNone), _arch(kArchNone),
_regSize(0), _regSize(0),
_features(static_cast<uint8_t>(IntUtil::mask(kCodeGenOptimizedAlign))),
_error(kErrorOk), _error(kErrorOk),
_features(IntUtil::mask(kCodeGenOptimizedAlign)),
_options(0), _options(0),
_baseZone(16384 - sizeof(Zone::Chunk) - kMemAllocOverhead) {} _baseZone(16384 - sizeof(Zone::Chunk) - kMemAllocOverhead) {}

View File

@@ -9,7 +9,6 @@
#define _ASMJIT_BASE_CODEGEN_H #define _ASMJIT_BASE_CODEGEN_H
// [Dependencies - AsmJit] // [Dependencies - AsmJit]
#include "../base/defs.h"
#include "../base/error.h" #include "../base/error.h"
#include "../base/logger.h" #include "../base/logger.h"
#include "../base/runtime.h" #include "../base/runtime.h"
@@ -20,16 +19,16 @@
namespace asmjit { namespace asmjit {
//! @addtogroup asmjit_base_codegen //! \addtogroup asmjit_base_general
//! @{ //! \{
// ============================================================================ // ============================================================================
// [asmjit::kCodeGen] // [asmjit::kCodeGen]
// ============================================================================ // ============================================================================
//! Features of `CodeGen`. //! Features of \ref CodeGen.
ASMJIT_ENUM(kCodeGen) { ASMJIT_ENUM(kCodeGen) {
//! Emit optimized code-alignment sequences. //! Emit optimized code-alignment sequences (true by default).
//! //!
//! X86/X64 //! X86/X64
//! ------- //! -------
@@ -41,11 +40,9 @@ ASMJIT_ENUM(kCodeGen) {
//! for alignment between 1 to 11 bytes. Also when `x86x64::Compiler` is //! for alignment between 1 to 11 bytes. Also when `x86x64::Compiler` is
//! used, it may add rex prefixes into the code to make some instructions //! used, it may add rex prefixes into the code to make some instructions
//! greater so no alignment sequences are needed. //! greater so no alignment sequences are needed.
//!
//! Default true.
kCodeGenOptimizedAlign = 0, kCodeGenOptimizedAlign = 0,
//! Emit jump-prediction hints. //! Emit jump-prediction hints (false by default).
//! //!
//! X86/X64 //! X86/X64
//! ------- //! -------
@@ -57,15 +54,39 @@ ASMJIT_ENUM(kCodeGen) {
//! However this behavior can be overridden by using instruction prefixes. //! However this behavior can be overridden by using instruction prefixes.
//! If this option is enabled these hints will be emitted. //! If this option is enabled these hints will be emitted.
//! //!
//! Default true. //! This feature is disabled by default, because the only processor that
//! used to take into consideration prediction hints was P4 that is not used
//! anymore.
kCodeGenPredictedJumps = 1 kCodeGenPredictedJumps = 1
}; };
// ============================================================================
// [asmjit::kAlignMode]
// ============================================================================
//! Code aligning mode.
ASMJIT_ENUM(kAlignMode) {
kAlignCode = 0,
kAlignData = 1
};
// ============================================================================
// [asmjit::kRelocMode]
// ============================================================================
//! Relocation mode.
ASMJIT_ENUM(kRelocMode) {
kRelocAbsToAbs = 0,
kRelocRelToAbs = 1,
kRelocAbsToRel = 2,
kRelocTrampoline = 3
};
// ============================================================================ // ============================================================================
// [asmjit::CodeGen] // [asmjit::CodeGen]
// ============================================================================ // ============================================================================
//! Abstract class inherited by `Assembler` and `Compiler`. //! Abstract class defining basics of \ref Assembler and \ref BaseCompiler.
struct CodeGen { struct CodeGen {
ASMJIT_NO_COPY(CodeGen) ASMJIT_NO_COPY(CodeGen)
@@ -137,12 +158,17 @@ struct CodeGen {
// [Options] // [Options]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Get options. //! Get options of the next instruction.
ASMJIT_INLINE uint32_t getOptions() const { return _options; } ASMJIT_INLINE uint32_t getOptions() const {
//! Set options. return _options;
ASMJIT_INLINE void setOptions(uint32_t options) { _options = options; } }
//! Get options and clear them. //! Set options of the next instruction.
ASMJIT_INLINE void setOptions(uint32_t options) {
_options = options;
}
//! Get options of the next instruction and clear them.
ASMJIT_INLINE uint32_t getOptionsAndClear() { ASMJIT_INLINE uint32_t getOptionsAndClear() {
uint32_t options = _options; uint32_t options = _options;
_options = 0; _options = 0;
@@ -153,8 +179,8 @@ struct CodeGen {
// [Purge] // [Purge]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Called by `clear()` and `reset()` to clear all data used by the code //! Called by \ref clear() and \ref reset() to clear all data used by the
//! generator. //! code generator.
virtual void _purge() = 0; virtual void _purge() = 0;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -177,17 +203,18 @@ struct CodeGen {
Runtime* _runtime; Runtime* _runtime;
//! Logger. //! Logger.
Logger* _logger; Logger* _logger;
//! Error handler, called by `setError()`. //! Error handler, called by \ref setError().
ErrorHandler* _errorHandler; ErrorHandler* _errorHandler;
//! Target architecture. //! Target architecture.
uint8_t _arch; uint8_t _arch;
//! Get the default register size of the architecture (4 or 8 bytes). //! Target general-purpose register size (4 or 8 bytes).
uint8_t _regSize; uint8_t _regSize;
//! Last error code.
uint8_t _error;
//! Target features. //! Target features.
uint8_t _features; uint8_t _features;
//! Last error code.
uint8_t _error;
//! Options for the next generated instruction (only 8-bits used). //! Options for the next generated instruction (only 8-bits used).
uint32_t _options; uint32_t _options;
@@ -195,7 +222,7 @@ struct CodeGen {
Zone _baseZone; Zone _baseZone;
}; };
//! @} //! \}
} // asmjit namespace } // asmjit namespace

View File

@@ -101,13 +101,13 @@ void BaseCompiler::_purge() {
// [asmjit::BaseCompiler - Node Management] // [asmjit::BaseCompiler - Node Management]
// ============================================================================ // ============================================================================
BaseNode* BaseCompiler::setCursor(BaseNode* node) { Node* BaseCompiler::setCursor(Node* node) {
BaseNode* old = _cursor; Node* old = _cursor;
_cursor = node; _cursor = node;
return old; return old;
} }
BaseNode* BaseCompiler::addNode(BaseNode* node) { Node* BaseCompiler::addNode(Node* node) {
ASMJIT_ASSERT(node != NULL); ASMJIT_ASSERT(node != NULL);
ASMJIT_ASSERT(node->_prev == NULL); ASMJIT_ASSERT(node->_prev == NULL);
ASMJIT_ASSERT(node->_next == NULL); ASMJIT_ASSERT(node->_next == NULL);
@@ -124,8 +124,8 @@ BaseNode* BaseCompiler::addNode(BaseNode* node) {
} }
} }
else { else {
BaseNode* prev = _cursor; Node* prev = _cursor;
BaseNode* next = _cursor->_next; Node* next = _cursor->_next;
node->_prev = prev; node->_prev = prev;
node->_next = next; node->_next = next;
@@ -141,14 +141,14 @@ BaseNode* BaseCompiler::addNode(BaseNode* node) {
return node; return node;
} }
BaseNode* BaseCompiler::addNodeBefore(BaseNode* node, BaseNode* ref) { Node* BaseCompiler::addNodeBefore(Node* node, Node* ref) {
ASMJIT_ASSERT(node != NULL); ASMJIT_ASSERT(node != NULL);
ASMJIT_ASSERT(node->_prev == NULL); ASMJIT_ASSERT(node->_prev == NULL);
ASMJIT_ASSERT(node->_next == NULL); ASMJIT_ASSERT(node->_next == NULL);
ASMJIT_ASSERT(ref != NULL); ASMJIT_ASSERT(ref != NULL);
BaseNode* prev = ref->_prev; Node* prev = ref->_prev;
BaseNode* next = ref; Node* next = ref;
node->_prev = prev; node->_prev = prev;
node->_next = next; node->_next = next;
@@ -162,14 +162,14 @@ BaseNode* BaseCompiler::addNodeBefore(BaseNode* node, BaseNode* ref) {
return node; return node;
} }
BaseNode* BaseCompiler::addNodeAfter(BaseNode* node, BaseNode* ref) { Node* BaseCompiler::addNodeAfter(Node* node, Node* ref) {
ASMJIT_ASSERT(node != NULL); ASMJIT_ASSERT(node != NULL);
ASMJIT_ASSERT(node->_prev == NULL); ASMJIT_ASSERT(node->_prev == NULL);
ASMJIT_ASSERT(node->_next == NULL); ASMJIT_ASSERT(node->_next == NULL);
ASMJIT_ASSERT(ref != NULL); ASMJIT_ASSERT(ref != NULL);
BaseNode* prev = ref; Node* prev = ref;
BaseNode* next = ref->_next; Node* next = ref->_next;
node->_prev = prev; node->_prev = prev;
node->_next = next; node->_next = next;
@@ -183,7 +183,7 @@ BaseNode* BaseCompiler::addNodeAfter(BaseNode* node, BaseNode* ref) {
return node; return node;
} }
static ASMJIT_INLINE void BaseCompiler_nodeRemoved(BaseCompiler* self, BaseNode* node_) { static ASMJIT_INLINE void BaseCompiler_nodeRemoved(BaseCompiler* self, Node* node_) {
if (node_->isJmpOrJcc()) { if (node_->isJmpOrJcc()) {
JumpNode* node = static_cast<JumpNode*>(node_); JumpNode* node = static_cast<JumpNode*>(node_);
TargetNode* target = node->getTarget(); TargetNode* target = node->getTarget();
@@ -209,9 +209,9 @@ static ASMJIT_INLINE void BaseCompiler_nodeRemoved(BaseCompiler* self, BaseNode*
} }
} }
BaseNode* BaseCompiler::removeNode(BaseNode* node) { Node* BaseCompiler::removeNode(Node* node) {
BaseNode* prev = node->_prev; Node* prev = node->_prev;
BaseNode* next = node->_next; Node* next = node->_next;
if (_firstNode == node) if (_firstNode == node)
_firstNode = next; _firstNode = next;
@@ -233,14 +233,14 @@ BaseNode* BaseCompiler::removeNode(BaseNode* node) {
return node; return node;
} }
void BaseCompiler::removeNodes(BaseNode* first, BaseNode* last) { void BaseCompiler::removeNodes(Node* first, Node* last) {
if (first == last) { if (first == last) {
removeNode(first); removeNode(first);
return; return;
} }
BaseNode* prev = first->_prev; Node* prev = first->_prev;
BaseNode* next = last->_next; Node* next = last->_next;
if (_firstNode == first) if (_firstNode == first)
_firstNode = next; _firstNode = next;
@@ -252,9 +252,9 @@ void BaseCompiler::removeNodes(BaseNode* first, BaseNode* last) {
else else
next->_prev = prev; next->_prev = prev;
BaseNode* node = first; Node* node = first;
for (;;) { for (;;) {
BaseNode* next = node->getNext(); Node* next = node->getNext();
ASMJIT_ASSERT(next != NULL); ASMJIT_ASSERT(next != NULL);
node->_prev = NULL; node->_prev = NULL;
@@ -274,8 +274,8 @@ void BaseCompiler::removeNodes(BaseNode* first, BaseNode* last) {
// [asmjit::BaseCompiler - Align] // [asmjit::BaseCompiler - Align]
// ============================================================================ // ============================================================================
AlignNode* BaseCompiler::newAlign(uint32_t m) { AlignNode* BaseCompiler::newAlign(uint32_t mode, uint32_t offset) {
AlignNode* node = newNode<AlignNode>(m); AlignNode* node = newNode<AlignNode>(mode, offset);
if (node == NULL) if (node == NULL)
goto _NoMemory; goto _NoMemory;
return node; return node;
@@ -285,8 +285,8 @@ _NoMemory:
return NULL; return NULL;
} }
AlignNode* BaseCompiler::addAlign(uint32_t m) { AlignNode* BaseCompiler::addAlign(uint32_t mode, uint32_t offset) {
AlignNode* node = newAlign(m); AlignNode* node = newAlign(mode, offset);
if (node == NULL) if (node == NULL)
return NULL; return NULL;
return static_cast<AlignNode*>(addNode(node)); return static_cast<AlignNode*>(addNode(node));

View File

@@ -12,10 +12,10 @@
#include "../base/assembler.h" #include "../base/assembler.h"
#include "../base/codegen.h" #include "../base/codegen.h"
#include "../base/constpool.h" #include "../base/constpool.h"
#include "../base/defs.h"
#include "../base/error.h" #include "../base/error.h"
#include "../base/func.h" #include "../base/func.h"
#include "../base/intutil.h" #include "../base/intutil.h"
#include "../base/operand.h"
#include "../base/podlist.h" #include "../base/podlist.h"
#include "../base/podvector.h" #include "../base/podvector.h"
#include "../base/runtime.h" #include "../base/runtime.h"
@@ -26,9 +26,6 @@
namespace asmjit { namespace asmjit {
//! @addtogroup asmjit_base_codegen
//! @{
// ============================================================================ // ============================================================================
// [Forward Declarations] // [Forward Declarations]
// ============================================================================ // ============================================================================
@@ -40,7 +37,7 @@ struct VarData;
struct BaseVarInst; struct BaseVarInst;
struct BaseVarState; struct BaseVarState;
struct BaseNode; struct Node;
struct EndNode; struct EndNode;
struct InstNode; struct InstNode;
struct JumpNode; struct JumpNode;
@@ -49,6 +46,9 @@ struct JumpNode;
// [asmjit::kConstScope] // [asmjit::kConstScope]
// ============================================================================ // ============================================================================
//! \addtogroup asmjit_base_general
//! \{
//! Scope of the constant. //! Scope of the constant.
ASMJIT_ENUM(kConstScope) { ASMJIT_ENUM(kConstScope) {
//! Local constant, always embedded right after the current function. //! Local constant, always embedded right after the current function.
@@ -57,10 +57,15 @@ ASMJIT_ENUM(kConstScope) {
kConstScopeGlobal = 1 kConstScopeGlobal = 1
}; };
//! \}
// ============================================================================ // ============================================================================
// [asmjit::kVarAttrFlags] // [asmjit::kVarAttrFlags]
// ============================================================================ // ============================================================================
//! \addtogroup asmjit_base_tree
//! \{
//! Variable attribute flags. //! Variable attribute flags.
ASMJIT_ENUM(kVarAttrFlags) { ASMJIT_ENUM(kVarAttrFlags) {
//! Variable is accessed through register on input. //! Variable is accessed through register on input.
@@ -101,6 +106,9 @@ ASMJIT_ENUM(kVarAttrFlags) {
//! Variable should be unused at the end of the instruction/node. //! Variable should be unused at the end of the instruction/node.
kVarAttrUnuse = 0x00000800, kVarAttrUnuse = 0x00000800,
//! \internal
//!
//! All in-flags.
kVarAttrInAll = kVarAttrInAll =
kVarAttrInReg | kVarAttrInReg |
kVarAttrInMem | kVarAttrInMem |
@@ -108,6 +116,9 @@ ASMJIT_ENUM(kVarAttrFlags) {
kVarAttrInCall | kVarAttrInCall |
kVarAttrInArg, kVarAttrInArg,
//! \internal
//!
//! All out-flags.
kVarAttrOutAll = kVarAttrOutAll =
kVarAttrOutReg | kVarAttrOutReg |
kVarAttrOutMem | kVarAttrOutMem |
@@ -146,7 +157,7 @@ ASMJIT_ENUM(kVarHint) {
//! State of variable. //! State of variable.
//! //!
//! @note State of variable is used only during make process and it's not //! \note State of variable is used only during make process and it's not
//! visible to the developer. //! visible to the developer.
ASMJIT_ENUM(kVarState) { ASMJIT_ENUM(kVarState) {
//! Variable is currently not used. //! Variable is currently not used.
@@ -168,31 +179,31 @@ ASMJIT_ENUM(kVarState) {
// [asmjit::kNodeType] // [asmjit::kNodeType]
// ============================================================================ // ============================================================================
//! Type of node (see `BaseNode)`. //! Type of node, see \ref Node.
ASMJIT_ENUM(kNodeType) { ASMJIT_ENUM(kNodeType) {
//! Invalid node (internal, can't be used). //! Invalid node (internal, can't be used).
kNodeTypeNone = 0, kNodeTypeNone = 0,
//! Node is an .align directive, see `AlignNode`. //! Node is an .align directive, see \ref AlignNode.
kNodeTypeAlign, kNodeTypeAlign,
//! Node is an embedded data, see `EmbedNode`. //! Node is an embedded data, see \ref EmbedNode.
kNodeTypeEmbed, kNodeTypeEmbed,
//! Node is a comment, see `CommentNode`. //! Node is a comment, see \ref CommentNode.
kNodeTypeComment, kNodeTypeComment,
//! Node is a variable hint (alloc, spill, use, unuse), see `HintNode`. //! Node is a variable hint (alloc, spill, use, unuse), see \ref HintNode.
kNodeTypeHint, kNodeTypeHint,
//! Node is a label, see `TargetNode`. //! Node is a label, see \ref TargetNode.
kNodeTypeTarget, kNodeTypeTarget,
//! Node is an instruction, see `InstNode`. //! Node is an instruction, see \ref InstNode.
kNodeTypeInst, kNodeTypeInst,
//! Node is a function declaration, see `FuncNode`. //! Node is a function declaration, see \ref FuncNode.
kNodeTypeFunc, kNodeTypeFunc,
//! Node is an end of the function, see `EndNode`. //! Node is an end of the function, see \ref EndNode.
kNodeTypeEnd, kNodeTypeEnd,
//! Node is a return, see `RetNode`. //! Node is a return, see \ref RetNode.
kNodeTypeRet, kNodeTypeRet,
//! Node is a function call, see `CallNode`. //! Node is a function call, see \ref CallNode.
kNodeTypeCall, kNodeTypeCall,
//! Node is a function call argument moved on stack, see `SArgNode`. //! Node is a function call argument moved on stack, see \ref SArgNode.
kNodeTypeSArg kNodeTypeSArg
}; };
@@ -225,10 +236,15 @@ ASMJIT_ENUM(kNodeFlag) {
kNodeFlagIsFp = 0x0040 kNodeFlagIsFp = 0x0040
}; };
//! \}
// ============================================================================ // ============================================================================
// [asmjit::MemCell] // [asmjit::MemCell]
// ============================================================================ // ============================================================================
//! \addtogroup asmjit_base_tree
//! \{
struct MemCell { struct MemCell {
ASMJIT_NO_COPY(MemCell) ASMJIT_NO_COPY(MemCell)
@@ -507,7 +523,7 @@ struct VarData {
uint8_t _saveOnUnuse : 1; uint8_t _saveOnUnuse : 1;
//! Whether variable was changed (connected with actual `BaseVarState)`. //! Whether variable was changed (connected with actual `BaseVarState)`.
uint8_t _modified : 1; uint8_t _modified : 1;
//! @internal //! \internal
uint8_t _reserved0 : 3; uint8_t _reserved0 : 3;
//! Variable natural alignment. //! Variable natural alignment.
uint8_t _alignment; uint8_t _alignment;
@@ -547,7 +563,9 @@ struct VarData {
//! back to zero/null. Initial value is NULL. //! back to zero/null. Initial value is NULL.
VarAttr* _va; VarAttr* _va;
//! @internal //! \internal
//!
//! Same as `_va` just provided as `uintptr_t`.
uintptr_t _vaUInt; uintptr_t _vaUInt;
}; };
}; };
@@ -677,11 +695,11 @@ struct VarAttr {
//! //!
//! Typically `kInvalidReg` if variable is only used on input. //! Typically `kInvalidReg` if variable is only used on input.
uint8_t _outRegIndex; uint8_t _outRegIndex;
//! @internal //! \internal
uint8_t _reserved; uint8_t _reserved;
}; };
//! @internal //! \internal
//! //!
//! Packed data #0. //! Packed data #0.
uint32_t _packed; uint32_t _packed;
@@ -721,36 +739,36 @@ struct BaseVarInst {};
struct BaseVarState {}; struct BaseVarState {};
// ============================================================================ // ============================================================================
// [asmjit::BaseNode] // [asmjit::Node]
// ============================================================================ // ============================================================================
//! Base node. //! Base node.
//! //!
//! `Every` node represents an abstract instruction, directive, label, or //! `Every` node represents an abstract instruction, directive, label, or
//! macro-instruction generated by compiler. //! macro-instruction generated by compiler.
struct BaseNode { struct Node {
ASMJIT_NO_COPY(BaseNode) ASMJIT_NO_COPY(Node)
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [Construction / Destruction] // [Construction / Destruction]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Create new `BaseNode`. //! Create new `Node`.
//! //!
//! @note Always use compiler to create nodes. //! \note Always use compiler to create nodes.
ASMJIT_INLINE BaseNode(BaseCompiler* compiler, uint32_t type); // Defined-Later. ASMJIT_INLINE Node(BaseCompiler* compiler, uint32_t type); // Defined-Later.
//! Destroy `BaseNode`. //! Destroy `Node`.
ASMJIT_INLINE ~BaseNode() {} ASMJIT_INLINE ~Node() {}
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [Accessors] // [Accessors]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Get previous node in the compiler stream. //! Get previous node in the compiler stream.
ASMJIT_INLINE BaseNode* getPrev() const { return _prev; } ASMJIT_INLINE Node* getPrev() const { return _prev; }
//! Get next node in the compiler stream. //! Get next node in the compiler stream.
ASMJIT_INLINE BaseNode* getNext() const { return _next; } ASMJIT_INLINE Node* getNext() const { return _next; }
//! Get comment string. //! Get comment string.
ASMJIT_INLINE const char* getComment() const { return _comment; } ASMJIT_INLINE const char* getComment() const { return _comment; }
@@ -827,9 +845,9 @@ struct BaseNode {
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Previous node. //! Previous node.
BaseNode* _prev; Node* _prev;
//! Next node. //! Next node.
BaseNode* _next; Node* _next;
//! Node type, see `kNodeType`. //! Node type, see `kNodeType`.
uint8_t _type; uint8_t _type;
@@ -863,7 +881,7 @@ struct BaseNode {
// ============================================================================ // ============================================================================
//! Align node. //! Align node.
struct AlignNode : public BaseNode { struct AlignNode : public Node {
ASMJIT_NO_COPY(AlignNode) ASMJIT_NO_COPY(AlignNode)
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -871,8 +889,11 @@ struct AlignNode : public BaseNode {
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Create a new `AlignNode` instance. //! Create a new `AlignNode` instance.
ASMJIT_INLINE AlignNode(BaseCompiler* compiler, uint32_t size) : BaseNode(compiler, kNodeTypeAlign) { ASMJIT_INLINE AlignNode(BaseCompiler* compiler, uint32_t mode, uint32_t offset) :
_size = size; Node(compiler, kNodeTypeAlign) {
_mode = mode;
_offset = offset;
} }
//! Destroy the `AlignNode` instance. //! Destroy the `AlignNode` instance.
@@ -882,17 +903,34 @@ struct AlignNode : public BaseNode {
// [Accessors] // [Accessors]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Get align size in bytes. //! Get alignment mode.
ASMJIT_INLINE uint32_t getSize() const { return _size; } ASMJIT_INLINE uint32_t getMode() const {
//! Set align size in bytes to `size`. return _mode;
ASMJIT_INLINE void setSize(uint32_t size) { _size = size; } }
//! 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] // [Members]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Size of the alignment. //! Alignment mode, see \ref kAlignMode.
uint32_t _size; uint32_t _mode;
//! Alignment offset in bytes.
uint32_t _offset;
}; };
// ============================================================================ // ============================================================================
@@ -903,7 +941,7 @@ struct AlignNode : public BaseNode {
//! //!
//! Embed node is used to embed data into final assembler stream. The data is //! 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. //! considered to be RAW; No analysis is performed on RAW data.
struct EmbedNode : public BaseNode { struct EmbedNode : public Node {
ASMJIT_NO_COPY(EmbedNode) ASMJIT_NO_COPY(EmbedNode)
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -917,7 +955,7 @@ struct EmbedNode : public BaseNode {
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Create a new `EmbedNode` instance. //! Create a new `EmbedNode` instance.
ASMJIT_INLINE EmbedNode(BaseCompiler* compiler, void* data, uint32_t size) : BaseNode(compiler, kNodeTypeEmbed) { ASMJIT_INLINE EmbedNode(BaseCompiler* compiler, void* data, uint32_t size) : Node(compiler, kNodeTypeEmbed) {
_size = size; _size = size;
if (size <= kInlineBufferSize) { if (size <= kInlineBufferSize) {
if (data != NULL) if (data != NULL)
@@ -964,7 +1002,7 @@ struct EmbedNode : public BaseNode {
//! Comments allows to comment your assembler stream for better debugging //! Comments allows to comment your assembler stream for better debugging
//! and visualization. Comments are usually ignored in release builds unless //! and visualization. Comments are usually ignored in release builds unless
//! the logger is present. //! the logger is present.
struct CommentNode : public BaseNode { struct CommentNode : public Node {
ASMJIT_NO_COPY(CommentNode) ASMJIT_NO_COPY(CommentNode)
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -972,7 +1010,7 @@ struct CommentNode : public BaseNode {
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Create a new `CommentNode` instance. //! Create a new `CommentNode` instance.
ASMJIT_INLINE CommentNode(BaseCompiler* compiler, const char* comment) : BaseNode(compiler, kNodeTypeComment) { ASMJIT_INLINE CommentNode(BaseCompiler* compiler, const char* comment) : Node(compiler, kNodeTypeComment) {
_comment = comment; _comment = comment;
} }
@@ -985,7 +1023,7 @@ struct CommentNode : public BaseNode {
// ============================================================================ // ============================================================================
//! Hint node. //! Hint node.
struct HintNode : public BaseNode { struct HintNode : public Node {
ASMJIT_NO_COPY(HintNode) ASMJIT_NO_COPY(HintNode)
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -993,7 +1031,7 @@ struct HintNode : public BaseNode {
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Create a new `HintNode` instance. //! Create a new `HintNode` instance.
ASMJIT_INLINE HintNode(BaseCompiler* compiler, VarData* vd, uint32_t hint, uint32_t value) : BaseNode(compiler, kNodeTypeHint) { ASMJIT_INLINE HintNode(BaseCompiler* compiler, VarData* vd, uint32_t hint, uint32_t value) : Node(compiler, kNodeTypeHint) {
_vd = vd; _vd = vd;
_hint = hint; _hint = hint;
_value = value; _value = value;
@@ -1036,7 +1074,7 @@ struct HintNode : public BaseNode {
// ============================================================================ // ============================================================================
//! label node. //! label node.
struct TargetNode : public BaseNode { struct TargetNode : public Node {
ASMJIT_NO_COPY(TargetNode) ASMJIT_NO_COPY(TargetNode)
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -1044,7 +1082,7 @@ struct TargetNode : public BaseNode {
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Create a new `TargetNode` instance. //! Create a new `TargetNode` instance.
ASMJIT_INLINE TargetNode(BaseCompiler* compiler, uint32_t labelId) : BaseNode(compiler, kNodeTypeTarget) { ASMJIT_INLINE TargetNode(BaseCompiler* compiler, uint32_t labelId) : Node(compiler, kNodeTypeTarget) {
_id = labelId; _id = labelId;
_numRefs = 0; _numRefs = 0;
_from = NULL; _from = NULL;
@@ -1100,7 +1138,7 @@ struct TargetNode : public BaseNode {
// ============================================================================ // ============================================================================
//! Instruction node. //! Instruction node.
struct InstNode : public BaseNode { struct InstNode : public Node {
ASMJIT_NO_COPY(InstNode) ASMJIT_NO_COPY(InstNode)
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -1108,7 +1146,7 @@ struct InstNode : public BaseNode {
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Create a new `InstNode` instance. //! Create a new `InstNode` instance.
ASMJIT_INLINE InstNode(BaseCompiler* compiler, uint32_t code, uint32_t options, Operand* opList, uint32_t opCount) : BaseNode(compiler, kNodeTypeInst) { ASMJIT_INLINE InstNode(BaseCompiler* compiler, uint32_t code, uint32_t options, Operand* opList, uint32_t opCount) : Node(compiler, kNodeTypeInst) {
_code = static_cast<uint16_t>(code); _code = static_cast<uint16_t>(code);
_options = static_cast<uint8_t>(options); _options = static_cast<uint8_t>(options);
@@ -1170,7 +1208,7 @@ struct InstNode : public BaseNode {
ASMJIT_INLINE Operand* getOpList() { ASMJIT_INLINE Operand* getOpList() {
return _opList; return _opList;
} }
//! @overload //! \overload
ASMJIT_INLINE const Operand* getOpList() const { ASMJIT_INLINE const Operand* getOpList() const {
return _opList; return _opList;
} }
@@ -1203,7 +1241,7 @@ struct InstNode : public BaseNode {
return static_cast<BaseMem*>(&_opList[_memOpIndex]); return static_cast<BaseMem*>(&_opList[_memOpIndex]);
} }
//! @overload //! \overload
template<typename T> template<typename T>
ASMJIT_INLINE T* getMemOp() const { ASMJIT_INLINE T* getMemOp() const {
ASMJIT_ASSERT(hasMemOp()); ASMJIT_ASSERT(hasMemOp());
@@ -1236,7 +1274,7 @@ _Update:
uint16_t _code; uint16_t _code;
//! Instruction options, see `kInstOptions`. //! Instruction options, see `kInstOptions`.
uint8_t _options; uint8_t _options;
//! @internal //! \internal
uint8_t _memOpIndex; uint8_t _memOpIndex;
//! Operands list. //! Operands list.
@@ -1289,7 +1327,7 @@ struct JumpNode : public InstNode {
//! `FuncNode` can be used to generate function prolog and epilog which are //! `FuncNode` can be used to generate function prolog and epilog which are
//! compatible with a given function calling convention and to allocate and //! compatible with a given function calling convention and to allocate and
//! manage variables that can be allocated/spilled during compilation phase. //! manage variables that can be allocated/spilled during compilation phase.
struct FuncNode : public BaseNode { struct FuncNode : public Node {
ASMJIT_NO_COPY(FuncNode) ASMJIT_NO_COPY(FuncNode)
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -1300,7 +1338,7 @@ struct FuncNode : public BaseNode {
//! //!
//! Always use `BaseCompiler::addFunc()` to create a `FuncNode` instance. //! Always use `BaseCompiler::addFunc()` to create a `FuncNode` instance.
ASMJIT_INLINE FuncNode(BaseCompiler* compiler) : ASMJIT_INLINE FuncNode(BaseCompiler* compiler) :
BaseNode(compiler, kNodeTypeFunc), Node(compiler, kNodeTypeFunc),
_entryNode(NULL), _entryNode(NULL),
_exitNode(NULL), _exitNode(NULL),
_decl(NULL), _decl(NULL),
@@ -1472,7 +1510,7 @@ struct FuncNode : public BaseNode {
//! Expected stack alignment (we depend on this value). //! Expected stack alignment (we depend on this value).
//! //!
//! @note It can be global alignment given by the OS or described by an //! \note It can be global alignment given by the OS or described by an
//! target platform ABI. //! target platform ABI.
uint32_t _expectedStackAlignment; uint32_t _expectedStackAlignment;
//! Required stack alignment (usually for multimedia instructions). //! Required stack alignment (usually for multimedia instructions).
@@ -1498,7 +1536,7 @@ struct FuncNode : public BaseNode {
// ============================================================================ // ============================================================================
//! End of function/block node. //! End of function/block node.
struct EndNode : public BaseNode { struct EndNode : public Node {
ASMJIT_NO_COPY(EndNode) ASMJIT_NO_COPY(EndNode)
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -1506,7 +1544,7 @@ struct EndNode : public BaseNode {
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Create a new `EndNode` instance. //! Create a new `EndNode` instance.
ASMJIT_INLINE EndNode(BaseCompiler* compiler) : BaseNode(compiler, kNodeTypeEnd) { ASMJIT_INLINE EndNode(BaseCompiler* compiler) : Node(compiler, kNodeTypeEnd) {
_flags |= kNodeFlagIsRet; _flags |= kNodeFlagIsRet;
} }
@@ -1519,7 +1557,7 @@ struct EndNode : public BaseNode {
// ============================================================================ // ============================================================================
//! Function return node. //! Function return node.
struct RetNode : public BaseNode { struct RetNode : public Node {
ASMJIT_NO_COPY(RetNode) ASMJIT_NO_COPY(RetNode)
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -1527,7 +1565,7 @@ struct RetNode : public BaseNode {
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Create a new `RetNode` instance. //! Create a new `RetNode` instance.
ASMJIT_INLINE RetNode(BaseCompiler* compiler, const Operand& o0, const Operand& o1) : BaseNode(compiler, kNodeTypeRet) { ASMJIT_INLINE RetNode(BaseCompiler* compiler, const Operand& o0, const Operand& o1) : Node(compiler, kNodeTypeRet) {
_flags |= kNodeFlagIsRet; _flags |= kNodeFlagIsRet;
_ret[0] = o0; _ret[0] = o0;
_ret[1] = o1; _ret[1] = o1;
@@ -1542,12 +1580,12 @@ struct RetNode : public BaseNode {
//! Get the first return operand. //! Get the first return operand.
ASMJIT_INLINE Operand& getFirst() { return _ret[0]; } ASMJIT_INLINE Operand& getFirst() { return _ret[0]; }
//! @overload //! \overload
ASMJIT_INLINE const Operand& getFirst() const { return _ret[0]; } ASMJIT_INLINE const Operand& getFirst() const { return _ret[0]; }
//! Get the second return operand. //! Get the second return operand.
ASMJIT_INLINE Operand& getSecond() { return _ret[1]; } ASMJIT_INLINE Operand& getSecond() { return _ret[1]; }
//! @overload //! \overload
ASMJIT_INLINE const Operand& getSecond() const { return _ret[1]; } ASMJIT_INLINE const Operand& getSecond() const { return _ret[1]; }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -1563,7 +1601,7 @@ struct RetNode : public BaseNode {
// ============================================================================ // ============================================================================
//! Function-call node. //! Function-call node.
struct CallNode : public BaseNode { struct CallNode : public Node {
ASMJIT_NO_COPY(CallNode) ASMJIT_NO_COPY(CallNode)
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -1572,7 +1610,7 @@ struct CallNode : public BaseNode {
//! Create a new `CallNode` instance. //! Create a new `CallNode` instance.
ASMJIT_INLINE CallNode(BaseCompiler* compiler, const Operand& target) : ASMJIT_INLINE CallNode(BaseCompiler* compiler, const Operand& target) :
BaseNode(compiler, kNodeTypeCall), Node(compiler, kNodeTypeCall),
_decl(NULL), _decl(NULL),
_target(target), _target(target),
_args(NULL) {} _args(NULL) {}
@@ -1589,7 +1627,7 @@ struct CallNode : public BaseNode {
//! Get target operand. //! Get target operand.
ASMJIT_INLINE Operand& getTarget() { return _target; } ASMJIT_INLINE Operand& getTarget() { return _target; }
//! @overload //! \overload
ASMJIT_INLINE const Operand& getTarget() const { return _target; } ASMJIT_INLINE const Operand& getTarget() const { return _target; }
//! Get return at `i`. //! Get return at `i`.
@@ -1597,7 +1635,7 @@ struct CallNode : public BaseNode {
ASMJIT_ASSERT(i < 2); ASMJIT_ASSERT(i < 2);
return _ret[i]; return _ret[i];
} }
//! @overload //! \overload
ASMJIT_INLINE const Operand& getRet(uint32_t i = 0) const { ASMJIT_INLINE const Operand& getRet(uint32_t i = 0) const {
ASMJIT_ASSERT(i < 2); ASMJIT_ASSERT(i < 2);
return _ret[i]; return _ret[i];
@@ -1608,7 +1646,7 @@ struct CallNode : public BaseNode {
ASMJIT_ASSERT(i < kFuncArgCountLoHi); ASMJIT_ASSERT(i < kFuncArgCountLoHi);
return _args[i]; return _args[i];
} }
//! @overload //! \overload
ASMJIT_INLINE const Operand& getArg(uint32_t i) const { ASMJIT_INLINE const Operand& getArg(uint32_t i) const {
ASMJIT_ASSERT(i < kFuncArgCountLoHi); ASMJIT_ASSERT(i < kFuncArgCountLoHi);
return _args[i]; return _args[i];
@@ -1634,7 +1672,7 @@ struct CallNode : public BaseNode {
// ============================================================================ // ============================================================================
//! Function-call 'argument on the stack' node. //! Function-call 'argument on the stack' node.
struct SArgNode : public BaseNode { struct SArgNode : public Node {
ASMJIT_NO_COPY(SArgNode) ASMJIT_NO_COPY(SArgNode)
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -1643,7 +1681,7 @@ struct SArgNode : public BaseNode {
//! Create a new `SArgNode` instance. //! Create a new `SArgNode` instance.
ASMJIT_INLINE SArgNode(BaseCompiler* compiler, CallNode* call, VarData* sVd, VarData* cVd) : ASMJIT_INLINE SArgNode(BaseCompiler* compiler, CallNode* call, VarData* sVd, VarData* cVd) :
BaseNode(compiler, kNodeTypeSArg), Node(compiler, kNodeTypeSArg),
_call(call), _call(call),
_sVd(sVd), _sVd(sVd),
_cVd(cVd), _cVd(cVd),
@@ -1678,10 +1716,15 @@ struct SArgNode : public BaseNode {
uint32_t _args; uint32_t _args;
}; };
//! \}
// ============================================================================ // ============================================================================
// [asmjit::BaseCompiler] // [asmjit::BaseCompiler]
// ============================================================================ // ============================================================================
//! \addtogroup asmjit_base_general
//! \{
//! Base compiler. //! Base compiler.
//! //!
//! @sa BaseAssembler. //! @sa BaseAssembler.
@@ -1712,11 +1755,11 @@ struct BaseCompiler : public CodeGen {
//! Clear everything, but keep buffers allocated. //! Clear everything, but keep buffers allocated.
//! //!
//! @note This method will destroy your code. //! \note This method will destroy your code.
ASMJIT_API void clear(); ASMJIT_API void clear();
//! Clear everything and reset all buffers. //! Clear everything and reset all buffers.
//! //!
//! @note This method will destroy your code. //! \note This method will destroy your code.
ASMJIT_API void reset(); ASMJIT_API void reset();
//! Called by clear() and reset() to clear all data related to derived //! Called by clear() and reset() to clear all data related to derived
//! class implementation. //! class implementation.
@@ -1751,30 +1794,30 @@ struct BaseCompiler : public CodeGen {
} }
//! Get first node. //! Get first node.
ASMJIT_INLINE BaseNode* getFirstNode() const { return _firstNode; } ASMJIT_INLINE Node* getFirstNode() const { return _firstNode; }
//! Get last node. //! Get last node.
ASMJIT_INLINE BaseNode* getLastNode() const { return _lastNode; } ASMJIT_INLINE Node* getLastNode() const { return _lastNode; }
//! Get current node. //! Get current node.
//! //!
//! @note If this method returns `NULL` it means that nothing has been emitted //! \note If this method returns `NULL` it means that nothing has been emitted
//! yet. //! yet.
ASMJIT_INLINE BaseNode* getCursor() const { return _cursor; } ASMJIT_INLINE Node* getCursor() const { return _cursor; }
//! Set the current node without returning the previous node (private). //! Set the current node without returning the previous node (private).
ASMJIT_INLINE void _setCursor(BaseNode* node) { _cursor = node; } ASMJIT_INLINE void _setCursor(Node* node) { _cursor = node; }
//! Set the current node to `node` and return the previous one. //! Set the current node to `node` and return the previous one.
ASMJIT_API BaseNode* setCursor(BaseNode* node); ASMJIT_API Node* setCursor(Node* node);
//! Add node `node` after current and set current to `node`. //! Add node `node` after current and set current to `node`.
ASMJIT_API BaseNode* addNode(BaseNode* node); ASMJIT_API Node* addNode(Node* node);
//! Add node before `ref`. //! Add node before `ref`.
ASMJIT_API BaseNode* addNodeBefore(BaseNode* node, BaseNode* ref); ASMJIT_API Node* addNodeBefore(Node* node, Node* ref);
//! Add node after `ref`. //! Add node after `ref`.
ASMJIT_API BaseNode* addNodeAfter(BaseNode* node, BaseNode* ref); ASMJIT_API Node* addNodeAfter(Node* node, Node* ref);
//! Remove node `node`. //! Remove node `node`.
ASMJIT_API BaseNode* removeNode(BaseNode* node); ASMJIT_API Node* removeNode(Node* node);
//! Remove multiple nodes. //! Remove multiple nodes.
ASMJIT_API void removeNodes(BaseNode* first, BaseNode* last); ASMJIT_API void removeNodes(Node* first, Node* last);
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [Func] // [Func]
@@ -1788,16 +1831,18 @@ struct BaseCompiler : public CodeGen {
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Create a new `AlignNode`. //! Create a new `AlignNode`.
ASMJIT_API AlignNode* newAlign(uint32_t m); ASMJIT_API AlignNode* newAlign(uint32_t mode, uint32_t offset);
//! Add a new `AlignNode`. //! Add a new `AlignNode`.
ASMJIT_API AlignNode* addAlign(uint32_t m); ASMJIT_API AlignNode* addAlign(uint32_t mode, uint32_t offset);
//! Align target buffer to `m` bytes. //! Align target buffer to `m` bytes.
//! //!
//! Typical usage of this is to align labels at start of the inner loops. //! Typical usage of this is to align labels at start of the inner loops.
//! //!
//! Inserts `nop()` instructions or CPU optimized NOPs. //! Inserts `nop()` instructions or CPU optimized NOPs.
ASMJIT_INLINE AlignNode* align(uint32_t m) { return addAlign(m); } ASMJIT_INLINE AlignNode* align(uint32_t mode, uint32_t offset) {
return addAlign(mode, offset);
}
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [Target] // [Target]
@@ -1826,14 +1871,16 @@ struct BaseCompiler : public CodeGen {
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Get count of created labels. //! Get count of created labels.
ASMJIT_INLINE size_t getLabelsCount() const ASMJIT_INLINE size_t getLabelsCount() const {
{ return _targets.getLength(); } return _targets.getLength();
}
//! Get whether `label` is created. //! Get whether `label` is created.
ASMJIT_INLINE bool isLabelCreated(const Label& label) const ASMJIT_INLINE bool isLabelCreated(const Label& label) const {
{ return static_cast<size_t>(label.getId()) < _targets.getLength(); } return static_cast<size_t>(label.getId()) < _targets.getLength();
}
//! @internal //! \internal
//! //!
//! Create and initialize a new `Label`. //! Create and initialize a new `Label`.
ASMJIT_API Error _newLabel(Label* dst); ASMJIT_API Error _newLabel(Label* dst);
@@ -1847,7 +1894,7 @@ struct BaseCompiler : public CodeGen {
//! Bind label to the current offset. //! Bind label to the current offset.
//! //!
//! @note Label can be bound only once! //! \note Label can be bound only once!
ASMJIT_API void bind(const Label& label); ASMJIT_API void bind(const Label& label);
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -1860,7 +1907,9 @@ struct BaseCompiler : public CodeGen {
ASMJIT_API EmbedNode* addEmbed(const void* data, uint32_t size); ASMJIT_API EmbedNode* addEmbed(const void* data, uint32_t size);
//! Embed data. //! Embed data.
ASMJIT_INLINE EmbedNode* embed(const void* data, uint32_t size) { return addEmbed(data, size); } ASMJIT_INLINE EmbedNode* embed(const void* data, uint32_t size) {
return addEmbed(data, size);
}
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [Comment] // [Comment]
@@ -1892,14 +1941,14 @@ struct BaseCompiler : public CodeGen {
return static_cast<size_t>(var.getId() & kOperandIdNum) < _vars.getLength(); return static_cast<size_t>(var.getId() & kOperandIdNum) < _vars.getLength();
} }
//! @internal //! \internal
//! //!
//! Get `VarData` by `var`. //! Get `VarData` by `var`.
ASMJIT_INLINE VarData* getVd(const BaseVar& var) const { ASMJIT_INLINE VarData* getVd(const BaseVar& var) const {
return getVdById(var.getId()); return getVdById(var.getId());
} }
//! @internal //! \internal
//! //!
//! Get `VarData` by `id`. //! Get `VarData` by `id`.
ASMJIT_INLINE VarData* getVdById(uint32_t id) const { ASMJIT_INLINE VarData* getVdById(uint32_t id) const {
@@ -1909,14 +1958,14 @@ struct BaseCompiler : public CodeGen {
return _vars[id & kOperandIdNum]; return _vars[id & kOperandIdNum];
} }
//! @internal //! \internal
//! //!
//! Get an array of 'VarData*'. //! Get an array of 'VarData*'.
ASMJIT_INLINE VarData** _getVdArray() const { ASMJIT_INLINE VarData** _getVdArray() const {
return const_cast<VarData**>(_vars.getData()); return const_cast<VarData**>(_vars.getData());
} }
//! @internal //! \internal
//! //!
//! Create a new `VarData`. //! Create a new `VarData`.
ASMJIT_API VarData* _newVd(uint32_t type, uint32_t size, uint32_t c, const char* name); ASMJIT_API VarData* _newVd(uint32_t type, uint32_t size, uint32_t c, const char* name);
@@ -1949,14 +1998,14 @@ struct BaseCompiler : public CodeGen {
//! Rename variable `var` to `name`. //! Rename variable `var` to `name`.
//! //!
//! @note Only new name will appear in the logger. //! \note Only new name will appear in the logger.
ASMJIT_API void rename(BaseVar& var, const char* name); ASMJIT_API void rename(BaseVar& var, const char* name);
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [Stack] // [Stack]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! @internal //! \internal
//! //!
//! Create a new memory chunk allocated on the current function's stack. //! 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; virtual Error _newStack(BaseMem* mem, uint32_t size, uint32_t alignment, const char* name) = 0;
@@ -1965,7 +2014,7 @@ struct BaseCompiler : public CodeGen {
// [Const] // [Const]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! @internal //! \internal
//! //!
//! Put data to a constant-pool and get a memory reference to it. //! 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; virtual Error _newConst(BaseMem* mem, uint32_t scope, const void* data, size_t size) = 0;
@@ -1993,12 +2042,12 @@ struct BaseCompiler : public CodeGen {
const uint8_t* _targetVarMapping; const uint8_t* _targetVarMapping;
//! First node. //! First node.
BaseNode* _firstNode; Node* _firstNode;
//! Last node. //! Last node.
BaseNode* _lastNode; Node* _lastNode;
//! Current node. //! Current node.
BaseNode* _cursor; Node* _cursor;
//! Current function. //! Current function.
FuncNode* _func; FuncNode* _func;
@@ -2025,6 +2074,8 @@ struct BaseCompiler : public CodeGen {
Label _globalConstPoolLabel; Label _globalConstPoolLabel;
}; };
//! \}
// ============================================================================ // ============================================================================
// [Defined-Later] // [Defined-Later]
// ============================================================================ // ============================================================================
@@ -2033,7 +2084,7 @@ ASMJIT_INLINE Label::Label(BaseCompiler& c) : Operand(NoInit) {
c._newLabel(this); c._newLabel(this);
} }
ASMJIT_INLINE BaseNode::BaseNode(BaseCompiler* compiler, uint32_t type) { ASMJIT_INLINE Node::Node(BaseCompiler* compiler, uint32_t type) {
_prev = NULL; _prev = NULL;
_next = NULL; _next = NULL;
_type = static_cast<uint8_t>(type); _type = static_cast<uint8_t>(type);
@@ -2046,8 +2097,6 @@ ASMJIT_INLINE BaseNode::BaseNode(BaseCompiler* compiler, uint32_t type) {
_state = NULL; _state = NULL;
} }
//! @}
} // asmjit namespace } // asmjit namespace
// [Api-End] // [Api-End]

View File

@@ -29,7 +29,7 @@ const ConstPoolNode ConstPoolTree::_sentinel = { {
const_cast<ConstPoolNode*>(&ConstPoolTree::_sentinel) const_cast<ConstPoolNode*>(&ConstPoolTree::_sentinel)
}, 0, 0, 0 }; }, 0, 0, 0 };
//! @internal //! \internal
//! //!
//! Remove left horizontal links. //! Remove left horizontal links.
static ASMJIT_INLINE ConstPoolNode* ConstPoolTree_skewNode(ConstPoolNode* node) { static ASMJIT_INLINE ConstPoolNode* ConstPoolTree_skewNode(ConstPoolNode* node) {
@@ -43,7 +43,7 @@ static ASMJIT_INLINE ConstPoolNode* ConstPoolTree_skewNode(ConstPoolNode* node)
return node; return node;
} }
//! @internal //! \internal
//! //!
//! Remove consecutive horizontal links. //! Remove consecutive horizontal links.
static ASMJIT_INLINE ConstPoolNode* ConstPoolTree_splitNode(ConstPoolNode* node) { static ASMJIT_INLINE ConstPoolNode* ConstPoolTree_splitNode(ConstPoolNode* node) {

View File

@@ -17,14 +17,14 @@
namespace asmjit { namespace asmjit {
//! @addtogroup asmjit_base_util //! \addtogroup asmjit_base_util
//! @{ //! \{
// ============================================================================ // ============================================================================
// [asmjit::ConstPoolNode] // [asmjit::ConstPoolNode]
// ============================================================================ // ============================================================================
//! @internal //! \internal
//! //!
//! Zone-allocated constant-pool node. //! Zone-allocated constant-pool node.
struct ConstPoolNode { struct ConstPoolNode {
@@ -54,7 +54,7 @@ struct ConstPoolNode {
// [asmjit::ConstPoolTree] // [asmjit::ConstPoolTree]
// ============================================================================ // ============================================================================
//! @internal //! \internal
//! //!
//! Zone-allocated constant-pool tree. //! Zone-allocated constant-pool tree.
struct ConstPoolTree { struct ConstPoolTree {
@@ -184,7 +184,7 @@ struct ConstPoolTree {
// [asmjit::ConstPoolGap] // [asmjit::ConstPoolGap]
// ============================================================================ // ============================================================================
//! @internal //! \internal
//! //!
//! Zone-allocated constant-pool gap. //! Zone-allocated constant-pool gap.
struct ConstPoolGap { struct ConstPoolGap {
@@ -291,7 +291,7 @@ struct ConstPool {
size_t _alignment; size_t _alignment;
}; };
//! @} //! \}
} // asmjit namespace } // asmjit namespace

View File

@@ -265,14 +265,14 @@ Error BaseContext::resolveCellOffsets() {
// ============================================================================ // ============================================================================
Error BaseContext::removeUnreachableCode() { Error BaseContext::removeUnreachableCode() {
PodList<BaseNode*>::Link* link = _unreachableList.getFirst(); PodList<Node*>::Link* link = _unreachableList.getFirst();
BaseNode* stop = getStop(); Node* stop = getStop();
while (link != NULL) { while (link != NULL) {
BaseNode* node = link->getValue(); Node* node = link->getValue();
if (node != NULL && node->getPrev() != NULL) { if (node != NULL && node->getPrev() != NULL) {
// Locate all unreachable nodes. // Locate all unreachable nodes.
BaseNode* first = node; Node* first = node;
do { do {
if (node->isFetched()) if (node->isFetched())
break; break;
@@ -281,7 +281,7 @@ Error BaseContext::removeUnreachableCode() {
// Remove. // Remove.
if (node != first) { if (node != first) {
BaseNode* last = (node != NULL) ? node->getPrev() : getCompiler()->getLastNode(); Node* last = (node != NULL) ? node->getPrev() : getCompiler()->getLastNode();
getCompiler()->removeNodes(first, last); getCompiler()->removeNodes(first, last);
} }
} }
@@ -296,7 +296,7 @@ Error BaseContext::removeUnreachableCode() {
// [asmjit::BaseContext - Cleanup] // [asmjit::BaseContext - Cleanup]
// ============================================================================ // ============================================================================
//! @internal //! \internal
//! //!
//! Translate the given function `func`. //! Translate the given function `func`.
void BaseContext::cleanup() { void BaseContext::cleanup() {
@@ -318,8 +318,8 @@ void BaseContext::cleanup() {
// ============================================================================ // ============================================================================
Error BaseContext::compile(FuncNode* func) { Error BaseContext::compile(FuncNode* func) {
BaseNode* end = func->getEnd(); Node* end = func->getEnd();
BaseNode* stop = end->getNext(); Node* stop = end->getNext();
_func = func; _func = func;
_stop = stop; _stop = stop;

View File

@@ -17,14 +17,14 @@
namespace asmjit { namespace asmjit {
//! @addtogroup asmjit_base_codegen //! \addtogroup asmjit_base_tree
//! @{ //! \{
// ============================================================================ // ============================================================================
// [asmjit::BaseContext] // [asmjit::BaseContext]
// ============================================================================ // ============================================================================
//! @internal //! \internal
//! //!
//! Code generation context is the logic behind `BaseCompiler`. The context is //! Code generation context is the logic behind `BaseCompiler`. The context is
//! used to compile the code stored in `BaseCompiler`. //! used to compile the code stored in `BaseCompiler`.
@@ -55,17 +55,17 @@ struct BaseContext {
//! Get function. //! Get function.
ASMJIT_INLINE FuncNode* getFunc() const { return _func; } ASMJIT_INLINE FuncNode* getFunc() const { return _func; }
//! Get stop node. //! Get stop node.
ASMJIT_INLINE BaseNode* getStop() const { return _stop; } ASMJIT_INLINE Node* getStop() const { return _stop; }
//! Get start of the current scope. //! Get start of the current scope.
ASMJIT_INLINE BaseNode* getStart() const { return _start; } ASMJIT_INLINE Node* getStart() const { return _start; }
//! Get end of the current scope. //! Get end of the current scope.
ASMJIT_INLINE BaseNode* getEnd() const { return _end; } ASMJIT_INLINE Node* getEnd() const { return _end; }
//! Get extra block. //! Get extra block.
ASMJIT_INLINE BaseNode* getExtraBlock() const { return _extraBlock; } ASMJIT_INLINE Node* getExtraBlock() const { return _extraBlock; }
//! Set extra block. //! Set extra block.
ASMJIT_INLINE void setExtraBlock(BaseNode* node) { _extraBlock = node; } ASMJIT_INLINE void setExtraBlock(Node* node) { _extraBlock = node; }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [Error] // [Error]
@@ -207,7 +207,7 @@ struct BaseContext {
// [Serialize] // [Serialize]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
virtual Error serialize(BaseAssembler* assembler, BaseNode* start, BaseNode* stop) = 0; virtual Error serialize(BaseAssembler* assembler, Node* start, Node* stop) = 0;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [Members] // [Members]
@@ -222,19 +222,19 @@ struct BaseContext {
Zone _baseZone; Zone _baseZone;
//! Start of the current active scope. //! Start of the current active scope.
BaseNode* _start; Node* _start;
//! End of the current active scope. //! End of the current active scope.
BaseNode* _end; Node* _end;
//! Node that is used to insert extra code after the function body. //! Node that is used to insert extra code after the function body.
BaseNode* _extraBlock; Node* _extraBlock;
//! Stop node. //! Stop node.
BaseNode* _stop; Node* _stop;
//! Unreachable nodes. //! Unreachable nodes.
PodList<BaseNode*> _unreachableList; PodList<Node*> _unreachableList;
//! Jump nodes. //! Jump nodes.
PodList<BaseNode*> _jccList; PodList<Node*> _jccList;
//! All variables used by the current function. //! All variables used by the current function.
PodVector<VarData*> _contextVd; PodVector<VarData*> _contextVd;
@@ -277,7 +277,7 @@ struct BaseContext {
BaseVarState* _state; BaseVarState* _state;
}; };
//! @} //! \}
} // asmjit namespace } // asmjit namespace

View File

@@ -16,11 +16,6 @@
// ? // ?
#endif // ASMJIT_HOST || ASMJIT_HOST_X64 #endif // ASMJIT_HOST || ASMJIT_HOST_X64
// [Dependencies - Windows]
#if defined(ASMJIT_OS_WINDOWS)
# include <windows.h>
#endif // ASMJIT_OS_WINDOWS
// [Dependencies - Posix] // [Dependencies - Posix]
#if defined(ASMJIT_OS_POSIX) #if defined(ASMJIT_OS_POSIX)
# include <errno.h> # include <errno.h>

View File

@@ -16,31 +16,30 @@
namespace asmjit { namespace asmjit {
//! @addtogroup asmjit_base_cpu_info //! \addtogroup asmjit_base_general
//! @{ //! \{
// ============================================================================ // ============================================================================
// [asmjit::kCpuVendor] // [asmjit::kCpuVendor]
// ============================================================================ // ============================================================================
//! Cpu vendor IDs. //! Cpu vendor ID.
//! //!
//! Cpu vendor IDs are specific for AsmJit library. Vendor ID is not directly //! Vendor IDs are specific to AsmJit library. During the library initialization
//! read from cpuid result, instead it's based on CPU vendor string. //! 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) { ASMJIT_ENUM(kCpuVendor) {
//! Unknown CPU vendor. //! No/Unknown vendor.
kCpuVendorUnknown = 0, kCpuVendorNone = 0,
//! Intel CPU vendor. //! Intel vendor.
kCpuVendorIntel = 1, kCpuVendorIntel = 1,
//! AMD CPU vendor. //! AMD vendor.
kCpuVendorAmd = 2, kCpuVendorAmd = 2,
//! National Semiconductor CPU vendor (applies also to Cyrix processors). //! VIA vendor.
kCpuVendorNSM = 3, kCpuVendorVia = 3
//! Transmeta CPU vendor.
kCpuVendorTransmeta = 4,
//! VIA CPU vendor.
kCpuVendorVia = 5
}; };
// ============================================================================ // ============================================================================
@@ -51,7 +50,7 @@ ASMJIT_ENUM(kCpuVendor) {
struct BaseCpuInfo { struct BaseCpuInfo {
ASMJIT_NO_COPY(BaseCpuInfo) ASMJIT_NO_COPY(BaseCpuInfo)
//! @internal //! \internal
enum { enum {
kFeaturesPerUInt32 = static_cast<int>(sizeof(uint32_t)) * 8 kFeaturesPerUInt32 = static_cast<int>(sizeof(uint32_t)) * 8
}; };
@@ -135,7 +134,7 @@ struct BaseCpuInfo {
uint32_t _features[4]; uint32_t _features[4];
}; };
//! @} //! \}
} // asmjit namespace } // asmjit namespace

View File

@@ -16,8 +16,8 @@
namespace asmjit { namespace asmjit {
//! @addtogroup asmjit_base_util //! \addtogroup asmjit_base_util
//! @{ //! \{
// ============================================================================ // ============================================================================
// [asmjit::CpuTicks] // [asmjit::CpuTicks]
@@ -29,7 +29,7 @@ struct CpuTicks {
static ASMJIT_API uint32_t now(); static ASMJIT_API uint32_t now();
}; };
//! @} //! \}
} // asmjit namespace } // asmjit namespace

View File

@@ -49,16 +49,10 @@ static const char* errorMessages[] = {
"Unknown instruction", "Unknown instruction",
"Illegal instruction", "Illegal instruction",
"Illegal addressing", "Illegal addressing",
"Illegal short jump", "Illegal displacement",
"No function defined", "Invalid function",
"Incomplete function",
"Overlapped arguments", "Overlapped arguments",
"No registers",
"Overlapped registers",
"Incompatible argument",
"Incompatible return",
"Unknown error" "Unknown error"
}; };

View File

@@ -11,10 +11,13 @@
// [Api-Begin] // [Api-Begin]
#include "../apibegin.h" #include "../apibegin.h"
// [Dependencies - AsmJit]
#include "../base/globals.h"
namespace asmjit { namespace asmjit {
//! @addtogroup asmjit_base_logging_and_errors //! \addtogroup asmjit_base_general
//! @{ //! \{
// ============================================================================ // ============================================================================
// [asmjit::kError] // [asmjit::kError]
@@ -29,73 +32,69 @@ ASMJIT_ENUM(kError) {
//! Heap memory allocation failed. //! Heap memory allocation failed.
kErrorNoHeapMemory = 1, kErrorNoHeapMemory = 1,
//! Virtual memory allocation failed. //! Virtual memory allocation failed.
kErrorNoVirtualMemory = 2, kErrorNoVirtualMemory = 2,
//! Invalid argument. //! Invalid argument.
kErrorInvalidArgument = 3, kErrorInvalidArgument = 3,
//! Invalid state. //! Invalid state.
kErrorInvalidState = 4, kErrorInvalidState = 4,
//! Unknown instruction. This happens only if instruction code is //! Unknown instruction. This happens only if instruction code is
//! out of bounds. Shouldn't happen. //! out of bounds. Shouldn't happen.
kErrorAssemblerUnknownInst = 5, kErrorUnknownInst = 5,
//! Illegal instruction, usually generated by asmjit::Assembler
//! class when emitting instruction opcode. If this error is generated the //! Illegal instruction (Assembler).
//! target buffer is not affected by this invalid instruction.
//! //!
//! You can also get this status code if you are under x64 (64-bit x86) and //! This status code can also be returned in X64 mode if AH, BH, CH or DH
//! you tried to decode instruction using AH, BH, CH or DH register with REX //! registers have been used together with a REX prefix. The instruction
//! prefix. These registers can't be accessed if REX prefix is used and AsmJit //! is not encodable in such case.
//! didn't check for this situation in intrinsics (`BaseCompiler` takes care of
//! this and rearrange registers if needed).
//! //!
//! Example of raising `kErrorAssemblerIllegalInst` error. //! Example of raising `kErrorIllegalInst` error.
//! //!
//! ~~~ //! ~~~
//! // Invalid address size. //! // Invalid address size.
//! a.mov(dword_ptr(eax), al); //! a.mov(dword_ptr(eax), al);
//! //!
//! // Undecodable instruction - AH used with r10 that can be encoded by using //! // Undecodable instruction - AH used with R10, however R10 can only be
//! // REX prefix only. //! // encoded by using REX prefix, which conflicts with AH.
//! a.mov(byte_ptr(r10), ah); //! a.mov(byte_ptr(r10), ah);
//! ~~~ //! ~~~
//! //!
//! @note In debug mode you get assertion failure instead of setting error //! \note In debug mode assertion is raised instead of returning an error.
//! code. kErrorIllegalInst = 6,
kErrorAssemblerIllegalInst = 6,
//! Illegal addressing used (unencodable).
kErrorAssemblerIllegalAddr = 7,
//! Short jump instruction used, but displacement is out of bounds.
kErrorAssemblerIllegalShortJump = 8,
//! No function defined. //! Illegal (unencodable) addressing used (Assembler).
kErrorCompilerNoFunc = 9, kErrorIllegalAddresing = 7,
//! Function generation is not finished by using `BaseCompiler::endFunc()`
//! or something bad happened during generation related to function. This can
//! be missing compiler node, etc...
kErrorCompilerIncompleteFunc = 10,
//! Tried to generate a function with overlapped arguments.
kErrorCompilerOverlappedArgs = 11,
//! Compiler can't allocate registers. //! Illegal (unencodable) displacement used (Assembler).
kErrorCompilerNoRegs = 12, //!
//! Compiler can't allocate registers, because they overlap. //! X86/X64
kErrorCompilerOverlappedRegs = 13, //! -------
//!
//! Short form of jump instruction has been used, but the displacement is out
//! of bounds.
kErrorIllegalDisplacement = 8,
//! Tried to call function with an incompatible argument. //! Invalid function (Compiler).
kErrorCompilerIncompatibleArg = 14, //!
//! Incompatible return value. //! Returned if no function is defined, but `make()` has been called.
kErrorCompilerIncompatibleRet = 15, kErrorInvalidFunction = 9,
//! A variable has been assigned more than once to a function argument (Compiler).
kErrorOverlappedArgs = 10,
//! Count of AsmJit status codes. Can grow in future. //! Count of AsmJit status codes. Can grow in future.
kErrorCount = 16 kErrorCount = 11
}; };
// ============================================================================ // ============================================================================
// [asmjit::Error] // [asmjit::Error]
// ============================================================================ // ============================================================================
//! AsmJit error type (unsigned integer).
typedef uint32_t Error; typedef uint32_t Error;
// ============================================================================ // ============================================================================
@@ -126,7 +125,7 @@ struct ErrorHandler {
//! Reference this error handler. //! Reference this error handler.
//! //!
//! @note This member function is provided for convenience. The default //! \note This member function is provided for convenience. The default
//! implementation does nothing. If you are working in environment where //! implementation does nothing. If you are working in environment where
//! multiple `ErrorHandler` instances are used by a different code generators //! multiple `ErrorHandler` instances are used by a different code generators
//! you may provide your own functionality for reference counting. In that //! you may provide your own functionality for reference counting. In that
@@ -135,7 +134,7 @@ struct ErrorHandler {
//! Release this error handler. //! Release this error handler.
//! //!
//! @note This member function is provided for convenience. See `addRef()` //! \note This member function is provided for convenience. See `addRef()`
//! for more detailed information related to reference counting. //! for more detailed information related to reference counting.
ASMJIT_API virtual void release(); ASMJIT_API virtual void release();
@@ -183,11 +182,13 @@ struct ErrorUtil {
static ASMJIT_API const char* asString(Error code); static ASMJIT_API const char* asString(Error code);
}; };
//! \}
// ============================================================================ // ============================================================================
// [ASMJIT_PROPAGATE_ERROR] // [ASMJIT_PROPAGATE_ERROR]
// ============================================================================ // ============================================================================
//! @internal //! \internal
//! //!
//! Used by AsmJit to return the `_Exp_` result if it's an error. //! Used by AsmJit to return the `_Exp_` result if it's an error.
#define ASMJIT_PROPAGATE_ERROR(_Exp_) \ #define ASMJIT_PROPAGATE_ERROR(_Exp_) \
@@ -197,8 +198,6 @@ struct ErrorUtil {
return errval_; \ return errval_; \
} while (0) } while (0)
//! @}
} // asmjit namespace } // asmjit namespace
// [Api-End] // [Api-End]

View File

@@ -9,23 +9,15 @@
#define _ASMJIT_BASE_FUNC_H #define _ASMJIT_BASE_FUNC_H
// [Dependencies - AsmJit] // [Dependencies - AsmJit]
#include "../base/defs.h" #include "../base/operand.h"
#include "../base/globals.h"
// [Api-Begin] // [Api-Begin]
#include "../apibegin.h" #include "../apibegin.h"
namespace asmjit { namespace asmjit {
//! @addtogroup asmjit_base_codegen //! \addtogroup asmjit_base_tree
//! @{ //! \{
// ============================================================================
// [Forward Declarations]
// ============================================================================
template<typename T>
struct FnTypeId;
// ============================================================================ // ============================================================================
// [asmjit::kFuncConv] // [asmjit::kFuncConv]
@@ -141,24 +133,15 @@ ASMJIT_ENUM(kFuncFlags) {
ASMJIT_ENUM(kFuncDir) { ASMJIT_ENUM(kFuncDir) {
//! Arguments are passed left to right. //! Arguments are passed left to right.
//! //!
//! This arguments direction is unusual to C programming, it's used by pascal //! This arguments direction is unusual in C, however it's used in Pascal.
//! compilers and in some calling conventions by Borland compiler).
kFuncDirLtr = 0, kFuncDirLtr = 0,
//! Arguments are passed right ro left //! Arguments are passed right ro left
//! //!
//! This is default argument direction in C programming. //! This is the default argument direction in C.
kFuncDirRtl = 1 kFuncDirRtl = 1
}; };
// ============================================================================
// [asmjit::kFuncStackInvalid]
// ============================================================================
enum {
//! Invalid stack offset in function or function parameter.
kFuncStackInvalid = -1
};
// ============================================================================ // ============================================================================
// [asmjit::kFuncArg] // [asmjit::kFuncArg]
// ============================================================================ // ============================================================================
@@ -196,23 +179,17 @@ ASMJIT_ENUM(kFuncRet) {
}; };
// ============================================================================ // ============================================================================
// [asmjit::FnTypeId] // [asmjit::kFuncStackInvalid]
// ============================================================================ // ============================================================================
//! @internal enum kFuncMisc {
#define ASMJIT_DECLARE_TYPE_CORE(_PtrId_) \ //! Invalid stack offset in function or function parameter.
template<typename T> \ kFuncStackInvalid = -1
struct TypeId { enum { kId = static_cast<int>(::asmjit::kVarTypeInvalid) }; }; \ };
\
template<typename T> \
struct TypeId<T*> { enum { kId = _PtrId_ }; }
//! @internal // ============================================================================
//! // [asmjit::FnTypeId]
//! Declare C/C++ type-id mapped to `kVarType`. // ============================================================================
#define ASMJIT_DECLARE_TYPE_ID(_T_, _Id_) \
template<> \
struct TypeId<_T_> { enum { kId = _Id_ }; }
//! Function builder 'void' type. //! Function builder 'void' type.
struct FnVoid {}; struct FnVoid {};
@@ -248,6 +225,20 @@ struct FnFloat {};
struct FnDouble {}; struct FnDouble {};
#if !defined(ASMJIT_DOCGEN) #if !defined(ASMJIT_DOCGEN)
template<typename T>
struct FnTypeId;
#define ASMJIT_DECLARE_TYPE_CORE(_PtrId_) \
template<typename T> \
struct TypeId { enum { kId = static_cast<int>(::asmjit::kVarTypeInvalid) }; }; \
\
template<typename T> \
struct TypeId<T*> { enum { kId = _PtrId_ }; }
#define ASMJIT_DECLARE_TYPE_ID(_T_, _Id_) \
template<> \
struct TypeId<_T_> { enum { kId = _Id_ }; }
ASMJIT_DECLARE_TYPE_CORE(kVarTypeIntPtr); ASMJIT_DECLARE_TYPE_CORE(kVarTypeIntPtr);
ASMJIT_DECLARE_TYPE_ID(void, kVarTypeInvalid); ASMJIT_DECLARE_TYPE_ID(void, kVarTypeInvalid);
@@ -398,7 +389,7 @@ struct FuncDecl {
//! //!
//! Direction should be always `kFuncDirRtl`. //! Direction should be always `kFuncDirRtl`.
//! //!
//! @note This is related to used calling convention, it's not affected by //! \note This is related to used calling convention, it's not affected by
//! number of function arguments or their types. //! number of function arguments or their types.
ASMJIT_INLINE uint32_t getDirection() const { return _direction; } ASMJIT_INLINE uint32_t getDirection() const { return _direction; }
@@ -471,12 +462,12 @@ struct FuncDecl {
//! Size of "Red Zone". //! Size of "Red Zone".
//! //!
//! @note Used by AMD64-ABI (128 bytes). //! \note Used by AMD64-ABI (128 bytes).
uint16_t _redZoneSize; uint16_t _redZoneSize;
//! Size of "Spill Zone". //! Size of "Spill Zone".
//! //!
//! @note Used by WIN64-ABI (32 bytes). //! \note Used by WIN64-ABI (32 bytes).
uint16_t _spillZoneSize; uint16_t _spillZoneSize;
//! Function arguments (including HI arguments) mapped to physical //! Function arguments (including HI arguments) mapped to physical
@@ -542,6 +533,7 @@ struct FuncBuilderX : public FuncPrototype {
uint32_t _builderArgList[kFuncArgCount]; uint32_t _builderArgList[kFuncArgCount];
}; };
//! \internal
#define _TID(_T_) TypeId<_T_>::kId #define _TID(_T_) TypeId<_T_>::kId
//! Function builder (no args). //! Function builder (no args).
@@ -644,7 +636,7 @@ struct FuncBuilder10 : public FuncPrototype {
#undef _TID #undef _TID
//! @} //! \}
} // asmjit namespace } // asmjit namespace

View File

@@ -16,15 +16,21 @@
namespace asmjit { namespace asmjit {
//! @addtogroup asmjit_base_globals //! \addtogroup asmjit_base_general
//! @{ //! \{
// ============================================================================ // ============================================================================
// [asmjit::kGlobals] // [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<size_t>(0); static const size_t kInvalidIndex = ~static_cast<size_t>(0);
//! Global constants.
ASMJIT_ENUM(kGlobals) { ASMJIT_ENUM(kGlobals) {
//! Invalid value or operand id. //! Invalid value or operand id.
kInvalidValue = 0xFFFFFFFF, kInvalidValue = 0xFFFFFFFF,
@@ -32,26 +38,20 @@ ASMJIT_ENUM(kGlobals) {
//! Invalid register index. //! Invalid register index.
kInvalidReg = 0xFF, kInvalidReg = 0xFF,
//! Minimum reserved bytes in `Buffer`. //! Host memory allocator overhead.
kBufferGrow = 32U, //!
//! The overhead is decremented from all zone allocators so the operating
//! Minimum size of assembler/compiler code buffer. //! system doesn't have allocate extra virtual page to keep tract of the
kMemAllocMinimum = 4096, //! requested memory block.
//!
//! The number is actually a guess.
kMemAllocOverhead = sizeof(intptr_t) * 4,
//! Memory grow threshold. //! Memory grow threshold.
//! //!
//! After the grow threshold is reached the capacity won't be doubled //! After the grow threshold is reached the capacity won't be doubled
//! anymore. //! anymore.
kMemAllocGrowMax = 8192 * 1024, kMemAllocGrowMax = 8192 * 1024
//! Host memory allocator overhead.
//!
//! We decrement the overhead from our pools so the host operating system
//! doesn't need allocate an extra virtual page to put the data it needs
//! to manage the requested memory block (for example if a single virtual
//! page is 4096 and we require the same memory size we decrease our
//! requirement by kMemAllocOverhead).
kMemAllocOverhead = sizeof(intptr_t) * 4,
}; };
// ============================================================================ // ============================================================================
@@ -87,7 +87,21 @@ ASMJIT_ENUM(kArch) {
kArchHost64Bit = sizeof(intptr_t) >= 8 kArchHost64Bit = sizeof(intptr_t) >= 8
}; };
//! @} // ============================================================================
// [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::Init / NoInit] // [asmjit::Init / NoInit]
@@ -105,17 +119,18 @@ static const _NoInit NoInit = {};
// [asmjit::Assert] // [asmjit::Assert]
// ============================================================================ // ============================================================================
//! @addtogroup asmjit_base_logging_and_errors //! \addtogroup asmjit_base_general
//! @{ //! \{
//! Called in debug build on assertion failure. //! Called in debug build on assertion failure.
//! //!
//! @param exp Expression that failed. //! \param exp Expression that failed.
//! @param file Source file name where it happened. //! \param file Source file name where it happened.
//! @param line Line in the source file. //! \param line Line in the source file.
//! //!
//! If you have problems with assertions put a breakpoint at assertionFailed() //! If you have problems with assertions put a breakpoint at assertionFailed()
//! function (asmjit/base/assert.cpp) to see what happened. //! 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); ASMJIT_API void assertionFailed(const char* exp, const char* file, int line);
#if defined(ASMJIT_DEBUG) #if defined(ASMJIT_DEBUG)
@@ -127,7 +142,7 @@ ASMJIT_API void assertionFailed(const char* exp, const char* file, int line);
#define ASMJIT_ASSERT(_Exp_) ASMJIT_NOP() #define ASMJIT_ASSERT(_Exp_) ASMJIT_NOP()
#endif // DEBUG #endif // DEBUG
//! @} //! \}
} // asmjit namespace } // asmjit namespace
@@ -135,8 +150,8 @@ ASMJIT_API void assertionFailed(const char* exp, const char* file, int line);
// [asmjit_cast<>] // [asmjit_cast<>]
// ============================================================================ // ============================================================================
//! @addtogroup asmjit_base_util //! \addtogroup asmjit_base_util
//! @{ //! \{
//! Cast used to cast pointer to function. It's like reinterpret_cast<>, //! Cast used to cast pointer to function. It's like reinterpret_cast<>,
//! but uses internally C style cast to work with MinGW. //! but uses internally C style cast to work with MinGW.
@@ -148,7 +163,7 @@ ASMJIT_API void assertionFailed(const char* exp, const char* file, int line);
template<typename T, typename Z> template<typename T, typename Z>
static ASMJIT_INLINE T asmjit_cast(Z* p) { return (T)p; } static ASMJIT_INLINE T asmjit_cast(Z* p) { return (T)p; }
//! @} //! \}
// [Api-End] // [Api-End]
#include "../apiend.h" #include "../apiend.h"

View File

@@ -20,14 +20,14 @@
namespace asmjit { namespace asmjit {
//! @addtogroup asmjit_base_util //! \addtogroup asmjit_base_util
//! @{ //! \{
// ============================================================================ // ============================================================================
// [asmjit::IntTraits] // [asmjit::IntTraits]
// ============================================================================ // ============================================================================
//! @internal //! \internal
template<typename T> template<typename T>
struct IntTraits { struct IntTraits {
enum { enum {
@@ -53,13 +53,13 @@ struct IntUtil {
// [Float <-> Int] // [Float <-> Int]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! @internal //! \internal
union Float { union Float {
int32_t i; int32_t i;
float f; float f;
}; };
//! @internal //! \internal
union Double { union Double {
int64_t i; int64_t i;
double d; double d;
@@ -144,7 +144,7 @@ struct IntUtil {
// [AsmJit - IsInt/IsUInt] // [AsmJit - IsInt/IsUInt]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Get whether the given integer `x` can be casted to a signed 8-bit integer. //! Get whether the given integer `x` can be casted to 8-bit signed integer.
template<typename T> template<typename T>
static ASMJIT_INLINE bool isInt8(T x) { static ASMJIT_INLINE bool isInt8(T x) {
if (IntTraits<T>::kIsSigned) if (IntTraits<T>::kIsSigned)
@@ -153,7 +153,7 @@ struct IntUtil {
return x <= T(127); return x <= T(127);
} }
//! Get whether the given integer `x` can be casted to an unsigned 8-bit integer. //! Get whether the given integer `x` can be casted to 8-bit unsigned integer.
template<typename T> template<typename T>
static ASMJIT_INLINE bool isUInt8(T x) { static ASMJIT_INLINE bool isUInt8(T x) {
if (IntTraits<T>::kIsSigned) if (IntTraits<T>::kIsSigned)
@@ -162,7 +162,7 @@ struct IntUtil {
return sizeof(T) <= sizeof(uint8_t) ? true : x <= T(255); return sizeof(T) <= sizeof(uint8_t) ? true : x <= T(255);
} }
//! Get whether the given integer `x` can be casted to a signed 16-bit integer. //! Get whether the given integer `x` can be casted to 16-bit signed integer.
template<typename T> template<typename T>
static ASMJIT_INLINE bool isInt16(T x) { static ASMJIT_INLINE bool isInt16(T x) {
if (IntTraits<T>::kIsSigned) if (IntTraits<T>::kIsSigned)
@@ -171,7 +171,7 @@ struct IntUtil {
return x >= T(0) && (sizeof(T) <= sizeof(int16_t) ? true : x <= T(32767)); return x >= T(0) && (sizeof(T) <= sizeof(int16_t) ? true : x <= T(32767));
} }
//! Get whether the given integer `x` can be casted to an unsigned 16-bit integer. //! Get whether the given integer `x` can be casted to 16-bit unsigned integer.
template<typename T> template<typename T>
static ASMJIT_INLINE bool isUInt16(T x) { static ASMJIT_INLINE bool isUInt16(T x) {
if (IntTraits<T>::kIsSigned) if (IntTraits<T>::kIsSigned)
@@ -180,7 +180,7 @@ struct IntUtil {
return sizeof(T) <= sizeof(uint16_t) ? true : x <= T(65535); return sizeof(T) <= sizeof(uint16_t) ? true : x <= T(65535);
} }
//! Get whether the given integer `x` can be casted to a signed 32-bit integer. //! Get whether the given integer `x` can be casted to 32-bit signed integer.
template<typename T> template<typename T>
static ASMJIT_INLINE bool isInt32(T x) { static ASMJIT_INLINE bool isInt32(T x) {
if (IntTraits<T>::kIsSigned) if (IntTraits<T>::kIsSigned)
@@ -189,7 +189,7 @@ struct IntUtil {
return x >= T(0) && (sizeof(T) <= sizeof(int32_t) ? true : x <= T(2147483647)); return x >= T(0) && (sizeof(T) <= sizeof(int32_t) ? true : x <= T(2147483647));
} }
//! Get whether the given integer `x` can be casted to an unsigned 32-bit integer. //! Get whether the given integer `x` can be casted to 32-bit unsigned integer.
template<typename T> template<typename T>
static ASMJIT_INLINE bool isUInt32(T x) { static ASMJIT_INLINE bool isUInt32(T x) {
if (IntTraits<T>::kIsSigned) if (IntTraits<T>::kIsSigned)
@@ -315,7 +315,7 @@ struct IntUtil {
// [AsmJit - FindFirstBit] // [AsmJit - FindFirstBit]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! @internal //! \internal
static ASMJIT_INLINE uint32_t findFirstBitSlow(uint32_t mask) { static ASMJIT_INLINE uint32_t findFirstBitSlow(uint32_t mask) {
// This is a reference (slow) implementation of findFirstBit(), used when // This is a reference (slow) implementation of findFirstBit(), used when
// we don't have compiler support for this task. The implementation speed // we don't have compiler support for this task. The implementation speed
@@ -716,7 +716,7 @@ union UInt64 {
}; };
}; };
//! @} //! \}
} // asmjit namespace } // asmjit namespace

View File

@@ -11,11 +11,6 @@
// [Dependencies - AsmJit] // [Dependencies - AsmJit]
#include "../build.h" #include "../build.h"
// [Dependencies - Windows]
#if defined(ASMJIT_OS_WINDOWS)
# include <windows.h>
#endif // ASMJIT_OS_WINDOWS
// [Dependencies - Posix] // [Dependencies - Posix]
#if defined(ASMJIT_OS_POSIX) #if defined(ASMJIT_OS_POSIX)
# include <pthread.h> # include <pthread.h>
@@ -26,8 +21,8 @@
namespace asmjit { namespace asmjit {
//! @addtogroup asmjit_base_util //! \addtogroup asmjit_base_util
//! @{ //! \{
// ============================================================================ // ============================================================================
// [asmjit::Lock] // [asmjit::Lock]
@@ -80,7 +75,7 @@ struct Lock {
//! Get handle. //! Get handle.
ASMJIT_INLINE Handle& getHandle() { return _handle; } ASMJIT_INLINE Handle& getHandle() { return _handle; }
//! @overload //! \overload
ASMJIT_INLINE const Handle& getHandle() const { return _handle; } ASMJIT_INLINE const Handle& getHandle() const { return _handle; }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -95,7 +90,7 @@ struct Lock {
// [asmjit::AutoLock] // [asmjit::AutoLock]
// ============================================================================ // ============================================================================
//! Scope auto locker. //! Scoped lock.
struct AutoLock { struct AutoLock {
ASMJIT_NO_COPY(AutoLock) ASMJIT_NO_COPY(AutoLock)
@@ -121,7 +116,7 @@ struct AutoLock {
Lock& _target; Lock& _target;
}; };
//! @} //! \}
} // asmjit namespace } // asmjit namespace

View File

@@ -9,7 +9,6 @@
#define _ASMJIT_BASE_LOGGER_H #define _ASMJIT_BASE_LOGGER_H
// [Dependencies - AsmJit] // [Dependencies - AsmJit]
#include "../base/defs.h"
#include "../base/string.h" #include "../base/string.h"
// [Dependencies - C] // [Dependencies - C]
@@ -20,8 +19,8 @@
namespace asmjit { namespace asmjit {
//! @addtogroup asmjit_base_logging_and_errors //! \addtogroup asmjit_base_util
//! @{ //! \{
// ============================================================================ // ============================================================================
// [asmjit::kLoggerOption] // [asmjit::kLoggerOption]
@@ -156,13 +155,11 @@ struct FileLogger : public Logger {
//! Get `FILE*` stream. //! Get `FILE*` stream.
//! //!
//! @note Return value can be `NULL`. //! \note Return value can be `NULL`.
ASMJIT_INLINE FILE* getStream() const { return _stream; } ASMJIT_INLINE FILE* getStream() const { return _stream; }
//! Set `FILE*` 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.
//! @param stream `FILE` stream where to log output, can be set to `NULL` to
//! disable logging.
ASMJIT_API void setStream(FILE* stream); ASMJIT_API void setStream(FILE* stream);
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -224,7 +221,7 @@ struct StringLogger : public Logger {
StringBuilder _stringBuilder; StringBuilder _stringBuilder;
}; };
//! @} //! \}
} // asmjit namespace } // asmjit namespace

View File

@@ -8,7 +8,7 @@
#define ASMJIT_EXPORTS #define ASMJIT_EXPORTS
// [Dependencies - AsmJit] // [Dependencies - AsmJit]
#include "../base/defs.h" #include "../base/operand.h"
// [Api-Begin] // [Api-Begin]
#include "../apibegin.h" #include "../apibegin.h"

View File

@@ -5,8 +5,8 @@
// Zlib - See LICENSE.md file in the package. // Zlib - See LICENSE.md file in the package.
// [Guard] // [Guard]
#ifndef _ASMJIT_BASE_DEFS_H #ifndef _ASMJIT_BASE_OPERAND_H
#define _ASMJIT_BASE_DEFS_H #define _ASMJIT_BASE_OPERAND_H
// [Dependencies - AsmJit] // [Dependencies - AsmJit]
#include "../base/intutil.h" #include "../base/intutil.h"
@@ -16,9 +16,6 @@
namespace asmjit { namespace asmjit {
//! @addtogroup asmjit_base_codegen
//! @{
// ============================================================================ // ============================================================================
// [Forward Declarations] // [Forward Declarations]
// ============================================================================ // ============================================================================
@@ -26,6 +23,9 @@ namespace asmjit {
struct BaseAssembler; struct BaseAssembler;
struct BaseCompiler; struct BaseCompiler;
//! \addtogroup asmjit_base_general
//! \{
// ============================================================================ // ============================================================================
// [asmjit::kOperandType] // [asmjit::kOperandType]
// ============================================================================ // ============================================================================
@@ -71,51 +71,6 @@ ASMJIT_ENUM(kRegClass) {
kRegClassInvalid = 0xFF kRegClassInvalid = 0xFF
}; };
// ============================================================================
// [asmjit::kInstCode]
// ============================================================================
//! Instruction codes (stub).
ASMJIT_ENUM(kInstCode) {
//! No instruction.
kInstNone = 0
};
// ============================================================================
// [asmjit::kInstOptions]
// ============================================================================
//! Instruction options (stub).
ASMJIT_ENUM(kInstOptions) {
//! No instruction options.
kInstOptionNone = 0x00,
//! 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 = 0x01,
//! 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 = 0x02,
//! Condition is likely to be taken (instruction).
kInstOptionTaken = 0x04,
//! Condition is unlikely to be taken (instruction).
kInstOptionNotTaken = 0x08
};
// ============================================================================ // ============================================================================
// [asmjit::kSize] // [asmjit::kSize]
// ============================================================================ // ============================================================================
@@ -174,21 +129,21 @@ ASMJIT_ENUM(kMemType) {
// ============================================================================ // ============================================================================
ASMJIT_ENUM(kVarType) { ASMJIT_ENUM(kVarType) {
//! Variable is signed 8-bit integer. //! Variable is 8-bit signed integer.
kVarTypeInt8 = 0, kVarTypeInt8 = 0,
//! Variable is unsigned 8-bit integer. //! Variable is 8-bit unsigned integer.
kVarTypeUInt8 = 1, kVarTypeUInt8 = 1,
//! Variable is signed 16-bit integer. //! Variable is 16-bit signed integer.
kVarTypeInt16 = 2, kVarTypeInt16 = 2,
//! Variable is unsigned 16-bit integer. //! Variable is 16-bit unsigned integer.
kVarTypeUInt16 = 3, kVarTypeUInt16 = 3,
//! Variable is signed 32-bit integer. //! Variable is 32-bit signed integer.
kVarTypeInt32 = 4, kVarTypeInt32 = 4,
//! Variable is unsigned 32-bit integer. //! Variable is 32-bit unsigned integer.
kVarTypeUInt32 = 5, kVarTypeUInt32 = 5,
//! Variable is signed 64-bit integer. //! Variable is 64-bit signed integer.
kVarTypeInt64 = 6, kVarTypeInt64 = 6,
//! Variable is unsigned 64-bit integer. //! Variable is 64-bit unsigned integer.
kVarTypeUInt64 = 7, kVarTypeUInt64 = 7,
//! Variable is target `intptr_t`, not compatible with host `intptr_t`. //! Variable is target `intptr_t`, not compatible with host `intptr_t`.
@@ -204,38 +159,17 @@ ASMJIT_ENUM(kVarType) {
//! Invalid variable type. //! Invalid variable type.
kVarTypeInvalid = 0xFF, kVarTypeInvalid = 0xFF,
//! @internal //! \internal
_kVarTypeIntStart = kVarTypeInt8, _kVarTypeIntStart = kVarTypeInt8,
//! @internal //! \internal
_kVarTypeIntEnd = kVarTypeUIntPtr, _kVarTypeIntEnd = kVarTypeUIntPtr,
//! @internal //! \internal
_kVarTypeFpStart = kVarTypeFp32, _kVarTypeFpStart = kVarTypeFp32,
//! @internal //! \internal
_kVarTypeFpEnd = kVarTypeFp64 _kVarTypeFpEnd = kVarTypeFp64
}; };
// ============================================================================
// [asmjit::kRelocMode]
// ============================================================================
ASMJIT_ENUM(kRelocMode) {
kRelocAbsToAbs = 0,
kRelocRelToAbs = 1,
kRelocAbsToRel = 2,
kRelocTrampoline = 3
};
// ============================================================================
// [asmjit::Ptr]
// ============================================================================
//! 64-bit signed pointer, compatible with JIT and non-JIT generators.
typedef int64_t SignedPtr;
//! 64-bit unsigned pointer, compatible with JIT and non-JIT generators.
typedef uint64_t Ptr;
// ============================================================================ // ============================================================================
// [asmjit::Operand] // [asmjit::Operand]
// ============================================================================ // ============================================================================
@@ -246,7 +180,7 @@ struct Operand {
// [Structs] // [Structs]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! @internal //! \internal
//! //!
//! Base operand data. //! Base operand data.
struct BaseOp { struct BaseOp {
@@ -261,11 +195,11 @@ struct Operand {
//! Operand id, identifier used by `BaseAssembler` and `BaseCompiler`. //! Operand id, identifier used by `BaseAssembler` and `BaseCompiler`.
//! //!
//! @note Uninitialized operand has always set id to `kInvalidValue`. //! \note Uninitialized operand has always set id to `kInvalidValue`.
uint32_t id; uint32_t id;
}; };
//! @internal //! \internal
//! //!
//! Register or Variable operand data. //! Register or Variable operand data.
struct VRegOp { struct VRegOp {
@@ -299,13 +233,13 @@ struct Operand {
//! Variable type. //! Variable type.
uint32_t vType; uint32_t vType;
//! @internal //! \internal
//! //!
//! Unused. //! Unused.
uint32_t vUnused; uint32_t vUnused;
}; };
//! @internal //! \internal
//! //!
//! Memory or Variable operand data. //! Memory or Variable operand data.
struct VMemOp { struct VMemOp {
@@ -328,7 +262,7 @@ struct Operand {
int32_t displacement; int32_t displacement;
}; };
//! @internal //! \internal
//! //!
//! Immediate operand data. //! Immediate operand data.
struct ImmOp { struct ImmOp {
@@ -345,24 +279,24 @@ struct Operand {
uint32_t id; uint32_t id;
union { union {
//! 8x signed 8-bit immediate values. //! 8x8-bit signed immediate values.
int8_t _i8[8]; int8_t _i8[8];
//! 8x unsigned 8-bit immediate values. //! 8x8-bit unsigned immediate values.
uint8_t _u8[8]; uint8_t _u8[8];
//! 4x signed 16-bit immediate values. //! 4x16-bit signed immediate values.
int16_t _i16[4]; int16_t _i16[4];
//! 4x unsigned 16-bit immediate values. //! 4x16-bit unsigned immediate values.
uint16_t _u16[4]; uint16_t _u16[4];
//! 2x signed 32-bit immediate values. //! 2x32-bit signed immediate values.
int32_t _i32[2]; int32_t _i32[2];
//! 2x unsigned 32-bit immediate values. //! 2x32-bit unsigned immediate values.
uint32_t _u32[2]; uint32_t _u32[2];
//! 1x signed 64-bit immediate value. //! 1x64-bit signed immediate value.
int64_t _i64[1]; int64_t _i64[1];
//! 1x unsigned 64-bit immediate value. //! 1x64-bit unsigned immediate value.
uint64_t _u64[1]; uint64_t _u64[1];
//! 2x SP-FP values. //! 2x SP-FP values.
@@ -372,7 +306,7 @@ struct Operand {
} value; } value;
}; };
//! @internal //! \internal
//! //!
//! Label operand data. //! Label operand data.
struct LabelOp { struct LabelOp {
@@ -419,7 +353,7 @@ struct Operand {
// [Init & Copy] // [Init & Copy]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! @internal //! \internal
//! //!
//! Initialize operand to `other` (used by constructors). //! Initialize operand to `other` (used by constructors).
ASMJIT_INLINE void _init(const Operand& other) { ASMJIT_INLINE void _init(const Operand& other) {
@@ -448,7 +382,7 @@ struct Operand {
_packed[1].setPacked_2x32(u2, u3); _packed[1].setPacked_2x32(u2, u3);
} }
//! @internal //! \internal
//! //!
//! Initialize operand to `other` (used by assign operators). //! Initialize operand to `other` (used by assign operators).
ASMJIT_INLINE void _copy(const Operand& other) { ASMJIT_INLINE void _copy(const Operand& other) {
@@ -553,8 +487,6 @@ struct Operand {
}; };
}; };
ASMJIT_VAR const Operand noOperand;
// ============================================================================ // ============================================================================
// [asmjit::OperandUtil] // [asmjit::OperandUtil]
// ============================================================================ // ============================================================================
@@ -578,7 +510,7 @@ struct OperandUtil {
//! Get whether the id refers to `BaseVar`. //! Get whether the id refers to `BaseVar`.
//! //!
//! @note The function will never return `true` if the id is `kInvalidValue`. //! \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 //! The trick is to compare a given id to -1 (kInvalidValue) so we check both
//! using only one comparison. //! using only one comparison.
static ASMJIT_INLINE bool isVarId(uint32_t id) { static ASMJIT_INLINE bool isVarId(uint32_t id) {
@@ -587,7 +519,7 @@ struct OperandUtil {
//! Get whether the id refers to `Label`. //! Get whether the id refers to `Label`.
//! //!
//! @note The function will never return `true` if the id is `kInvalidValue`. //! \note The function will never return `true` if the id is `kInvalidValue`.
static ASMJIT_INLINE bool isLabelId(uint32_t id) { static ASMJIT_INLINE bool isLabelId(uint32_t id) {
return static_cast<int32_t>(id) >= 0; return static_cast<int32_t>(id) >= 0;
} }
@@ -1075,21 +1007,6 @@ struct Imm : public Operand {
} }
}; };
//! 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<int64_t>(val));
}
//! Create void* pointer immediate value operand.
static ASMJIT_INLINE Imm imm_ptr(void* p) {
return Imm(static_cast<int64_t>((intptr_t)p));
}
// ============================================================================ // ============================================================================
// [asmjit::Label] // [asmjit::Label]
// ============================================================================ // ============================================================================
@@ -1164,7 +1081,30 @@ struct Label : public Operand {
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<int64_t>(val));
}
//! Create void* pointer immediate value operand.
static ASMJIT_INLINE Imm imm_ptr(void* p) {
return Imm(static_cast<int64_t>((intptr_t)p));
}
//! \}
} // asmjit namespace } // asmjit namespace
@@ -1172,4 +1112,4 @@ struct Label : public Operand {
#include "../apiend.h" #include "../apiend.h"
// [Guard] // [Guard]
#endif // _ASMJIT_BASE_DEFS_H #endif // _ASMJIT_BASE_OPERAND_H

View File

@@ -9,7 +9,6 @@
#define _ASMJIT_BASE_PODLIST_H #define _ASMJIT_BASE_PODLIST_H
// [Dependencies - AsmJit] // [Dependencies - AsmJit]
#include "../base/defs.h"
#include "../base/globals.h" #include "../base/globals.h"
// [Api-Begin] // [Api-Begin]
@@ -17,14 +16,14 @@
namespace asmjit { namespace asmjit {
//! @addtogroup asmjit_base_util //! \addtogroup asmjit_base_util
//! @{ //! \{
// ============================================================================ // ============================================================================
// [asmjit::PodList<T>] // [asmjit::PodList<T>]
// ============================================================================ // ============================================================================
//! @internal //! \internal
template <typename T> template <typename T>
struct PodList { struct PodList {
ASMJIT_NO_COPY(PodList<T>) ASMJIT_NO_COPY(PodList<T>)
@@ -107,7 +106,7 @@ struct PodList {
Link* _last; Link* _last;
}; };
//! @} //! \}
} // asmjit namespace } // asmjit namespace

View File

@@ -9,23 +9,21 @@
#define _ASMJIT_BASE_PODVECTOR_H #define _ASMJIT_BASE_PODVECTOR_H
// [Dependencies - AsmJit] // [Dependencies - AsmJit]
#include "../base/defs.h"
#include "../base/error.h" #include "../base/error.h"
#include "../base/globals.h"
// [Api-Begin] // [Api-Begin]
#include "../apibegin.h" #include "../apibegin.h"
namespace asmjit { namespace asmjit {
//! @addtogroup asmjit_base_util //! \addtogroup asmjit_base_util
//! @{ //! \{
// ============================================================================ // ============================================================================
// [asmjit::PodVectorData] // [asmjit::PodVectorData]
// ============================================================================ // ============================================================================
//! @internal //! \internal
struct PodVectorData { struct PodVectorData {
//! Get data. //! Get data.
ASMJIT_INLINE void* getData() const { ASMJIT_INLINE void* getData() const {
@@ -42,7 +40,7 @@ struct PodVectorData {
// [asmjit::PodVectorBase] // [asmjit::PodVectorBase]
// ============================================================================ // ============================================================================
//! @internal //! \internal
struct PodVectorBase { struct PodVectorBase {
static ASMJIT_API const PodVectorData _nullData; static ASMJIT_API const PodVectorData _nullData;
@@ -124,7 +122,7 @@ struct PodVector : PodVectorBase {
return static_cast<T*>(_d->getData()); return static_cast<T*>(_d->getData());
} }
//! @overload //! \overload
ASMJIT_INLINE const T* getData() const { ASMJIT_INLINE const T* getData() const {
return static_cast<const T*>(_d->getData()); return static_cast<const T*>(_d->getData());
} }
@@ -271,7 +269,7 @@ struct PodVector : PodVectorBase {
} }
}; };
//! @} //! \}
} // asmjit namespace } // asmjit namespace

View File

@@ -10,7 +10,6 @@
// [Dependencies - AsmJit] // [Dependencies - AsmJit]
#include "../base/assembler.h" #include "../base/assembler.h"
#include "../base/cpuinfo.h" #include "../base/cpuinfo.h"
#include "../base/defs.h"
#include "../base/error.h" #include "../base/error.h"
#include "../base/runtime.h" #include "../base/runtime.h"
@@ -77,7 +76,7 @@ Error JitRuntime::add(void** dst, BaseAssembler* assembler) {
if (codeSize == 0) { if (codeSize == 0) {
*dst = NULL; *dst = NULL;
return kErrorCompilerNoFunc; return kErrorInvalidFunction;
} }
void* p = _memMgr.alloc(codeSize, getAllocType()); void* p = _memMgr.alloc(codeSize, getAllocType());
@@ -96,6 +95,8 @@ Error JitRuntime::add(void** dst, BaseAssembler* assembler) {
// Return the code. // Return the code.
*dst = p; *dst = p;
flush(p, relocSize);
return kErrorOk; return kErrorOk;
} }
@@ -103,6 +104,18 @@ Error JitRuntime::release(void* p) {
return _memMgr.release(p); return _memMgr.release(p);
} }
void JitRuntime::flush(void* p, size_t size) {
// Only useful on non-x86 architectures.
#if !defined(ASMJIT_HOST_X86) && !defined(ASMJIT_HOST_X64)
// Windows has built-in support in kernel32.dll.
#if defined(ASMJIT_OS_WINDOWS)
::FlushInstructionCache(_memMgr.getProcessHandle(), p, size);
#endif // ASMJIT_OS_WINDOWS
#endif // !ASMJIT_HOST_X86 && !ASMJIT_HOST_X64
}
} // asmjit namespace } // asmjit namespace
// [Api-End] // [Api-End]

View File

@@ -17,9 +17,6 @@
namespace asmjit { namespace asmjit {
//! @addtogroup asmjit_base_codegen
//! @{
// ============================================================================ // ============================================================================
// [Forward Declarations] // [Forward Declarations]
// ============================================================================ // ============================================================================
@@ -27,6 +24,9 @@ namespace asmjit {
struct BaseAssembler; struct BaseAssembler;
struct BaseCpuInfo; struct BaseCpuInfo;
//! \addtogroup asmjit_base_general
//! \{
// ============================================================================ // ============================================================================
// [asmjit::Runtime] // [asmjit::Runtime]
// ============================================================================ // ============================================================================
@@ -54,10 +54,12 @@ struct Runtime {
//! Get CPU information. //! Get CPU information.
virtual const BaseCpuInfo* getCpuInfo() = 0; virtual const BaseCpuInfo* getCpuInfo() = 0;
//! Allocate a memory needed for a code generated by `BaseAssembler` and //! Allocate a memory needed for a code generated by `assembler` and
//! relocate it to the target location. //! relocate it to the target location.
//! //!
//! Returns Status code as `kError`. //! 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, BaseAssembler* assembler) = 0; virtual Error add(void** dst, BaseAssembler* assembler) = 0;
//! Release memory allocated by `add`. //! Release memory allocated by `add`.
@@ -115,6 +117,19 @@ struct JitRuntime : public Runtime {
ASMJIT_API virtual Error add(void** dst, BaseAssembler* assembler); ASMJIT_API virtual Error add(void** dst, BaseAssembler* assembler);
ASMJIT_API virtual Error release(void* p); ASMJIT_API virtual Error release(void* p);
//! Flush 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 to flush the processor cache so it will not use the old data.
//!
//! Flushing is basically a NOP under X86/X64, but is needed by architectures
//! not having a transparent cache.
//!
//! This function can also be overridden to improve compatibility with tools
//! like Valgrind, but this is not an official part of AsmJit.
ASMJIT_API virtual void flush(void* p, size_t size);
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [Members] // [Members]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -125,7 +140,7 @@ struct JitRuntime : public Runtime {
uint32_t _allocType; uint32_t _allocType;
}; };
//! @} //! \}
} // asmjit namespace } // asmjit namespace

View File

@@ -8,7 +8,6 @@
#define ASMJIT_EXPORTS #define ASMJIT_EXPORTS
// [Dependencies - AsmJit] // [Dependencies - AsmJit]
#include "../base/defs.h"
#include "../base/intutil.h" #include "../base/intutil.h"
#include "../base/string.h" #include "../base/string.h"

View File

@@ -9,7 +9,6 @@
#define _ASMJIT_BASE_STRING_H #define _ASMJIT_BASE_STRING_H
// [Dependencies - AsmJit] // [Dependencies - AsmJit]
#include "../base/defs.h"
#include "../base/globals.h" #include "../base/globals.h"
// [Dependencies - C] // [Dependencies - C]
@@ -20,14 +19,14 @@
namespace asmjit { namespace asmjit {
//! @addtogroup asmjit_base_util //! \addtogroup asmjit_base_util
//! @{ //! \{
// ============================================================================ // ============================================================================
// [asmjit::kStringOp] // [asmjit::kStringOp]
// ============================================================================ // ============================================================================
//! @internal //! \internal
//! //!
//! String operation. //! String operation.
ASMJIT_ENUM(kStringOp) { ASMJIT_ENUM(kStringOp) {
@@ -41,7 +40,7 @@ ASMJIT_ENUM(kStringOp) {
// [asmjit::kStringFormat] // [asmjit::kStringFormat]
// ============================================================================ // ============================================================================
//! @internal //! \internal
//! //!
//! String format flags. //! String format flags.
ASMJIT_ENUM(kStringFormat) { ASMJIT_ENUM(kStringFormat) {
@@ -55,8 +54,6 @@ ASMJIT_ENUM(kStringFormat) {
// [asmjit::StringUtil] // [asmjit::StringUtil]
// ============================================================================ // ============================================================================
//! @internal
//!
//! String utilities. //! String utilities.
struct StringUtil { struct StringUtil {
static ASMJIT_INLINE size_t nlen(const char* s, size_t maxlen) { static ASMJIT_INLINE size_t nlen(const char* s, size_t maxlen) {
@@ -72,8 +69,6 @@ struct StringUtil {
// [asmjit::StringBuilder] // [asmjit::StringBuilder]
// ============================================================================ // ============================================================================
//! @internal
//!
//! String builder. //! String builder.
//! //!
//! String builder was designed to be able to build a string using append like //! String builder was designed to be able to build a string using append like
@@ -339,7 +334,7 @@ struct StringBuilder {
// [asmjit::StringBuilderT] // [asmjit::StringBuilderT]
// ============================================================================ // ============================================================================
//! @internal //! \internal
template<size_t N> template<size_t N>
struct StringBuilderT : public StringBuilder { struct StringBuilderT : public StringBuilder {
ASMJIT_NO_COPY(StringBuilderT<N>) ASMJIT_NO_COPY(StringBuilderT<N>)
@@ -366,7 +361,7 @@ struct StringBuilderT : public StringBuilder {
N + 1 + sizeof(intptr_t)) & ~static_cast<size_t>(sizeof(intptr_t) - 1)]; N + 1 + sizeof(intptr_t)) & ~static_cast<size_t>(sizeof(intptr_t) - 1)];
}; };
//! @} //! \}
} // asmjit namespace } // asmjit namespace

View File

@@ -9,15 +9,15 @@
#define _ASMJIT_BASE_VECTYPES_H #define _ASMJIT_BASE_VECTYPES_H
// [Dependencies - AsmJit] // [Dependencies - AsmJit]
#include "../base/defs.h" #include "../base/globals.h"
// [Api-Begin] // [Api-Begin]
#include "../apibegin.h" #include "../apibegin.h"
namespace asmjit { namespace asmjit {
//! @addtogroup asmjit_base_vectypes //! \addtogroup asmjit_base_util
//! @{ //! \{
// ============================================================================ // ============================================================================
// [asmjit::Vec64Data] // [asmjit::Vec64Data]
@@ -29,7 +29,7 @@ union Vec64Data {
// [Construction / Destruction] // [Construction / Destruction]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Set all eight signed 8-bit integers. //! Set all eight 8-bit signed integers.
static ASMJIT_INLINE Vec64Data fromSb( static ASMJIT_INLINE Vec64Data 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 x0, int8_t x1, int8_t x2, int8_t x3, int8_t x4, int8_t x5, int8_t x6, int8_t x7)
{ {
@@ -38,7 +38,7 @@ union Vec64Data {
return self; return self;
} }
//! Set all eight signed 8-bit integers. //! Set all eight 8-bit signed integers.
static ASMJIT_INLINE Vec64Data fromSb( static ASMJIT_INLINE Vec64Data fromSb(
int8_t x0) int8_t x0)
{ {
@@ -47,7 +47,7 @@ union Vec64Data {
return self; return self;
} }
//! Set all eight unsigned 8-bit integers. //! Set all eight 8-bit unsigned integers.
static ASMJIT_INLINE Vec64Data fromUb( static ASMJIT_INLINE Vec64Data 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 x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7)
{ {
@@ -56,7 +56,7 @@ union Vec64Data {
return self; return self;
} }
//! Set all eight unsigned 8-bit integers. //! Set all eight 8-bit unsigned integers.
static ASMJIT_INLINE Vec64Data fromUb( static ASMJIT_INLINE Vec64Data fromUb(
uint8_t x0) uint8_t x0)
{ {
@@ -65,7 +65,7 @@ union Vec64Data {
return self; return self;
} }
//! Set all four signed 16-bit integers. //! Set all four 16-bit signed integers.
static ASMJIT_INLINE Vec64Data fromSw( static ASMJIT_INLINE Vec64Data fromSw(
int16_t x0, int16_t x1, int16_t x2, int16_t x3) int16_t x0, int16_t x1, int16_t x2, int16_t x3)
{ {
@@ -74,7 +74,7 @@ union Vec64Data {
return self; return self;
} }
//! Set all four signed 16-bit integers. //! Set all four 16-bit signed integers.
static ASMJIT_INLINE Vec64Data fromSw( static ASMJIT_INLINE Vec64Data fromSw(
int16_t x0) int16_t x0)
{ {
@@ -83,7 +83,7 @@ union Vec64Data {
return self; return self;
} }
//! Set all four unsigned 16-bit integers. //! Set all four 16-bit unsigned integers.
static ASMJIT_INLINE Vec64Data fromUw( static ASMJIT_INLINE Vec64Data fromUw(
uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3) uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3)
{ {
@@ -92,7 +92,7 @@ union Vec64Data {
return self; return self;
} }
//! Set all four unsigned 16-bit integers. //! Set all four 16-bit unsigned integers.
static ASMJIT_INLINE Vec64Data fromUw( static ASMJIT_INLINE Vec64Data fromUw(
uint16_t x0) uint16_t x0)
{ {
@@ -101,7 +101,7 @@ union Vec64Data {
return self; return self;
} }
//! Set all two signed 32-bit integers. //! Set all two 32-bit signed integers.
static ASMJIT_INLINE Vec64Data fromSd( static ASMJIT_INLINE Vec64Data fromSd(
int32_t x0, int32_t x1) int32_t x0, int32_t x1)
{ {
@@ -110,7 +110,7 @@ union Vec64Data {
return self; return self;
} }
//! Set all two signed 32-bit integers. //! Set all two 32-bit signed integers.
static ASMJIT_INLINE Vec64Data fromSd( static ASMJIT_INLINE Vec64Data fromSd(
int32_t x0) int32_t x0)
{ {
@@ -119,7 +119,7 @@ union Vec64Data {
return self; return self;
} }
//! Set all two unsigned 32-bit integers. //! Set all two 32-bit unsigned integers.
static ASMJIT_INLINE Vec64Data fromUd( static ASMJIT_INLINE Vec64Data fromUd(
uint32_t x0, uint32_t x1) uint32_t x0, uint32_t x1)
{ {
@@ -128,7 +128,7 @@ union Vec64Data {
return self; return self;
} }
//! Set all two unsigned 32-bit integers. //! Set all two 32-bit unsigned integers.
static ASMJIT_INLINE Vec64Data fromUd( static ASMJIT_INLINE Vec64Data fromUd(
uint32_t x0) uint32_t x0)
{ {
@@ -137,7 +137,7 @@ union Vec64Data {
return self; return self;
} }
//! Set signed 64-bit integer. //! Set 64-bit signed integer.
static ASMJIT_INLINE Vec64Data fromSq( static ASMJIT_INLINE Vec64Data fromSq(
int64_t x0) int64_t x0)
{ {
@@ -146,7 +146,7 @@ union Vec64Data {
return self; return self;
} }
//! Set unsigned 64-bit integer. //! Set 64-bit unsigned integer.
static ASMJIT_INLINE Vec64Data fromUq( static ASMJIT_INLINE Vec64Data fromUq(
uint64_t x0) uint64_t x0)
{ {
@@ -186,7 +186,7 @@ union Vec64Data {
// [Accessors] // [Accessors]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Set all eight signed 8-bit integers. //! Set all eight 8-bit signed integers.
ASMJIT_INLINE void setSb( 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 x0, int8_t x1, int8_t x2, int8_t x3, int8_t x4, int8_t x5, int8_t x6, int8_t x7)
{ {
@@ -194,14 +194,14 @@ union Vec64Data {
sb[4] = x4; sb[5] = x5; sb[6] = x6; sb[7] = x7; sb[4] = x4; sb[5] = x5; sb[6] = x6; sb[7] = x7;
} }
//! Set all eight signed 8-bit integers. //! Set all eight 8-bit signed integers.
ASMJIT_INLINE void setSb( ASMJIT_INLINE void setSb(
int8_t x0) int8_t x0)
{ {
setUb(static_cast<uint8_t>(x0)); setUb(static_cast<uint8_t>(x0));
} }
//! Set all eight unsigned 8-bit integers. //! Set all eight 8-bit unsigned integers.
ASMJIT_INLINE void setUb( 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 x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7)
{ {
@@ -209,7 +209,7 @@ union Vec64Data {
ub[4] = x4; ub[5] = x5; ub[6] = x6; ub[7] = x7; ub[4] = x4; ub[5] = x5; ub[6] = x6; ub[7] = x7;
} }
//! Set all eight unsigned 8-bit integers. //! Set all eight 8-bit unsigned integers.
ASMJIT_INLINE void setUb( ASMJIT_INLINE void setUb(
uint8_t x0) uint8_t x0)
{ {
@@ -224,28 +224,28 @@ union Vec64Data {
} }
} }
//! Set all four signed 16-bit integers. //! Set all four 16-bit signed integers.
ASMJIT_INLINE void setSw( ASMJIT_INLINE void setSw(
int16_t x0, int16_t x1, int16_t x2, int16_t x3) int16_t x0, int16_t x1, int16_t x2, int16_t x3)
{ {
sw[0] = x0; sw[1] = x1; sw[2] = x2; sw[3] = x3; sw[0] = x0; sw[1] = x1; sw[2] = x2; sw[3] = x3;
} }
//! Set all four signed 16-bit integers. //! Set all four 16-bit signed integers.
ASMJIT_INLINE void setSw( ASMJIT_INLINE void setSw(
int16_t x0) int16_t x0)
{ {
setUw(static_cast<uint16_t>(x0)); setUw(static_cast<uint16_t>(x0));
} }
//! Set all four unsigned 16-bit integers. //! Set all four 16-bit unsigned integers.
ASMJIT_INLINE void setUw( ASMJIT_INLINE void setUw(
uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3) uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3)
{ {
uw[0] = x0; uw[1] = x1; uw[2] = x2; uw[3] = x3; uw[0] = x0; uw[1] = x1; uw[2] = x2; uw[3] = x3;
} }
//! Set all four unsigned 16-bit integers. //! Set all four 16-bit unsigned integers.
ASMJIT_INLINE void setUw( ASMJIT_INLINE void setUw(
uint16_t x0) uint16_t x0)
{ {
@@ -260,42 +260,42 @@ union Vec64Data {
} }
} }
//! Set all two signed 32-bit integers. //! Set all two 32-bit signed integers.
ASMJIT_INLINE void setSd( ASMJIT_INLINE void setSd(
int32_t x0, int32_t x1) int32_t x0, int32_t x1)
{ {
sd[0] = x0; sd[1] = x1; sd[0] = x0; sd[1] = x1;
} }
//! Set all two signed 32-bit integers. //! Set all two 32-bit signed integers.
ASMJIT_INLINE void setSd( ASMJIT_INLINE void setSd(
int32_t x0) int32_t x0)
{ {
sd[0] = x0; sd[1] = x0; sd[0] = x0; sd[1] = x0;
} }
//! Set all two unsigned 32-bit integers. //! Set all two 32-bit unsigned integers.
ASMJIT_INLINE void setUd( ASMJIT_INLINE void setUd(
uint32_t x0, uint32_t x1) uint32_t x0, uint32_t x1)
{ {
ud[0] = x0; ud[1] = x1; ud[0] = x0; ud[1] = x1;
} }
//! Set all two unsigned 32-bit integers. //! Set all two 32-bit unsigned integers.
ASMJIT_INLINE void setUd( ASMJIT_INLINE void setUd(
uint32_t x0) uint32_t x0)
{ {
ud[0] = x0; ud[1] = x0; ud[0] = x0; ud[1] = x0;
} }
//! Set signed 64-bit integer. //! Set 64-bit signed integer.
ASMJIT_INLINE void setSq( ASMJIT_INLINE void setSq(
int64_t x0) int64_t x0)
{ {
sq[0] = x0; sq[0] = x0;
} }
//! Set unsigned 64-bit integer. //! Set 64-bit unsigned integer.
ASMJIT_INLINE void setUq( ASMJIT_INLINE void setUq(
uint64_t x0) uint64_t x0)
{ {
@@ -327,21 +327,21 @@ union Vec64Data {
// [Members] // [Members]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Array of eight signed 8-bit integers. //! Array of eight 8-bit signed integers.
int8_t sb[8]; int8_t sb[8];
//! Array of eight unsigned 8-bit integers. //! Array of eight 8-bit unsigned integers.
uint8_t ub[8]; uint8_t ub[8];
//! Array of four signed 16-bit integers. //! Array of four 16-bit signed integers.
int16_t sw[4]; int16_t sw[4];
//! Array of four unsigned 16-bit integers. //! Array of four 16-bit unsigned integers.
uint16_t uw[4]; uint16_t uw[4];
//! Array of two signed 32-bit integers. //! Array of two 32-bit signed integers.
int32_t sd[2]; int32_t sd[2];
//! Array of two unsigned 32-bit integers. //! Array of two 32-bit unsigned integers.
uint32_t ud[2]; uint32_t ud[2];
//! Array of one signed 64-bit integer. //! Array of one 64-bit signed integer.
int64_t sq[1]; int64_t sq[1];
//! Array of one unsigned 64-bit integer. //! Array of one 64-bit unsigned integer.
uint64_t uq[1]; uint64_t uq[1];
//! Array of two SP-FP values. //! Array of two SP-FP values.
@@ -360,7 +360,7 @@ union Vec128Data {
// [Construction / Destruction] // [Construction / Destruction]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Set all sixteen signed 8-bit integers. //! Set all sixteen 8-bit signed integers.
static ASMJIT_INLINE Vec128Data fromSb( static ASMJIT_INLINE Vec128Data fromSb(
int8_t x0 , int8_t x1 , int8_t x2 , int8_t x3 , 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 x4 , int8_t x5 , int8_t x6 , int8_t x7 ,
@@ -372,7 +372,7 @@ union Vec128Data {
return self; return self;
} }
//! Set all sixteen signed 8-bit integers. //! Set all sixteen 8-bit signed integers.
static ASMJIT_INLINE Vec128Data fromSb( static ASMJIT_INLINE Vec128Data fromSb(
int8_t x0) int8_t x0)
{ {
@@ -381,7 +381,7 @@ union Vec128Data {
return self; return self;
} }
//! Set all sixteen unsigned 8-bit integers. //! Set all sixteen 8-bit unsigned integers.
static ASMJIT_INLINE Vec128Data fromUb( static ASMJIT_INLINE Vec128Data fromUb(
uint8_t x0 , uint8_t x1 , uint8_t x2 , uint8_t x3 , 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 x4 , uint8_t x5 , uint8_t x6 , uint8_t x7 ,
@@ -393,7 +393,7 @@ union Vec128Data {
return self; return self;
} }
//! Set all sixteen unsigned 8-bit integers. //! Set all sixteen 8-bit unsigned integers.
static ASMJIT_INLINE Vec128Data fromUb( static ASMJIT_INLINE Vec128Data fromUb(
uint8_t x0) uint8_t x0)
{ {
@@ -402,7 +402,7 @@ union Vec128Data {
return self; return self;
} }
//! Set all eight signed 16-bit integers. //! Set all eight 16-bit signed integers.
static ASMJIT_INLINE Vec128Data fromSw( static ASMJIT_INLINE Vec128Data 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 x0, int16_t x1, int16_t x2, int16_t x3, int16_t x4, int16_t x5, int16_t x6, int16_t x7)
{ {
@@ -411,7 +411,7 @@ union Vec128Data {
return self; return self;
} }
//! Set all eight signed 16-bit integers. //! Set all eight 16-bit signed integers.
static ASMJIT_INLINE Vec128Data fromSw( static ASMJIT_INLINE Vec128Data fromSw(
int16_t x0) int16_t x0)
{ {
@@ -420,7 +420,7 @@ union Vec128Data {
return self; return self;
} }
//! Set all eight unsigned 16-bit integers. //! Set all eight 16-bit unsigned integers.
static ASMJIT_INLINE Vec128Data fromUw( static ASMJIT_INLINE Vec128Data 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 x0, uint16_t x1, uint16_t x2, uint16_t x3, uint16_t x4, uint16_t x5, uint16_t x6, uint16_t x7)
{ {
@@ -429,7 +429,7 @@ union Vec128Data {
return self; return self;
} }
//! Set all eight unsigned 16-bit integers. //! Set all eight 16-bit unsigned integers.
static ASMJIT_INLINE Vec128Data fromUw( static ASMJIT_INLINE Vec128Data fromUw(
uint16_t x0) uint16_t x0)
{ {
@@ -438,7 +438,7 @@ union Vec128Data {
return self; return self;
} }
//! Set all four signed 32-bit integers. //! Set all four 32-bit signed integers.
static ASMJIT_INLINE Vec128Data fromSd( static ASMJIT_INLINE Vec128Data fromSd(
int32_t x0, int32_t x1, int32_t x2, int32_t x3) int32_t x0, int32_t x1, int32_t x2, int32_t x3)
{ {
@@ -447,7 +447,7 @@ union Vec128Data {
return self; return self;
} }
//! Set all four signed 32-bit integers. //! Set all four 32-bit signed integers.
static ASMJIT_INLINE Vec128Data fromSd( static ASMJIT_INLINE Vec128Data fromSd(
int32_t x0) int32_t x0)
{ {
@@ -456,7 +456,7 @@ union Vec128Data {
return self; return self;
} }
//! Set all four unsigned 32-bit integers. //! Set all four 32-bit unsigned integers.
static ASMJIT_INLINE Vec128Data fromUd( static ASMJIT_INLINE Vec128Data fromUd(
uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3) uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3)
{ {
@@ -465,7 +465,7 @@ union Vec128Data {
return self; return self;
} }
//! Set all four unsigned 32-bit integers. //! Set all four 32-bit unsigned integers.
static ASMJIT_INLINE Vec128Data fromUd( static ASMJIT_INLINE Vec128Data fromUd(
uint32_t x0) uint32_t x0)
{ {
@@ -474,7 +474,7 @@ union Vec128Data {
return self; return self;
} }
//! Set all two signed 64-bit integers. //! Set all two 64-bit signed integers.
static ASMJIT_INLINE Vec128Data fromSq( static ASMJIT_INLINE Vec128Data fromSq(
int64_t x0, int64_t x1) int64_t x0, int64_t x1)
{ {
@@ -483,7 +483,7 @@ union Vec128Data {
return self; return self;
} }
//! Set all two signed 64-bit integers. //! Set all two 64-bit signed integers.
static ASMJIT_INLINE Vec128Data fromSq( static ASMJIT_INLINE Vec128Data fromSq(
int64_t x0) int64_t x0)
{ {
@@ -492,7 +492,7 @@ union Vec128Data {
return self; return self;
} }
//! Set all two unsigned 64-bit integers. //! Set all two 64-bit unsigned integers.
static ASMJIT_INLINE Vec128Data fromUq( static ASMJIT_INLINE Vec128Data fromUq(
uint64_t x0, uint64_t x1) uint64_t x0, uint64_t x1)
{ {
@@ -501,7 +501,7 @@ union Vec128Data {
return self; return self;
} }
//! Set all two unsigned 64-bit integers. //! Set all two 64-bit unsigned integers.
static ASMJIT_INLINE Vec128Data fromUq( static ASMJIT_INLINE Vec128Data fromUq(
uint64_t x0) uint64_t x0)
{ {
@@ -550,7 +550,7 @@ union Vec128Data {
// [Accessors] // [Accessors]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Set all sixteen signed 8-bit integers. //! Set all sixteen 8-bit signed integers.
ASMJIT_INLINE void setSb( ASMJIT_INLINE void setSb(
int8_t x0 , int8_t x1 , int8_t x2 , int8_t x3 , 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 x4 , int8_t x5 , int8_t x6 , int8_t x7 ,
@@ -563,14 +563,14 @@ union Vec128Data {
sb[12] = x12; sb[13] = x13; sb[14] = x14; sb[15] = x15; sb[12] = x12; sb[13] = x13; sb[14] = x14; sb[15] = x15;
} }
//! Set all sixteen signed 8-bit integers. //! Set all sixteen 8-bit signed integers.
ASMJIT_INLINE void setSb( ASMJIT_INLINE void setSb(
int8_t x0) int8_t x0)
{ {
setUb(static_cast<uint8_t>(x0)); setUb(static_cast<uint8_t>(x0));
} }
//! Set all sixteen unsigned 8-bit integers. //! Set all sixteen 8-bit unsigned integers.
ASMJIT_INLINE void setUb( ASMJIT_INLINE void setUb(
uint8_t x0 , uint8_t x1 , uint8_t x2 , uint8_t x3 , 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 x4 , uint8_t x5 , uint8_t x6 , uint8_t x7 ,
@@ -583,7 +583,7 @@ union Vec128Data {
ub[12] = x12; ub[13] = x13; ub[14] = x14; ub[15] = x15; ub[12] = x12; ub[13] = x13; ub[14] = x14; ub[15] = x15;
} }
//! Set all sixteen unsigned 8-bit integers. //! Set all sixteen 8-bit unsigned integers.
ASMJIT_INLINE void setUb( ASMJIT_INLINE void setUb(
uint8_t x0) uint8_t x0)
{ {
@@ -601,7 +601,7 @@ union Vec128Data {
} }
} }
//! Set all eight signed 16-bit integers. //! Set all eight 16-bit signed integers.
ASMJIT_INLINE void setSw( 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 x0, int16_t x1, int16_t x2, int16_t x3, int16_t x4, int16_t x5, int16_t x6, int16_t x7)
{ {
@@ -609,14 +609,14 @@ union Vec128Data {
sw[4] = x4; sw[5] = x5; sw[6] = x6; sw[7] = x7; sw[4] = x4; sw[5] = x5; sw[6] = x6; sw[7] = x7;
} }
//! Set all eight signed 16-bit integers. //! Set all eight 16-bit signed integers.
ASMJIT_INLINE void setSw( ASMJIT_INLINE void setSw(
int16_t x0) int16_t x0)
{ {
setUw(static_cast<uint16_t>(x0)); setUw(static_cast<uint16_t>(x0));
} }
//! Set all eight unsigned 16-bit integers. //! Set all eight 16-bit unsigned integers.
ASMJIT_INLINE void setUw( 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 x0, uint16_t x1, uint16_t x2, uint16_t x3, uint16_t x4, uint16_t x5, uint16_t x6, uint16_t x7)
{ {
@@ -624,7 +624,7 @@ union Vec128Data {
uw[4] = x4; uw[5] = x5; uw[6] = x6; uw[7] = x7; uw[4] = x4; uw[5] = x5; uw[6] = x6; uw[7] = x7;
} }
//! Set all eight unsigned 16-bit integers. //! Set all eight 16-bit unsigned integers.
ASMJIT_INLINE void setUw( ASMJIT_INLINE void setUw(
uint16_t x0) uint16_t x0)
{ {
@@ -642,28 +642,28 @@ union Vec128Data {
} }
} }
//! Set all four signed 32-bit integers. //! Set all four 32-bit signed integers.
ASMJIT_INLINE void setSd( ASMJIT_INLINE void setSd(
int32_t x0, int32_t x1, int32_t x2, int32_t x3) int32_t x0, int32_t x1, int32_t x2, int32_t x3)
{ {
sd[0] = x0; sd[1] = x1; sd[2] = x2; sd[3] = x3; sd[0] = x0; sd[1] = x1; sd[2] = x2; sd[3] = x3;
} }
//! Set all four signed 32-bit integers. //! Set all four 32-bit signed integers.
ASMJIT_INLINE void setSd( ASMJIT_INLINE void setSd(
int32_t x0) int32_t x0)
{ {
setUd(static_cast<uint32_t>(x0)); setUd(static_cast<uint32_t>(x0));
} }
//! Set all four unsigned 32-bit integers. //! Set all four 32-bit unsigned integers.
ASMJIT_INLINE void setUd( ASMJIT_INLINE void setUd(
uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3) uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3)
{ {
ud[0] = x0; ud[1] = x1; ud[2] = x2; ud[3] = x3; ud[0] = x0; ud[1] = x1; ud[2] = x2; ud[3] = x3;
} }
//! Set all four unsigned 32-bit integers. //! Set all four 32-bit unsigned integers.
ASMJIT_INLINE void setUd( ASMJIT_INLINE void setUd(
uint32_t x0) uint32_t x0)
{ {
@@ -680,28 +680,28 @@ union Vec128Data {
} }
} }
//! Set all two signed 64-bit integers. //! Set all two 64-bit signed integers.
ASMJIT_INLINE void setSq( ASMJIT_INLINE void setSq(
int64_t x0, int64_t x1) int64_t x0, int64_t x1)
{ {
sq[0] = x0; sq[1] = x1; sq[0] = x0; sq[1] = x1;
} }
//! Set all two signed 64-bit integers. //! Set all two 64-bit signed integers.
ASMJIT_INLINE void setSq( ASMJIT_INLINE void setSq(
int64_t x0) int64_t x0)
{ {
sq[0] = x0; sq[1] = x0; sq[0] = x0; sq[1] = x0;
} }
//! Set all two unsigned 64-bit integers. //! Set all two 64-bit unsigned integers.
ASMJIT_INLINE void setUq( ASMJIT_INLINE void setUq(
uint64_t x0, uint64_t x1) uint64_t x0, uint64_t x1)
{ {
uq[0] = x0; uq[1] = x1; uq[0] = x0; uq[1] = x1;
} }
//! Set all two unsigned 64-bit integers. //! Set all two 64-bit unsigned integers.
ASMJIT_INLINE void setUq( ASMJIT_INLINE void setUq(
uint64_t x0) uint64_t x0)
{ {
@@ -740,21 +740,21 @@ union Vec128Data {
// [Members] // [Members]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Array of sixteen signed 8-bit integers. //! Array of sixteen 8-bit signed integers.
int8_t sb[16]; int8_t sb[16];
//! Array of sixteen unsigned 8-bit integers. //! Array of sixteen 8-bit unsigned integers.
uint8_t ub[16]; uint8_t ub[16];
//! Array of eight signed 16-bit integers. //! Array of eight 16-bit signed integers.
int16_t sw[8]; int16_t sw[8];
//! Array of eight unsigned 16-bit integers. //! Array of eight 16-bit unsigned integers.
uint16_t uw[8]; uint16_t uw[8];
//! Array of four signed 32-bit integers. //! Array of four 32-bit signed integers.
int32_t sd[4]; int32_t sd[4];
//! Array of four unsigned 32-bit integers. //! Array of four 32-bit unsigned integers.
uint32_t ud[4]; uint32_t ud[4];
//! Array of two signed 64-bit integers. //! Array of two 64-bit signed integers.
int64_t sq[2]; int64_t sq[2];
//! Array of two unsigned 64-bit integers. //! Array of two 64-bit unsigned integers.
uint64_t uq[2]; uint64_t uq[2];
//! Array of four 32-bit single precision floating points. //! Array of four 32-bit single precision floating points.
@@ -773,7 +773,7 @@ union Vec256Data {
// [Construction / Destruction] // [Construction / Destruction]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Set all thirty two signed 8-bit integers. //! Set all thirty two 8-bit signed integers.
static ASMJIT_INLINE Vec256Data fromSb( static ASMJIT_INLINE Vec256Data fromSb(
int8_t x0 , int8_t x1 , int8_t x2 , int8_t x3 , 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 x4 , int8_t x5 , int8_t x6 , int8_t x7 ,
@@ -791,7 +791,7 @@ union Vec256Data {
return self; return self;
} }
//! Set all thirty two signed 8-bit integers. //! Set all thirty two 8-bit signed integers.
static ASMJIT_INLINE Vec256Data fromSb( static ASMJIT_INLINE Vec256Data fromSb(
int8_t x0) int8_t x0)
{ {
@@ -800,7 +800,7 @@ union Vec256Data {
return self; return self;
} }
//! Set all thirty two unsigned 8-bit integers. //! Set all thirty two 8-bit unsigned integers.
static ASMJIT_INLINE Vec256Data fromUb( static ASMJIT_INLINE Vec256Data fromUb(
uint8_t x0 , uint8_t x1 , uint8_t x2 , uint8_t x3 , 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 x4 , uint8_t x5 , uint8_t x6 , uint8_t x7 ,
@@ -818,7 +818,7 @@ union Vec256Data {
return self; return self;
} }
//! Set all thirty two unsigned 8-bit integers. //! Set all thirty two 8-bit unsigned integers.
static ASMJIT_INLINE Vec256Data fromUb( static ASMJIT_INLINE Vec256Data fromUb(
uint8_t x0) uint8_t x0)
{ {
@@ -827,7 +827,7 @@ union Vec256Data {
return self; return self;
} }
//! Set all sixteen signed 16-bit integers. //! Set all sixteen 16-bit signed integers.
static ASMJIT_INLINE Vec256Data fromSw( static ASMJIT_INLINE Vec256Data 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 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) int16_t x8, int16_t x9, int16_t x10, int16_t x11, int16_t x12, int16_t x13, int16_t x14, int16_t x15)
@@ -837,7 +837,7 @@ union Vec256Data {
return self; return self;
} }
//! Set all sixteen signed 16-bit integers. //! Set all sixteen 16-bit signed integers.
static ASMJIT_INLINE Vec256Data fromSw( static ASMJIT_INLINE Vec256Data fromSw(
int16_t x0) int16_t x0)
{ {
@@ -846,7 +846,7 @@ union Vec256Data {
return self; return self;
} }
//! Set all sixteen unsigned 16-bit integers. //! Set all sixteen 16-bit unsigned integers.
static ASMJIT_INLINE Vec256Data fromUw( static ASMJIT_INLINE Vec256Data 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 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) uint16_t x8, uint16_t x9, uint16_t x10, uint16_t x11, uint16_t x12, uint16_t x13, uint16_t x14, uint16_t x15)
@@ -856,7 +856,7 @@ union Vec256Data {
return self; return self;
} }
//! Set all sixteen unsigned 16-bit integers. //! Set all sixteen 16-bit unsigned integers.
static ASMJIT_INLINE Vec256Data fromUw( static ASMJIT_INLINE Vec256Data fromUw(
uint16_t x0) uint16_t x0)
{ {
@@ -865,7 +865,7 @@ union Vec256Data {
return self; return self;
} }
//! Set all eight signed 32-bit integers. //! Set all eight 32-bit signed integers.
static ASMJIT_INLINE Vec256Data fromSd( static ASMJIT_INLINE Vec256Data fromSd(
int32_t x0, int32_t x1, int32_t x2, int32_t x3, int32_t x0, int32_t x1, int32_t x2, int32_t x3,
int32_t x4, int32_t x5, int32_t x6, int32_t x7) int32_t x4, int32_t x5, int32_t x6, int32_t x7)
@@ -875,7 +875,7 @@ union Vec256Data {
return self; return self;
} }
//! Set all eight signed 32-bit integers. //! Set all eight 32-bit signed integers.
static ASMJIT_INLINE Vec256Data fromSd( static ASMJIT_INLINE Vec256Data fromSd(
int32_t x0) int32_t x0)
{ {
@@ -884,7 +884,7 @@ union Vec256Data {
return self; return self;
} }
//! Set all eight unsigned 32-bit integers. //! Set all eight 32-bit unsigned integers.
static ASMJIT_INLINE Vec256Data fromUd( static ASMJIT_INLINE Vec256Data fromUd(
uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, 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 x4, uint32_t x5, uint32_t x6, uint32_t x7)
@@ -894,7 +894,7 @@ union Vec256Data {
return self; return self;
} }
//! Set all eight unsigned 32-bit integers. //! Set all eight 32-bit unsigned integers.
static ASMJIT_INLINE Vec256Data fromUd( static ASMJIT_INLINE Vec256Data fromUd(
uint32_t x0) uint32_t x0)
{ {
@@ -903,7 +903,7 @@ union Vec256Data {
return self; return self;
} }
//! Set all four signed 64-bit integers. //! Set all four 64-bit signed integers.
static ASMJIT_INLINE Vec256Data fromSq( static ASMJIT_INLINE Vec256Data fromSq(
int64_t x0, int64_t x1, int64_t x2, int64_t x3) int64_t x0, int64_t x1, int64_t x2, int64_t x3)
{ {
@@ -912,7 +912,7 @@ union Vec256Data {
return self; return self;
} }
//! Set all four signed 64-bit integers. //! Set all four 64-bit signed integers.
static ASMJIT_INLINE Vec256Data fromSq( static ASMJIT_INLINE Vec256Data fromSq(
int64_t x0) int64_t x0)
{ {
@@ -921,7 +921,7 @@ union Vec256Data {
return self; return self;
} }
//! Set all four unsigned 64-bit integers. //! Set all four 64-bit unsigned integers.
static ASMJIT_INLINE Vec256Data fromUq( static ASMJIT_INLINE Vec256Data fromUq(
uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3) uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3)
{ {
@@ -930,7 +930,7 @@ union Vec256Data {
return self; return self;
} }
//! Set all four unsigned 64-bit integers. //! Set all four 64-bit unsigned integers.
static ASMJIT_INLINE Vec256Data fromUq( static ASMJIT_INLINE Vec256Data fromUq(
uint64_t x0) uint64_t x0)
{ {
@@ -980,7 +980,7 @@ union Vec256Data {
// [Accessors] // [Accessors]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Set all thirty two signed 8-bit integers. //! Set all thirty two 8-bit signed integers.
ASMJIT_INLINE void setSb( ASMJIT_INLINE void setSb(
int8_t x0 , int8_t x1 , int8_t x2 , int8_t x3 , 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 x4 , int8_t x5 , int8_t x6 , int8_t x7 ,
@@ -1001,14 +1001,14 @@ union Vec256Data {
sb[28] = x28; sb[29] = x29; sb[30] = x30; sb[31] = x31; sb[28] = x28; sb[29] = x29; sb[30] = x30; sb[31] = x31;
} }
//! Set all thirty two signed 8-bit integers. //! Set all thirty two 8-bit signed integers.
ASMJIT_INLINE void setSb( ASMJIT_INLINE void setSb(
int8_t x0) int8_t x0)
{ {
setUb(static_cast<uint8_t>(x0)); setUb(static_cast<uint8_t>(x0));
} }
//! Set all thirty two unsigned 8-bit integers. //! Set all thirty two 8-bit unsigned integers.
ASMJIT_INLINE void setUb( ASMJIT_INLINE void setUb(
uint8_t x0 , uint8_t x1 , uint8_t x2 , uint8_t x3 , 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 x4 , uint8_t x5 , uint8_t x6 , uint8_t x7 ,
@@ -1029,7 +1029,7 @@ union Vec256Data {
ub[28] = x28; ub[29] = x29; ub[30] = x30; ub[31] = x31; ub[28] = x28; ub[29] = x29; ub[30] = x30; ub[31] = x31;
} }
//! Set all thirty two unsigned 8-bit integers. //! Set all thirty two 8-bit unsigned integers.
ASMJIT_INLINE void setUb( ASMJIT_INLINE void setUb(
uint8_t x0) uint8_t x0)
{ {
@@ -1053,7 +1053,7 @@ union Vec256Data {
} }
} }
//! Set all sixteen signed 16-bit integers. //! Set all sixteen 16-bit signed integers.
ASMJIT_INLINE void setSw( 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 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) int16_t x8, int16_t x9, int16_t x10, int16_t x11, int16_t x12, int16_t x13, int16_t x14, int16_t x15)
@@ -1064,14 +1064,14 @@ union Vec256Data {
sw[12] = x12; sw[13] = x13; sw[14] = x14; sw[15] = x15; sw[12] = x12; sw[13] = x13; sw[14] = x14; sw[15] = x15;
} }
//! Set all sixteen signed 16-bit integers. //! Set all sixteen 16-bit signed integers.
ASMJIT_INLINE void setSw( ASMJIT_INLINE void setSw(
int16_t x0) int16_t x0)
{ {
setUw(static_cast<uint16_t>(x0)); setUw(static_cast<uint16_t>(x0));
} }
//! Set all sixteen unsigned 16-bit integers. //! Set all sixteen 16-bit unsigned integers.
ASMJIT_INLINE void setUw( 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 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) uint16_t x8, uint16_t x9, uint16_t x10, uint16_t x11, uint16_t x12, uint16_t x13, uint16_t x14, uint16_t x15)
@@ -1082,7 +1082,7 @@ union Vec256Data {
uw[12] = x12; uw[13] = x13; uw[14] = x14; uw[15] = x15; uw[12] = x12; uw[13] = x13; uw[14] = x14; uw[15] = x15;
} }
//! Set all eight unsigned 16-bit integers. //! Set all eight 16-bit unsigned integers.
ASMJIT_INLINE void setUw( ASMJIT_INLINE void setUw(
uint16_t x0) uint16_t x0)
{ {
@@ -1106,7 +1106,7 @@ union Vec256Data {
} }
} }
//! Set all eight signed 32-bit integers. //! Set all eight 32-bit signed integers.
ASMJIT_INLINE void setSd( ASMJIT_INLINE void setSd(
int32_t x0, int32_t x1, int32_t x2, int32_t x3, int32_t x0, int32_t x1, int32_t x2, int32_t x3,
int32_t x4, int32_t x5, int32_t x6, int32_t x7) int32_t x4, int32_t x5, int32_t x6, int32_t x7)
@@ -1115,14 +1115,14 @@ union Vec256Data {
sd[4] = x4; sd[5] = x5; sd[6] = x6; sd[7] = x7; sd[4] = x4; sd[5] = x5; sd[6] = x6; sd[7] = x7;
} }
//! Set all eight signed 32-bit integers. //! Set all eight 32-bit signed integers.
ASMJIT_INLINE void setSd( ASMJIT_INLINE void setSd(
int32_t x0) int32_t x0)
{ {
setUd(static_cast<uint32_t>(x0)); setUd(static_cast<uint32_t>(x0));
} }
//! Set all eight unsigned 32-bit integers. //! Set all eight 32-bit unsigned integers.
ASMJIT_INLINE void setUd( ASMJIT_INLINE void setUd(
uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, 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 x4, uint32_t x5, uint32_t x6, uint32_t x7)
@@ -1131,7 +1131,7 @@ union Vec256Data {
ud[4] = x4; ud[5] = x5; ud[6] = x6; ud[7] = x7; ud[4] = x4; ud[5] = x5; ud[6] = x6; ud[7] = x7;
} }
//! Set all eight unsigned 32-bit integers. //! Set all eight 32-bit unsigned integers.
ASMJIT_INLINE void setUd( ASMJIT_INLINE void setUd(
uint32_t x0) uint32_t x0)
{ {
@@ -1154,28 +1154,28 @@ union Vec256Data {
} }
} }
//! Set all four signed 64-bit integers. //! Set all four 64-bit signed integers.
ASMJIT_INLINE void setSq( ASMJIT_INLINE void setSq(
int64_t x0, int64_t x1, int64_t x2, int64_t x3) int64_t x0, int64_t x1, int64_t x2, int64_t x3)
{ {
sq[0] = x0; sq[1] = x1; sq[2] = x2; sq[3] = x3; sq[0] = x0; sq[1] = x1; sq[2] = x2; sq[3] = x3;
} }
//! Set all four signed 64-bit integers. //! Set all four 64-bit signed integers.
ASMJIT_INLINE void setSq( ASMJIT_INLINE void setSq(
int64_t x0) int64_t x0)
{ {
sq[0] = x0; sq[1] = x0; sq[2] = x0; sq[3] = x0; sq[0] = x0; sq[1] = x0; sq[2] = x0; sq[3] = x0;
} }
//! Set all four unsigned 64-bit integers. //! Set all four 64-bit unsigned integers.
ASMJIT_INLINE void setUq( ASMJIT_INLINE void setUq(
uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3) uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3)
{ {
uq[0] = x0; uq[1] = x1; uq[2] = x2; uq[3] = x3; uq[0] = x0; uq[1] = x1; uq[2] = x2; uq[3] = x3;
} }
//! Set all four unsigned 64-bit integers. //! Set all four 64-bit unsigned integers.
ASMJIT_INLINE void setUq( ASMJIT_INLINE void setUq(
uint64_t x0) uint64_t x0)
{ {
@@ -1217,21 +1217,21 @@ union Vec256Data {
// [Members] // [Members]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Array of thirty two signed 8-bit integers. //! Array of thirty two 8-bit signed integers.
int8_t sb[32]; int8_t sb[32];
//! Array of thirty two unsigned 8-bit integers. //! Array of thirty two 8-bit unsigned integers.
uint8_t ub[32]; uint8_t ub[32];
//! Array of sixteen signed 16-bit integers. //! Array of sixteen 16-bit signed integers.
int16_t sw[16]; int16_t sw[16];
//! Array of sixteen unsigned 16-bit integers. //! Array of sixteen 16-bit unsigned integers.
uint16_t uw[16]; uint16_t uw[16];
//! Array of eight signed 32-bit integers. //! Array of eight 32-bit signed integers.
int32_t sd[8]; int32_t sd[8];
//! Array of eight unsigned 32-bit integers. //! Array of eight 32-bit unsigned integers.
uint32_t ud[8]; uint32_t ud[8];
//! Array of four signed 64-bit integers. //! Array of four 64-bit signed integers.
int64_t sq[4]; int64_t sq[4];
//! Array of four unsigned 64-bit integers. //! Array of four 64-bit unsigned integers.
uint64_t uq[4]; uint64_t uq[4];
//! Array of eight 32-bit single precision floating points. //! Array of eight 32-bit single precision floating points.
@@ -1240,7 +1240,7 @@ union Vec256Data {
double df[4]; double df[4];
}; };
//! @} //! \}
} // asmjit namespace } // asmjit namespace

View File

@@ -14,11 +14,6 @@
#include "../base/lock.h" #include "../base/lock.h"
#include "../base/vmem.h" #include "../base/vmem.h"
// [Dependencies - Windows]
#if defined(ASMJIT_OS_WINDOWS)
# include <windows.h>
#endif // ASMJIT_OS_WINDOWS
// [Dependencies - Posix] // [Dependencies - Posix]
#if defined(ASMJIT_OS_POSIX) #if defined(ASMJIT_OS_POSIX)
# include <sys/types.h> # include <sys/types.h>
@@ -190,12 +185,12 @@ void VMemUtil::release(void* addr, size_t length) {
// [VMem - Ops] // [VMem - Ops]
// ============================================================================ // ============================================================================
//! @internal //! \internal
enum { enum {
kBitsPerEntity = (sizeof(size_t) * 8) kBitsPerEntity = (sizeof(size_t) * 8)
}; };
//! @internal //! \internal
//! //!
//! Set `len` bits in `buf` starting at `index` bit index. //! Set `len` bits in `buf` starting at `index` bit index.
static void _SetBits(size_t* buf, size_t index, size_t len) { static void _SetBits(size_t* buf, size_t index, size_t len) {
@@ -231,7 +226,7 @@ static void _SetBits(size_t* buf, size_t index, size_t len) {
#define M_DIV(x, y) ((x) / (y)) #define M_DIV(x, y) ((x) / (y))
#define M_MOD(x, y) ((x) % (y)) #define M_MOD(x, y) ((x) % (y))
//! @internal //! \internal
//! //!
//! Base red-black tree node. //! Base red-black tree node.
struct RbNode { struct RbNode {
@@ -255,7 +250,7 @@ struct RbNode {
uint8_t* mem; uint8_t* mem;
}; };
//! @internal //! \internal
//! //!
//! Get whether the node is red (NULL or node with red flag). //! Get whether the node is red (NULL or node with red flag).
static ASMJIT_INLINE bool rbIsRed(RbNode* node) { static ASMJIT_INLINE bool rbIsRed(RbNode* node) {
@@ -303,7 +298,7 @@ struct MemNode : public RbNode {
// [asmjit::PermanentNode] // [asmjit::PermanentNode]
// ============================================================================ // ============================================================================
//! @internal //! \internal
//! //!
//! Permanent node. //! Permanent node.
struct PermanentNode { struct PermanentNode {
@@ -330,7 +325,7 @@ struct PermanentNode {
// [asmjit::VMemPrivate] // [asmjit::VMemPrivate]
// ============================================================================ // ============================================================================
//! @internal //! \internal
struct VMemPrivate { struct VMemPrivate {
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [Construction / Destruction] // [Construction / Destruction]

View File

@@ -9,21 +9,15 @@
#define _ASMJIT_BASE_VMEM_H #define _ASMJIT_BASE_VMEM_H
// [Dependencies] // [Dependencies]
#include "../base/defs.h"
#include "../base/error.h" #include "../base/error.h"
// [Dependencies - Windows]
#if defined(ASMJIT_OS_WINDOWS)
# include <windows.h>
#endif // ASMJIT_OS_WINDOWS
// [Api-Begin] // [Api-Begin]
#include "../apibegin.h" #include "../apibegin.h"
namespace asmjit { namespace asmjit {
//! @addtogroup asmjit_base_util //! \addtogroup asmjit_base_util
//! @{ //! \{
// ============================================================================ // ============================================================================
// [asmjit::kVMemAlloc] // [asmjit::kVMemAlloc]
@@ -72,12 +66,12 @@ struct VMemUtil {
#if defined(ASMJIT_OS_WINDOWS) #if defined(ASMJIT_OS_WINDOWS)
//! Allocate virtual memory of `hProcess`. //! Allocate virtual memory of `hProcess`.
//! //!
//! @note This function is Windows specific. //! \note This function is Windows specific.
static ASMJIT_API void* allocProcessMemory(HANDLE hProcess, size_t length, size_t* allocated, bool canExecute); static ASMJIT_API void* allocProcessMemory(HANDLE hProcess, size_t length, size_t* allocated, bool canExecute);
//! Free virtual memory of `hProcess`. //! Free virtual memory of `hProcess`.
//! //!
//! @note This function is Windows specific. //! \note This function is Windows specific.
static ASMJIT_API void releaseProcessMemory(HANDLE hProcess, void* addr, size_t length); static ASMJIT_API void releaseProcessMemory(HANDLE hProcess, void* addr, size_t length);
#endif // ASMJIT_OS_WINDOWS #endif // ASMJIT_OS_WINDOWS
}; };
@@ -130,7 +124,7 @@ struct VMemMgr {
//! Get whether to keep allocated memory after the `VMemMgr` is destroyed. //! Get whether to keep allocated memory after the `VMemMgr` is destroyed.
//! //!
//! @sa `setKeepVirtualMemory()`. //! \sa \ref setKeepVirtualMemory.
ASMJIT_API bool getKeepVirtualMemory() const; ASMJIT_API bool getKeepVirtualMemory() const;
//! Set whether to keep allocated memory after memory manager is //! Set whether to keep allocated memory after memory manager is
@@ -142,9 +136,9 @@ struct VMemMgr {
//! VMemMgr destructor. After destruction all internal //! VMemMgr destructor. After destruction all internal
//! structures are freed, only the process virtual memory remains. //! structures are freed, only the process virtual memory remains.
//! //!
//! @note Memory allocated with kVMemAllocPermanent is always kept. //! \note Memory allocated with kVMemAllocPermanent is always kept.
//! //!
//! @sa `getKeepVirtualMemory()`. //! \sa \ref getKeepVirtualMemory.
ASMJIT_API void setKeepVirtualMemory(bool keepVirtualMemory); ASMJIT_API void setKeepVirtualMemory(bool keepVirtualMemory);
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -168,13 +162,13 @@ struct VMemMgr {
// [Members] // [Members]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! @internal //! \internal
//! //!
//! Pointer to private data hidden out of the public API. //! Pointer to private data hidden out of the public API.
void* _d; void* _d;
}; };
//! @} //! \}
} // asmjit namespace } // asmjit namespace

View File

@@ -8,7 +8,6 @@
#define ASMJIT_EXPORTS #define ASMJIT_EXPORTS
// [Dependencies - AsmJit] // [Dependencies - AsmJit]
#include "../base/defs.h"
#include "../base/intutil.h" #include "../base/intutil.h"
#include "../base/zone.h" #include "../base/zone.h"

View File

@@ -16,8 +16,8 @@
namespace asmjit { namespace asmjit {
//! @addtogroup asmjit_base_util //! \addtogroup asmjit_base_util
//! @{ //! \{
// ============================================================================ // ============================================================================
// [asmjit::Zone] // [asmjit::Zone]
@@ -32,7 +32,7 @@ struct Zone {
// [Chunk] // [Chunk]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! @internal //! \internal
//! //!
//! One allocated chunk of memory. //! One allocated chunk of memory.
struct Chunk { struct Chunk {
@@ -56,33 +56,37 @@ struct Zone {
//! Create a new instance of `Zone` allocator. //! Create a new instance of `Zone` allocator.
//! //!
//! @param chunkSize Default size of the first chunk. //! The `chunkSize` parameter describes the size of the chunk. If `alloc()`
//! requires more memory than `chunkSize` then a bigger chunk will be
//! allocated, however `chunkSize` will not be changed.
ASMJIT_API Zone(size_t chunkSize); ASMJIT_API Zone(size_t chunkSize);
//! Destroy `Zone` instance. //! Destroy `Zone` instance.
//!
//! Destructor released all chunks allocated by `Zone`. The `reset()` member
//! function does the same without actually destroying `Zone` object itself.
ASMJIT_API ~Zone(); ASMJIT_API ~Zone();
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [Clear / Reset] // [Clear / Reset]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Free all allocated memory except first block that remains for reuse. //! Reset the `Zone` releasing all chunks allocated.
//! //!
//! Note that this method will invalidate all instances using this memory //! Calling `clear()` will release all chunks allocated by `Zone` except the
//! allocated by this zone instance. //! first one that will be reused if needed.
ASMJIT_API void clear(); ASMJIT_API void clear();
//! Free all allocated memory at once. //! Reset the `Zone` releasing all chunks allocated.
//! //!
//! Note that this method will invalidate all instances using this memory //! Calling `reset()` will release all chunks allocated by `Zone`.
//! allocated by this zone instance.
ASMJIT_API void reset(); ASMJIT_API void reset();
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [Accessors] // [Accessors]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! Get (default) chunk size. //! Get chunk size.
ASMJIT_INLINE size_t getChunkSize() const { return _chunkSize; } ASMJIT_INLINE size_t getChunkSize() const { return _chunkSize; }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -140,7 +144,7 @@ struct Zone {
return static_cast<T*>(alloc(size)); return static_cast<T*>(alloc(size));
} }
//! @internal //! \internal
ASMJIT_API void* _alloc(size_t size); ASMJIT_API void* _alloc(size_t size);
//! Allocate `size` bytes of zeroed memory. //! Allocate `size` bytes of zeroed memory.
@@ -158,7 +162,7 @@ struct Zone {
return (void*)p; return (void*)p;
} }
//! @internal //! \internal
ASMJIT_API void* _calloc(size_t size); ASMJIT_API void* _calloc(size_t size);
//! Helper to duplicate data. //! Helper to duplicate data.
@@ -180,7 +184,7 @@ struct Zone {
size_t _chunkSize; size_t _chunkSize;
}; };
//! @} //! \}
} // asmjit namespace } // asmjit namespace

View File

@@ -31,16 +31,6 @@
// [Dependencies - C++] // [Dependencies - C++]
#include <new> #include <new>
// ============================================================================
// [asmjit::build - Documentation]
// ============================================================================
#if defined(ASMJIT_DOCGEN)
# define ASMJIT_BUILD_X86
# define ASMJIT_BUILD_X64
# define ASMJIT_API
#endif // ASMJIT_DOCGEN
// ============================================================================ // ============================================================================
// [asmjit::build - OS] // [asmjit::build - OS]
// ============================================================================ // ============================================================================

View File

@@ -70,6 +70,11 @@ uint32_t WinRemoteRuntime::add(void** dest, BaseAssembler* assembler) {
return kErrorOk; return kErrorOk;
} }
// NOP.
Error WinRemoteRuntime::release(void* p) {
return kErrorOk;
}
} // contrib namespace } // contrib namespace
} // asmjit namespace } // asmjit namespace

View File

@@ -17,6 +17,9 @@
namespace asmjit { namespace asmjit {
namespace contrib { namespace contrib {
//! \addtogroup asmjit_contrib
//! \{
// ============================================================================ // ============================================================================
// [asmjit::contrib::WinRemoteRuntime] // [asmjit::contrib::WinRemoteRuntime]
// ============================================================================ // ============================================================================
@@ -54,6 +57,7 @@ struct WinRemoteRuntime : public Runtime {
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
ASMJIT_API virtual uint32_t add(void** dest, BaseAssembler* assembler); ASMJIT_API virtual uint32_t add(void** dest, BaseAssembler* assembler);
ASMJIT_API virtual Error release(void* p);
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [Members] // [Members]
@@ -63,6 +67,8 @@ struct WinRemoteRuntime : public Runtime {
VMemMgr _memMgr; VMemMgr _memMgr;
}; };
//! \}
} // contrib namespace } // contrib namespace
} // asmjit namespace } // asmjit namespace

View File

@@ -8,121 +8,16 @@
#ifndef _ASMJIT_X86_H #ifndef _ASMJIT_X86_H
#define _ASMJIT_X86_H #define _ASMJIT_X86_H
// ============================================================================
// [asmjit_x86x64]
// ============================================================================
//! @defgroup asmjit_x86x64 X86/X64
//!
//! @brief X86/X64 API
// ============================================================================
// [asmjit_x86x64_codegen]
// ============================================================================
//! @defgroup asmjit_x86x64_codegen Code Generation (X86/X64)
//! @ingroup asmjit_x86x64
//!
//! @brief Low-level and high-level code generation.
// ============================================================================
// [asmjit_x86x64_cpu_info]
// ============================================================================
//! @defgroup asmjit_x86x64_cpu_info CPU Information (X86/X64)
//! @ingroup asmjit_x86x64
//!
//! @brief CPU information specific to X86/X64 architecture.
//!
//! The CPUID instruction can be used to get an exhaustive information related
//! to 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 `CpuInfo` extends `BaseCpuInfo` 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 `CpuInfo` 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 `CpuInfo` and setting
//! up its members. `CpuUtil::detect` can be used to detect CPU features into
//! an existing `CpuInfo` instance - it may become handly if only one property
//! has to be turned on/off.
//!
//! If the high-level interface `CpuInfo` offers is not enough there is also
//! `CpuUtil::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;
//! using namespace asmjit::host;
//!
//! // Get `CpuInfo` global instance.
//! const CpuInfo* cpuInfo = CpuInfo::getHost();
//!
//! if (cpuInfo->hasFeature(kCpuFeatureSse2)) {
//! // Processor has SSE2.
//! }
//! else if (cpuInfo->hasFeature(kCpuFeatureMmx)) {
//! // Processor doesn't have SSE2, but has MMX.
//! }
//! else {
//! // An archaic processor, it's a wonder AsmJit works here!
//! }
//! ~~~
//!
//! The next example shows how to call CPUID directly:
//!
//! ~~~
//! using namespace asmjit;
//!
//! // The result of CPUID call.
//! CpuId out;
//!
//! // Call CPUID, first two arguments are passed in EAX/ECX.
//! CpuUtil::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);
//! ~~~
//!
//! @sa @ref asmjit_base_cpu_info
// ============================================================================
// [asmjit_x86x64_constants]
// ============================================================================
//! @defgroup asmjit_x86x64_constants Constants (X86/X64)
//! @ingroup asmjit_x86x64
//!
//! @brief Constants and definitions specific to X86/X64 architecture.
// ============================================================================
// [Dependencies - AsmJit] // [Dependencies - AsmJit]
// ============================================================================
#include "base.h" #include "base.h"
#include "x86/x86assembler.h" #include "x86/x86assembler.h"
#include "x86/x86compiler.h" #include "x86/x86compiler.h"
#include "x86/x86cpuinfo.h" #include "x86/x86cpuinfo.h"
#include "x86/x86defs.h"
#include "x86/x86func.h" #include "x86/x86func.h"
#include "x86/x86inst.h"
#include "x86/x86operand.h"
#include "x86/x86util.h"
// [Guard] // [Guard]
#endif // _ASMJIT_X86_H #endif // _ASMJIT_X86_H

View File

@@ -19,7 +19,6 @@
#include "../base/vmem.h" #include "../base/vmem.h"
#include "../x86/x86assembler.h" #include "../x86/x86assembler.h"
#include "../x86/x86cpuinfo.h" #include "../x86/x86cpuinfo.h"
#include "../x86/x86defs.h"
// [Api-Begin] // [Api-Begin]
#include "../apibegin.h" #include "../apibegin.h"
@@ -58,7 +57,7 @@ enum kVexVVVV {
kVexVVVVMask = 0xF << kVexVVVVShift kVexVVVVMask = 0xF << kVexVVVVShift
}; };
//! @internal //! \internal
//! //!
//! Instruction 2-byte/3-byte opcode prefix definition. //! Instruction 2-byte/3-byte opcode prefix definition.
struct OpCodeMM { struct OpCodeMM {
@@ -66,7 +65,7 @@ struct OpCodeMM {
uint8_t data[3]; uint8_t data[3];
}; };
//! @internal //! \internal
//! //!
//! Mandatory prefixes encoded in 'asmjit' opcode [66, F3, F2] and asmjit //! Mandatory prefixes encoded in 'asmjit' opcode [66, F3, F2] and asmjit
//! extensions //! extensions
@@ -81,7 +80,7 @@ static const uint8_t x86OpCodePP[8] = {
0x9B 0x9B
}; };
//! @internal //! \internal
//! //!
//! Instruction 2-byte/3-byte opcode prefix data. //! Instruction 2-byte/3-byte opcode prefix data.
static const OpCodeMM x86OpCodeMM[] = { static const OpCodeMM x86OpCodeMM[] = {
@@ -111,7 +110,7 @@ static const uint8_t x86OpCodePopSeg[8] = { 0x00, 0x07, 0x00, 0x17, 0x1F, 0xA1,
// [asmjit::X64TrampolineWriter] // [asmjit::X64TrampolineWriter]
// ============================================================================ // ============================================================================
//! @internal //! \internal
//! //!
//! Trampoline writer. //! Trampoline writer.
struct X64TrampolineWriter { struct X64TrampolineWriter {
@@ -271,7 +270,7 @@ void X86X64Assembler::_bind(const Label& label) {
if (IntUtil::isInt8(patchedValue)) if (IntUtil::isInt8(patchedValue))
setByteAt(offset, static_cast<uint8_t>(patchedValue & 0xFF)); setByteAt(offset, static_cast<uint8_t>(patchedValue & 0xFF));
else else
setError(kErrorAssemblerIllegalShortJump); setError(kErrorIllegalDisplacement);
} }
} }
@@ -352,22 +351,27 @@ Error X86X64Assembler::embedLabel(const Label& op) {
// [asmjit::x86x64::Assembler - Align] // [asmjit::x86x64::Assembler - Align]
// ============================================================================ // ============================================================================
Error X86X64Assembler::_align(uint32_t m) { Error X86X64Assembler::_align(uint32_t mode, uint32_t offset) {
if (_logger) { if (_logger) {
_logger->logFormat(kLoggerStyleDirective, _logger->logFormat(kLoggerStyleDirective,
"%s.align %u\n", _logger->getIndentation(), static_cast<unsigned int>(m)); "%s.align %u\n", _logger->getIndentation(), static_cast<unsigned int>(offset));
} }
if (m <= 1 || !IntUtil::isPowerOf2(m) || m > 64) if (offset <= 1 || !IntUtil::isPowerOf2(offset) || offset > 64)
return setError(kErrorInvalidArgument); return setError(kErrorInvalidArgument);
uint32_t i = static_cast<uint32_t>(IntUtil::deltaTo<size_t>(getOffset(), m)); uint32_t i = static_cast<uint32_t>(IntUtil::deltaTo<size_t>(getOffset(), offset));
if (i == 0) if (i == 0)
return kErrorOk; return kErrorOk;
if (getRemainingSpace() < i) if (getRemainingSpace() < i)
ASMJIT_PROPAGATE_ERROR(_grow(i)); ASMJIT_PROPAGATE_ERROR(_grow(i));
uint8_t* cursor = getCursor(); uint8_t* cursor = getCursor();
uint8_t alignPattern = 0xCC;
if (mode == kAlignCode) {
alignPattern = 0x90;
if (IntUtil::hasBit(_features, kCodeGenOptimizedAlign)) { if (IntUtil::hasBit(_features, kCodeGenOptimizedAlign)) {
const CpuInfo* cpuInfo = static_cast<const CpuInfo*>(getRuntime()->getCpuInfo()); const CpuInfo* cpuInfo = static_cast<const CpuInfo*>(getRuntime()->getCpuInfo());
@@ -400,7 +404,9 @@ Error X86X64Assembler::_align(uint32_t m) {
const uint8_t* p; const uint8_t* p;
uint32_t n; uint32_t n;
if (cpuInfo->getVendorId() == kCpuVendorIntel && ((cpuInfo->getFamily() & 0x0F) == 0x06 || (cpuInfo->getFamily() & 0x0F) == 0x0F)) { if (cpuInfo->getVendorId() == kCpuVendorIntel && (
(cpuInfo->getFamily() & 0x0F) == 0x06 ||
(cpuInfo->getFamily() & 0x0F) == 0x0F)) {
do { do {
switch (i) { switch (i) {
case 1: p = nop1; n = 1; break; case 1: p = nop1; n = 1; break;
@@ -442,23 +448,11 @@ Error X86X64Assembler::_align(uint32_t m) {
} while (--n); } while (--n);
} while (i); } while (i);
} }
// Legacy NOPs, 0x90 with 0x66 prefix.
if (getArch() == kArchX86) {
while (i) {
switch (i) {
default: EMIT_BYTE(0x66); i--;
case 3: EMIT_BYTE(0x66); i--;
case 2: EMIT_BYTE(0x66); i--;
case 1: EMIT_BYTE(0x90); i--;
}
}
} }
} }
// Legacy NOPs, only 0x90.
while (i) { while (i) {
EMIT_BYTE(0x90); EMIT_BYTE(alignPattern);
i--; i--;
} }
@@ -898,7 +892,7 @@ static ASMJIT_INLINE uint32_t x86EncodeSib(uint32_t s, uint32_t i, uint32_t b) {
return (s << 6) + (i << 3) + b; return (s << 6) + (i << 3) + b;
} }
//! @internal //! \internal
static const Operand::VRegOp x86PatchedHiRegs[4] = { static const Operand::VRegOp x86PatchedHiRegs[4] = {
// --------------+---+--------------------------------+--------------+------+ // --------------+---+--------------------------------+--------------+------+
// Operand | S | Register Code | OperandId |Unused| // Operand | S | Register Code | OperandId |Unused|
@@ -1006,7 +1000,7 @@ _Prepare:
// Check if one or more register operand is one of BPL, SPL, SIL, DIL and // Check if one or more register operand is one of BPL, SPL, SIL, DIL and
// force a REX prefix in such case. // force a REX prefix in such case.
if (x86IsGpbRegOp(o0)) { if (X86Util::isGpbRegOp(*o0)) {
uint32_t index = static_cast<const X86Reg*>(o0)->getRegIndex(); uint32_t index = static_cast<const X86Reg*>(o0)->getRegIndex();
if (static_cast<const X86Reg*>(o0)->isGpbLo()) { if (static_cast<const X86Reg*>(o0)->isGpbLo()) {
opX |= (index >= 4) << kRexShift; opX |= (index >= 4) << kRexShift;
@@ -1017,7 +1011,7 @@ _Prepare:
} }
} }
if (x86IsGpbRegOp(o1)) { if (X86Util::isGpbRegOp(*o1)) {
uint32_t index = static_cast<const X86Reg*>(o1)->getRegIndex(); uint32_t index = static_cast<const X86Reg*>(o1)->getRegIndex();
if (static_cast<const X86Reg*>(o1)->isGpbLo()) { if (static_cast<const X86Reg*>(o1)->isGpbLo()) {
opX |= (index >= 4) << kRexShift; opX |= (index >= 4) << kRexShift;
@@ -1509,6 +1503,37 @@ _Prepare:
} }
break; break;
case kInstGroupX86Jecxz:
if (encoded == ENC_OPS(Reg, Label, None)) {
ASMJIT_ASSERT(static_cast<const X86Reg*>(o0)->getRegIndex() == kRegIndexCx);
if ((Arch == kArchX86 && o0->getSize() == 2) ||
Arch == kArchX64 && o0->getSize() == 4) {
EMIT_BYTE(0x67);
}
EMIT_BYTE(0xE3);
label = self->getLabelDataById(static_cast<const Label*>(o1)->getId());
if (label->offset != -1) {
// Bound label.
intptr_t offs = label->offset - (intptr_t)(cursor - self->_buffer) - 1;
if (!IntUtil::isInt8(offs))
goto _IllegalInst;
EMIT_BYTE(offs);
goto _EmitDone;
}
else {
// Non-bound label.
dispOffset = -1;
dispSize = 1;
relocId = -1;
goto _EmitDisplacement;
}
}
break;
case kInstGroupX86Jmp: case kInstGroupX86Jmp:
if (encoded == ENC_OPS(Reg, None, None)) { if (encoded == ENC_OPS(Reg, None, None)) {
rmReg = static_cast<const GpReg*>(o0)->getRegIndex(); rmReg = static_cast<const GpReg*>(o0)->getRegIndex();
@@ -3371,19 +3396,25 @@ _EmitAvxRvm:
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
_IllegalInst: _IllegalInst:
self->setError(kErrorAssemblerIllegalInst); self->setError(kErrorIllegalInst);
#if defined(ASMJIT_DEBUG) #if defined(ASMJIT_DEBUG)
assertIllegal = true; assertIllegal = true;
#endif // ASMJIT_DEBUG #endif // ASMJIT_DEBUG
goto _EmitDone; goto _EmitDone;
_IllegalAddr: _IllegalAddr:
self->setError(kErrorAssemblerIllegalAddr); self->setError(kErrorIllegalAddresing);
#if defined(ASMJIT_DEBUG) #if defined(ASMJIT_DEBUG)
assertIllegal = true; assertIllegal = true;
#endif // ASMJIT_DEBUG #endif // ASMJIT_DEBUG
goto _EmitDone; goto _EmitDone;
_IllegalDisp:
self->setError(kErrorIllegalDisplacement);
#if defined(ASMJIT_DEBUG)
assertIllegal = true;
#endif // ASMJIT_DEBUG
goto _EmitDone;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [Emit - X86] // [Emit - X86]
@@ -3623,7 +3654,7 @@ _EmitSib:
// Indexing is invalid. // Indexing is invalid.
if (mIndex < kInvalidReg) if (mIndex < kInvalidReg)
goto _IllegalAddr; goto _IllegalDisp;
EMIT_BYTE(x86EncodeMod(0, opReg, 5)); EMIT_BYTE(x86EncodeMod(0, opReg, 5));
dispOffset -= (4 + imLen); dispOffset -= (4 + imLen);
@@ -4067,7 +4098,7 @@ _EmitDone:
_UnknownInst: _UnknownInst:
self->_comment = NULL; self->_comment = NULL;
return self->setError(kErrorAssemblerUnknownInst); return self->setError(kErrorUnknownInst);
_GrowBuffer: _GrowBuffer:
ASMJIT_PROPAGATE_ERROR(self->_grow(16)); ASMJIT_PROPAGATE_ERROR(self->_grow(16));

File diff suppressed because it is too large Load Diff

View File

@@ -78,7 +78,7 @@ static Error X86X64Compiler_emitConstPool(X86X64Compiler* self,
if (label.getId() == kInvalidValue) if (label.getId() == kInvalidValue)
return kErrorOk; return kErrorOk;
self->align(static_cast<uint32_t>(pool.getAlignment())); self->align(kAlignData, static_cast<uint32_t>(pool.getAlignment()));
self->bind(label); self->bind(label);
EmbedNode* embedNode = self->embed(NULL, static_cast<uint32_t>(pool.getSize())); EmbedNode* embedNode = self->embed(NULL, static_cast<uint32_t>(pool.getSize()));
@@ -656,8 +656,8 @@ Error X86X64Compiler::serialize(BaseAssembler& assembler) {
X86X64Context context(this); X86X64Context context(this);
Error error = kErrorOk; Error error = kErrorOk;
BaseNode* node = _firstNode; Node* node = _firstNode;
BaseNode* start; Node* start;
// Find function and use the context to translate/emit. // Find function and use the context to translate/emit.
do { do {

File diff suppressed because it is too large Load Diff

View File

@@ -78,10 +78,10 @@ void X86X64Context::reset() {
_clobberedRegs.reset(); _clobberedRegs.reset();
_stackFrameCell = NULL; _stackFrameCell = NULL;
_gaRegs[kRegClassGp] = IntUtil::bits(_baseRegsCount) & ~IntUtil::mask(kRegIndexSp); _gaRegs[kRegClassGp ] = IntUtil::bits(_baseRegsCount) & ~IntUtil::mask(kRegIndexSp);
_gaRegs[kRegClassFp] = IntUtil::bits(kRegCountFp); _gaRegs[kRegClassFp ] = IntUtil::bits(kRegCountFp);
_gaRegs[kRegClassMm] = IntUtil::bits(kRegCountMm); _gaRegs[kRegClassMm ] = IntUtil::bits(kRegCountMm);
_gaRegs[kRegClassXy] = IntUtil::bits(_baseRegsCount); _gaRegs[kRegClassXyz] = IntUtil::bits(_baseRegsCount);
_argBaseReg = kInvalidReg; // Used by patcher. _argBaseReg = kInvalidReg; // Used by patcher.
_varBaseReg = kInvalidReg; // Used by patcher. _varBaseReg = kInvalidReg; // Used by patcher.
@@ -142,6 +142,10 @@ static const X86X64SpecialInst x86SpecialInstDiv[] = {
{ kInvalidReg, kInvalidReg, kVarAttrInReg } { kInvalidReg, kInvalidReg, kVarAttrInReg }
}; };
static const X86X64SpecialInst x86SpecialInstJecxz[] = {
{ kRegIndexCx, kInvalidReg, kVarAttrInReg }
};
static const X86X64SpecialInst x86SpecialInstMul[] = { static const X86X64SpecialInst x86SpecialInstMul[] = {
{ kInvalidReg, kRegIndexDx, kVarAttrOutReg }, { kInvalidReg, kRegIndexDx, kVarAttrOutReg },
{ kRegIndexAx, kRegIndexAx, kVarAttrInOutReg }, { kRegIndexAx, kRegIndexAx, kVarAttrInOutReg },
@@ -240,6 +244,9 @@ static ASMJIT_INLINE const X86X64SpecialInst* X86X64SpecialInst_get(uint32_t cod
case kInstDas: case kInstDas:
return x86SpecialInstDaaDas; return x86SpecialInstDaaDas;
case kInstJecxz:
return x86SpecialInstJecxz;
case kInstIdiv: case kInstIdiv:
case kInstDiv: case kInstDiv:
return x86SpecialInstDiv; return x86SpecialInstDiv;
@@ -384,7 +391,7 @@ void X86X64Context::emitLoad(VarData* vd, uint32_t regIndex, const char* reason)
X86X64Compiler* compiler = getCompiler(); X86X64Compiler* compiler = getCompiler();
Mem m = getVarMem(vd); Mem m = getVarMem(vd);
BaseNode* node = NULL; Node* node = NULL;
bool comment = _emitComments; bool comment = _emitComments;
switch (vd->getType()) { switch (vd->getType()) {
@@ -465,7 +472,7 @@ void X86X64Context::emitSave(VarData* vd, uint32_t regIndex, const char* reason)
X86X64Compiler* compiler = getCompiler(); X86X64Compiler* compiler = getCompiler();
Mem m = getVarMem(vd); Mem m = getVarMem(vd);
BaseNode* node = NULL; Node* node = NULL;
bool comment = _emitComments; bool comment = _emitComments;
switch (vd->getType()) { switch (vd->getType()) {
@@ -546,7 +553,7 @@ void X86X64Context::emitMove(VarData* vd, uint32_t toRegIndex, uint32_t fromRegI
X86X64Compiler* compiler = getCompiler(); X86X64Compiler* compiler = getCompiler();
BaseNode* node = NULL; Node* node = NULL;
bool comment = _emitComments; bool comment = _emitComments;
switch (vd->getType()) { switch (vd->getType()) {
@@ -615,7 +622,7 @@ void X86X64Context::emitSwapGp(VarData* aVd, VarData* bVd, uint32_t aIndex, uint
X86X64Compiler* compiler = getCompiler(); X86X64Compiler* compiler = getCompiler();
BaseNode* node = NULL; Node* node = NULL;
bool comment = _emitComments; bool comment = _emitComments;
#if defined(ASMJIT_BUILD_X64) #if defined(ASMJIT_BUILD_X64)
@@ -1161,8 +1168,8 @@ _Move32:
case kVarTypeInt64: case kVarTypeInt64:
case kVarTypeUInt64: case kVarTypeUInt64:
// Move to GPD register will clear the HI-DWORD of GPQ register in 64-bit // Move to Gpd register will clear also high DWORD of Gpq register in
// mode. // 64-bit mode.
if (imm.isUInt32()) if (imm.isUInt32())
goto _Move32Truncate; goto _Move32Truncate;
@@ -1226,9 +1233,9 @@ static ASMJIT_INLINE void X86X64Context_checkStateVars(X86X64Context* self) {
} }
void X86X64Context::_checkState() { void X86X64Context::_checkState() {
X86X64Context_checkStateVars<kRegClassGp>(this); X86X64Context_checkStateVars<kRegClassGp >(this);
X86X64Context_checkStateVars<kRegClassMm>(this); X86X64Context_checkStateVars<kRegClassMm >(this);
X86X64Context_checkStateVars<kRegClassXy>(this); X86X64Context_checkStateVars<kRegClassXyz>(this);
} }
#else #else
void X86X64Context::_checkState() {} void X86X64Context::_checkState() {}
@@ -1270,9 +1277,9 @@ void X86X64Context::loadState(BaseVarState* src_) {
uint32_t vdCount = static_cast<uint32_t>(_contextVd.getLength()); uint32_t vdCount = static_cast<uint32_t>(_contextVd.getLength());
// Load allocated variables. // Load allocated variables.
X86X64Context_loadStateVars<kRegClassGp>(this, src); X86X64Context_loadStateVars<kRegClassGp >(this, src);
X86X64Context_loadStateVars<kRegClassMm>(this, src); X86X64Context_loadStateVars<kRegClassMm >(this, src);
X86X64Context_loadStateVars<kRegClassXy>(this, src); X86X64Context_loadStateVars<kRegClassXyz>(this, src);
// Load masks. // Load masks.
cur->_occupied = src->_occupied; cur->_occupied = src->_occupied;
@@ -1290,7 +1297,7 @@ void X86X64Context::loadState(BaseVarState* src_) {
vdArray[i]->setModified(false); vdArray[i]->setModified(false);
} }
ASMJIT_CONTEXT_CHECK_STATE ASMJIT_X86_CHECK_STATE
} }
// ============================================================================ // ============================================================================
@@ -1463,9 +1470,9 @@ void X86X64Context::switchState(BaseVarState* src_) {
return; return;
// Switch variables. // Switch variables.
X86X64Context_switchStateVars<kRegClassGp>(this, src); X86X64Context_switchStateVars<kRegClassGp >(this, src);
X86X64Context_switchStateVars<kRegClassMm>(this, src); X86X64Context_switchStateVars<kRegClassMm >(this, src);
X86X64Context_switchStateVars<kRegClassXy>(this, src); X86X64Context_switchStateVars<kRegClassXyz>(this, src);
// Calculate changed state. // Calculate changed state.
VarData** vdArray = _contextVd.getData(); VarData** vdArray = _contextVd.getData();
@@ -1483,7 +1490,7 @@ void X86X64Context::switchState(BaseVarState* src_) {
} }
} }
ASMJIT_CONTEXT_CHECK_STATE ASMJIT_X86_CHECK_STATE
} }
// ============================================================================ // ============================================================================
@@ -1495,23 +1502,23 @@ void X86X64Context::intersectStates(BaseVarState* a_, BaseVarState* b_) {
VarState* bState = static_cast<VarState*>(b_); VarState* bState = static_cast<VarState*>(b_);
// TODO: [COMPILER] Intersect states. // TODO: [COMPILER] Intersect states.
ASMJIT_CONTEXT_CHECK_STATE ASMJIT_X86_CHECK_STATE
} }
// ============================================================================ // ============================================================================
// [asmjit::x86x64::X86X64Context - GetJccFlow / GetOppositeJccFlow] // [asmjit::x86x64::X86X64Context - GetJccFlow / GetOppositeJccFlow]
// ============================================================================ // ============================================================================
//! @internal //! \internal
static ASMJIT_INLINE BaseNode* X86X64Context_getJccFlow(JumpNode* jNode) { static ASMJIT_INLINE Node* X86X64Context_getJccFlow(JumpNode* jNode) {
if (jNode->isTaken()) if (jNode->isTaken())
return jNode->getTarget(); return jNode->getTarget();
else else
return jNode->getNext(); return jNode->getNext();
} }
//! @internal //! \internal
static ASMJIT_INLINE BaseNode* X86X64Context_getOppositeJccFlow(JumpNode* jNode) { static ASMJIT_INLINE Node* X86X64Context_getOppositeJccFlow(JumpNode* jNode) {
if (jNode->isTaken()) if (jNode->isTaken())
return jNode->getNext(); return jNode->getNext();
else else
@@ -1522,7 +1529,7 @@ static ASMJIT_INLINE BaseNode* X86X64Context_getOppositeJccFlow(JumpNode* jNode)
// [asmjit::x86x64::X86X64Context - SingleVarInst] // [asmjit::x86x64::X86X64Context - SingleVarInst]
// ============================================================================ // ============================================================================
//! @internal //! \internal
static void X86X64Context_prepareSingleVarInst(uint32_t code, VarAttr* va) { static void X86X64Context_prepareSingleVarInst(uint32_t code, VarAttr* va) {
switch (code) { switch (code) {
// - andn reg, reg ; Set all bits in reg to 0. // - andn reg, reg ; Set all bits in reg to 0.
@@ -1555,11 +1562,11 @@ static void X86X64Context_prepareSingleVarInst(uint32_t code, VarAttr* va) {
// [asmjit::x86x64::X86X64Context - Helpers] // [asmjit::x86x64::X86X64Context - Helpers]
// ============================================================================ // ============================================================================
//! @internal //! \internal
//! //!
//! Add unreachable-flow data to the unreachable flow list. //! Add unreachable-flow data to the unreachable flow list.
static ASMJIT_INLINE Error X86X64Context_addUnreachableNode(X86X64Context* self, BaseNode* node) { static ASMJIT_INLINE Error X86X64Context_addUnreachableNode(X86X64Context* self, Node* node) {
PodList<BaseNode*>::Link* link = self->_baseZone.allocT<PodList<BaseNode*>::Link>(); PodList<Node*>::Link* link = self->_baseZone.allocT<PodList<Node*>::Link>();
if (link == NULL) if (link == NULL)
return self->setError(kErrorNoHeapMemory); return self->setError(kErrorNoHeapMemory);
@@ -1569,11 +1576,11 @@ static ASMJIT_INLINE Error X86X64Context_addUnreachableNode(X86X64Context* self,
return kErrorOk; return kErrorOk;
} }
//! @internal //! \internal
//! //!
//! Add jump-flow data to the jcc flow list. //! Add jump-flow data to the jcc flow list.
static ASMJIT_INLINE Error X86X64Context_addJccNode(X86X64Context* self, BaseNode* node) { static ASMJIT_INLINE Error X86X64Context_addJccNode(X86X64Context* self, Node* node) {
PodList<BaseNode*>::Link* link = self->_baseZone.allocT<PodList<BaseNode*>::Link>(); PodList<Node*>::Link* link = self->_baseZone.allocT<PodList<Node*>::Link>();
if (link == NULL) if (link == NULL)
ASMJIT_PROPAGATE_ERROR(self->setError(kErrorNoHeapMemory)); ASMJIT_PROPAGATE_ERROR(self->setError(kErrorNoHeapMemory));
@@ -1584,7 +1591,7 @@ static ASMJIT_INLINE Error X86X64Context_addJccNode(X86X64Context* self, BaseNod
return kErrorOk; return kErrorOk;
} }
//! @internal //! \internal
//! //!
//! Get mask of all registers actually used to pass function arguments. //! Get mask of all registers actually used to pass function arguments.
static ASMJIT_INLINE RegMask X86X64Context_getUsedArgs(X86X64Context* self, X86X64CallNode* node, X86X64FuncDecl* decl) { static ASMJIT_INLINE RegMask X86X64Context_getUsedArgs(X86X64Context* self, X86X64CallNode* node, X86X64FuncDecl* decl) {
@@ -1813,7 +1820,7 @@ static ASMJIT_INLINE Error X86X64Context_insertSArgNode(
// [asmjit::x86x64::X86X64Context - Fetch] // [asmjit::x86x64::X86X64Context - Fetch]
// ============================================================================ // ============================================================================
//! @internal //! \internal
//! //!
//! Prepare the given function `func`. //! Prepare the given function `func`.
//! //!
@@ -1826,9 +1833,9 @@ Error X86X64Context::fetch() {
uint32_t arch = compiler->getArch(); uint32_t arch = compiler->getArch();
BaseNode* node_ = func; Node* node_ = func;
BaseNode* next = NULL; Node* next = NULL;
BaseNode* stop = getStop(); Node* stop = getStop();
uint32_t groupId = 1; uint32_t groupId = 1;
uint32_t flowId = 0; uint32_t flowId = 0;
@@ -1836,7 +1843,7 @@ Error X86X64Context::fetch() {
VarAttr vaTmpList[80]; VarAttr vaTmpList[80];
SArgData sArgList[80]; SArgData sArgList[80];
PodList<BaseNode*>::Link* jLink = NULL; PodList<Node*>::Link* jLink = NULL;
// Function flags. // Function flags.
func->clearFuncFlags( func->clearFuncFlags(
@@ -1913,7 +1920,7 @@ Error X86X64Context::fetch() {
else if (va->_outRegIndex != kInvalidReg) \ else if (va->_outRegIndex != kInvalidReg) \
va->_allocableRegs = IntUtil::mask(va->_outRegIndex); \ va->_allocableRegs = IntUtil::mask(va->_outRegIndex); \
else \ else \
va->_allocableRegs &= ~inRegs._regs[class_]; \ va->_allocableRegs &= ~inRegs.get(class_); \
\ \
vd->_va = NULL; \ vd->_va = NULL; \
vi->getVa(index)[0] = va[0]; \ vi->getVa(index)[0] = va[0]; \
@@ -2001,10 +2008,10 @@ _NextGroup:
uint32_t remain[kRegClassCount]; uint32_t remain[kRegClassCount];
HintNode* cur = node; HintNode* cur = node;
remain[kRegClassGp] = _baseRegsCount - 1 - func->hasFuncFlag(kFuncFlagIsNaked); remain[kRegClassGp ] = _baseRegsCount - 1 - func->hasFuncFlag(kFuncFlagIsNaked);
remain[kRegClassFp] = kRegCountFp; remain[kRegClassFp ] = kRegCountFp;
remain[kRegClassMm] = kRegCountMm; remain[kRegClassMm ] = kRegCountMm;
remain[kRegClassXy] = _baseRegsCount; remain[kRegClassXyz] = _baseRegsCount;
// Merge as many alloc-hints as possible. // Merge as many alloc-hints as possible.
for (;;) { for (;;) {
@@ -2020,14 +2027,14 @@ _NextGroup:
regMask = IntUtil::mask(regIndex); regMask = IntUtil::mask(regIndex);
if (va == NULL) { if (va == NULL) {
if ((inRegs._regs[regClass] & regMask) != 0) if (inRegs.has(regClass, regMask))
break; break;
if (remain[regClass] == 0) if (remain[regClass] == 0)
break; break;
VI_ADD_VAR(vd, va, kVarAttrInReg, gaRegs[regClass]); VI_ADD_VAR(vd, va, kVarAttrInReg, gaRegs[regClass]);
if (regMask != 0) { if (regMask != 0) {
inRegs._regs[regClass] ^= static_cast<uint16_t>(regMask); inRegs.xor_(regClass, regMask);
va->setInRegs(regMask); va->setInRegs(regMask);
va->setInRegIndex(regIndex); va->setInRegIndex(regIndex);
} }
@@ -2035,10 +2042,10 @@ _NextGroup:
remain[regClass]--; remain[regClass]--;
} }
else if (regMask != 0) { else if (regMask != 0) {
if ((inRegs._regs[regClass] & regMask) != 0 && va->getInRegs() != regMask) if (inRegs.has(regClass, regMask) && va->getInRegs() != regMask)
break; break;
inRegs._regs[regClass] ^= static_cast<uint16_t>(va->getInRegs() | regMask); inRegs.xor_(regClass, va->getInRegs() | regMask);
va->setInRegs(regMask); va->setInRegs(regMask);
va->setInRegIndex(regIndex); va->setInRegIndex(regIndex);
} }
@@ -2160,7 +2167,7 @@ _NextGroup:
if (static_cast<const X86Reg*>(op)->isGp()) if (static_cast<const X86Reg*>(op)->isGp())
c = kRegClassGp; c = kRegClassGp;
else else
c = kRegClassXy; c = kRegClassXyz;
if (inReg != kInvalidReg) { if (inReg != kInvalidReg) {
uint32_t mask = IntUtil::mask(inReg); uint32_t mask = IntUtil::mask(inReg);
@@ -2316,7 +2323,7 @@ _NextGroup:
if (node->isJmpOrJcc()) { if (node->isJmpOrJcc()) {
JumpNode* jNode = static_cast<JumpNode*>(node); JumpNode* jNode = static_cast<JumpNode*>(node);
BaseNode* jNext = jNode->getNext(); Node* jNext = jNode->getNext();
TargetNode* jTarget = jNode->getTarget(); TargetNode* jTarget = jNode->getTarget();
// If this jump is unconditional we put next node to unreachable node // If this jump is unconditional we put next node to unreachable node
@@ -2378,7 +2385,7 @@ _NextGroup:
// Overlapped function arguments. // Overlapped function arguments.
if (vd->getVa() != NULL) if (vd->getVa() != NULL)
return compiler->setError(kErrorCompilerOverlappedArgs); return compiler->setError(kErrorOverlappedArgs);
VI_ADD_VAR(vd, va, 0, 0); VI_ADD_VAR(vd, va, 0, 0);
uint32_t aType = arg.getVarType(); uint32_t aType = arg.getVarType();
@@ -2575,10 +2582,10 @@ _NextGroup:
} }
// Init clobbered. // Init clobbered.
clobberedRegs.set(kRegClassGp, IntUtil::bits(_baseRegsCount) & (~decl->getPreserved(kRegClassGp))); clobberedRegs.set(kRegClassGp , IntUtil::bits(_baseRegsCount) & (~decl->getPreserved(kRegClassGp )));
clobberedRegs.set(kRegClassFp, IntUtil::bits(kRegCountFp ) ); clobberedRegs.set(kRegClassFp , IntUtil::bits(kRegCountFp ));
clobberedRegs.set(kRegClassMm, IntUtil::bits(kRegCountMm ) & (~decl->getPreserved(kRegClassMm))); clobberedRegs.set(kRegClassMm , IntUtil::bits(kRegCountMm ) & (~decl->getPreserved(kRegClassMm )));
clobberedRegs.set(kRegClassXy, IntUtil::bits(_baseRegsCount) & (~decl->getPreserved(kRegClassXy))); clobberedRegs.set(kRegClassXyz, IntUtil::bits(_baseRegsCount) & (~decl->getPreserved(kRegClassXyz)));
VI_END(node_); VI_END(node_);
break; break;
@@ -2606,7 +2613,7 @@ _NoMemory:
// [asmjit::x86x64::X86X64Context - Analyze] // [asmjit::x86x64::X86X64Context - Analyze]
// ============================================================================ // ============================================================================
//! @internal //! \internal
struct LivenessTarget { struct LivenessTarget {
//! Previous target. //! Previous target.
LivenessTarget* prev; LivenessTarget* prev;
@@ -2620,7 +2627,7 @@ struct LivenessTarget {
Error X86X64Context::analyze() { Error X86X64Context::analyze() {
FuncNode* func = getFunc(); FuncNode* func = getFunc();
BaseNode* node = func->getEnd(); Node* node = func->getEnd();
JumpNode* from = NULL; JumpNode* from = NULL;
uint32_t bLen = static_cast<uint32_t>( uint32_t bLen = static_cast<uint32_t>(
@@ -2905,8 +2912,8 @@ static bool X86X64Context_annotateInstruction(X86X64Context* self,
Error X86X64Context::annotate() { Error X86X64Context::annotate() {
FuncNode* func = getFunc(); FuncNode* func = getFunc();
BaseNode* node_ = func; Node* node_ = func;
BaseNode* end = func->getEnd(); Node* end = func->getEnd();
Zone& sa = _compiler->_stringZone; Zone& sa = _compiler->_stringZone;
StringBuilderT<128> sb; StringBuilderT<128> sb;
@@ -2958,7 +2965,7 @@ struct X86X64BaseAlloc {
ASMJIT_INLINE VarState* getState() const { return _context->getState(); } ASMJIT_INLINE VarState* getState() const { return _context->getState(); }
//! Get the node. //! Get the node.
ASMJIT_INLINE BaseNode* getNode() const { return _node; } ASMJIT_INLINE Node* getNode() const { return _node; }
//! Get VarAttr list (all). //! Get VarAttr list (all).
ASMJIT_INLINE VarAttr* getVaList() const { return _vaList[0]; } ASMJIT_INLINE VarAttr* getVaList() const { return _vaList[0]; }
@@ -2990,7 +2997,7 @@ struct X86X64BaseAlloc {
protected: protected:
// Just to prevent calling these methods by X86X64Context::translate(). // Just to prevent calling these methods by X86X64Context::translate().
ASMJIT_INLINE void init(BaseNode* node, VarInst* vi); ASMJIT_INLINE void init(Node* node, VarInst* vi);
ASMJIT_INLINE void cleanup(); ASMJIT_INLINE void cleanup();
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -3013,7 +3020,7 @@ protected:
X86X64Compiler* _compiler; X86X64Compiler* _compiler;
//! Node. //! Node.
BaseNode* _node; Node* _node;
//! Variable instructions. //! Variable instructions.
VarInst* _vi; VarInst* _vi;
@@ -3033,7 +3040,7 @@ protected:
// [asmjit::x86x64::X86X64BaseAlloc - Init / Cleanup] // [asmjit::x86x64::X86X64BaseAlloc - Init / Cleanup]
// ============================================================================ // ============================================================================
ASMJIT_INLINE void X86X64BaseAlloc::init(BaseNode* node, VarInst* vi) { ASMJIT_INLINE void X86X64BaseAlloc::init(Node* node, VarInst* vi) {
_node = node; _node = node;
_vi = vi; _vi = vi;
@@ -3045,10 +3052,10 @@ ASMJIT_INLINE void X86X64BaseAlloc::init(BaseNode* node, VarInst* vi) {
// Setup the lists of variables. // Setup the lists of variables.
{ {
VarAttr* va = vi->getVaList(); VarAttr* va = vi->getVaList();
_vaList[kRegClassGp] = va; _vaList[kRegClassGp ] = va;
_vaList[kRegClassFp] = va + vi->getVaStart(kRegClassFp); _vaList[kRegClassFp ] = va + vi->getVaStart(kRegClassFp );
_vaList[kRegClassMm] = va + vi->getVaStart(kRegClassMm); _vaList[kRegClassMm ] = va + vi->getVaStart(kRegClassMm );
_vaList[kRegClassXy] = va + vi->getVaStart(kRegClassXy); _vaList[kRegClassXyz] = va + vi->getVaStart(kRegClassXyz);
} }
// Setup counters. // Setup counters.
@@ -3118,7 +3125,7 @@ ASMJIT_INLINE void X86X64BaseAlloc::unuseAfter() {
// [asmjit::x86x64::X86X64VarAlloc] // [asmjit::x86x64::X86X64VarAlloc]
// ============================================================================ // ============================================================================
//! @internal //! \internal
//! //!
//! Register allocator context (asm instructions). //! Register allocator context (asm instructions).
struct X86X64VarAlloc : public X86X64BaseAlloc { struct X86X64VarAlloc : public X86X64BaseAlloc {
@@ -3133,7 +3140,7 @@ struct X86X64VarAlloc : public X86X64BaseAlloc {
// [Run] // [Run]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
ASMJIT_INLINE Error run(BaseNode* node); ASMJIT_INLINE Error run(Node* node);
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [Init / Cleanup] // [Init / Cleanup]
@@ -3142,7 +3149,7 @@ struct X86X64VarAlloc : public X86X64BaseAlloc {
protected: protected:
// Just to prevent calling these methods by X86X64Context::translate(). // Just to prevent calling these methods by X86X64Context::translate().
ASMJIT_INLINE void init(BaseNode* node, VarInst* vi); ASMJIT_INLINE void init(Node* node, VarInst* vi);
ASMJIT_INLINE void cleanup(); ASMJIT_INLINE void cleanup();
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -3198,7 +3205,7 @@ protected:
// [asmjit::X86X64VarAlloc - Run] // [asmjit::X86X64VarAlloc - Run]
// ============================================================================ // ============================================================================
ASMJIT_INLINE Error X86X64VarAlloc::run(BaseNode* node_) { ASMJIT_INLINE Error X86X64VarAlloc::run(Node* node_) {
// Initialize. // Initialize.
VarInst* vi = node_->getVarInst<VarInst>(); VarInst* vi = node_->getVarInst<VarInst>();
if (vi == NULL) if (vi == NULL)
@@ -3208,25 +3215,25 @@ ASMJIT_INLINE Error X86X64VarAlloc::run(BaseNode* node_) {
init(node_, vi); init(node_, vi);
// Unuse overwritten variables. // Unuse overwritten variables.
unuseBefore<kRegClassGp>(); unuseBefore<kRegClassGp >();
unuseBefore<kRegClassMm>(); unuseBefore<kRegClassMm >();
unuseBefore<kRegClassXy>(); unuseBefore<kRegClassXyz>();
// Plan the allocation. Planner assigns input/output registers for each // Plan the allocation. Planner assigns input/output registers for each
// variable and decides whether to allocate it in register or stack. // variable and decides whether to allocate it in register or stack.
plan<kRegClassGp>(); plan<kRegClassGp >();
plan<kRegClassMm>(); plan<kRegClassMm >();
plan<kRegClassXy>(); plan<kRegClassXyz>();
// Spill all variables marked by plan(). // Spill all variables marked by plan().
spill<kRegClassGp>(); spill<kRegClassGp >();
spill<kRegClassMm>(); spill<kRegClassMm >();
spill<kRegClassXy>(); spill<kRegClassXyz>();
// Alloc all variables marked by plan(). // Alloc all variables marked by plan().
alloc<kRegClassGp>(); alloc<kRegClassGp >();
alloc<kRegClassMm>(); alloc<kRegClassMm >();
alloc<kRegClassXy>(); alloc<kRegClassXyz>();
// Translate node operands. // Translate node operands.
if (node_->getType() == kNodeTypeInst) { if (node_->getType() == kNodeTypeInst) {
@@ -3271,9 +3278,9 @@ ASMJIT_INLINE Error X86X64VarAlloc::run(BaseNode* node_) {
} }
// Mark variables as modified. // Mark variables as modified.
modified<kRegClassGp>(); modified<kRegClassGp >();
modified<kRegClassMm>(); modified<kRegClassMm >();
modified<kRegClassXy>(); modified<kRegClassXyz>();
// Cleanup; disconnect Vd->Va. // Cleanup; disconnect Vd->Va.
cleanup(); cleanup();
@@ -3283,9 +3290,9 @@ ASMJIT_INLINE Error X86X64VarAlloc::run(BaseNode* node_) {
_context->_clobberedRegs.add(vi->_clobberedRegs); _context->_clobberedRegs.add(vi->_clobberedRegs);
// Unuse. // Unuse.
unuseAfter<kRegClassGp>(); unuseAfter<kRegClassGp >();
unuseAfter<kRegClassMm>(); unuseAfter<kRegClassMm >();
unuseAfter<kRegClassXy>(); unuseAfter<kRegClassXyz>();
return kErrorOk; return kErrorOk;
} }
@@ -3294,7 +3301,7 @@ ASMJIT_INLINE Error X86X64VarAlloc::run(BaseNode* node_) {
// [asmjit::x86x64::X86X64VarAlloc - Init / Cleanup] // [asmjit::x86x64::X86X64VarAlloc - Init / Cleanup]
// ============================================================================ // ============================================================================
ASMJIT_INLINE void X86X64VarAlloc::init(BaseNode* node, VarInst* vi) { ASMJIT_INLINE void X86X64VarAlloc::init(Node* node, VarInst* vi) {
X86X64BaseAlloc::init(node, vi); X86X64BaseAlloc::init(node, vi);
// These will block planner from assigning them during planning. Planner will // These will block planner from assigning them during planning. Planner will
@@ -3663,7 +3670,7 @@ ASMJIT_INLINE uint32_t X86X64VarAlloc::guessAlloc(VarData* vd, uint32_t allocabl
uint32_t maxLookAhead = _compiler->getMaxLookAhead(); uint32_t maxLookAhead = _compiler->getMaxLookAhead();
// Look ahead and calculate mask of special registers on both - input/output. // Look ahead and calculate mask of special registers on both - input/output.
BaseNode* node = _node; Node* node = _node;
for (i = 0; i < maxLookAhead; i++) { for (i = 0; i < maxLookAhead; i++) {
// Stop on 'RetNode' and 'EndNode. // Stop on 'RetNode' and 'EndNode.
if (node->hasFlag(kNodeFlagIsRet)) if (node->hasFlag(kNodeFlagIsRet))
@@ -3743,7 +3750,7 @@ ASMJIT_INLINE void X86X64VarAlloc::modified() {
// [asmjit::x86x64::X86X64CallAlloc] // [asmjit::x86x64::X86X64CallAlloc]
// ============================================================================ // ============================================================================
//! @internal //! \internal
//! //!
//! Register allocator context (function call). //! Register allocator context (function call).
struct X86X64CallAlloc : public X86X64BaseAlloc { struct X86X64CallAlloc : public X86X64BaseAlloc {
@@ -3858,33 +3865,33 @@ ASMJIT_INLINE Error X86X64CallAlloc::run(X86X64CallNode* node) {
// Plan register allocation. Planner is only able to assign one register per // Plan register allocation. Planner is only able to assign one register per
// variable. If any variable is used multiple times it will be handled later. // variable. If any variable is used multiple times it will be handled later.
plan<kRegClassGp>(); plan<kRegClassGp >();
plan<kRegClassMm>(); plan<kRegClassMm >();
plan<kRegClassXy>(); plan<kRegClassXyz>();
// Spill. // Spill.
spill<kRegClassGp>(); spill<kRegClassGp >();
spill<kRegClassMm>(); spill<kRegClassMm >();
spill<kRegClassXy>(); spill<kRegClassXyz>();
// Alloc. // Alloc.
alloc<kRegClassGp>(); alloc<kRegClassGp >();
alloc<kRegClassMm>(); alloc<kRegClassMm >();
alloc<kRegClassXy>(); alloc<kRegClassXyz>();
// Unuse clobbered registers that are not used to pass function arguments and // Unuse clobbered registers that are not used to pass function arguments and
// save variables used to pass function arguments that will be reused later on. // save variables used to pass function arguments that will be reused later on.
save<kRegClassGp>(); save<kRegClassGp >();
save<kRegClassMm>(); save<kRegClassMm >();
save<kRegClassXy>(); save<kRegClassXyz>();
// Allocate immediates in registers and on the stack. // Allocate immediates in registers and on the stack.
allocImmsOnStack(); allocImmsOnStack();
// Duplicate. // Duplicate.
duplicate<kRegClassGp>(); duplicate<kRegClassGp >();
duplicate<kRegClassMm>(); duplicate<kRegClassMm >();
duplicate<kRegClassXy>(); duplicate<kRegClassXyz>();
// Translate call operand. // Translate call operand.
ASMJIT_PROPAGATE_ERROR(X86X64Context_translateOperands(_context, &node->_target, 1)); ASMJIT_PROPAGATE_ERROR(X86X64Context_translateOperands(_context, &node->_target, 1));
@@ -3899,17 +3906,17 @@ ASMJIT_INLINE Error X86X64CallAlloc::run(X86X64CallNode* node) {
} }
// Clobber. // Clobber.
clobber<kRegClassGp>(); clobber<kRegClassGp >();
clobber<kRegClassMm>(); clobber<kRegClassMm >();
clobber<kRegClassXy>(); clobber<kRegClassXyz>();
// Return. // Return.
ret(); ret();
// Unuse. // Unuse.
unuseAfter<kRegClassGp>(); unuseAfter<kRegClassGp >();
unuseAfter<kRegClassMm>(); unuseAfter<kRegClassMm >();
unuseAfter<kRegClassXy>(); unuseAfter<kRegClassXyz>();
// Cleanup; disconnect Vd->Va. // Cleanup; disconnect Vd->Va.
cleanup(); cleanup();
@@ -4253,7 +4260,7 @@ ASMJIT_INLINE uint32_t X86X64CallAlloc::guessAlloc(VarData* vd, uint32_t allocab
uint32_t maxLookAhead = _compiler->getMaxLookAhead(); uint32_t maxLookAhead = _compiler->getMaxLookAhead();
// Look ahead and calculate mask of special registers on both - input/output. // Look ahead and calculate mask of special registers on both - input/output.
BaseNode* node = _node; Node* node = _node;
for (i = 0; i < maxLookAhead; i++) { for (i = 0; i < maxLookAhead; i++) {
// Stop on 'RetNode' and 'EndNode. // Stop on 'RetNode' and 'EndNode.
if (node->hasFlag(kNodeFlagIsRet)) if (node->hasFlag(kNodeFlagIsRet))
@@ -4392,10 +4399,10 @@ ASMJIT_INLINE void X86X64CallAlloc::ret() {
_context->unuse<kRegClassMm>(vd); _context->unuse<kRegClassMm>(vd);
_context->attach<kRegClassMm>(vd, regIndex, true); _context->attach<kRegClassMm>(vd, regIndex, true);
break; break;
case kRegClassXy: case kRegClassXyz:
if (vd->getRegIndex() != kInvalidReg) if (vd->getRegIndex() != kInvalidReg)
_context->unuse<kRegClassXy>(vd); _context->unuse<kRegClassXyz>(vd);
_context->attach<kRegClassXy>(vd, regIndex, true); _context->attach<kRegClassXyz>(vd, regIndex, true);
break; break;
} }
} }
@@ -4405,7 +4412,7 @@ ASMJIT_INLINE void X86X64CallAlloc::ret() {
// [asmjit::x86x64::X86X64Context - TranslateOperands] // [asmjit::x86x64::X86X64Context - TranslateOperands]
// ============================================================================ // ============================================================================
//! @internal //! \internal
static Error X86X64Context_translateOperands(X86X64Context* self, Operand* opList, uint32_t opCount) { static Error X86X64Context_translateOperands(X86X64Context* self, Operand* opList, uint32_t opCount) {
X86X64Compiler* compiler = self->getCompiler(); X86X64Compiler* compiler = self->getCompiler();
const VarInfo* varInfo = _varInfo; const VarInfo* varInfo = _varInfo;
@@ -4460,7 +4467,7 @@ static Error X86X64Context_translateOperands(X86X64Context* self, Operand* opLis
// [asmjit::x86x64::X86X64Context - TranslatePrologEpilog] // [asmjit::x86x64::X86X64Context - TranslatePrologEpilog]
// ============================================================================ // ============================================================================
//! @internal //! \internal
static Error X86X64Context_initFunc(X86X64Context* self, X86X64FuncNode* func) { static Error X86X64Context_initFunc(X86X64Context* self, X86X64FuncNode* func) {
X86X64Compiler* compiler = self->getCompiler(); X86X64Compiler* compiler = self->getCompiler();
X86X64FuncDecl* decl = func->getDecl(); X86X64FuncDecl* decl = func->getDecl();
@@ -4469,10 +4476,10 @@ static Error X86X64Context_initFunc(X86X64Context* self, X86X64FuncNode* func) {
uint32_t regSize = compiler->getRegSize(); uint32_t regSize = compiler->getRegSize();
// Setup "Save-Restore" registers. // Setup "Save-Restore" registers.
func->_saveRestoreRegs.set(kRegClassGp, clobberedRegs.get(kRegClassGp) & decl->getPreserved(kRegClassGp)); func->_saveRestoreRegs.set(kRegClassGp , clobberedRegs.get(kRegClassGp ) & decl->getPreserved(kRegClassGp ));
func->_saveRestoreRegs.set(kRegClassFp, 0 ); func->_saveRestoreRegs.set(kRegClassFp , 0);
func->_saveRestoreRegs.set(kRegClassMm, clobberedRegs.get(kRegClassMm) & decl->getPreserved(kRegClassMm)); func->_saveRestoreRegs.set(kRegClassMm , clobberedRegs.get(kRegClassMm ) & decl->getPreserved(kRegClassMm ));
func->_saveRestoreRegs.set(kRegClassXy, clobberedRegs.get(kRegClassXy) & decl->getPreserved(kRegClassXy)); func->_saveRestoreRegs.set(kRegClassXyz, clobberedRegs.get(kRegClassXyz) & decl->getPreserved(kRegClassXyz));
ASMJIT_ASSERT(!func->_saveRestoreRegs.has(kRegClassGp, IntUtil::mask(kRegIndexSp))); ASMJIT_ASSERT(!func->_saveRestoreRegs.has(kRegClassGp, IntUtil::mask(kRegIndexSp)));
@@ -4484,7 +4491,7 @@ static Error X86X64Context_initFunc(X86X64Context* self, X86X64FuncNode* func) {
// Require 16-byte alignment if 8-byte vars are used. // Require 16-byte alignment if 8-byte vars are used.
if (self->_mem8ByteVarsUsed) if (self->_mem8ByteVarsUsed)
requiredStackAlignment = 16; requiredStackAlignment = 16;
else if (func->_saveRestoreRegs.get(kRegClassMm) || func->_saveRestoreRegs.get(kRegClassXy)) else if (func->_saveRestoreRegs.get(kRegClassMm) || func->_saveRestoreRegs.get(kRegClassXyz))
requiredStackAlignment = 16; requiredStackAlignment = 16;
else if (IntUtil::inInterval<uint32_t>(func->getRequiredStackAlignment(), 8, 16)) else if (IntUtil::inInterval<uint32_t>(func->getRequiredStackAlignment(), 8, 16))
requiredStackAlignment = 16; requiredStackAlignment = 16;
@@ -4580,9 +4587,9 @@ static Error X86X64Context_initFunc(X86X64Context* self, X86X64FuncNode* func) {
// Setup stack size used to save preserved registers. // Setup stack size used to save preserved registers.
{ {
uint32_t memGpSize = IntUtil::bitCount(func->_saveRestoreRegs.get(kRegClassGp)) * regSize; uint32_t memGpSize = IntUtil::bitCount(func->_saveRestoreRegs.get(kRegClassGp )) * regSize;
uint32_t memMmSize = IntUtil::bitCount(func->_saveRestoreRegs.get(kRegClassMm)) * 8; uint32_t memMmSize = IntUtil::bitCount(func->_saveRestoreRegs.get(kRegClassMm )) * 8;
uint32_t memXmmSize = IntUtil::bitCount(func->_saveRestoreRegs.get(kRegClassXy)) * 16; uint32_t memXmmSize = IntUtil::bitCount(func->_saveRestoreRegs.get(kRegClassXyz)) * 16;
if (func->hasFuncFlag(kFuncFlagPushPop)) { if (func->hasFuncFlag(kFuncFlagPushPop)) {
func->_pushPopStackSize = memGpSize; func->_pushPopStackSize = memGpSize;
@@ -4663,10 +4670,10 @@ static Error X86X64Context_initFunc(X86X64Context* self, X86X64FuncNode* func) {
return kErrorOk; return kErrorOk;
} }
//! @internal //! \internal
static Error X86X64Context_patchFuncMem(X86X64Context* self, X86X64FuncNode* func, BaseNode* stop) { static Error X86X64Context_patchFuncMem(X86X64Context* self, X86X64FuncNode* func, Node* stop) {
X86X64Compiler* compiler = self->getCompiler(); X86X64Compiler* compiler = self->getCompiler();
BaseNode* node = func; Node* node = func;
do { do {
if (node->getType() == kNodeTypeInst) { if (node->getType() == kNodeTypeInst) {
@@ -4702,7 +4709,7 @@ static Error X86X64Context_patchFuncMem(X86X64Context* self, X86X64FuncNode* fun
return kErrorOk; return kErrorOk;
} }
//! @internal //! \internal
static Error X86X64Context_translatePrologEpilog(X86X64Context* self, X86X64FuncNode* func) { static Error X86X64Context_translatePrologEpilog(X86X64Context* self, X86X64FuncNode* func) {
X86X64Compiler* compiler = self->getCompiler(); X86X64Compiler* compiler = self->getCompiler();
X86X64FuncDecl* decl = func->getDecl(); X86X64FuncDecl* decl = func->getDecl();
@@ -4733,9 +4740,9 @@ static Error X86X64Context_translatePrologEpilog(X86X64Context* self, X86X64Func
} }
uint32_t i, mask; uint32_t i, mask;
uint32_t regsGp = func->getSaveRestoreRegs(kRegClassGp); uint32_t regsGp = func->getSaveRestoreRegs(kRegClassGp );
uint32_t regsMm = func->getSaveRestoreRegs(kRegClassMm); uint32_t regsMm = func->getSaveRestoreRegs(kRegClassMm );
uint32_t regsXmm = func->getSaveRestoreRegs(kRegClassXy); uint32_t regsXmm = func->getSaveRestoreRegs(kRegClassXyz);
bool earlyPushPop = false; bool earlyPushPop = false;
bool useLeaEpilog = false; bool useLeaEpilog = false;
@@ -4966,10 +4973,10 @@ static Error X86X64Context_translatePrologEpilog(X86X64Context* self, X86X64Func
// [asmjit::x86x64::X86X64Context - Translate - Jump] // [asmjit::x86x64::X86X64Context - Translate - Jump]
// ============================================================================ // ============================================================================
//! @internal //! \internal
static void X86X64Context_translateJump(X86X64Context* self, JumpNode* jNode, TargetNode* jTarget) { static void X86X64Context_translateJump(X86X64Context* self, JumpNode* jNode, TargetNode* jTarget) {
X86X64Compiler* compiler = self->getCompiler(); X86X64Compiler* compiler = self->getCompiler();
BaseNode* extNode = self->getExtraBlock(); Node* extNode = self->getExtraBlock();
// TODO: [COMPILER] State Change. // TODO: [COMPILER] State Change.
compiler->_setCursor(extNode); compiler->_setCursor(extNode);
@@ -5003,7 +5010,7 @@ static void X86X64Context_translateJump(X86X64Context* self, JumpNode* jNode, Ta
// ============================================================================ // ============================================================================
static Error X86X64Context_translateRet(X86X64Context* self, RetNode* rNode, TargetNode* exitTarget) { static Error X86X64Context_translateRet(X86X64Context* self, RetNode* rNode, TargetNode* exitTarget) {
BaseNode* node = rNode->getNext(); Node* node = rNode->getNext();
while (node != NULL) { while (node != NULL) {
switch (node->getType()) { switch (node->getType()) {
@@ -5061,11 +5068,11 @@ Error X86X64Context::translate() {
X86X64CallAlloc cAlloc(this); X86X64CallAlloc cAlloc(this);
// Flow. // Flow.
BaseNode* node_ = func; Node* node_ = func;
BaseNode* next = NULL; Node* next = NULL;
BaseNode* stop = getStop(); Node* stop = getStop();
PodList<BaseNode*>::Link* jLink = _jccList.getFirst(); PodList<Node*>::Link* jLink = _jccList.getFirst();
for (;;) { for (;;) {
while (node_->isTranslated()) { while (node_->isTranslated()) {
@@ -5084,7 +5091,7 @@ _NextGroup:
node_ = jLink->getValue(); node_ = jLink->getValue();
jLink = jLink->getNext(); jLink = jLink->getNext();
BaseNode* jFlow = X86X64Context_getOppositeJccFlow(static_cast<JumpNode*>(node_)); Node* jFlow = X86X64Context_getOppositeJccFlow(static_cast<JumpNode*>(node_));
loadState(node_->getState()); loadState(node_->getState());
if (jFlow->getState()) { if (jFlow->getState()) {
@@ -5180,7 +5187,7 @@ _NextGroup:
} }
} }
else { else {
BaseNode* jNext = node->getNext(); Node* jNext = node->getNext();
if (jTarget->isTranslated()) { if (jTarget->isTranslated()) {
if (jNext->isTranslated()) { if (jNext->isTranslated()) {
@@ -5245,9 +5252,9 @@ _NextGroup:
uint32_t regIndex = va->getOutRegIndex(); uint32_t regIndex = va->getOutRegIndex();
if (regIndex != kInvalidReg && (va->getFlags() & kVarAttrOutConv) == 0) { if (regIndex != kInvalidReg && (va->getFlags() & kVarAttrOutConv) == 0) {
switch (vd->getClass()) { switch (vd->getClass()) {
case kRegClassGp: attach<kRegClassGp>(vd, regIndex, true); break; case kRegClassGp : attach<kRegClassGp >(vd, regIndex, true); break;
case kRegClassMm: attach<kRegClassMm>(vd, regIndex, true); break; case kRegClassMm : attach<kRegClassMm >(vd, regIndex, true); break;
case kRegClassXy: attach<kRegClassXy>(vd, regIndex, true); break; case kRegClassXyz: attach<kRegClassXyz>(vd, regIndex, true); break;
} }
} }
else if (va->hasFlag(kVarAttrOutConv)) { else if (va->hasFlag(kVarAttrOutConv)) {
@@ -5294,8 +5301,8 @@ _Done:
// ============================================================================ // ============================================================================
template<int LoggingEnabled> template<int LoggingEnabled>
static ASMJIT_INLINE Error X86X64Context_serialize(X86X64Context* self, X86X64Assembler* assembler, BaseNode* start, BaseNode* stop) { static ASMJIT_INLINE Error X86X64Context_serialize(X86X64Context* self, X86X64Assembler* assembler, Node* start, Node* stop) {
BaseNode* node_ = start; Node* node_ = start;
StringBuilder& sb = self->_stringBuilder; StringBuilder& sb = self->_stringBuilder;
Logger* logger; Logger* logger;
@@ -5365,7 +5372,7 @@ static ASMJIT_INLINE Error X86X64Context_serialize(X86X64Context* self, X86X64As
switch (node_->getType()) { switch (node_->getType()) {
case kNodeTypeAlign: { case kNodeTypeAlign: {
AlignNode* node = static_cast<AlignNode*>(node_); AlignNode* node = static_cast<AlignNode*>(node_);
assembler->align(node->getSize()); assembler->align(node->getMode(), node->getOffset());
break; break;
} }
@@ -5562,7 +5569,7 @@ static ASMJIT_INLINE Error X86X64Context_serialize(X86X64Context* self, X86X64As
return kErrorOk; return kErrorOk;
} }
Error X86X64Context::serialize(BaseAssembler* assembler, BaseNode* start, BaseNode* stop) { Error X86X64Context::serialize(BaseAssembler* assembler, Node* start, Node* stop) {
if (!assembler->hasLogger()) if (!assembler->hasLogger())
return X86X64Context_serialize<0>(this, static_cast<X86X64Assembler*>(assembler), start, stop); return X86X64Context_serialize<0>(this, static_cast<X86X64Assembler*>(assembler), start, stop);
else else

View File

@@ -14,7 +14,6 @@
#include "../base/intutil.h" #include "../base/intutil.h"
#include "../x86/x86assembler.h" #include "../x86/x86assembler.h"
#include "../x86/x86compiler.h" #include "../x86/x86compiler.h"
#include "../x86/x86defs.h"
// [Api-Begin] // [Api-Begin]
#include "../apibegin.h" #include "../apibegin.h"
@@ -22,14 +21,20 @@
namespace asmjit { namespace asmjit {
namespace x86x64 { namespace x86x64 {
//! @addtogroup asmjit_x86x64_codegen
//! @{
// ============================================================================ // ============================================================================
// [asmjit::Context] // [asmjit::Context]
// ============================================================================ // ============================================================================
//! @internal #if defined(ASMJIT_DEBUG)
# define ASMJIT_X86_CHECK_STATE _checkState();
#else
# define ASMJIT_X86_CHECK_STATE
#endif // ASMJIT_DEBUG
//! \addtogroup asmjit_x86x64_tree
//! \{
//! \internal
//! //!
//! Compiler context is used by `X86X64Compiler`. //! Compiler context is used by `X86X64Compiler`.
//! //!
@@ -110,14 +115,8 @@ struct X86X64Context : public BaseContext {
void _checkState(); void _checkState();
#if defined(ASMJIT_DEBUG)
#define ASMJIT_CONTEXT_CHECK_STATE _checkState();
#else
#define ASMJIT_CONTEXT_CHECK_STATE
#endif // ASMJIT_DEBUG
ASMJIT_INLINE uint32_t getRegsCount(uint32_t c) const { ASMJIT_INLINE uint32_t getRegsCount(uint32_t c) const {
if (c == kRegClassGp || c == kRegClassXy) if (c == kRegClassGp || c == kRegClassXyz)
return _baseRegsCount; return _baseRegsCount;
else else
return 8; return 8;
@@ -154,7 +153,7 @@ struct X86X64Context : public BaseContext {
_x86State._occupied.add(C, regMask); _x86State._occupied.add(C, regMask);
_x86State._modified.add(C, static_cast<uint32_t>(modified) << regIndex); _x86State._modified.add(C, static_cast<uint32_t>(modified) << regIndex);
ASMJIT_CONTEXT_CHECK_STATE ASMJIT_X86_CHECK_STATE
} }
//! Detach. //! Detach.
@@ -178,7 +177,7 @@ struct X86X64Context : public BaseContext {
_x86State._occupied.del(C, regMask); _x86State._occupied.del(C, regMask);
_x86State._modified.del(C, regMask); _x86State._modified.del(C, regMask);
ASMJIT_CONTEXT_CHECK_STATE ASMJIT_X86_CHECK_STATE
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -206,7 +205,7 @@ struct X86X64Context : public BaseContext {
_x86State._occupied.xor_(C, bothRegMask); _x86State._occupied.xor_(C, bothRegMask);
_x86State._modified.xor_(C, bothRegMask & -static_cast<int32_t>(vd->isModified())); _x86State._modified.xor_(C, bothRegMask & -static_cast<int32_t>(vd->isModified()));
ASMJIT_CONTEXT_CHECK_STATE ASMJIT_X86_CHECK_STATE
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -227,7 +226,7 @@ struct X86X64Context : public BaseContext {
emitLoad(vd, regIndex, "Load"); emitLoad(vd, regIndex, "Load");
attach<C>(vd, regIndex, false); attach<C>(vd, regIndex, false);
ASMJIT_CONTEXT_CHECK_STATE ASMJIT_X86_CHECK_STATE
} }
//! Save. //! Save.
@@ -247,7 +246,7 @@ struct X86X64Context : public BaseContext {
vd->setModified(false); vd->setModified(false);
_x86State._modified.del(C, regMask); _x86State._modified.del(C, regMask);
ASMJIT_CONTEXT_CHECK_STATE ASMJIT_X86_CHECK_STATE
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -270,7 +269,7 @@ struct X86X64Context : public BaseContext {
rebase<C>(vd, regIndex, oldIndex); rebase<C>(vd, regIndex, oldIndex);
} }
ASMJIT_CONTEXT_CHECK_STATE ASMJIT_X86_CHECK_STATE
} }
//! Swap two registers //! Swap two registers
@@ -301,7 +300,7 @@ struct X86X64Context : public BaseContext {
uint32_t m = aVd->isModified() ^ bVd->isModified(); uint32_t m = aVd->isModified() ^ bVd->isModified();
_x86State._modified.xor_(kRegClassGp, (m << aIndex) | (m << bIndex)); _x86State._modified.xor_(kRegClassGp, (m << aIndex) | (m << bIndex));
ASMJIT_CONTEXT_CHECK_STATE ASMJIT_X86_CHECK_STATE
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -332,7 +331,7 @@ struct X86X64Context : public BaseContext {
regMask ^= IntUtil::mask(oldRegIndex); regMask ^= IntUtil::mask(oldRegIndex);
} }
else { else {
ASMJIT_CONTEXT_CHECK_STATE ASMJIT_X86_CHECK_STATE
return; return;
} }
@@ -343,7 +342,7 @@ struct X86X64Context : public BaseContext {
_x86State._occupied.xor_(C, regMask); _x86State._occupied.xor_(C, regMask);
_x86State._modified.xor_(C, regMask & -static_cast<int32_t>(vd->isModified())); _x86State._modified.xor_(C, regMask & -static_cast<int32_t>(vd->isModified()));
ASMJIT_CONTEXT_CHECK_STATE ASMJIT_X86_CHECK_STATE
} }
//! Spill. //! Spill.
@@ -354,7 +353,7 @@ struct X86X64Context : public BaseContext {
ASMJIT_ASSERT(vd->getClass() == C); ASMJIT_ASSERT(vd->getClass() == C);
if (vd->getState() != kVarStateReg) { if (vd->getState() != kVarStateReg) {
ASMJIT_CONTEXT_CHECK_STATE ASMJIT_X86_CHECK_STATE
return; return;
} }
@@ -367,7 +366,7 @@ struct X86X64Context : public BaseContext {
emitSave(vd, regIndex, "Spill"); emitSave(vd, regIndex, "Spill");
detach<C>(vd, regIndex, kVarStateMem); detach<C>(vd, regIndex, kVarStateMem);
ASMJIT_CONTEXT_CHECK_STATE ASMJIT_X86_CHECK_STATE
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -384,7 +383,7 @@ struct X86X64Context : public BaseContext {
vd->setModified(true); vd->setModified(true);
_x86State._modified.add(C, regMask); _x86State._modified.add(C, regMask);
ASMJIT_CONTEXT_CHECK_STATE ASMJIT_X86_CHECK_STATE
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -406,7 +405,7 @@ struct X86X64Context : public BaseContext {
else else
vd->setState(vState); vd->setState(vState);
ASMJIT_CONTEXT_CHECK_STATE ASMJIT_X86_CHECK_STATE
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -459,7 +458,7 @@ struct X86X64Context : public BaseContext {
// [Serialize] // [Serialize]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
virtual Error serialize(BaseAssembler* assembler, BaseNode* start, BaseNode* stop); virtual Error serialize(BaseAssembler* assembler, Node* start, Node* stop);
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [Members] // [Members]
@@ -507,7 +506,7 @@ struct X86X64Context : public BaseContext {
StringBuilderT<256> _stringBuilder; StringBuilderT<256> _stringBuilder;
}; };
//! @} //! \}
} // x86x64 namespace } // x86x64 namespace
} // asmjit namespace } // asmjit namespace

View File

@@ -37,15 +37,11 @@ struct CpuVendor {
}; };
static const CpuVendor cpuVendorTable[] = { static const CpuVendor cpuVendorTable[] = {
{ kCpuVendorAmd , { 'A', 'M', 'D', 'i', 's', 'b', 'e', 't', 't', 'e', 'r', '!' } },
{ kCpuVendorAmd , { 'A', 'u', 't', 'h', 'e', 'n', 't', 'i', 'c', 'A', 'M', 'D' } },
{ kCpuVendorVia , { 'C', 'e', 'n', 't', 'a', 'u', 'r', 'H', 'a', 'u', 'l', 's' } },
{ kCpuVendorNSM , { 'C', 'y', 'r', 'i', 'x', 'I', 'n', 's', 't', 'e', 'a', 'd' } },
{ kCpuVendorIntel , { 'G', 'e', 'n', 'u', 'i', 'n', 'e', 'I', 'n', 't', 'e', 'l' } }, { kCpuVendorIntel , { 'G', 'e', 'n', 'u', 'i', 'n', 'e', 'I', 'n', 't', 'e', 'l' } },
{ kCpuVendorTransmeta, { 'G', 'e', 'n', 'u', 'i', 'n', 'e', 'T', 'M', 'x', '8', '6' } }, { kCpuVendorAmd , { 'A', 'u', 't', 'h', 'e', 'n', 't', 'i', 'c', 'A', 'M', 'D' } },
{ kCpuVendorNSM , { 'G', 'e', 'o', 'd', 'e', ' ', 'b', 'y', ' ', 'N', 'S', 'C' } }, { kCpuVendorAmd , { 'A', 'M', 'D', 'i', 's', 'b', 'e', 't', 't', 'e', 'r', '!' } },
{ kCpuVendorTransmeta, { 'T', 'r', 'a', 'n', 's', 'm', 'e', 't', 'a', 'C', 'P', 'U' } }, { kCpuVendorVia , { 'V', 'I', 'A', 0 , 'V', 'I', 'A', 0 , 'V', 'I', 'A', 0 } },
{ kCpuVendorVia , { 'V', 'I', 'A', 0 , 'V', 'I', 'A', 0 , 'V', 'I', 'A', 0 } } { kCpuVendorVia , { 'C', 'e', 'n', 't', 'a', 'u', 'r', 'H', 'a', 'u', 'l', 's' } }
}; };
static ASMJIT_INLINE bool cpuVendorEq(const CpuVendor& info, const char* vendorString) { static ASMJIT_INLINE bool cpuVendorEq(const CpuVendor& info, const char* vendorString) {
@@ -162,7 +158,7 @@ void CpuUtil::detect(CpuInfo* cpuInfo) {
::memcpy(cpuInfo->_vendorString + 4, &regs.edx, 4); ::memcpy(cpuInfo->_vendorString + 4, &regs.edx, 4);
::memcpy(cpuInfo->_vendorString + 8, &regs.ecx, 4); ::memcpy(cpuInfo->_vendorString + 8, &regs.ecx, 4);
for (i = 0; i < 3; i++) { for (i = 0; i < ASMJIT_ARRAY_SIZE(cpuVendorTable); i++) {
if (cpuVendorEq(cpuVendorTable[i], cpuInfo->_vendorString)) { if (cpuVendorEq(cpuVendorTable[i], cpuInfo->_vendorString)) {
cpuInfo->_vendorId = cpuVendorTable[i].id; cpuInfo->_vendorId = cpuVendorTable[i].id;
break; break;

View File

@@ -10,7 +10,6 @@
// [Dependencies - AsmJit] // [Dependencies - AsmJit]
#include "../base/cpuinfo.h" #include "../base/cpuinfo.h"
#include "../base/defs.h"
// [Api-Begin] // [Api-Begin]
#include "../apibegin.h" #include "../apibegin.h"
@@ -18,15 +17,15 @@
namespace asmjit { namespace asmjit {
namespace x86x64 { namespace x86x64 {
//! @addtogroup asmjit_x86x64_cpu_info
//! @{
// ============================================================================ // ============================================================================
// [Forward Declarations] // [Forward Declarations]
// ============================================================================ // ============================================================================
struct CpuInfo; struct CpuInfo;
//! \addtogroup asmjit_x86x64_general
//! \{
// ============================================================================ // ============================================================================
// [asmjit::x86x64::kCpuFeature] // [asmjit::x86x64::kCpuFeature]
// ============================================================================ // ============================================================================
@@ -221,7 +220,7 @@ struct CpuInfo : public BaseCpuInfo {
uint32_t _maxLogicalProcessors; uint32_t _maxLogicalProcessors;
}; };
//! @} //! \}
} // x86x64 namespace } // x86x64 namespace
} // asmjit namespace } // asmjit namespace

View File

@@ -15,8 +15,8 @@
#include "../base/globals.h" #include "../base/globals.h"
#include "../base/intutil.h" #include "../base/intutil.h"
#include "../base/string.h" #include "../base/string.h"
#include "../x86/x86defs.h"
#include "../x86/x86func.h" #include "../x86/x86func.h"
#include "../x86/x86operand.h"
// [Api-Begin] // [Api-Begin]
#include "../apibegin.h" #include "../apibegin.h"
@@ -46,6 +46,13 @@ static ASMJIT_INLINE uint32_t x86ArgTypeToXmmType(uint32_t aType) {
return aType; return aType;
} }
//! Get an architecture from calling convention.
//!
//! Returns `kArchX86` or `kArchX64` depending on `conv`.
static ASMJIT_INLINE uint32_t x86GetArchFromCConv(uint32_t conv) {
return IntUtil::inInterval<uint32_t>(conv, kFuncConvX64W, kFuncConvX64U) ? kArchX64 : kArchX86;
}
// ============================================================================ // ============================================================================
// [asmjit::X86X64FuncDecl - SetPrototype] // [asmjit::X86X64FuncDecl - SetPrototype]
// ============================================================================ // ============================================================================
@@ -147,44 +154,44 @@ static uint32_t X86X64FuncDecl_initConv(X86X64FuncDecl* self, uint32_t arch, uin
case kFuncConvX64W: case kFuncConvX64W:
self->_spillZoneSize = 32; self->_spillZoneSize = 32;
self->_passed.set(kRegClassGp, IntUtil::mask(R(Cx), R(Dx), R(R8), R(R9))); self->_passed.set(kRegClassGp, IntUtil::mask(R(Cx), R(Dx), 8, 9));
self->_passedOrderGp[0] = R(Cx); self->_passedOrderGp[0] = R(Cx);
self->_passedOrderGp[1] = R(Dx); self->_passedOrderGp[1] = R(Dx);
self->_passedOrderGp[2] = R(R8); self->_passedOrderGp[2] = 8;
self->_passedOrderGp[3] = R(R9); self->_passedOrderGp[3] = 9;
self->_passed.set(kRegClassXy, IntUtil::mask(R(Xmm0), R(Xmm1), R(Xmm2), R(Xmm3))); self->_passed.set(kRegClassXyz, IntUtil::mask(0, 1, 2, 3));
self->_passedOrderXmm[0] = R(Xmm0); self->_passedOrderXmm[0] = 0;
self->_passedOrderXmm[1] = R(Xmm1); self->_passedOrderXmm[1] = 1;
self->_passedOrderXmm[2] = R(Xmm2); self->_passedOrderXmm[2] = 2;
self->_passedOrderXmm[3] = R(Xmm3); self->_passedOrderXmm[3] = 3;
self->_preserved.set(kRegClassGp, IntUtil::mask(R(Bx), R(Sp), R(Bp), R(Si), R(Di), R(R12), R(R13), R(R14), R(R15))); self->_preserved.set(kRegClassGp , IntUtil::mask(R(Bx), R(Sp), R(Bp), R(Si), R(Di), 12, 13, 14, 15));
self->_preserved.set(kRegClassXy, IntUtil::mask(R(Xmm6), R(Xmm7), R(Xmm8), R(Xmm9), R(Xmm10), R(Xmm11), R(Xmm12), R(Xmm13), R(Xmm14), R(Xmm15))); self->_preserved.set(kRegClassXyz, IntUtil::mask(6, 7, 8, 9, 10, 11, 12, 13, 14, 15));
break; break;
case kFuncConvX64U: case kFuncConvX64U:
self->_redZoneSize = 128; self->_redZoneSize = 128;
self->_passed.set(kRegClassGp, IntUtil::mask(R(Di), R(Si), R(Dx), R(Cx), R(R8), R(R9))); self->_passed.set(kRegClassGp, IntUtil::mask(R(Di), R(Si), R(Dx), R(Cx), 8, 9));
self->_passedOrderGp[0] = R(Di); self->_passedOrderGp[0] = R(Di);
self->_passedOrderGp[1] = R(Si); self->_passedOrderGp[1] = R(Si);
self->_passedOrderGp[2] = R(Dx); self->_passedOrderGp[2] = R(Dx);
self->_passedOrderGp[3] = R(Cx); self->_passedOrderGp[3] = R(Cx);
self->_passedOrderGp[4] = R(R8); self->_passedOrderGp[4] = 8;
self->_passedOrderGp[5] = R(R9); self->_passedOrderGp[5] = 9;
self->_passed.set(kRegClassXy, IntUtil::mask(R(Xmm0), R(Xmm1), R(Xmm2), R(Xmm3), R(Xmm4), R(Xmm5), R(Xmm6), R(Xmm7))); self->_passed.set(kRegClassXyz, IntUtil::mask(0, 1, 2, 3, 4, 5, 6, 7));
self->_passedOrderXmm[0] = R(Xmm0); self->_passedOrderXmm[0] = 0;
self->_passedOrderXmm[1] = R(Xmm1); self->_passedOrderXmm[1] = 1;
self->_passedOrderXmm[2] = R(Xmm2); self->_passedOrderXmm[2] = 2;
self->_passedOrderXmm[3] = R(Xmm3); self->_passedOrderXmm[3] = 3;
self->_passedOrderXmm[4] = R(Xmm4); self->_passedOrderXmm[4] = 4;
self->_passedOrderXmm[5] = R(Xmm5); self->_passedOrderXmm[5] = 5;
self->_passedOrderXmm[6] = R(Xmm6); self->_passedOrderXmm[6] = 6;
self->_passedOrderXmm[7] = R(Xmm7); self->_passedOrderXmm[7] = 7;
self->_preserved.set(kRegClassGp, IntUtil::mask(R(Bx), R(Sp), R(Bp), R(R12), R(R13), R(R14), R(R15))); self->_preserved.set(kRegClassGp, IntUtil::mask(R(Bx), R(Sp), R(Bp), 12, 13, 14, 15));
break; break;
default: default:
@@ -271,18 +278,18 @@ static Error X86X64FuncDecl_initFunc(X86X64FuncDecl* self, uint32_t arch,
case kVarTypeMm: case kVarTypeMm:
self->_retCount = 1; self->_retCount = 1;
self->_retList[0]._varType = static_cast<uint8_t>(ret); self->_retList[0]._varType = static_cast<uint8_t>(ret);
self->_retList[0]._regIndex = kRegIndexMm0; self->_retList[0]._regIndex = 0;
break; break;
case kVarTypeFp32: case kVarTypeFp32:
self->_retCount = 1; self->_retCount = 1;
if (arch == kArchX86) { if (arch == kArchX86) {
self->_retList[0]._varType = kVarTypeFp32; self->_retList[0]._varType = kVarTypeFp32;
self->_retList[0]._regIndex = kRegIndexFp0; self->_retList[0]._regIndex = 0;
} }
else { else {
self->_retList[0]._varType = kVarTypeXmmSs; self->_retList[0]._varType = kVarTypeXmmSs;
self->_retList[0]._regIndex = kRegIndexXmm0; self->_retList[0]._regIndex = 0;
} }
break; break;
@@ -290,11 +297,11 @@ static Error X86X64FuncDecl_initFunc(X86X64FuncDecl* self, uint32_t arch,
self->_retCount = 1; self->_retCount = 1;
if (arch == kArchX86) { if (arch == kArchX86) {
self->_retList[0]._varType = kVarTypeFp64; self->_retList[0]._varType = kVarTypeFp64;
self->_retList[0]._regIndex = kRegIndexFp0; self->_retList[0]._regIndex = 0;
} }
else { else {
self->_retList[0]._varType = kVarTypeXmmSd; self->_retList[0]._varType = kVarTypeXmmSd;
self->_retList[0]._regIndex = kRegIndexXmm0; self->_retList[0]._regIndex = 0;
break; break;
} }
break; break;
@@ -306,7 +313,7 @@ static Error X86X64FuncDecl_initFunc(X86X64FuncDecl* self, uint32_t arch,
case kVarTypeXmmPd: case kVarTypeXmmPd:
self->_retCount = 1; self->_retCount = 1;
self->_retList[0]._varType = static_cast<uint8_t>(ret); self->_retList[0]._varType = static_cast<uint8_t>(ret);
self->_retList[0]._regIndex = kRegIndexXmm0; self->_retList[0]._regIndex = 0;
break; break;
} }
} }
@@ -381,7 +388,7 @@ static Error X86X64FuncDecl_initFunc(X86X64FuncDecl* self, uint32_t arch,
if (x86ArgIsFp(varType) && i < ASMJIT_ARRAY_SIZE(self->_passedOrderXmm)) { if (x86ArgIsFp(varType) && i < ASMJIT_ARRAY_SIZE(self->_passedOrderXmm)) {
arg._varType = static_cast<uint8_t>(x86ArgTypeToXmmType(varType)); arg._varType = static_cast<uint8_t>(x86ArgTypeToXmmType(varType));
arg._regIndex = self->_passedOrderXmm[i]; arg._regIndex = self->_passedOrderXmm[i];
self->_used.add(kRegClassXy, IntUtil::mask(arg.getRegIndex())); self->_used.add(kRegClassXyz, IntUtil::mask(arg.getRegIndex()));
} }
} }
@@ -430,7 +437,7 @@ static Error X86X64FuncDecl_initFunc(X86X64FuncDecl* self, uint32_t arch,
if (x86ArgIsFp(varType)) { if (x86ArgIsFp(varType)) {
arg._varType = static_cast<uint8_t>(x86ArgTypeToXmmType(varType)); arg._varType = static_cast<uint8_t>(x86ArgTypeToXmmType(varType));
arg._regIndex = self->_passedOrderXmm[xmmPos++]; arg._regIndex = self->_passedOrderXmm[xmmPos++];
self->_used.add(kRegClassXy, IntUtil::mask(arg.getRegIndex())); self->_used.add(kRegClassXyz, IntUtil::mask(arg.getRegIndex()));
} }
} }

View File

@@ -9,9 +9,8 @@
#define _ASMJIT_X86_X86FUNC_H #define _ASMJIT_X86_X86FUNC_H
// [Dependencies - AsmJit] // [Dependencies - AsmJit]
#include "../base/defs.h"
#include "../base/func.h" #include "../base/func.h"
#include "../x86/x86defs.h" #include "../x86/x86util.h"
// [Api-Begin] // [Api-Begin]
#include "../apibegin.h" #include "../apibegin.h"
@@ -19,8 +18,8 @@
namespace asmjit { namespace asmjit {
namespace x86x64 { namespace x86x64 {
//! @addtogroup asmjit_x86x64_codegen //! \addtogroup asmjit_x86x64_tree
//! @{ //! \{
// ============================================================================ // ============================================================================
// [asmjit::x86x64::kFuncConv] // [asmjit::x86x64::kFuncConv]
@@ -83,8 +82,8 @@ ASMJIT_ENUM(kFuncConv) {
//! - Caller. //! - Caller.
//! //!
//! Return value: //! Return value:
//! - Integer types - RAX register. //! - Integer types - Rax register.
//! - Floating points - XMM0 register. //! - Floating points - Xmm0 register.
//! //!
//! Stack is always aligned by 16 bytes. //! Stack is always aligned by 16 bytes.
//! //!
@@ -109,8 +108,8 @@ ASMJIT_ENUM(kFuncConv) {
//! - Caller. //! - Caller.
//! //!
//! Return value: //! Return value:
//! - Integer types - RAX register. //! - Integer types - Rax register.
//! - Floating points - XMM0 register. //! - Floating points - Xmm0 register.
//! //!
//! Stack is always aligned by 16 bytes. //! Stack is always aligned by 16 bytes.
kFuncConvX64U = 2, kFuncConvX64U = 2,
@@ -165,7 +164,7 @@ ASMJIT_ENUM(kFuncConv) {
//! C++ class methods that have variable count of arguments uses different //! C++ class methods that have variable count of arguments uses different
//! calling convention called cdecl. //! calling convention called cdecl.
//! //!
//! @note This calling convention is always used by MSVC for class methods, //! \note This calling convention is always used by MSVC for class methods,
//! it's implicit and there is no way how to override it. //! it's implicit and there is no way how to override it.
kFuncConvMsThisCall = 5, kFuncConvMsThisCall = 5,
@@ -184,7 +183,7 @@ ASMJIT_ENUM(kFuncConv) {
//! - Integer types - EAX:EDX registers. //! - Integer types - EAX:EDX registers.
//! - Floating points - fp0 register. //! - Floating points - fp0 register.
//! //!
//! @note This calling convention differs to GCC one in stack cleaning //! \note This calling convention differs to GCC one in stack cleaning
//! mechanism. //! mechanism.
kFuncConvMsFastCall = 6, kFuncConvMsFastCall = 6,
@@ -203,7 +202,7 @@ ASMJIT_ENUM(kFuncConv) {
//! - Integer types - EAX:EDX registers. //! - Integer types - EAX:EDX registers.
//! - Floating points - fp0 register. //! - Floating points - fp0 register.
//! //!
//! @note Arguments on the stack are in left-to-right order that differs //! \note Arguments on the stack are in left-to-right order that differs
//! to other fastcall conventions used in different compilers. //! to other fastcall conventions used in different compilers.
kFuncConvBorlandFastCall = 7, kFuncConvBorlandFastCall = 7,
@@ -222,7 +221,7 @@ ASMJIT_ENUM(kFuncConv) {
//! - Integer types - EAX:EDX registers. //! - Integer types - EAX:EDX registers.
//! - Floating points - fp0 register. //! - Floating points - fp0 register.
//! //!
//! @note This calling convention should be compatible with `kFuncConvMsFastCall`. //! \note This calling convention should be compatible with `kFuncConvMsFastCall`.
kFuncConvGccFastCall = 8, kFuncConvGccFastCall = 8,
//! GCC specific regparm(1) convention. //! GCC specific regparm(1) convention.
@@ -273,7 +272,7 @@ ASMJIT_ENUM(kFuncConv) {
//! - Floating points - fp0 register. //! - Floating points - fp0 register.
kFuncConvGccRegParm3 = 11, kFuncConvGccRegParm3 = 11,
//! @internal //! \internal
//! //!
//! Count of function calling conventions. //! Count of function calling conventions.
_kFuncConvCount = 12, _kFuncConvCount = 12,
@@ -282,55 +281,51 @@ ASMJIT_ENUM(kFuncConv) {
// [Host] // [Host]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//! @def kFuncConvHost #if defined(ASMJIT_DOCGEN)
//! Default calling convention for current platform / operating system. //! Default calling convention for current platform / operating system.
kFuncConvHost = DependsOnHost,
//! @def kFuncConvHostCDecl
//! Default C calling convention based on current compiler's settings. //! Default C calling convention based on current compiler's settings.
kFuncConvHostCDecl = DependsOnHost,
//! @def kFuncConvHostStdCall
//! Compatibility for `__stdcall` calling convention. //! Compatibility for `__stdcall` calling convention.
//! //!
//! @note This enumeration is always set to a value which is compatible with //! \note This enumeration is always set to a value which is compatible with
//! current compilers __stdcall calling convention. In 64-bit mode the value //! current compilers __stdcall calling convention. In 64-bit mode the value
//! is compatible with `kFuncConvX64W` or `kFuncConvX64U`. //! is compatible with `kFuncConvX64W` or `kFuncConvX64U`.
kFuncConvHostStdCall = DependsOnHost,
//! @def kFuncConvHostFastCall
//! Compatibility for `__fastcall` calling convention. //! Compatibility for `__fastcall` calling convention.
//! //!
//! @note This enumeration is always set to a value which is compatible with //! \note This enumeration is always set to a value which is compatible with
//! current compilers `__fastcall` calling convention. In 64-bit mode the value //! current compilers `__fastcall` calling convention. In 64-bit mode the value
//! is compatible with `kFuncConvX64W` or `kFuncConvX64U`. //! is compatible with `kFuncConvX64W` or `kFuncConvX64U`.
kFuncConvHostFastCall = DependsOnHost
#if defined(ASMJIT_HOST_X86) #elif defined(ASMJIT_HOST_X86)
// X86.
kFuncConvHost = kFuncConvCDecl, kFuncConvHost = kFuncConvCDecl,
kFuncConvHostCDecl = kFuncConvCDecl, kFuncConvHostCDecl = kFuncConvCDecl,
kFuncConvHostStdCall = kFuncConvStdCall, kFuncConvHostStdCall = kFuncConvStdCall,
#if defined(_MSC_VER)
# if defined(_MSC_VER)
kFuncConvHostFastCall = kFuncConvMsFastCall kFuncConvHostFastCall = kFuncConvMsFastCall
# elif defined(__GNUC__) #elif defined(__GNUC__)
kFuncConvHostFastCall = kFuncConvGccFastCall kFuncConvHostFastCall = kFuncConvGccFastCall
# elif defined(__BORLANDC__) #elif defined(__BORLANDC__)
kFuncConvHostFastCall = kFuncConvBorlandFastCall kFuncConvHostFastCall = kFuncConvBorlandFastCall
# else
# error "asmjit/x86/x86func.h - asmjit::kFuncConvHostFastCall not supported."
# endif
#else #else
#error "kFuncConvHostFastCall not determined."
# if defined(ASMJIT_OS_WINDOWS) #endif
#else
// X64.
#if defined(ASMJIT_OS_WINDOWS)
kFuncConvHost = kFuncConvX64W, kFuncConvHost = kFuncConvX64W,
# else #else
kFuncConvHost = kFuncConvX64U, kFuncConvHost = kFuncConvX64U,
# endif #endif
kFuncConvHostCDecl = kFuncConvHost, kFuncConvHostCDecl = kFuncConvHost,
kFuncConvHostStdCall = kFuncConvHost, kFuncConvHostStdCall = kFuncConvHost,
kFuncConvHostFastCall = kFuncConvHost kFuncConvHostFastCall = kFuncConvHost
#endif
#endif // ASMJIT_HOST
}; };
// ============================================================================ // ============================================================================
@@ -385,17 +380,6 @@ ASMJIT_ENUM(kFuncFlags) {
kFuncFlagLFence = 0x04000000 kFuncFlagLFence = 0x04000000
}; };
// ============================================================================
// [asmjit::x86x64::x86GetArchFromCConv]
// ============================================================================
//! Get architecture by a calling convention.
//!
//! Returns `kArchX86` or `kArchX64` depending on `conv`.
static ASMJIT_INLINE uint32_t x86GetArchFromCConv(uint32_t conv) {
return IntUtil::inInterval<uint32_t>(conv, kFuncConvX64W, kFuncConvX64U) ? kArchX64 : kArchX86;
}
// ============================================================================ // ============================================================================
// [asmjit::x86x64::X86X64FuncDecl] // [asmjit::x86x64::X86X64FuncDecl]
// ============================================================================ // ============================================================================
@@ -418,7 +402,7 @@ struct X86X64FuncDecl : public FuncDecl {
//! Get used registers (mask). //! Get used registers (mask).
//! //!
//! @note The result depends on the function calling convention AND the //! \note The result depends on the function calling convention AND the
//! function prototype. Returned mask contains only registers actually used //! function prototype. Returned mask contains only registers actually used
//! to pass function arguments. //! to pass function arguments.
ASMJIT_INLINE uint32_t getUsed(uint32_t c) const { ASMJIT_INLINE uint32_t getUsed(uint32_t c) const {
@@ -427,7 +411,7 @@ struct X86X64FuncDecl : public FuncDecl {
//! Get passed registers (mask). //! Get passed registers (mask).
//! //!
//! @note The result depends on the function calling convention used; the //! \note The result depends on the function calling convention used; the
//! prototype of the function doesn't affect the mask returned. //! prototype of the function doesn't affect the mask returned.
ASMJIT_INLINE uint32_t getPassed(uint32_t c) const { ASMJIT_INLINE uint32_t getPassed(uint32_t c) const {
return _passed.get(c); return _passed.get(c);
@@ -435,7 +419,7 @@ struct X86X64FuncDecl : public FuncDecl {
//! Get preserved registers (mask). //! Get preserved registers (mask).
//! //!
//! @note The result depends on the function calling convention used; the //! \note The result depends on the function calling convention used; the
//! prototype of the function doesn't affect the mask returned. //! prototype of the function doesn't affect the mask returned.
ASMJIT_INLINE uint32_t getPreserved(uint32_t c) const { ASMJIT_INLINE uint32_t getPreserved(uint32_t c) const {
return _preserved.get(c); return _preserved.get(c);
@@ -443,7 +427,7 @@ struct X86X64FuncDecl : public FuncDecl {
//! Get ther order of passed registers (Gp). //! Get ther order of passed registers (Gp).
//! //!
//! @note The result depends on the function calling convention used; the //! \note The result depends on the function calling convention used; the
//! prototype of the function doesn't affect the mask returned. //! prototype of the function doesn't affect the mask returned.
ASMJIT_INLINE const uint8_t* getPassedOrderGp() const { ASMJIT_INLINE const uint8_t* getPassedOrderGp() const {
return _passedOrderGp; return _passedOrderGp;
@@ -451,7 +435,7 @@ struct X86X64FuncDecl : public FuncDecl {
//! Get ther order of passed registers (Xmm). //! Get ther order of passed registers (Xmm).
//! //!
//! @note The result depends on the function calling convention used; the //! \note The result depends on the function calling convention used; the
//! prototype of the function doesn't affect the mask returned. //! prototype of the function doesn't affect the mask returned.
ASMJIT_INLINE const uint8_t* getPassedOrderXmm() const { ASMJIT_INLINE const uint8_t* getPassedOrderXmm() const {
return _passedOrderXmm; return _passedOrderXmm;
@@ -465,7 +449,7 @@ struct X86X64FuncDecl : public FuncDecl {
//! //!
//! This will set function calling convention and setup arguments variables. //! This will set function calling convention and setup arguments variables.
//! //!
//! @note This function will allocate variables, it can be called only once. //! \note This function will allocate variables, it can be called only once.
ASMJIT_API Error setPrototype(uint32_t conv, const FuncPrototype& p); ASMJIT_API Error setPrototype(uint32_t conv, const FuncPrototype& p);
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -492,7 +476,7 @@ struct X86X64FuncDecl : public FuncDecl {
uint8_t _passedOrderXmm[8]; uint8_t _passedOrderXmm[8];
}; };
//! @} //! \}
} // x86x64 namespace } // x86x64 namespace
} // asmjit namespace } // asmjit namespace

File diff suppressed because it is too large Load Diff

1837
src/asmjit/x86/x86inst.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,338 @@
// [AsmJit]
// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
// Zlib - See LICENSE.md file in the package.
// [Export]
#define ASMJIT_EXPORTS
// [Guard]
#include "../build.h"
#if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64)
// [Dependencies - AsmJit]
#include "../x86/x86operand.h"
// [Api-Begin]
#include "../apibegin.h"
namespace asmjit {
namespace x86x64 {
// ============================================================================
// [asmjit::x86x64::Variables]
// ============================================================================
#define C(_Class_) kRegClass##_Class_
#define D(_Desc_) kVarDesc##_Desc_
const VarInfo _varInfo[] = {
/* 00: kVarTypeInt8 */ { kRegTypeGpbLo, 1 , C(Gp) , 0 , "gpb" },
/* 01: kVarTypeUInt8 */ { kRegTypeGpbLo, 1 , C(Gp) , 0 , "gpb" },
/* 02: kVarTypeInt16 */ { kRegTypeGpw , 2 , C(Gp) , 0 , "gpw" },
/* 03: kVarTypeUInt16 */ { kRegTypeGpw , 2 , C(Gp) , 0 , "gpw" },
/* 04: kVarTypeInt32 */ { kRegTypeGpd , 4 , C(Gp) , 0 , "gpd" },
/* 05: kVarTypeUInt32 */ { kRegTypeGpd , 4 , C(Gp) , 0 , "gpd" },
/* 06: kVarTypeInt64 */ { kRegTypeGpq , 8 , C(Gp) , 0 , "gpq" },
/* 07: kVarTypeUInt64 */ { kRegTypeGpq , 8 , C(Gp) , 0 , "gpq" },
/* 08: kVarTypeIntPtr */ { 0 , 0 , C(Gp) , 0 , "" }, // Remapped.
/* 09: kVarTypeUIntPtr */ { 0 , 0 , C(Gp) , 0 , "" }, // Remapped.
/* 10: kVarTypeFp32 */ { kRegTypeFp , 4 , C(Fp) , D(Sp) , "fp" },
/* 11: kVarTypeFp64 */ { kRegTypeFp , 8 , C(Fp) , D(Dp) , "fp" },
/* 12: kVarTypeMm */ { kRegTypeMm , 8 , C(Mm) , 0 , "mm" },
/* 13: kVarTypeXmm */ { kRegTypeXmm , 16, C(Xyz), 0 , "xmm" },
/* 14: kVarTypeXmmSs */ { kRegTypeXmm , 4 , C(Xyz), D(Sp) , "xmm" },
/* 15: kVarTypeXmmPs */ { kRegTypeXmm , 16, C(Xyz), D(Sp) | D(Packed), "xmm" },
/* 16: kVarTypeXmmSd */ { kRegTypeXmm , 8 , C(Xyz), D(Dp) , "xmm" },
/* 17: kVarTypeXmmPd */ { kRegTypeXmm , 16, C(Xyz), D(Dp) | D(Packed), "xmm" },
/* 18: kVarTypeYmm */ { kRegTypeYmm , 32, C(Xyz), 0 , "ymm" },
/* 19: kVarTypeYmmPs */ { kRegTypeYmm , 32, C(Xyz), D(Sp) | D(Packed), "ymm" },
/* 20: kVarTypeYmmPd */ { kRegTypeYmm , 32, C(Xyz), D(Dp) | D(Packed), "ymm" }
};
#undef D
#undef C
// ============================================================================
// [asmjit::x86x64::Registers]
// ============================================================================
const GpReg noGpReg(kInvalidReg, kInvalidReg, 0);
const GpReg al(kRegTypeGpbLo, kRegIndexAx, 1);
const GpReg cl(kRegTypeGpbLo, kRegIndexCx, 1);
const GpReg dl(kRegTypeGpbLo, kRegIndexDx, 1);
const GpReg bl(kRegTypeGpbLo, kRegIndexBx, 1);
const GpReg spl(kRegTypeGpbLo, kRegIndexSp, 1);
const GpReg bpl(kRegTypeGpbLo, kRegIndexBp, 1);
const GpReg sil(kRegTypeGpbLo, kRegIndexSi, 1);
const GpReg dil(kRegTypeGpbLo, kRegIndexDi, 1);
const GpReg r8b(kRegTypeGpbLo, 8, 1);
const GpReg r9b(kRegTypeGpbLo, 9, 1);
const GpReg r10b(kRegTypeGpbLo, 10, 1);
const GpReg r11b(kRegTypeGpbLo, 11, 1);
const GpReg r12b(kRegTypeGpbLo, 12, 1);
const GpReg r13b(kRegTypeGpbLo, 13, 1);
const GpReg r14b(kRegTypeGpbLo, 14, 1);
const GpReg r15b(kRegTypeGpbLo, 15, 1);
const GpReg ah(kRegTypeGpbHi, kRegIndexAx, 1);
const GpReg ch(kRegTypeGpbHi, kRegIndexCx, 1);
const GpReg dh(kRegTypeGpbHi, kRegIndexDx, 1);
const GpReg bh(kRegTypeGpbHi, kRegIndexBx, 1);
const GpReg ax(kRegTypeGpw, kRegIndexAx, 2);
const GpReg cx(kRegTypeGpw, kRegIndexCx, 2);
const GpReg dx(kRegTypeGpw, kRegIndexDx, 2);
const GpReg bx(kRegTypeGpw, kRegIndexBx, 2);
const GpReg sp(kRegTypeGpw, kRegIndexSp, 2);
const GpReg bp(kRegTypeGpw, kRegIndexBp, 2);
const GpReg si(kRegTypeGpw, kRegIndexSi, 2);
const GpReg di(kRegTypeGpw, kRegIndexDi, 2);
const GpReg r8w(kRegTypeGpw, 8, 2);
const GpReg r9w(kRegTypeGpw, 9, 2);
const GpReg r10w(kRegTypeGpw, 10, 2);
const GpReg r11w(kRegTypeGpw, 11, 2);
const GpReg r12w(kRegTypeGpw, 12, 2);
const GpReg r13w(kRegTypeGpw, 13, 2);
const GpReg r14w(kRegTypeGpw, 14, 2);
const GpReg r15w(kRegTypeGpw, 15, 2);
const GpReg eax(kRegTypeGpd, kRegIndexAx, 4);
const GpReg ecx(kRegTypeGpd, kRegIndexCx, 4);
const GpReg edx(kRegTypeGpd, kRegIndexDx, 4);
const GpReg ebx(kRegTypeGpd, kRegIndexBx, 4);
const GpReg esp(kRegTypeGpd, kRegIndexSp, 4);
const GpReg ebp(kRegTypeGpd, kRegIndexBp, 4);
const GpReg esi(kRegTypeGpd, kRegIndexSi, 4);
const GpReg edi(kRegTypeGpd, kRegIndexDi, 4);
const GpReg r8d(kRegTypeGpd, 8, 4);
const GpReg r9d(kRegTypeGpd, 9, 4);
const GpReg r10d(kRegTypeGpd, 10, 4);
const GpReg r11d(kRegTypeGpd, 11, 4);
const GpReg r12d(kRegTypeGpd, 12, 4);
const GpReg r13d(kRegTypeGpd, 13, 4);
const GpReg r14d(kRegTypeGpd, 14, 4);
const GpReg r15d(kRegTypeGpd, 15, 4);
const GpReg rax(kRegTypeGpq, kRegIndexAx, 8);
const GpReg rcx(kRegTypeGpq, kRegIndexCx, 8);
const GpReg rdx(kRegTypeGpq, kRegIndexDx, 8);
const GpReg rbx(kRegTypeGpq, kRegIndexBx, 8);
const GpReg rsp(kRegTypeGpq, kRegIndexSp, 8);
const GpReg rbp(kRegTypeGpq, kRegIndexBp, 8);
const GpReg rsi(kRegTypeGpq, kRegIndexSi, 8);
const GpReg rdi(kRegTypeGpq, kRegIndexDi, 8);
const GpReg r8(kRegTypeGpq, 8, 8);
const GpReg r9(kRegTypeGpq, 9, 8);
const GpReg r10(kRegTypeGpq, 10, 8);
const GpReg r11(kRegTypeGpq, 11, 8);
const GpReg r12(kRegTypeGpq, 12, 8);
const GpReg r13(kRegTypeGpq, 13, 8);
const GpReg r14(kRegTypeGpq, 14, 8);
const GpReg r15(kRegTypeGpq, 15, 8);
const FpReg fp0(kRegTypeFp, 0, 10);
const FpReg fp1(kRegTypeFp, 1, 10);
const FpReg fp2(kRegTypeFp, 2, 10);
const FpReg fp3(kRegTypeFp, 3, 10);
const FpReg fp4(kRegTypeFp, 4, 10);
const FpReg fp5(kRegTypeFp, 5, 10);
const FpReg fp6(kRegTypeFp, 6, 10);
const FpReg fp7(kRegTypeFp, 7, 10);
const MmReg mm0(kRegTypeMm, 0, 8);
const MmReg mm1(kRegTypeMm, 1, 8);
const MmReg mm2(kRegTypeMm, 2, 8);
const MmReg mm3(kRegTypeMm, 3, 8);
const MmReg mm4(kRegTypeMm, 4, 8);
const MmReg mm5(kRegTypeMm, 5, 8);
const MmReg mm6(kRegTypeMm, 6, 8);
const MmReg mm7(kRegTypeMm, 7, 8);
const XmmReg xmm0(kRegTypeXmm, 0, 16);
const XmmReg xmm1(kRegTypeXmm, 1, 16);
const XmmReg xmm2(kRegTypeXmm, 2, 16);
const XmmReg xmm3(kRegTypeXmm, 3, 16);
const XmmReg xmm4(kRegTypeXmm, 4, 16);
const XmmReg xmm5(kRegTypeXmm, 5, 16);
const XmmReg xmm6(kRegTypeXmm, 6, 16);
const XmmReg xmm7(kRegTypeXmm, 7, 16);
const XmmReg xmm8(kRegTypeXmm, 8, 16);
const XmmReg xmm9(kRegTypeXmm, 9, 16);
const XmmReg xmm10(kRegTypeXmm, 10, 16);
const XmmReg xmm11(kRegTypeXmm, 11, 16);
const XmmReg xmm12(kRegTypeXmm, 12, 16);
const XmmReg xmm13(kRegTypeXmm, 13, 16);
const XmmReg xmm14(kRegTypeXmm, 14, 16);
const XmmReg xmm15(kRegTypeXmm, 15, 16);
const YmmReg ymm0(kRegTypeYmm, 0, 32);
const YmmReg ymm1(kRegTypeYmm, 1, 32);
const YmmReg ymm2(kRegTypeYmm, 2, 32);
const YmmReg ymm3(kRegTypeYmm, 3, 32);
const YmmReg ymm4(kRegTypeYmm, 4, 32);
const YmmReg ymm5(kRegTypeYmm, 5, 32);
const YmmReg ymm6(kRegTypeYmm, 6, 32);
const YmmReg ymm7(kRegTypeYmm, 7, 32);
const YmmReg ymm8(kRegTypeYmm, 8, 32);
const YmmReg ymm9(kRegTypeYmm, 9, 32);
const YmmReg ymm10(kRegTypeYmm, 10, 32);
const YmmReg ymm11(kRegTypeYmm, 11, 32);
const YmmReg ymm12(kRegTypeYmm, 12, 32);
const YmmReg ymm13(kRegTypeYmm, 13, 32);
const YmmReg ymm14(kRegTypeYmm, 14, 32);
const YmmReg ymm15(kRegTypeYmm, 15, 32);
const SegReg cs(kRegTypeSeg, kSegCs, 2);
const SegReg ss(kRegTypeSeg, kSegSs, 2);
const SegReg ds(kRegTypeSeg, kSegDs, 2);
const SegReg es(kRegTypeSeg, kSegEs, 2);
const SegReg fs(kRegTypeSeg, kSegFs, 2);
const SegReg gs(kRegTypeSeg, kSegGs, 2);
// ============================================================================
// [asmjit::Mem - abs[]]
// ============================================================================
Mem ptr_abs(Ptr pAbs, int32_t disp, uint32_t size) {
Mem m(NoInit);
m._init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeAbsolute, 0, kInvalidValue);
m._vmem.index = kInvalidValue;
m._vmem.displacement = static_cast<int32_t>((intptr_t)(pAbs + disp));
return m;
}
Mem ptr_abs(Ptr pAbs, const X86Reg& index, uint32_t shift, int32_t disp, uint32_t size) {
Mem m(NoInit);
uint32_t flags = shift << kMemShiftIndex;
if (index.isGp()) flags |= Mem::_getGpdFlags(reinterpret_cast<const BaseVar&>(index));
if (index.isXmm()) flags |= kMemVSibXmm << kMemVSibIndex;
if (index.isYmm()) flags |= kMemVSibYmm << kMemVSibIndex;
m._init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeAbsolute, flags, kInvalidValue);
m._vmem.index = index.getRegIndex();
m._vmem.displacement = static_cast<int32_t>((intptr_t)(pAbs + disp));
return m;
}
Mem ptr_abs(Ptr pAbs, const X86Var& index, uint32_t shift, int32_t disp, uint32_t size) {
Mem m(NoInit);
uint32_t flags = shift << kMemShiftIndex;
if (index.isGp()) flags |= Mem::_getGpdFlags(reinterpret_cast<const BaseVar&>(index));
if (index.isXmm()) flags |= kMemVSibXmm << kMemVSibIndex;
if (index.isYmm()) flags |= kMemVSibYmm << kMemVSibIndex;
m._init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeAbsolute, flags, kInvalidValue);
m._vmem.index = index.getId();
m._vmem.displacement = static_cast<int32_t>((intptr_t)(pAbs + disp));
return m;
}
} // x86x64 namespace
} // asmjit namespace
// ============================================================================
// [asmjit::x86]
// ============================================================================
#if defined(ASMJIT_BUILD_X86)
namespace asmjit {
namespace x86 {
const uint8_t _varMapping[kVarTypeCount] = {
/* 00: kVarTypeInt8 */ kVarTypeInt8,
/* 01: kVarTypeUInt8 */ kVarTypeUInt8,
/* 02: kVarTypeInt16 */ kVarTypeInt16,
/* 03: kVarTypeUInt16 */ kVarTypeUInt16,
/* 04: kVarTypeInt32 */ kVarTypeInt32,
/* 05: kVarTypeUInt32 */ kVarTypeUInt32,
/* 06: kVarTypeInt64 */ kVarTypeInvalid, // Invalid in 32-bit mode.
/* 07: kVarTypeUInt64 */ kVarTypeInvalid, // Invalid in 32-bit mode.
/* 08: kVarTypeIntPtr */ kVarTypeInt32, // Remapped.
/* 09: kVarTypeUIntPtr */ kVarTypeUInt32, // Remapped.
/* 10: kVarTypeFp32 */ kVarTypeFp32,
/* 11: kVarTypeFp64 */ kVarTypeFp64,
/* 12: kVarTypeMm */ kVarTypeMm,
/* 13: kVarTypeXmm */ kVarTypeXmm,
/* 14: kVarTypeXmmSs */ kVarTypeXmmSs,
/* 15: kVarTypeXmmPs */ kVarTypeXmmPs,
/* 16: kVarTypeXmmSd */ kVarTypeXmmSd,
/* 17: kVarTypeXmmPd */ kVarTypeXmmPd,
/* 18: kVarTypeYmm */ kVarTypeYmm,
/* 19: kVarTypeYmmPs */ kVarTypeYmmPs,
/* 20: kVarTypeYmmPd */ kVarTypeYmmPd
};
const GpReg zax(kRegTypeGpd, kRegIndexAx, 4);
const GpReg zcx(kRegTypeGpd, kRegIndexCx, 4);
const GpReg zdx(kRegTypeGpd, kRegIndexDx, 4);
const GpReg zbx(kRegTypeGpd, kRegIndexBx, 4);
const GpReg zsp(kRegTypeGpd, kRegIndexSp, 4);
const GpReg zbp(kRegTypeGpd, kRegIndexBp, 4);
const GpReg zsi(kRegTypeGpd, kRegIndexSi, 4);
const GpReg zdi(kRegTypeGpd, kRegIndexDi, 4);
} // x86 namespace
} // asmjit namespace
#endif // ASMJIT_BUILD_X86
// ============================================================================
// [asmjit::x64]
// ============================================================================
#if defined(ASMJIT_BUILD_X64)
namespace asmjit {
namespace x64 {
const uint8_t _varMapping[kVarTypeCount] = {
/* 00: kVarTypeInt8 */ kVarTypeInt8,
/* 01: kVarTypeUInt8 */ kVarTypeUInt8,
/* 02: kVarTypeInt16 */ kVarTypeInt16,
/* 03: kVarTypeUInt16 */ kVarTypeUInt16,
/* 04: kVarTypeInt32 */ kVarTypeInt32,
/* 05: kVarTypeUInt32 */ kVarTypeUInt32,
/* 06: kVarTypeInt64 */ kVarTypeInt64,
/* 07: kVarTypeUInt64 */ kVarTypeUInt64,
/* 08: kVarTypeIntPtr */ kVarTypeInt64, // Remapped.
/* 09: kVarTypeUIntPtr */ kVarTypeUInt64, // Remapped.
/* 10: kVarTypeFp32 */ kVarTypeFp32,
/* 11: kVarTypeFp64 */ kVarTypeFp64,
/* 12: kVarTypeMm */ kVarTypeMm,
/* 13: kVarTypeXmm */ kVarTypeXmm,
/* 14: kVarTypeXmmSs */ kVarTypeXmmSs,
/* 15: kVarTypeXmmPs */ kVarTypeXmmPs,
/* 16: kVarTypeXmmSd */ kVarTypeXmmSd,
/* 17: kVarTypeXmmPd */ kVarTypeXmmPd,
/* 18: kVarTypeYmm */ kVarTypeYmm,
/* 19: kVarTypeYmmPs */ kVarTypeYmmPs,
/* 20: kVarTypeYmmPd */ kVarTypeYmmPd
};
const GpReg zax(kRegTypeGpq, kRegIndexAx, 8);
const GpReg zcx(kRegTypeGpq, kRegIndexCx, 8);
const GpReg zdx(kRegTypeGpq, kRegIndexDx, 8);
const GpReg zbx(kRegTypeGpq, kRegIndexBx, 8);
const GpReg zsp(kRegTypeGpq, kRegIndexSp, 8);
const GpReg zbp(kRegTypeGpq, kRegIndexBp, 8);
const GpReg zsi(kRegTypeGpq, kRegIndexSi, 8);
const GpReg zdi(kRegTypeGpq, kRegIndexDi, 8);
} // x64 namespace
} // asmjit namespace
#endif // ASMJIT_BUILD_X64
#include "../apiend.h"
// [Guard]
#endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64

1988
src/asmjit/x86/x86operand.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,90 @@
// [AsmJit]
// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
// Zlib - See LICENSE.md file in the package.
// [Export]
#define ASMJIT_EXPORTS
// [Guard]
#include "../build.h"
#if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64)
// [Dependencies - AsmJit]
#include "../x86/x86util.h"
// [Api-Begin]
#include "../apibegin.h"
namespace asmjit {
namespace x86x64 {
// ============================================================================
// [asmjit::x86x64::Cond]
// ============================================================================
#define CC_TO_INST(_Inst_) { \
_Inst_##o, \
_Inst_##no, \
_Inst_##b, \
_Inst_##ae, \
_Inst_##e, \
_Inst_##ne, \
_Inst_##be, \
_Inst_##a, \
_Inst_##s, \
_Inst_##ns, \
_Inst_##pe, \
_Inst_##po, \
_Inst_##l, \
_Inst_##ge, \
_Inst_##le, \
_Inst_##g, \
\
kInstNone, \
kInstNone, \
kInstNone, \
kInstNone \
}
const uint32_t _reverseCond[20] = {
/* kCondO -> */ kCondO,
/* kCondNO -> */ kCondNO,
/* kCondB -> */ kCondA,
/* kCondAE -> */ kCondBE,
/* kCondE -> */ kCondE,
/* kCondNE -> */ kCondNE,
/* kCondBE -> */ kCondAE,
/* kCondA -> */ kCondB,
/* kCondS -> */ kCondS,
/* kCondNS -> */ kCondNS,
/* kCondPE -> */ kCondPE,
/* kCondPO -> */ kCondPO,
/* kCondL -> */ kCondG,
/* kCondGE -> */ kCondLE,
/* kCondLE -> */ kCondGE,
/* kCondG -> */ kCondL,
/* kCondFpuUnordered -> */ kCondFpuUnordered,
/* kCondFpuNotUnordered -> */ kCondFpuNotUnordered,
0x12,
0x13
};
const uint32_t _condToCmovcc[20] = CC_TO_INST(kInstCmov);
const uint32_t _condToJcc [20] = CC_TO_INST(kInstJ );
const uint32_t _condToSetcc [20] = CC_TO_INST(kInstSet );
#undef CC_TO_INST
} // x86x64 namespace
} // asmjit namespace
#include "../apiend.h"
// [Guard]
#endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64

369
src/asmjit/x86/x86util.h Normal file
View File

@@ -0,0 +1,369 @@
// [AsmJit]
// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
// Zlib - See LICENSE.md file in the package.
// [Guard]
#ifndef _ASMJIT_X86_X86UTIL_H
#define _ASMJIT_X86_X86UTIL_H
// [Dependencies - AsmJit]
#include "../base/func.h"
#include "../x86/x86inst.h"
#include "../x86/x86operand.h"
// [Api-Begin]
#include "../apibegin.h"
namespace asmjit {
namespace x86x64 {
//! \addtogroup asmjit_x86x64_util
//! \{
// ============================================================================
// [asmjit::x86x64::Internal]
// ============================================================================
//! \internal
//!
//! X86/X64 condition codes to reversed condition codes map.
ASMJIT_VAR const uint32_t _reverseCond[20];
//! \internal
//!
//! X86X64 condition codes to "cmovcc" group map.
ASMJIT_VAR const uint32_t _condToCmovcc[20];
//! \internal
//!
//! X86X64 condition codes to "jcc" group map.
ASMJIT_VAR const uint32_t _condToJcc[20];
//! \internal
//!
//! X86X64 condition codes to "setcc" group map.
ASMJIT_VAR const uint32_t _condToSetcc[20];
// ============================================================================
// [asmjit::x86x64::RegCount]
// ============================================================================
//! \internal
//!
//! X86/X64 registers count (Gp, Fp, Mm, Xmm).
struct RegCount {
// --------------------------------------------------------------------------
// [Zero]
// --------------------------------------------------------------------------
ASMJIT_INLINE void reset() {
_packed = 0;
}
// --------------------------------------------------------------------------
// [Get]
// --------------------------------------------------------------------------
ASMJIT_INLINE uint32_t get(uint32_t c) const {
ASMJIT_ASSERT(c < kRegClassCount);
return _regs[c];
}
// --------------------------------------------------------------------------
// [Set]
// --------------------------------------------------------------------------
ASMJIT_INLINE void set(uint32_t c, uint32_t n) {
ASMJIT_ASSERT(c < kRegClassCount);
ASMJIT_ASSERT(n < 0x100);
_regs[c] = static_cast<uint8_t>(n);
}
// --------------------------------------------------------------------------
// [Add]
// --------------------------------------------------------------------------
ASMJIT_INLINE void add(uint32_t c, uint32_t n = 1) {
ASMJIT_ASSERT(c < kRegClassCount);
ASMJIT_ASSERT(n < 0x100);
_regs[c] += static_cast<uint8_t>(n);
}
// --------------------------------------------------------------------------
// [Misc]
// --------------------------------------------------------------------------
ASMJIT_INLINE void makeIndex(const RegCount& count) {
uint8_t a = count._regs[0];
uint8_t b = count._regs[1];
uint8_t c = count._regs[2];
_regs[0] = 0;
_regs[1] = a;
_regs[2] = a + b;
_regs[3] = a + b + c;
}
// --------------------------------------------------------------------------
// [Members]
// --------------------------------------------------------------------------
union {
struct {
uint8_t _gp;
uint8_t _fp;
uint8_t _mm;
uint8_t _xy;
};
uint8_t _regs[4];
uint32_t _packed;
};
};
// ============================================================================
// [asmjit::x86x64::RegMask]
// ============================================================================
//! \internal
//!
//! X86/X64 registers mask (Gp, Fp, Mm, Xmm/Ymm/Zmm).
struct RegMask {
// --------------------------------------------------------------------------
// [Reset]
// --------------------------------------------------------------------------
ASMJIT_INLINE void reset() {
_packed.reset();
}
// --------------------------------------------------------------------------
// [IsEmpty / Has]
// --------------------------------------------------------------------------
ASMJIT_INLINE bool isEmpty() const {
return _packed.isZero();
}
ASMJIT_INLINE bool has(uint32_t c, uint32_t mask = 0xFFFFFFFF) const {
switch (c) {
case kRegClassGp : return (static_cast<uint32_t>(_gp ) & mask) != 0;
case kRegClassFp : return (static_cast<uint32_t>(_fp ) & mask) != 0;
case kRegClassMm : return (static_cast<uint32_t>(_mm ) & mask) != 0;
case kRegClassXyz: return (static_cast<uint32_t>(_xyz) & mask) != 0;
}
ASMJIT_ASSERT(!"Reached");
return false;
}
// --------------------------------------------------------------------------
// [Zero]
// --------------------------------------------------------------------------
ASMJIT_INLINE void zero(uint32_t c) {
switch (c) {
case kRegClassGp : _gp = 0; break;
case kRegClassFp : _fp = 0; break;
case kRegClassMm : _mm = 0; break;
case kRegClassXyz: _xyz = 0; break;
}
}
// --------------------------------------------------------------------------
// [Get]
// --------------------------------------------------------------------------
ASMJIT_INLINE uint32_t get(uint32_t c) const {
switch (c) {
case kRegClassGp : return _gp;
case kRegClassFp : return _fp;
case kRegClassMm : return _mm;
case kRegClassXyz: return _xyz;
}
ASMJIT_ASSERT(!"Reached");
return 0;
}
// --------------------------------------------------------------------------
// [Set]
// --------------------------------------------------------------------------
ASMJIT_INLINE void set(uint32_t c, uint32_t mask) {
switch (c) {
case kRegClassGp : _gp = static_cast<uint16_t>(mask); break;
case kRegClassFp : _fp = static_cast<uint8_t >(mask); break;
case kRegClassMm : _mm = static_cast<uint8_t >(mask); break;
case kRegClassXyz: _xyz = static_cast<uint32_t>(mask); break;
}
}
ASMJIT_INLINE void set(const RegMask& other) {
_packed.setUInt64(other._packed);
}
// --------------------------------------------------------------------------
// [Add]
// --------------------------------------------------------------------------
ASMJIT_INLINE void add(uint32_t c, uint32_t mask) {
switch (c) {
case kRegClassGp : _gp |= static_cast<uint16_t>(mask); break;
case kRegClassFp : _fp |= static_cast<uint8_t >(mask); break;
case kRegClassMm : _mm |= static_cast<uint8_t >(mask); break;
case kRegClassXyz: _xyz |= static_cast<uint32_t>(mask); break;
}
}
ASMJIT_INLINE void add(const RegMask& other) {
_packed.or_(other._packed);
}
// --------------------------------------------------------------------------
// [Del]
// --------------------------------------------------------------------------
ASMJIT_INLINE void del(uint32_t c, uint32_t mask) {
switch (c) {
case kRegClassGp : _gp &= ~static_cast<uint16_t>(mask); break;
case kRegClassFp : _fp &= ~static_cast<uint8_t >(mask); break;
case kRegClassMm : _mm &= ~static_cast<uint8_t >(mask); break;
case kRegClassXyz: _xyz &= ~static_cast<uint32_t>(mask); break;
}
}
ASMJIT_INLINE void del(const RegMask& other) {
_packed.del(other._packed);
}
// --------------------------------------------------------------------------
// [And]
// --------------------------------------------------------------------------
ASMJIT_INLINE void and_(uint32_t c, uint32_t mask) {
switch (c) {
case kRegClassGp : _gp &= static_cast<uint16_t>(mask); break;
case kRegClassFp : _fp &= static_cast<uint8_t >(mask); break;
case kRegClassMm : _mm &= static_cast<uint8_t >(mask); break;
case kRegClassXyz: _xyz &= static_cast<uint32_t>(mask); break;
}
}
ASMJIT_INLINE void and_(const RegMask& other) {
_packed.and_(other._packed);
}
// --------------------------------------------------------------------------
// [Xor]
// --------------------------------------------------------------------------
ASMJIT_INLINE void xor_(uint32_t c, uint32_t mask) {
switch (c) {
case kRegClassGp : _gp ^= static_cast<uint16_t>(mask); break;
case kRegClassFp : _fp ^= static_cast<uint8_t >(mask); break;
case kRegClassMm : _mm ^= static_cast<uint8_t >(mask); break;
case kRegClassXyz: _xyz ^= static_cast<uint32_t>(mask); break;
}
}
ASMJIT_INLINE void xor_(const RegMask& other) {
_packed.xor_(other._packed);
}
// --------------------------------------------------------------------------
// [Members]
// --------------------------------------------------------------------------
union {
//! Gp mask (16-bit).
uint16_t _gp;
//! Fp mask (8-bit).
uint8_t _fp;
//! Mm mask (8-bit).
uint8_t _mm;
//! Xmm/Ymm/Zmm mask (32-bit).
uint32_t _xyz;
//! All masks as 64-bit integer.
UInt64 _packed;
};
};
// ============================================================================
// [asmjit::x86x64::X86Util]
// ============================================================================
//! X86/X64 utilities.
struct X86Util {
//! Corresponds to transposing the operands of a comparison.
static ASMJIT_INLINE uint32_t reverseCond(uint32_t cond) {
ASMJIT_ASSERT(cond < ASMJIT_ARRAY_SIZE(_reverseCond));
return _reverseCond[cond];
}
//! Get the equivalent of negated condition code.
static ASMJIT_INLINE uint32_t negateCond(uint32_t cond) {
ASMJIT_ASSERT(cond < ASMJIT_ARRAY_SIZE(_reverseCond));
return static_cast<kCond>(cond ^ static_cast<uint32_t>(cond < kCondNone));
}
//! Translate condition code `cc` to `cmovcc` instruction code.
//! \sa \ref kInstCode, \ref _kInstCmovcc.
static ASMJIT_INLINE uint32_t condToCmovcc(uint32_t cond) {
ASMJIT_ASSERT(static_cast<uint32_t>(cond) < ASMJIT_ARRAY_SIZE(_condToCmovcc));
return _condToCmovcc[cond];
}
//! Translate condition code `cc` to `jcc` instruction code.
//! \sa \ref kInstCode, \ref _kInstJcc.
static ASMJIT_INLINE uint32_t condToJcc(uint32_t cond) {
ASMJIT_ASSERT(static_cast<uint32_t>(cond) < ASMJIT_ARRAY_SIZE(_condToJcc));
return _condToJcc[cond];
}
//! Translate condition code `cc` to `setcc` instruction code.
//! \sa \ref kInstCode, \ref _kInstSetcc.
static ASMJIT_INLINE uint32_t condToSetcc(uint32_t cond) {
ASMJIT_ASSERT(static_cast<uint32_t>(cond) < ASMJIT_ARRAY_SIZE(_condToSetcc));
return _condToSetcc[cond];
}
//! Get whether the `op` operand is Gpb-Lo or Gpb-Hi register.
static ASMJIT_INLINE bool isGpbRegOp(const Operand& op) {
const uint32_t mask = IntUtil::pack32_2x8_1x16(0xFF, 0xFF, ~(kRegTypePatchedGpbHi << 8) & 0xFF00);
return (op._packed[0].u32[0] & mask) == IntUtil::pack32_2x8_1x16(kOperandTypeReg, 1, 0x0000);
}
//! Pack a shuffle constant to be used with multimedia instrutions.
//!
//! \param z First component position, number at interval [0, 3] inclusive.
//! \param x Second component position, number at interval [0, 3] inclusive.
//! \param y Third component position, number at interval [0, 3] inclusive.
//! \param w Fourth component position, number at interval [0, 3] inclusive.
//!
//! Shuffle constants can be used to make immediate value for these intrinsics:
//! - `X86X64Assembler::pshufw()` and `X86X64Compiler::pshufw()`
//! - `X86X64Assembler::pshufd()` and `X86X64Compiler::pshufd()`
//! - `X86X64Assembler::pshufhw()` and `X86X64Compiler::pshufhw()`
//! - `X86X64Assembler::pshuflw()` and `X86X64Compiler::pshuflw()`
//! - `X86X64Assembler::shufps()` and `X86X64Compiler::shufps()`
static ASMJIT_INLINE uint32_t mmShuffle(uint32_t z, uint32_t y, uint32_t x, uint32_t w) {
return (z << 6) | (y << 4) | (x << 2) | w;
}
};
//! \}
} // x86x64 namespace
} // asmjit namespace
// [Api-End]
#include "../apiend.h"
// [Guard]
#endif // _ASMJIT_X86_X86UTIL_H

View File

@@ -1,408 +0,0 @@
# Doxyfile 1.8.7
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "AsmJit"
PROJECT_NUMBER = "1.1"
PROJECT_BRIEF = "Complete Remote and JIT Assembler for x86/x64"
OUTPUT_DIRECTORY = .
CREATE_SUBDIRS = NO
ALLOW_UNICODE_NAMES = NO
OUTPUT_LANGUAGE = English
# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member
# descriptions after the members that are listed in the file and class
# documentation (similar to Javadoc). Set to NO to disable this.
# The default value is: YES.
BRIEF_MEMBER_DESC = YES
# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief
# description of a member or function before the detailed description
#
# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
# brief descriptions will be completely suppressed.
# The default value is: YES.
REPEAT_BRIEF = YES
# This tag implements a quasi-intelligent brief description abbreviator that is
# used to form the text in various listings. Each string in this list, if found
# as the leading text of the brief description, will be stripped from the text
# and the result, after processing the whole list, is used as the annotated
# text. Otherwise, the brief description is used as-is. If left blank, the
# following values are used ($name is automatically replaced with the name of
# the entity):The $name class, The $name widget, The $name file, is, provides,
# specifies, contains, represents, a, an and the.
ABBREVIATE_BRIEF =
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
# doxygen will generate a detailed section even if there is only a brief
# description.
# The default value is: NO.
ALWAYS_DETAILED_SEC = NO
# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
# inherited members of a class in the documentation of that class as if those
# members were ordinary class members. Constructors, destructors and assignment
# operators of the base classes will not be shown.
# The default value is: NO.
INLINE_INHERITED_MEMB = NO
# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path
# before files name in the file list and in the header files. If set to NO the
# shortest path that makes the file name unique will be used
# The default value is: YES.
FULL_PATH_NAMES = YES
# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
# Stripping is only done if one of the specified strings matches the left-hand
# part of the path. The tag can be used to show relative paths in the file list.
# If left blank the directory from which doxygen is run is used as the path to
# strip.
#
# Note that you can specify absolute paths here, but also relative paths, which
# will be relative from the directory where doxygen is started.
# This tag requires that the tag FULL_PATH_NAMES is set to YES.
STRIP_FROM_PATH =
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
# path mentioned in the documentation of a class, which tells the reader which
# header file to include in order to use a class. If left blank only the name of
# the header file containing the class definition is used. Otherwise one should
# specify the list of include paths that are normally passed to the compiler
# using the -I flag.
STRIP_FROM_INC_PATH =
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
# less readable) file names. This can be useful is your file systems doesn't
# support long names like on DOS, Mac, or CD-ROM.
# The default value is: NO.
SHORT_NAMES = NO
# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
# first line (until the first dot) of a Javadoc-style comment as the brief
# description. If set to NO, the Javadoc-style will behave just like regular Qt-
# style comments (thus requiring an explicit @brief command for a brief
# description.)
# The default value is: NO.
JAVADOC_AUTOBRIEF = NO
# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
# line (until the first dot) of a Qt-style comment as the brief description. If
# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
# requiring an explicit \brief command for a brief description.)
# The default value is: NO.
QT_AUTOBRIEF = NO
# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
# a brief description. This used to be the default behavior. The new default is
# to treat a multi-line C++ comment block as a detailed description. Set this
# tag to YES if you prefer the old behavior instead.
#
# Note that setting this tag to YES also means that rational rose comments are
# not recognized any more.
# The default value is: NO.
MULTILINE_CPP_IS_BRIEF = NO
# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
# documentation from any documented member that it re-implements.
# The default value is: YES.
INHERIT_DOCS = YES
# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a
# new page for each member. If set to NO, the documentation of a member will be
# part of the file/class/namespace that contains it.
# The default value is: NO.
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 2
MARKDOWN_SUPPORT = YES
AUTOLINK_SUPPORT = NO
IDL_PROPERTY_SUPPORT = NO
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
# tag is set to YES, then doxygen will reuse the documentation of the first
# member in the group (if any) for the other members of the group. By default
# all members of a group must be documented explicitly.
# The default value is: NO.
DISTRIBUTE_GROUP_DOC = NO
# Set the SUBGROUPING tag to YES to allow class member groups of the same type
# (for instance a group of public functions) to be put as a subgroup of that
# type (e.g. under the Public Functions section). Set it to NO to prevent
# subgrouping. Alternatively, this can be done per class using the
# \nosubgrouping command.
# The default value is: YES.
SUBGROUPING = YES
# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
# are shown inside the group in which they are included (e.g. using \ingroup)
# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
# and RTF).
#
# Note that this feature does not work in combination with
# SEPARATE_MEMBER_PAGES.
# The default value is: NO.
INLINE_GROUPED_CLASSES = NO
# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
# with only public data fields or simple typedef fields will be shown inline in
# the documentation of the scope in which they are defined (i.e. file,
# namespace, or group documentation), provided this scope is documented. If set
# to NO, structs, classes, and unions are shown on a separate page (for HTML and
# Man pages) or section (for LaTeX and RTF).
# The default value is: NO.
INLINE_SIMPLE_STRUCTS = NO
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_PACKAGE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = NO
HIDE_UNDOC_CLASSES = YES
HIDE_FRIEND_COMPOUNDS = YES
HIDE_IN_BODY_DOCS = YES
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = NO
# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
# their full class and namespace scopes in the documentation. If set to YES the
# scope will be hidden.
# The default value is: NO.
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = NO
SHOW_GROUPED_MEMB_INC = NO
INLINE_INFO = YES
SORT_MEMBER_DOCS = NO
SORT_BRIEF_DOCS = NO
SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = YES
STRICT_PROTO_MATCHING = NO
GENERATE_TODOLIST = NO
GENERATE_TESTLIST = NO
GENERATE_BUGLIST = NO
GENERATE_DEPRECATEDLIST= NO
MAX_INITIALIZER_LINES = 0
SHOW_USED_FILES = NO
SHOW_FILES = NO
SHOW_NAMESPACES = NO
#---------------------------------------------------------------------------
# Configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = YES
WARNINGS = YES
WARN_IF_UNDOCUMENTED = NO
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# Configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = ../src/asmjit
INPUT_ENCODING = UTF-8
RECURSIVE = YES
EXCLUDE =
USE_MDFILE_AS_MAINPAGE = ../README.md
#---------------------------------------------------------------------------
# Configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
SOURCE_TOOLTIPS = YES
VERBATIM_HEADERS = NO
#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = NO
#---------------------------------------------------------------------------
# Configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
GENERATE_LATEX = NO
GENERATE_RTF = NO
GENERATE_MAN = NO
HTML_OUTPUT = doc
HTML_FILE_EXTENSION = .html
LAYOUT_FILE = doc-layout.xml
HTML_HEADER = doc-header.html
HTML_FOOTER = doc-footer.html
HTML_STYLESHEET = doc-style.css
HTML_EXTRA_STYLESHEET =
HTML_EXTRA_FILES =
HTML_COLORSTYLE_HUE = 220
HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80
HTML_TIMESTAMP = NO
HTML_DYNAMIC_SECTIONS = NO
HTML_INDEX_NUM_ENTRIES = 0
SEARCHENGINE = NO
#---------------------------------------------------------------------------
# Configuration options related to the CHM output
#---------------------------------------------------------------------------
# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
# Windows.
#
# The HTML Help Workshop contains a compiler that can convert all HTML output
# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
# files are now used as the Windows 98 help format, and will replace the old
# Windows help format (.hlp) on all Windows platforms in the future. Compressed
# HTML files also contain an index, a table of contents, and you can search for
# words in the documentation. The HTML workshop also contains a viewer for
# compressed HTML files.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
GENERATE_HTMLHELP = NO
# The CHM_FILE tag can be used to specify the file name of the resulting .chm
# file. You can add a path in front of the file if the result should not be
# written to the html output directory.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
CHM_FILE =
# The HHC_LOCATION tag can be used to specify the location (absolute path
# including file name) of the HTML help compiler ( hhc.exe). If non-empty
# doxygen will try to run the HTML help compiler on the generated index.hhp.
# The file has to be specified with full path.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
HHC_LOCATION =
# The BINARY_TOC flag controls whether a binary table of contents is generated (
# YES) or a normal table of contents ( NO) in the .chm file. Furthermore it
# enables the Previous and Next buttons.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
BINARY_TOC = NO
# The TOC_EXPAND flag can be set to YES to add extra items for group members to
# the table of contents of the HTML help documentation and to the tree view.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
TOC_EXPAND = NO
# If you want full control over the layout of the generated HTML pages it might
# be necessary to disable the index and replace it with your own. The
# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
# of each HTML page. A value of NO enables the index and the value YES disables
# it. Since the tabs in the index contain the same information as the navigation
# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
DISABLE_INDEX = NO
# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
# structure should be generated to display hierarchical information. If the tag
# value is set to YES, a side panel will be generated containing a tree-like
# index structure (just like the one that is generated for HTML Help). For this
# to work a browser that supports JavaScript, DHTML, CSS and frames is required
# (i.e. any modern browser). Windows users are probably better off using the
# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can
# further fine-tune the look of the index. As an example, the default style
# sheet generated by doxygen has an example that shows how to put an image at
# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
# the same information as the tab index, you could consider setting
# DISABLE_INDEX to YES when enabling this option.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
GENERATE_TREEVIEW = NO
# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
# doxygen will group on one line in the generated HTML documentation.
#
# Note that a value of 0 will completely suppress the enum values from appearing
# in the overview section.
# Minimum value: 0, maximum value: 20, default value: 4.
# This tag requires that the tag GENERATE_HTML is set to YES.
ENUM_VALUES_PER_LINE = 0
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
# to set the initial width (in pixels) of the frame in which the tree is shown.
# Minimum value: 0, maximum value: 1500, default value: 250.
# This tag requires that the tag GENERATE_HTML is set to YES.
TREEVIEW_WIDTH = 250
# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to
# external symbols imported via tag files in a separate window.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
EXT_LINKS_IN_WINDOW = NO
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = NO
PREDEFINED = ASMJIT_DOCGEN=1
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = NO
CLASS_GRAPH = NO

View File

@@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html lang="en">
<head> <head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>

View File

@@ -14,7 +14,6 @@
<class> <class>
<briefdescription title=""/> <briefdescription title=""/>
<inheritancegraph visible="$CLASS_GRAPH"/> <inheritancegraph visible="$CLASS_GRAPH"/>
<detaileddescription title=""/>
<memberdecl> <memberdecl>
<nestedclasses visible="yes" title=""/> <nestedclasses visible="yes" title=""/>
<publictypes title=""/> <publictypes title=""/>
@@ -49,6 +48,7 @@
<related title="" subtitle=""/> <related title="" subtitle=""/>
<membergroups visible="yes"/> <membergroups visible="yes"/>
</memberdecl> </memberdecl>
<detaileddescription title=""/>
<memberdef> <memberdef>
<inlineclasses title=""/> <inlineclasses title=""/>
<typedefs title=""/> <typedefs title=""/>
@@ -67,8 +67,8 @@
<!-- Layout definition for a group page --> <!-- Layout definition for a group page -->
<group> <group>
<briefdescription title=""/>
<groupgraph visible="$GROUP_GRAPHS"/> <groupgraph visible="$GROUP_GRAPHS"/>
<detaileddescription title=""/>
<memberdecl> <memberdecl>
<nestedgroups visible="yes" title=""/> <nestedgroups visible="yes" title=""/>
<dirs visible="yes" title=""/> <dirs visible="yes" title=""/>
@@ -90,6 +90,7 @@
<friends title=""/> <friends title=""/>
<membergroups visible="yes"/> <membergroups visible="yes"/>
</memberdecl> </memberdecl>
<detaileddescription title=""/>
<memberdef> <memberdef>
<pagedocs/> <pagedocs/>
<inlineclasses title=""/> <inlineclasses title=""/>
@@ -107,6 +108,5 @@
<properties title=""/> <properties title=""/>
<friends title=""/> <friends title=""/>
</memberdef> </memberdef>
<authorsection visible="yes"/>
</group> </group>
</doxygenlayout> </doxygenlayout>

View File

@@ -531,18 +531,9 @@ table.memberdecls {
background-image:url('nav_g.png'); background-image:url('nav_g.png');
background-repeat:repeat-x; background-repeat:repeat-x;
background-color: #FFFFFF; background-color: #FFFFFF;
/* opera specific markup */
border-bottom-left-radius: 4px; border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px; border-bottom-right-radius: 4px;
box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); /* box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); */
/* firefox specific markup */
-moz-border-radius-bottomleft: 4px;
-moz-border-radius-bottomright: 4px;
-moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
/* webkit specific markup */
-webkit-border-bottom-left-radius: 4px;
-webkit-border-bottom-right-radius: 4px;
-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
} }
dl.reflist dt { dl.reflist dt {
@@ -827,11 +818,11 @@ table.fieldtable {
.fieldtable td.fieldname { .fieldtable td.fieldname {
padding-top: 3px; padding-top: 3px;
font-weight: bold;
} }
.fieldtable td.fielddoc { .fieldtable td.fielddoc {
border-bottom: 1px solid #A8B8D9; border-bottom: 1px solid #A8B8D9;
/*width: 100%;*/
} }
.fieldtable td.fielddoc p:first-child { .fieldtable td.fielddoc p:first-child {
@@ -966,8 +957,8 @@ dl {
/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ /* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */
dl.section { dl.section {
margin-left: 0px; margin-left: 0;
padding-left: 0px; padding-left: 0;
} }
dl.note { dl.note {
@@ -977,6 +968,10 @@ dl.note {
border-color: #D0C000; border-color: #D0C000;
} }
dl.note dd {
margin-left: 0;
}
dl.warning, dl.attention { dl.warning, dl.attention {
margin-left:-7px; margin-left:-7px;
padding-left: 3px; padding-left: 3px;

View File

@@ -225,7 +225,7 @@ var main = function(files) {
main([ main([
{ {
name: "../src/asmjit/x86/x86defs.cpp", name: "../src/asmjit/x86/x86inst.cpp",
arch: "x86", arch: "x86",
suffixes: [ suffixes: [
"a", "ae", "a", "ae",