| ... | ... |
@@ -324,7 +324,7 @@ |
| 324 | 324 |
//! vendor[12] = '\0'; |
| 325 | 325 |
//! |
| 326 | 326 |
//! // Print a CPU vendor retrieved from CPUID. |
| 327 |
-//! ::printf("%s", cpuVendor);
|
|
| 327 |
+//! ::fprintf(stderr, "%s", cpuVendor); |
|
| 328 | 328 |
//! ~~~ |
| 329 | 329 |
|
| 330 | 330 |
// ============================================================================ |
* [2SF] Used more up-to-date asmjit, despite the ugly looking code.
| ... | ... |
@@ -1,337 +1,374 @@ |
| 1 | 1 |
// [AsmJit] |
| 2 |
-// Complete JIT Assembler for C++ Language. |
|
| 2 |
+// Complete x86/x64 JIT and Remote Assembler for C++. |
|
| 3 | 3 |
// |
| 4 | 4 |
// [License] |
| 5 |
-// Zlib - See COPYING file in this package. |
|
| 5 |
+// Zlib - See LICENSE.md file in the package. |
|
| 6 | 6 |
|
| 7 | 7 |
#pragma once |
| 8 | 8 |
|
| 9 |
+// ============================================================================ |
|
| 10 |
+// [asmjit_mainpage] |
|
| 11 |
+// ============================================================================ |
|
| 12 |
+ |
|
| 9 | 13 |
//! @mainpage |
| 10 | 14 |
//! |
| 11 |
-//! @brief AsmJit is a complete x86/x64 JIT Assembler for C++ language. |
|
| 12 |
-//! |
|
| 13 |
-//! It supports FPU, MMX, 3dNow, SSE, SSE2, SSE3 and SSE4 intrinsics, powerful |
|
| 14 |
-//! compiler that helps to write portable functions for 32-bit (x86) and 64-bit |
|
| 15 |
-//! (x64) architectures. AsmJit can be used to create functions at runtime that |
|
| 16 |
-//! can be called from existing (but also generated) C/C++ code. |
|
| 17 |
-//! |
|
| 18 |
-//! AsmJit is a cross-platform library that supports various compilers and |
|
| 19 |
-//! operating systems. Currently only limitation is x86 (32-bit) or x64 (64-bit) |
|
| 20 |
-//! processor. Currently tested operating systems are Windows (32-bit and 64-bit), |
|
| 21 |
-//! Linux (32-bit and 64-bit) and MacOSX (32-bit and 64-bit). |
|
| 22 |
-//! |
|
| 23 |
-//! @section AsmJit_Main_Introduction Introduction |
|
| 24 |
-//! |
|
| 25 |
-//! AsmJit library contains two main classes for code generation with different |
|
| 26 |
-//! goals. First main code generation class is called @c AsmJit::Assembler and |
|
| 27 |
-//! contains low level API that can be used to generate JIT binary code. It |
|
| 28 |
-//! directly emits binary stream that represents encoded x86/x64 assembler |
|
| 29 |
-//! opcodes. Together with operands and labels it can be used to generate |
|
| 30 |
-//! complete code. For details look to @ref AsmJit_Core and @ref AsmJit_Compiler |
|
| 31 |
-//! sections. |
|
| 32 |
-//! |
|
| 33 |
-//! There is also class named @c AsmJit::Compiler that allows to develop |
|
| 34 |
-//! cross-platform assembler code without worring about function calling |
|
| 35 |
-//! conventions and registers allocation. It can be also used to write 32-bit |
|
| 36 |
-//! and 64-bit portable code. Compiler is recommended class to use for code |
|
| 37 |
-//! generation. |
|
| 38 |
-//! |
|
| 39 |
-//! Everything in AsmJit library is in @c AsmJit namespace. |
|
| 15 |
+//! AsmJit - Complete x86/x64 JIT and Remote Assembler for C++. |
|
| 16 |
+//! |
|
| 17 |
+//! AsmJit is a complete JIT and remote assembler for C++ language. It can |
|
| 18 |
+//! generate native code for x86 and x64 architectures having support for |
|
| 19 |
+//! a full instruction set, from legacy MMX to the newest AVX2. It has a |
|
| 20 |
+//! type-safe API that allows C++ compiler to do a semantic checks at |
|
| 21 |
+//! compile-time even before the assembled code is generated or run. |
|
| 22 |
+//! |
|
| 23 |
+//! AsmJit is not a virtual machine (VM). It doesn't have functionality to |
|
| 24 |
+//! implement VM out of the box; however, it can be be used as a JIT backend |
|
| 25 |
+//! for your own VM. The usage of AsmJit is not limited at all; it's suitable |
|
| 26 |
+//! for multimedia, VM backends or remote code generation. |
|
| 27 |
+//! |
|
| 28 |
+//! @section AsmJit_Concepts Code Generation Concepts |
|
| 29 |
+//! |
|
| 30 |
+//! AsmJit has two completely different code generation concepts. The difference |
|
| 31 |
+//! is in how the code is generated. The first concept, also referred as the low |
|
| 32 |
+//! level concept, is called 'Assembler' and it's the same as writing RAW |
|
| 33 |
+//! assembly by using physical registers directly. In this case AsmJit does only |
|
| 34 |
+//! instruction encoding, verification and relocation. |
|
| 35 |
+//! |
|
| 36 |
+//! The second concept, also referred as the high level concept, is called |
|
| 37 |
+//! 'Compiler'. Compiler lets you use virtually unlimited number of registers |
|
| 38 |
+//! (called variables) significantly simplifying the code generation process. |
|
| 39 |
+//! Compiler allocates these virtual registers to physical registers after the |
|
| 40 |
+//! code generation is done. This requires some extra effort - Compiler has to |
|
| 41 |
+//! generate information for each node (instruction, function declaration, |
|
| 42 |
+//! function call) in the code, perform a variable liveness analysis and |
|
| 43 |
+//! translate the code having variables into code having only registers. |
|
| 44 |
+//! |
|
| 45 |
+//! In addition, Compiler understands functions and function calling conventions. |
|
| 46 |
+//! It has been designed in a way that the code generated is always a function |
|
| 47 |
+//! having prototype like in a programming language. By having a function |
|
| 48 |
+//! prototype the Compiler is able to insert prolog and epilog to a function |
|
| 49 |
+//! being generated and it is able to call a function inside a generated one. |
|
| 50 |
+//! |
|
| 51 |
+//! There is no conclusion on which concept is better. Assembler brings full |
|
| 52 |
+//! control on how the code is generated, while Compiler makes the generation |
|
| 53 |
+//! more portable. |
|
| 40 | 54 |
//! |
| 41 | 55 |
//! @section AsmJit_Main_CodeGeneration Code Generation |
| 42 | 56 |
//! |
| 43 |
-//! - @ref AsmJit_Core "Assembler core" - Operands, intrinsics and low-level assembler. |
|
| 44 |
-//! - @ref AsmJit_Compiler "Compiler" - High level code generation. |
|
| 45 |
-//! - @ref AsmJit_CpuInfo "Cpu Information" - Get information about host processor. |
|
| 46 |
-//! - @ref AsmJit_Logging "Logging" - Logging and error handling. |
|
| 47 |
-//! - @ref AsmJit_MemoryManagement "Memory Management" - Virtual memory management. |
|
| 48 |
-//! |
|
| 49 |
-//! @section AsmJit_Main_Configuration Configuration, Definitions and Utilities |
|
| 50 |
-//! |
|
| 51 |
-//! - @ref AsmJit_Config "Configuration" - Macros used to configure AsmJit. |
|
| 57 |
+//! - \ref asmjit_base_general "Assembler core" - Operands, intrinsics and low-level assembler. |
|
| 58 |
+//! - \ref asmjit_compiler "Compiler" - High level code generation. |
|
| 59 |
+//! - \ref asmjit_cpuinfo "Cpu Information" - Get information about host processor. |
|
| 60 |
+//! - \ref asmjit_logging "Logging" - Logging and error handling. |
|
| 61 |
+//! - \ref AsmJit_MemoryManagement "Memory Management" - Virtual memory management. |
|
| 52 | 62 |
//! |
| 53 | 63 |
//! @section AsmJit_Main_HomePage AsmJit Homepage |
| 54 | 64 |
//! |
| 55 |
-//! - http://code.google.com/p/asmjit/ |
|
| 56 |
-//! |
|
| 57 |
-//! @section AsmJit_Main_ResourcesX86 External X86/X64 Assembler Resources |
|
| 58 |
-//! - http://www.agner.org/optimize/ |
|
| 59 |
-//! - http://www.mark.masmcode.com/ (Assembler Tips) |
|
| 60 |
-//! - http://avisynth.org/mediawiki/Filter_SDK/Assembler_optimizing (Optimizing) |
|
| 61 |
-//! - http://www.ragestorm.net/distorm/ (Disassembling) |
|
| 62 |
-//! |
|
| 63 |
-//! @section AsmJit_Main_Terminology Terminology |
|
| 64 |
-//! |
|
| 65 |
-//! - <b>Non-volatile (preserved) register</b> - Register that can't be changed |
|
| 66 |
-//! by callee (callee must save and restore it if it want to use it inside). |
|
| 67 |
-//! |
|
| 68 |
-//! - <b>Volatile (non-preserved) register</b> - The opossite. Register that can |
|
| 69 |
-//! be freely used by callee. The caller must free all registers before calling |
|
| 70 |
-//! other function. |
|
| 65 |
+//! - https://github.com/kobalicek/asmjit |
|
| 71 | 66 |
|
| 67 |
+// ============================================================================ |
|
| 68 |
+// [asmjit_base] |
|
| 69 |
+// ============================================================================ |
|
| 72 | 70 |
|
| 73 |
-//! @defgroup AsmJit_Core Assembler core (operands, intrinsics and low-level assembler). |
|
| 71 |
+//! \defgroup asmjit_base AsmJit |
|
| 74 | 72 |
//! |
| 75 |
-//! Contains classes related to @c AsmJit::Assembler that're directly used |
|
| 76 |
-//! to generate machine code stream. It's one of oldest and fastest method |
|
| 77 |
-//! to generate machine code using AsmJit library. |
|
| 73 |
+//! \brief AsmJit. |
|
| 74 |
+ |
|
| 75 |
+// ============================================================================ |
|
| 76 |
+// [asmjit_base_general] |
|
| 77 |
+// ============================================================================ |
|
| 78 |
+ |
|
| 79 |
+//! \defgroup asmjit_base_general AsmJit General API |
|
| 80 |
+//! \ingroup asmjit_base |
|
| 78 | 81 |
//! |
| 79 |
-//! - See @c AsmJit::Assembler class for low level code generation |
|
| 80 |
-//! documentation. |
|
| 81 |
-//! - See @c AsmJit::Operand for AsmJit operand's overview. |
|
| 82 |
+//! \brief AsmJit general API. |
|
| 82 | 83 |
//! |
| 83 |
-//! @section AsmJit_Core_Registers Registers |
|
| 84 |
+//! Contains all `asmjit` classes and helper functions that are architecture |
|
| 85 |
+//! independent or abstract. Abstract classes are implemented by the backend, |
|
| 86 |
+//! for example `Assembler` is implemented by `X86Assembler`. |
|
| 84 | 87 |
//! |
| 85 |
-//! There are static objects that represents X86 and X64 registers. They can |
|
| 86 |
-//! be used directly (like @c eax, @c mm, @c xmm, ...) or created through |
|
| 87 |
-//! these functions: |
|
| 88 |
+//! - See `Assembler` for low level code generation documentation. |
|
| 89 |
+//! - See `Compiler` for high level code generation documentation. |
|
| 90 |
+//! - See `Operand` for operand's overview. |
|
| 88 | 91 |
//! |
| 89 |
-//! - @c AsmJit::mk_gpb() - make general purpose byte register |
|
| 90 |
-//! - @c AsmJit::mk_gpw() - make general purpose word register |
|
| 91 |
-//! - @c AsmJit::mk_gpd() - make general purpose dword register |
|
| 92 |
-//! - @c AsmJit::mk_gpq() - make general purpose qword register |
|
| 93 |
-//! - @c AsmJit::mk_mm() - make mmx register |
|
| 94 |
-//! - @c AsmJit::mk_xmm() - make sse register |
|
| 95 |
-//! - @c AsmJit::st() - make x87 register |
|
| 92 |
+//! Logging and Error Handling |
|
| 93 |
+//! -------------------------- |
|
| 96 | 94 |
//! |
| 97 |
-//! @section AsmJit_Core_Addressing Addressing |
|
| 95 |
+//! AsmJit contains robust interface that can be used to log the generated code |
|
| 96 |
+//! and to handle possible errors. Base logging interface is defined in `Logger` |
|
| 97 |
+//! class that is abstract and can be overridden. AsmJit contains two loggers |
|
| 98 |
+//! that can be used out of the box - `FileLogger` that logs into a pure C |
|
| 99 |
+//! `FILE*` stream and `StringLogger` that just concatenates all log messages |
|
| 100 |
+//! by using a `StringBuilder` class. |
|
| 98 | 101 |
//! |
| 99 |
-//! X86 and x64 architectures contains several addressing modes and most ones |
|
| 100 |
-//! are possible with AsmJit library. Memory represents are represented by |
|
| 101 |
-//! @c AsmJit::Mem class. These functions are used to make operands that |
|
| 102 |
-//! represents memory addresses: |
|
| 103 |
-//! |
|
| 104 |
-//! - @c AsmJit::ptr() |
|
| 105 |
-//! - @c AsmJit::byte_ptr() |
|
| 106 |
-//! - @c AsmJit::word_ptr() |
|
| 107 |
-//! - @c AsmJit::dword_ptr() |
|
| 108 |
-//! - @c AsmJit::qword_ptr() |
|
| 109 |
-//! - @c AsmJit::tword_ptr() |
|
| 110 |
-//! - @c AsmJit::dqword_ptr() |
|
| 111 |
-//! - @c AsmJit::mmword_ptr() |
|
| 112 |
-//! - @c AsmJit::xmmword_ptr() |
|
| 113 |
-//! - @c AsmJit::sysint_ptr() |
|
| 114 |
-//! |
|
| 115 |
-//! Most useful function to make pointer should be @c AsmJit::ptr(). It creates |
|
| 116 |
-//! pointer to the target with unspecified size. Unspecified size works in all |
|
| 117 |
-//! intrinsics where are used registers (this means that size is specified by |
|
| 118 |
-//! register operand or by instruction itself). For example @c AsmJit::ptr() |
|
| 119 |
-//! can't be used with @c AsmJit::Assembler::inc() instruction. In this case |
|
| 120 |
-//! size must be specified and it's also reason to make difference between |
|
| 121 |
-//! pointer sizes. |
|
| 102 |
+//! The following snippet shows how to setup a logger that logs to `stderr`: |
|
| 122 | 103 |
//! |
| 123 |
-//! Supported are simple address forms (register + displacement) and complex |
|
| 124 |
-//! address forms (register + (register << shift) + displacement). |
|
| 104 |
+//! ~~~ |
|
| 105 |
+//! // `FileLogger` instance. |
|
| 106 |
+//! FileLogger logger(stderr); |
|
| 125 | 107 |
//! |
| 126 |
-//! @section AsmJit_Core_Immediates Immediates |
|
| 108 |
+//! // `Compiler` or any other `CodeGen` interface. |
|
| 109 |
+//! host::Compiler c; |
|
| 127 | 110 |
//! |
| 128 |
-//! Immediate values are constants thats passed directly after instruction |
|
| 129 |
-//! opcode. To create such value use @c AsmJit::imm() or @c AsmJit::uimm() |
|
| 130 |
-//! methods to create signed or unsigned immediate value. |
|
| 111 |
+//! // use `setLogger` to replace the `CodeGen` logger. |
|
| 112 |
+//! c.setLogger(&logger); |
|
| 113 |
+//! ~~~ |
|
| 131 | 114 |
//! |
| 132 |
-//! @sa @c AsmJit::Compiler. |
|
| 115 |
+//! \sa \ref Logger, \ref FileLogger, \ref StringLogger. |
|
| 133 | 116 |
|
| 117 |
+// ============================================================================ |
|
| 118 |
+// [asmjit_base_compiler] |
|
| 119 |
+// ============================================================================ |
|
| 134 | 120 |
|
| 135 |
-//! @defgroup AsmJit_Compiler Compiler (high-level code generation). |
|
| 121 |
+//! \defgroup asmjit_base_compiler AsmJit Compiler |
|
| 122 |
+//! \ingroup asmjit_base |
|
| 136 | 123 |
//! |
| 137 |
-//! Contains classes related to @c AsmJit::Compiler that can be used |
|
| 138 |
-//! to generate code using high-level constructs. |
|
| 124 |
+//! \brief AsmJit code-tree used by Compiler. |
|
| 139 | 125 |
//! |
| 140 |
-//! - See @c Compiler class for high level code generation |
|
| 141 |
-//! documentation - calling conventions, function declaration |
|
| 142 |
-//! and variables management. |
|
| 143 |
- |
|
| 144 |
-//! @defgroup AsmJit_Config Configuration. |
|
| 126 |
+//! AsmJit intermediate code-tree is a double-linked list that is made of nodes |
|
| 127 |
+//! that represent assembler instructions, directives, labels and high-level |
|
| 128 |
+//! constructs compiler is using to represent functions and function calls. The |
|
| 129 |
+//! node list can only be used together with \ref Compiler. |
|
| 145 | 130 |
//! |
| 146 |
-//! Contains macros that can be redefined to fit into any project. |
|
| 131 |
+//! TODO |
|
| 147 | 132 |
|
| 133 |
+// ============================================================================ |
|
| 134 |
+// [asmjit_base_util] |
|
| 135 |
+// ============================================================================ |
|
| 148 | 136 |
|
| 149 |
-//! @defgroup AsmJit_CpuInfo CPU information. |
|
| 137 |
+//! \defgroup asmjit_base_util AsmJit Utilities |
|
| 138 |
+//! \ingroup asmjit_base |
|
| 150 | 139 |
//! |
| 151 |
-//! X86 or x64 cpuid instruction allows to get information about processor |
|
| 152 |
-//! vendor and it's features. It's always used to detect features like MMX, |
|
| 153 |
-//! SSE and other newer ones. |
|
| 140 |
+//! \brief AsmJit utility classes. |
|
| 154 | 141 |
//! |
| 155 |
-//! AsmJit library supports low level cpuid call implemented internally as |
|
| 156 |
-//! C++ function using inline assembler or intrinsics and also higher level |
|
| 157 |
-//! CPU features detection. The low level function (also used by higher level |
|
| 158 |
-//! one) is @c AsmJit::cpuid(). |
|
| 142 |
+//! AsmJit contains numerous utility classes that are needed by the library |
|
| 143 |
+//! itself. The most useful ones have been made public and are now exported. |
|
| 159 | 144 |
//! |
| 160 |
-//! AsmJit library also contains higher level function @c AsmJit::getCpuInfo() |
|
| 161 |
-//! that returns features detected by the library. The detection process is |
|
| 162 |
-//! done only once and it's cached for all next calls. @c AsmJit::CpuInfo |
|
| 163 |
-//! structure not contains only information through @c AsmJit::cpuid(), but |
|
| 164 |
-//! there is also small multiplatform code to detect number of processors |
|
| 165 |
-//! (or cores) through operating system API. |
|
| 145 |
+//! POD Containers |
|
| 146 |
+//! -------------- |
|
| 166 | 147 |
//! |
| 167 |
-//! It's recommended to use @c AsmJit::cpuInfo to detect and check for |
|
| 168 |
-//! host processor features. |
|
| 148 |
+//! POD containers are used by AsmJit to manage its own data structures. The |
|
| 149 |
+//! following classes can be used by AsmJit consumers: |
|
| 169 | 150 |
//! |
| 170 |
-//! Example how to use AsmJit::cpuid(): |
|
| 151 |
+//! - \ref PodVector - Simple growing array-like container for POD data. |
|
| 152 |
+//! - \ref StringBuilder - Simple string builder that can append string |
|
| 153 |
+//! and integers. |
|
| 171 | 154 |
//! |
| 172 |
-//! @code |
|
| 173 |
-//! // All functions and structures are in AsmJit namesapce. |
|
| 174 |
-//! using namespace AsmJit; |
|
| 155 |
+//! Zone Memory Allocator |
|
| 156 |
+//! --------------------- |
|
| 175 | 157 |
//! |
| 176 |
-//! // Here will be retrieved result of cpuid call. |
|
| 177 |
-//! CpuId out; |
|
| 158 |
+//! Zone memory allocator is an incremental memory allocator that can be used |
|
| 159 |
+//! to allocate data of short life-time. It has much better performance |
|
| 160 |
+//! characteristics than all other allocators, because the only thing it can do |
|
| 161 |
+//! is to increment a pointer and return its previous address. See \ref Zone |
|
| 162 |
+//! for more details. |
|
| 178 | 163 |
//! |
| 179 |
-//! // Use cpuid function to do the job. |
|
| 180 |
-//! cpuid(0 /* eax */, &out /* eax, ebx, ecx, edx */); |
|
| 164 |
+//! CPU Ticks |
|
| 165 |
+//! --------- |
|
| 181 | 166 |
//! |
| 182 |
-//! // Id eax argument to cpuid is 0, ebx, ecx and edx registers |
|
| 183 |
-//! // are filled with cpu vendor. |
|
| 184 |
-//! char vendor[13]; |
|
| 185 |
-//! memcpy(i->vendor, &out.ebx, 4); |
|
| 186 |
-//! memcpy(i->vendor + 4, &out.edx, 4); |
|
| 187 |
-//! memcpy(i->vendor + 8, &out.ecx, 4); |
|
| 188 |
-//! vendor[12] = '\0'; |
|
| 189 |
-//! |
|
| 190 |
-//! // Print vendor |
|
| 191 |
-//! puts(vendor); |
|
| 192 |
-//! @endcode |
|
| 167 |
+//! CPU Ticks is a simple helper that can be used to do basic benchmarks. See |
|
| 168 |
+//! \ref CpuTicks class for more details. |
|
| 193 | 169 |
//! |
| 194 |
-//! If you want to use AsmJit::cpuid() function instead of higher level |
|
| 195 |
-//! @c AsmJit::getCpuInfo(), please read processor manuals provided by Intel, |
|
| 196 |
-//! AMD or other manufacturers for cpuid instruction details. |
|
| 170 |
+//! Integer Utilities |
|
| 171 |
+//! ----------------- |
|
| 197 | 172 |
//! |
| 198 |
-//! Example of using @c AsmJit::getCpuInfo(): |
|
| 173 |
+//! Integer utilities are all implemented by a static class \ref IntUtil. |
|
| 174 |
+//! There are utilities for bit manipulation and bit counting, utilities to get |
|
| 175 |
+//! an integer minimum / maximum and various other helpers required to perform |
|
| 176 |
+//! alignment checks and binary casting from float to integer and vica versa. |
|
| 199 | 177 |
//! |
| 200 |
-//! @code |
|
| 201 |
-//! // All functions and structures are in AsmJit namesapce. |
|
| 202 |
-//! using namespace AsmJit; |
|
| 178 |
+//! Vector Utilities |
|
| 179 |
+//! ---------------- |
|
| 203 | 180 |
//! |
| 204 |
-//! // Call to cpuInfo return CpuInfo structure that shouldn't be modified. |
|
| 205 |
-//! // Make it const by default. |
|
| 206 |
-//! const CpuInfo *i = getCpuInfo(); |
|
| 181 |
+//! SIMD code generation often requires to embed constants after each function |
|
| 182 |
+//! or a block of functions generated. AsmJit contains classes `Vec64`, |
|
| 183 |
+//! `Vec128` and `Vec256` that can be used to prepare data useful when |
|
| 184 |
+//! generating SIMD code. |
|
| 207 | 185 |
//! |
| 208 |
-//! // Now you are able to get specific features. |
|
| 186 |
+//! X86/X64 code generator contains member functions `dmm`, `dxmm` and `dymm` |
|
| 187 |
+//! which can be used to embed 64-bit, 128-bit and 256-bit data structures into |
|
| 188 |
+//! machine code (both assembler and compiler are supported). |
|
| 209 | 189 |
//! |
| 210 |
-//! // Processor has SSE2 |
|
| 211 |
-//! if (i->features & kX86FeatureSse2) |
|
| 212 |
-//! {
|
|
| 213 |
-//! // your code... |
|
| 214 |
-//! } |
|
| 215 |
-//! // Processor has MMX |
|
| 216 |
-//! else if (i->features & kX86Feature_MMX) |
|
| 217 |
-//! {
|
|
| 218 |
-//! // your code... |
|
| 219 |
-//! } |
|
| 220 |
-//! // Processor is old, no SSE2 or MMX support. |
|
| 221 |
-//! else |
|
| 222 |
-//! {
|
|
| 223 |
-//! // your code... |
|
| 224 |
-//! } |
|
| 225 |
-//! @endcode |
|
| 226 |
-//! |
|
| 227 |
-//! Better example is in AsmJit/Test/testcpu.cpp file. |
|
| 190 |
+//! \note Compiler contains a constant pool, which should be used instead of |
|
| 191 |
+//! embedding constants manually after the function body. |
|
| 192 |
+ |
|
| 193 |
+// ============================================================================ |
|
| 194 |
+// [asmjit_x86] |
|
| 195 |
+// ============================================================================ |
|
| 196 |
+ |
|
| 197 |
+//! \defgroup asmjit_x86 X86/X64 |
|
| 228 | 198 |
//! |
| 229 |
-//! @sa AsmJit::cpuid, @c AsmJit::cpuInfo. |
|
| 199 |
+//! \brief X86/X64 module |
|
| 230 | 200 |
|
| 201 |
+// ============================================================================ |
|
| 202 |
+// [asmjit_x86_general] |
|
| 203 |
+// ============================================================================ |
|
| 231 | 204 |
|
| 232 |
-//! @defgroup AsmJit_Logging Logging and error handling. |
|
| 205 |
+//! \defgroup asmjit_x86_general X86/X64 General API |
|
| 206 |
+//! \ingroup asmjit_x86 |
|
| 233 | 207 |
//! |
| 234 |
-//! Contains classes related to loging assembler output. Currently logging |
|
| 235 |
-//! is implemented in @c AsmJit::Logger class.You can override |
|
| 236 |
-//! @c AsmJit::Logger::log() to log messages into your stream. There is also |
|
| 237 |
-//! @c FILE based logger implemented in @c AsmJit::FileLogger class. |
|
| 208 |
+//! \brief X86/X64 general API. |
|
| 238 | 209 |
//! |
| 239 |
-//! To log your assembler output to FILE stream use this code: |
|
| 210 |
+//! X86/X64 Registers |
|
| 211 |
+//! ----------------- |
|
| 240 | 212 |
//! |
| 241 |
-//! @code |
|
| 242 |
-//! // Create assembler |
|
| 243 |
-//! Assembler a; |
|
| 213 |
+//! There are static objects that represents X86 and X64 registers. They can |
|
| 214 |
+//! be used directly (like `eax`, `mm`, `xmm`, ...) or created through |
|
| 215 |
+//! these functions: |
|
| 244 | 216 |
//! |
| 245 |
-//! // Create and set file based logger |
|
| 246 |
-//! FileLogger logger(stderr); |
|
| 247 |
-//! a.setLogger(&logger); |
|
| 248 |
-//! @endcode |
|
| 217 |
+//! - `asmjit::gpb_lo()` - Get Gpb-lo register. |
|
| 218 |
+//! - `asmjit::gpb_hi()` - Get Gpb-hi register. |
|
| 219 |
+//! - `asmjit::gpw()` - Get Gpw register. |
|
| 220 |
+//! - `asmjit::gpd()` - Get Gpd register. |
|
| 221 |
+//! - `asmjit::gpq()` - Get Gpq Gp register. |
|
| 222 |
+//! - `asmjit::gpz()` - Get Gpd/Gpq register. |
|
| 223 |
+//! - `asmjit::fp()` - Get Fp register. |
|
| 224 |
+//! - `asmjit::mm()` - Get Mm register. |
|
| 225 |
+//! - `asmjit::xmm()` - Get Xmm register. |
|
| 226 |
+//! - `asmjit::ymm()` - Get Ymm register. |
|
| 249 | 227 |
//! |
| 250 |
-//! You can see that logging goes through @c Assembler. If you are using |
|
| 251 |
-//! @c Compiler and you want to log messages in correct assembler order, |
|
| 252 |
-//! you should look at @ref Compiler::comment() method. It allows you to |
|
| 253 |
-//! insert text message into items stream so the @c Compiler is able to |
|
| 254 |
-//! send messages to @ref Assembler in correct order. |
|
| 228 |
+//! X86/X64 Addressing |
|
| 229 |
+//! ------------------ |
|
| 255 | 230 |
//! |
| 256 |
-//! @sa @c AsmJit::Logger, @c AsmJit::FileLogger. |
|
| 257 |
- |
|
| 258 |
- |
|
| 259 |
-//! @defgroup AsmJit_MemoryManagement Virtual memory management. |
|
| 260 |
-//! |
|
| 261 |
-//! Using @c AsmJit::Assembler or @c AsmJit::Compiler to generate machine |
|
| 262 |
-//! code is not final step. Each generated code needs to run in memory |
|
| 263 |
-//! that is not protected against code execution. To alloc this code it's |
|
| 264 |
-//! needed to use operating system functions provided to enable execution |
|
| 265 |
-//! code in specified memory block or to allocate memory that is not |
|
| 266 |
-//! protected. The solution is always to use @c See AsmJit::Assembler::make() |
|
| 267 |
-//! and @c AsmJit::Compiler::make() functions that can allocate memory and |
|
| 268 |
-//! relocate code for you. But AsmJit also contains classes for manual memory |
|
| 269 |
-//! management thats internally used by AsmJit but can be used by programmers |
|
| 270 |
-//! too. |
|
| 271 |
-//! |
|
| 272 |
-//! Memory management contains low level and high level classes related to |
|
| 273 |
-//! allocating and freeing virtual memory. Low level class is |
|
| 274 |
-//! @c AsmJit::VirtualMemory that can allocate and free full pages of |
|
| 275 |
-//! virtual memory provided by operating system. Higher level class is |
|
| 276 |
-//! @c AsmJit::MemoryManager that is able to manage complete allocation and |
|
| 277 |
-//! free mechanism. It internally uses larger chunks of memory to make |
|
| 278 |
-//! allocation fast and effective. |
|
| 279 |
-//! |
|
| 280 |
-//! Using @c AsmJit::VirtualMemory::alloc() is cross-platform way how to |
|
| 281 |
-//! allocate this kind of memory without worrying about operating system |
|
| 282 |
-//! and it's API. Each memory block that is no longer needed should be |
|
| 283 |
-//! freed by @c AsmJit::VirtualMemory::free() method. If you want better |
|
| 284 |
-//! comfort and malloc()/free() interface, look at the |
|
| 285 |
-//! @c AsmJit::MemoryManager class. |
|
| 286 |
-//! |
|
| 287 |
-//! @sa @c AsmJit::VirtualMemory, @ AsmJit::MemoryManager. |
|
| 288 |
- |
|
| 289 |
- |
|
| 290 |
-//! @addtogroup AsmJit_Config |
|
| 291 |
-//! @{
|
|
| 292 |
- |
|
| 293 |
-//! @def ASMJIT_WINDOWS |
|
| 294 |
-//! @brief Macro that is declared if AsmJit is compiled for Windows. |
|
| 295 |
- |
|
| 296 |
-//! @def ASMJIT_POSIX |
|
| 297 |
-//! @brief Macro that is declared if AsmJit is compiled for unix like |
|
| 298 |
-//! operating system. |
|
| 299 |
- |
|
| 300 |
-//! @def ASMJIT_API |
|
| 301 |
-//! @brief Attribute that's added to classes that can be exported if AsmJit |
|
| 302 |
-//! is compiled as a dll library. |
|
| 303 |
- |
|
| 304 |
-//! @def ASMJIT_MALLOC |
|
| 305 |
-//! @brief Function to call to allocate dynamic memory. |
|
| 231 |
+//! X86 and x64 architectures contains several addressing modes and most ones |
|
| 232 |
+//! are possible with AsmJit library. Memory represents are represented by |
|
| 233 |
+//! `BaseMem` class. These functions are used to make operands that represents |
|
| 234 |
+//! memory addresses: |
|
| 235 |
+//! |
|
| 236 |
+//! - `asmjit::ptr()` |
|
| 237 |
+//! - `asmjit::byte_ptr()` |
|
| 238 |
+//! - `asmjit::word_ptr()` |
|
| 239 |
+//! - `asmjit::dword_ptr()` |
|
| 240 |
+//! - `asmjit::qword_ptr()` |
|
| 241 |
+//! - `asmjit::tword_ptr()` |
|
| 242 |
+//! - `asmjit::oword_ptr()` |
|
| 243 |
+//! - `asmjit::yword_ptr()` |
|
| 244 |
+//! - `asmjit::zword_ptr()` |
|
| 245 |
+//! |
|
| 246 |
+//! Most useful function to make pointer should be `asmjit::ptr()`. It creates |
|
| 247 |
+//! pointer to the target with unspecified size. Unspecified size works in all |
|
| 248 |
+//! intrinsics where are used registers (this means that size is specified by |
|
| 249 |
+//! register operand or by instruction itself). For example `asmjit::ptr()` |
|
| 250 |
+//! can't be used with `Assembler::inc()` instruction. In this case size must |
|
| 251 |
+//! be specified and it's also reason to make difference between pointer sizes. |
|
| 252 |
+//! |
|
| 253 |
+//! Supported are simple address forms `[base + displacement]` and complex |
|
| 254 |
+//! address forms `[base + index * scale + displacement]`. |
|
| 255 |
+//! |
|
| 256 |
+//! X86/X64 Immediates |
|
| 257 |
+//! ------------------ |
|
| 258 |
+//! |
|
| 259 |
+//! Immediate values are constants thats passed directly after instruction |
|
| 260 |
+//! opcode. To create such value use `imm()` or `imm_u()` methods to create |
|
| 261 |
+//! signed or unsigned immediate value. |
|
| 262 |
+//! |
|
| 263 |
+//! X86/X64 CPU Information |
|
| 264 |
+//! ----------------------- |
|
| 265 |
+//! |
|
| 266 |
+//! The CPUID instruction can be used to get an exhaustive information about |
|
| 267 |
+//! the host X86/X64 processor. AsmJit contains utilities that can get the most |
|
| 268 |
+//! important information related to the features supported by the CPU and the |
|
| 269 |
+//! host operating system, in addition to host processor name and number of |
|
| 270 |
+//! cores. Class `X86CpuInfo` extends `CpuInfo` and provides functionality |
|
| 271 |
+//! specific to X86 and X64. |
|
| 272 |
+//! |
|
| 273 |
+//! By default AsmJit queries the CPU information after the library is loaded |
|
| 274 |
+//! and the queried information is reused by all instances of `JitRuntime`. |
|
| 275 |
+//! The global instance of `X86CpuInfo` can't be changed, because it will affect |
|
| 276 |
+//! the code generation of all `Runtime`s. If there is a need to have a |
|
| 277 |
+//! specific CPU information which contains modified features or processor |
|
| 278 |
+//! vendor it's possible by creating a new instance of `X86CpuInfo` and setting |
|
| 279 |
+//! up its members. `X86CpuUtil::detect` can be used to detect CPU features into |
|
| 280 |
+//! an existing `X86CpuInfo` instance - it may become handly if only one property |
|
| 281 |
+//! has to be turned on/off. |
|
| 282 |
+//! |
|
| 283 |
+//! If the high-level interface `X86CpuInfo` offers is not enough there is also |
|
| 284 |
+//! `X86CpuUtil::callCpuId` helper that can be used to call CPUID instruction |
|
| 285 |
+//! with a given parameters and to consume the output. |
|
| 286 |
+//! |
|
| 287 |
+//! Cpu detection is important when generating a JIT code that may or may not |
|
| 288 |
+//! use certain CPU features. For example there used to be a SSE/SSE2 detection |
|
| 289 |
+//! in the past and today there is often AVX/AVX2 detection. |
|
| 290 |
+//! |
|
| 291 |
+//! The example below shows how to detect SSE2: |
|
| 292 |
+//! |
|
| 293 |
+//! ~~~ |
|
| 294 |
+//! using namespace asmjit; |
|
| 295 |
+//! |
|
| 296 |
+//! // Get `X86CpuInfo` global instance. |
|
| 297 |
+//! const X86CpuInfo* cpuInfo = X86CpuInfo::getHost(); |
|
| 298 |
+//! |
|
| 299 |
+//! if (cpuInfo->hasFeature(kX86CpuFeatureSse2)) {
|
|
| 300 |
+//! // Processor has SSE2. |
|
| 301 |
+//! } |
|
| 302 |
+//! else if (cpuInfo->hasFeature(kX86CpuFeatureMmx)) {
|
|
| 303 |
+//! // Processor doesn't have SSE2, but has MMX. |
|
| 304 |
+//! } |
|
| 305 |
+//! else {
|
|
| 306 |
+//! // Processor is archaic; it's a wonder AsmJit works here! |
|
| 307 |
+//! } |
|
| 308 |
+//! ~~~ |
|
| 309 |
+//! |
|
| 310 |
+//! The next example shows how to call `CPUID` directly: |
|
| 311 |
+//! |
|
| 312 |
+//! ~~~ |
|
| 313 |
+//! using namespace asmjit; |
|
| 314 |
+//! |
|
| 315 |
+//! // Call cpuid, first two arguments are passed in Eax/Ecx. |
|
| 316 |
+//! X86CpuId out; |
|
| 317 |
+//! X86CpuUtil::callCpuId(0, 0, &out); |
|
| 318 |
+//! |
|
| 319 |
+//! // If Eax argument is 0, Ebx, Ecx and Edx registers are filled with a cpu vendor. |
|
| 320 |
+//! char cpuVendor[13]; |
|
| 321 |
+//! ::memcpy(cpuVendor, &out.ebx, 4); |
|
| 322 |
+//! ::memcpy(cpuVendor + 4, &out.edx, 4); |
|
| 323 |
+//! ::memcpy(cpuVendor + 8, &out.ecx, 4); |
|
| 324 |
+//! vendor[12] = '\0'; |
|
| 325 |
+//! |
|
| 326 |
+//! // Print a CPU vendor retrieved from CPUID. |
|
| 327 |
+//! ::printf("%s", cpuVendor);
|
|
| 328 |
+//! ~~~ |
|
| 306 | 329 |
|
| 307 |
-//! @def ASMJIT_REALLOC |
|
| 308 |
-//! @brief Function to call to reallocate dynamic memory. |
|
| 330 |
+// ============================================================================ |
|
| 331 |
+// [asmjit_x86_compiler] |
|
| 332 |
+// ============================================================================ |
|
| 309 | 333 |
|
| 310 |
-//! @def ASMJIT_FREE |
|
| 311 |
-//! @brief Function to call to free dynamic memory. |
|
| 334 |
+//! \defgroup asmjit_x86_compiler X86/X64 Code-Tree |
|
| 335 |
+//! \ingroup asmjit_x86 |
|
| 336 |
+//! |
|
| 337 |
+//! \brief X86/X64 code-tree and helpers. |
|
| 312 | 338 |
|
| 313 |
-//! @def ASMJIT_ASSERT |
|
| 314 |
-//! @brief Assertion macro. Default implementation calls |
|
| 315 |
-//! @c AsmJit::assertionFailure() function. |
|
| 339 |
+// ============================================================================ |
|
| 340 |
+// [asmjit_x86_inst] |
|
| 341 |
+// ============================================================================ |
|
| 316 | 342 |
|
| 317 |
-//! @} |
|
| 343 |
+//! \defgroup asmjit_x86_inst X86/X64 Instructions |
|
| 344 |
+//! \ingroup asmjit_x86 |
|
| 345 |
+//! |
|
| 346 |
+//! \brief X86/X64 low-level instruction definitions. |
|
| 318 | 347 |
|
| 348 |
+// ============================================================================ |
|
| 349 |
+// [asmjit_x86_util] |
|
| 350 |
+// ============================================================================ |
|
| 319 | 351 |
|
| 320 |
-//! @namespace AsmJit |
|
| 321 |
-//! @brief Main AsmJit library namespace. |
|
| 352 |
+//! \defgroup asmjit_x86_util X86/X64 Utilities |
|
| 353 |
+//! \ingroup asmjit_x86 |
|
| 322 | 354 |
//! |
| 323 |
-//! There are not other namespaces used in AsmJit library. |
|
| 355 |
+//! \brief X86/X64 utility classes. |
|
| 324 | 356 |
|
| 325 |
-// ---------------------------------------------------------------------------- |
|
| 326 |
-// [Dependencies - Core] |
|
| 327 |
-// ---------------------------------------------------------------------------- |
|
| 357 |
+// ============================================================================ |
|
| 358 |
+// [asmjit_contrib] |
|
| 359 |
+// ============================================================================ |
|
| 328 | 360 |
|
| 329 |
-#include "core.h" |
|
| 361 |
+//! \defgroup asmjit_contrib Contributions |
|
| 362 |
+//! |
|
| 363 |
+//! \brief Contributions. |
|
| 330 | 364 |
|
| 331 |
-// ---------------------------------------------------------------------------- |
|
| 332 |
-// [Dependencies - X86 / X64] |
|
| 333 |
-// ---------------------------------------------------------------------------- |
|
| 365 |
+// [Dependencies - Base] |
|
| 366 |
+#include "base.h" |
|
| 334 | 367 |
|
| 335 |
-#if defined(ASMJIT_X86) || defined(ASMJIT_X64) |
|
| 368 |
+// [Dependencies - X86/X64] |
|
| 369 |
+#if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64) |
|
| 336 | 370 |
#include "x86.h" |
| 337 |
-#endif // ASMJIT_X86 || ASMJIT_X64 |
|
| 371 |
+#endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64 |
|
| 372 |
+ |
|
| 373 |
+// [Dependencies - Host] |
|
| 374 |
+#include "host.h" |
| ... | ... |
@@ -4,9 +4,7 @@ |
| 4 | 4 |
// [License] |
| 5 | 5 |
// Zlib - See COPYING file in this package. |
| 6 | 6 |
|
| 7 |
-// [Guard] |
|
| 8 |
-#ifndef _ASMJIT_ASMJIT_H |
|
| 9 |
-#define _ASMJIT_ASMJIT_H |
|
| 7 |
+#pragma once |
|
| 10 | 8 |
|
| 11 | 9 |
//! @mainpage |
| 12 | 10 |
//! |
| ... | ... |
@@ -337,6 +335,3 @@ |
| 337 | 335 |
#if defined(ASMJIT_X86) || defined(ASMJIT_X64) |
| 338 | 336 |
#include "x86.h" |
| 339 | 337 |
#endif // ASMJIT_X86 || ASMJIT_X64 |
| 340 |
- |
|
| 341 |
-// [Guard] |
|
| 342 |
-#endif // _ASMJIT_ASMJIT_H |
| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,342 @@ |
| 1 |
+// [AsmJit] |
|
| 2 |
+// Complete JIT Assembler for C++ Language. |
|
| 3 |
+// |
|
| 4 |
+// [License] |
|
| 5 |
+// Zlib - See COPYING file in this package. |
|
| 6 |
+ |
|
| 7 |
+// [Guard] |
|
| 8 |
+#ifndef _ASMJIT_ASMJIT_H |
|
| 9 |
+#define _ASMJIT_ASMJIT_H |
|
| 10 |
+ |
|
| 11 |
+//! @mainpage |
|
| 12 |
+//! |
|
| 13 |
+//! @brief AsmJit is a complete x86/x64 JIT Assembler for C++ language. |
|
| 14 |
+//! |
|
| 15 |
+//! It supports FPU, MMX, 3dNow, SSE, SSE2, SSE3 and SSE4 intrinsics, powerful |
|
| 16 |
+//! compiler that helps to write portable functions for 32-bit (x86) and 64-bit |
|
| 17 |
+//! (x64) architectures. AsmJit can be used to create functions at runtime that |
|
| 18 |
+//! can be called from existing (but also generated) C/C++ code. |
|
| 19 |
+//! |
|
| 20 |
+//! AsmJit is a cross-platform library that supports various compilers and |
|
| 21 |
+//! operating systems. Currently only limitation is x86 (32-bit) or x64 (64-bit) |
|
| 22 |
+//! processor. Currently tested operating systems are Windows (32-bit and 64-bit), |
|
| 23 |
+//! Linux (32-bit and 64-bit) and MacOSX (32-bit and 64-bit). |
|
| 24 |
+//! |
|
| 25 |
+//! @section AsmJit_Main_Introduction Introduction |
|
| 26 |
+//! |
|
| 27 |
+//! AsmJit library contains two main classes for code generation with different |
|
| 28 |
+//! goals. First main code generation class is called @c AsmJit::Assembler and |
|
| 29 |
+//! contains low level API that can be used to generate JIT binary code. It |
|
| 30 |
+//! directly emits binary stream that represents encoded x86/x64 assembler |
|
| 31 |
+//! opcodes. Together with operands and labels it can be used to generate |
|
| 32 |
+//! complete code. For details look to @ref AsmJit_Core and @ref AsmJit_Compiler |
|
| 33 |
+//! sections. |
|
| 34 |
+//! |
|
| 35 |
+//! There is also class named @c AsmJit::Compiler that allows to develop |
|
| 36 |
+//! cross-platform assembler code without worring about function calling |
|
| 37 |
+//! conventions and registers allocation. It can be also used to write 32-bit |
|
| 38 |
+//! and 64-bit portable code. Compiler is recommended class to use for code |
|
| 39 |
+//! generation. |
|
| 40 |
+//! |
|
| 41 |
+//! Everything in AsmJit library is in @c AsmJit namespace. |
|
| 42 |
+//! |
|
| 43 |
+//! @section AsmJit_Main_CodeGeneration Code Generation |
|
| 44 |
+//! |
|
| 45 |
+//! - @ref AsmJit_Core "Assembler core" - Operands, intrinsics and low-level assembler. |
|
| 46 |
+//! - @ref AsmJit_Compiler "Compiler" - High level code generation. |
|
| 47 |
+//! - @ref AsmJit_CpuInfo "Cpu Information" - Get information about host processor. |
|
| 48 |
+//! - @ref AsmJit_Logging "Logging" - Logging and error handling. |
|
| 49 |
+//! - @ref AsmJit_MemoryManagement "Memory Management" - Virtual memory management. |
|
| 50 |
+//! |
|
| 51 |
+//! @section AsmJit_Main_Configuration Configuration, Definitions and Utilities |
|
| 52 |
+//! |
|
| 53 |
+//! - @ref AsmJit_Config "Configuration" - Macros used to configure AsmJit. |
|
| 54 |
+//! |
|
| 55 |
+//! @section AsmJit_Main_HomePage AsmJit Homepage |
|
| 56 |
+//! |
|
| 57 |
+//! - http://code.google.com/p/asmjit/ |
|
| 58 |
+//! |
|
| 59 |
+//! @section AsmJit_Main_ResourcesX86 External X86/X64 Assembler Resources |
|
| 60 |
+//! - http://www.agner.org/optimize/ |
|
| 61 |
+//! - http://www.mark.masmcode.com/ (Assembler Tips) |
|
| 62 |
+//! - http://avisynth.org/mediawiki/Filter_SDK/Assembler_optimizing (Optimizing) |
|
| 63 |
+//! - http://www.ragestorm.net/distorm/ (Disassembling) |
|
| 64 |
+//! |
|
| 65 |
+//! @section AsmJit_Main_Terminology Terminology |
|
| 66 |
+//! |
|
| 67 |
+//! - <b>Non-volatile (preserved) register</b> - Register that can't be changed |
|
| 68 |
+//! by callee (callee must save and restore it if it want to use it inside). |
|
| 69 |
+//! |
|
| 70 |
+//! - <b>Volatile (non-preserved) register</b> - The opossite. Register that can |
|
| 71 |
+//! be freely used by callee. The caller must free all registers before calling |
|
| 72 |
+//! other function. |
|
| 73 |
+ |
|
| 74 |
+ |
|
| 75 |
+//! @defgroup AsmJit_Core Assembler core (operands, intrinsics and low-level assembler). |
|
| 76 |
+//! |
|
| 77 |
+//! Contains classes related to @c AsmJit::Assembler that're directly used |
|
| 78 |
+//! to generate machine code stream. It's one of oldest and fastest method |
|
| 79 |
+//! to generate machine code using AsmJit library. |
|
| 80 |
+//! |
|
| 81 |
+//! - See @c AsmJit::Assembler class for low level code generation |
|
| 82 |
+//! documentation. |
|
| 83 |
+//! - See @c AsmJit::Operand for AsmJit operand's overview. |
|
| 84 |
+//! |
|
| 85 |
+//! @section AsmJit_Core_Registers Registers |
|
| 86 |
+//! |
|
| 87 |
+//! There are static objects that represents X86 and X64 registers. They can |
|
| 88 |
+//! be used directly (like @c eax, @c mm, @c xmm, ...) or created through |
|
| 89 |
+//! these functions: |
|
| 90 |
+//! |
|
| 91 |
+//! - @c AsmJit::mk_gpb() - make general purpose byte register |
|
| 92 |
+//! - @c AsmJit::mk_gpw() - make general purpose word register |
|
| 93 |
+//! - @c AsmJit::mk_gpd() - make general purpose dword register |
|
| 94 |
+//! - @c AsmJit::mk_gpq() - make general purpose qword register |
|
| 95 |
+//! - @c AsmJit::mk_mm() - make mmx register |
|
| 96 |
+//! - @c AsmJit::mk_xmm() - make sse register |
|
| 97 |
+//! - @c AsmJit::st() - make x87 register |
|
| 98 |
+//! |
|
| 99 |
+//! @section AsmJit_Core_Addressing Addressing |
|
| 100 |
+//! |
|
| 101 |
+//! X86 and x64 architectures contains several addressing modes and most ones |
|
| 102 |
+//! are possible with AsmJit library. Memory represents are represented by |
|
| 103 |
+//! @c AsmJit::Mem class. These functions are used to make operands that |
|
| 104 |
+//! represents memory addresses: |
|
| 105 |
+//! |
|
| 106 |
+//! - @c AsmJit::ptr() |
|
| 107 |
+//! - @c AsmJit::byte_ptr() |
|
| 108 |
+//! - @c AsmJit::word_ptr() |
|
| 109 |
+//! - @c AsmJit::dword_ptr() |
|
| 110 |
+//! - @c AsmJit::qword_ptr() |
|
| 111 |
+//! - @c AsmJit::tword_ptr() |
|
| 112 |
+//! - @c AsmJit::dqword_ptr() |
|
| 113 |
+//! - @c AsmJit::mmword_ptr() |
|
| 114 |
+//! - @c AsmJit::xmmword_ptr() |
|
| 115 |
+//! - @c AsmJit::sysint_ptr() |
|
| 116 |
+//! |
|
| 117 |
+//! Most useful function to make pointer should be @c AsmJit::ptr(). It creates |
|
| 118 |
+//! pointer to the target with unspecified size. Unspecified size works in all |
|
| 119 |
+//! intrinsics where are used registers (this means that size is specified by |
|
| 120 |
+//! register operand or by instruction itself). For example @c AsmJit::ptr() |
|
| 121 |
+//! can't be used with @c AsmJit::Assembler::inc() instruction. In this case |
|
| 122 |
+//! size must be specified and it's also reason to make difference between |
|
| 123 |
+//! pointer sizes. |
|
| 124 |
+//! |
|
| 125 |
+//! Supported are simple address forms (register + displacement) and complex |
|
| 126 |
+//! address forms (register + (register << shift) + displacement). |
|
| 127 |
+//! |
|
| 128 |
+//! @section AsmJit_Core_Immediates Immediates |
|
| 129 |
+//! |
|
| 130 |
+//! Immediate values are constants thats passed directly after instruction |
|
| 131 |
+//! opcode. To create such value use @c AsmJit::imm() or @c AsmJit::uimm() |
|
| 132 |
+//! methods to create signed or unsigned immediate value. |
|
| 133 |
+//! |
|
| 134 |
+//! @sa @c AsmJit::Compiler. |
|
| 135 |
+ |
|
| 136 |
+ |
|
| 137 |
+//! @defgroup AsmJit_Compiler Compiler (high-level code generation). |
|
| 138 |
+//! |
|
| 139 |
+//! Contains classes related to @c AsmJit::Compiler that can be used |
|
| 140 |
+//! to generate code using high-level constructs. |
|
| 141 |
+//! |
|
| 142 |
+//! - See @c Compiler class for high level code generation |
|
| 143 |
+//! documentation - calling conventions, function declaration |
|
| 144 |
+//! and variables management. |
|
| 145 |
+ |
|
| 146 |
+//! @defgroup AsmJit_Config Configuration. |
|
| 147 |
+//! |
|
| 148 |
+//! Contains macros that can be redefined to fit into any project. |
|
| 149 |
+ |
|
| 150 |
+ |
|
| 151 |
+//! @defgroup AsmJit_CpuInfo CPU information. |
|
| 152 |
+//! |
|
| 153 |
+//! X86 or x64 cpuid instruction allows to get information about processor |
|
| 154 |
+//! vendor and it's features. It's always used to detect features like MMX, |
|
| 155 |
+//! SSE and other newer ones. |
|
| 156 |
+//! |
|
| 157 |
+//! AsmJit library supports low level cpuid call implemented internally as |
|
| 158 |
+//! C++ function using inline assembler or intrinsics and also higher level |
|
| 159 |
+//! CPU features detection. The low level function (also used by higher level |
|
| 160 |
+//! one) is @c AsmJit::cpuid(). |
|
| 161 |
+//! |
|
| 162 |
+//! AsmJit library also contains higher level function @c AsmJit::getCpuInfo() |
|
| 163 |
+//! that returns features detected by the library. The detection process is |
|
| 164 |
+//! done only once and it's cached for all next calls. @c AsmJit::CpuInfo |
|
| 165 |
+//! structure not contains only information through @c AsmJit::cpuid(), but |
|
| 166 |
+//! there is also small multiplatform code to detect number of processors |
|
| 167 |
+//! (or cores) through operating system API. |
|
| 168 |
+//! |
|
| 169 |
+//! It's recommended to use @c AsmJit::cpuInfo to detect and check for |
|
| 170 |
+//! host processor features. |
|
| 171 |
+//! |
|
| 172 |
+//! Example how to use AsmJit::cpuid(): |
|
| 173 |
+//! |
|
| 174 |
+//! @code |
|
| 175 |
+//! // All functions and structures are in AsmJit namesapce. |
|
| 176 |
+//! using namespace AsmJit; |
|
| 177 |
+//! |
|
| 178 |
+//! // Here will be retrieved result of cpuid call. |
|
| 179 |
+//! CpuId out; |
|
| 180 |
+//! |
|
| 181 |
+//! // Use cpuid function to do the job. |
|
| 182 |
+//! cpuid(0 /* eax */, &out /* eax, ebx, ecx, edx */); |
|
| 183 |
+//! |
|
| 184 |
+//! // Id eax argument to cpuid is 0, ebx, ecx and edx registers |
|
| 185 |
+//! // are filled with cpu vendor. |
|
| 186 |
+//! char vendor[13]; |
|
| 187 |
+//! memcpy(i->vendor, &out.ebx, 4); |
|
| 188 |
+//! memcpy(i->vendor + 4, &out.edx, 4); |
|
| 189 |
+//! memcpy(i->vendor + 8, &out.ecx, 4); |
|
| 190 |
+//! vendor[12] = '\0'; |
|
| 191 |
+//! |
|
| 192 |
+//! // Print vendor |
|
| 193 |
+//! puts(vendor); |
|
| 194 |
+//! @endcode |
|
| 195 |
+//! |
|
| 196 |
+//! If you want to use AsmJit::cpuid() function instead of higher level |
|
| 197 |
+//! @c AsmJit::getCpuInfo(), please read processor manuals provided by Intel, |
|
| 198 |
+//! AMD or other manufacturers for cpuid instruction details. |
|
| 199 |
+//! |
|
| 200 |
+//! Example of using @c AsmJit::getCpuInfo(): |
|
| 201 |
+//! |
|
| 202 |
+//! @code |
|
| 203 |
+//! // All functions and structures are in AsmJit namesapce. |
|
| 204 |
+//! using namespace AsmJit; |
|
| 205 |
+//! |
|
| 206 |
+//! // Call to cpuInfo return CpuInfo structure that shouldn't be modified. |
|
| 207 |
+//! // Make it const by default. |
|
| 208 |
+//! const CpuInfo *i = getCpuInfo(); |
|
| 209 |
+//! |
|
| 210 |
+//! // Now you are able to get specific features. |
|
| 211 |
+//! |
|
| 212 |
+//! // Processor has SSE2 |
|
| 213 |
+//! if (i->features & kX86FeatureSse2) |
|
| 214 |
+//! {
|
|
| 215 |
+//! // your code... |
|
| 216 |
+//! } |
|
| 217 |
+//! // Processor has MMX |
|
| 218 |
+//! else if (i->features & kX86Feature_MMX) |
|
| 219 |
+//! {
|
|
| 220 |
+//! // your code... |
|
| 221 |
+//! } |
|
| 222 |
+//! // Processor is old, no SSE2 or MMX support. |
|
| 223 |
+//! else |
|
| 224 |
+//! {
|
|
| 225 |
+//! // your code... |
|
| 226 |
+//! } |
|
| 227 |
+//! @endcode |
|
| 228 |
+//! |
|
| 229 |
+//! Better example is in AsmJit/Test/testcpu.cpp file. |
|
| 230 |
+//! |
|
| 231 |
+//! @sa AsmJit::cpuid, @c AsmJit::cpuInfo. |
|
| 232 |
+ |
|
| 233 |
+ |
|
| 234 |
+//! @defgroup AsmJit_Logging Logging and error handling. |
|
| 235 |
+//! |
|
| 236 |
+//! Contains classes related to loging assembler output. Currently logging |
|
| 237 |
+//! is implemented in @c AsmJit::Logger class.You can override |
|
| 238 |
+//! @c AsmJit::Logger::log() to log messages into your stream. There is also |
|
| 239 |
+//! @c FILE based logger implemented in @c AsmJit::FileLogger class. |
|
| 240 |
+//! |
|
| 241 |
+//! To log your assembler output to FILE stream use this code: |
|
| 242 |
+//! |
|
| 243 |
+//! @code |
|
| 244 |
+//! // Create assembler |
|
| 245 |
+//! Assembler a; |
|
| 246 |
+//! |
|
| 247 |
+//! // Create and set file based logger |
|
| 248 |
+//! FileLogger logger(stderr); |
|
| 249 |
+//! a.setLogger(&logger); |
|
| 250 |
+//! @endcode |
|
| 251 |
+//! |
|
| 252 |
+//! You can see that logging goes through @c Assembler. If you are using |
|
| 253 |
+//! @c Compiler and you want to log messages in correct assembler order, |
|
| 254 |
+//! you should look at @ref Compiler::comment() method. It allows you to |
|
| 255 |
+//! insert text message into items stream so the @c Compiler is able to |
|
| 256 |
+//! send messages to @ref Assembler in correct order. |
|
| 257 |
+//! |
|
| 258 |
+//! @sa @c AsmJit::Logger, @c AsmJit::FileLogger. |
|
| 259 |
+ |
|
| 260 |
+ |
|
| 261 |
+//! @defgroup AsmJit_MemoryManagement Virtual memory management. |
|
| 262 |
+//! |
|
| 263 |
+//! Using @c AsmJit::Assembler or @c AsmJit::Compiler to generate machine |
|
| 264 |
+//! code is not final step. Each generated code needs to run in memory |
|
| 265 |
+//! that is not protected against code execution. To alloc this code it's |
|
| 266 |
+//! needed to use operating system functions provided to enable execution |
|
| 267 |
+//! code in specified memory block or to allocate memory that is not |
|
| 268 |
+//! protected. The solution is always to use @c See AsmJit::Assembler::make() |
|
| 269 |
+//! and @c AsmJit::Compiler::make() functions that can allocate memory and |
|
| 270 |
+//! relocate code for you. But AsmJit also contains classes for manual memory |
|
| 271 |
+//! management thats internally used by AsmJit but can be used by programmers |
|
| 272 |
+//! too. |
|
| 273 |
+//! |
|
| 274 |
+//! Memory management contains low level and high level classes related to |
|
| 275 |
+//! allocating and freeing virtual memory. Low level class is |
|
| 276 |
+//! @c AsmJit::VirtualMemory that can allocate and free full pages of |
|
| 277 |
+//! virtual memory provided by operating system. Higher level class is |
|
| 278 |
+//! @c AsmJit::MemoryManager that is able to manage complete allocation and |
|
| 279 |
+//! free mechanism. It internally uses larger chunks of memory to make |
|
| 280 |
+//! allocation fast and effective. |
|
| 281 |
+//! |
|
| 282 |
+//! Using @c AsmJit::VirtualMemory::alloc() is cross-platform way how to |
|
| 283 |
+//! allocate this kind of memory without worrying about operating system |
|
| 284 |
+//! and it's API. Each memory block that is no longer needed should be |
|
| 285 |
+//! freed by @c AsmJit::VirtualMemory::free() method. If you want better |
|
| 286 |
+//! comfort and malloc()/free() interface, look at the |
|
| 287 |
+//! @c AsmJit::MemoryManager class. |
|
| 288 |
+//! |
|
| 289 |
+//! @sa @c AsmJit::VirtualMemory, @ AsmJit::MemoryManager. |
|
| 290 |
+ |
|
| 291 |
+ |
|
| 292 |
+//! @addtogroup AsmJit_Config |
|
| 293 |
+//! @{
|
|
| 294 |
+ |
|
| 295 |
+//! @def ASMJIT_WINDOWS |
|
| 296 |
+//! @brief Macro that is declared if AsmJit is compiled for Windows. |
|
| 297 |
+ |
|
| 298 |
+//! @def ASMJIT_POSIX |
|
| 299 |
+//! @brief Macro that is declared if AsmJit is compiled for unix like |
|
| 300 |
+//! operating system. |
|
| 301 |
+ |
|
| 302 |
+//! @def ASMJIT_API |
|
| 303 |
+//! @brief Attribute that's added to classes that can be exported if AsmJit |
|
| 304 |
+//! is compiled as a dll library. |
|
| 305 |
+ |
|
| 306 |
+//! @def ASMJIT_MALLOC |
|
| 307 |
+//! @brief Function to call to allocate dynamic memory. |
|
| 308 |
+ |
|
| 309 |
+//! @def ASMJIT_REALLOC |
|
| 310 |
+//! @brief Function to call to reallocate dynamic memory. |
|
| 311 |
+ |
|
| 312 |
+//! @def ASMJIT_FREE |
|
| 313 |
+//! @brief Function to call to free dynamic memory. |
|
| 314 |
+ |
|
| 315 |
+//! @def ASMJIT_ASSERT |
|
| 316 |
+//! @brief Assertion macro. Default implementation calls |
|
| 317 |
+//! @c AsmJit::assertionFailure() function. |
|
| 318 |
+ |
|
| 319 |
+//! @} |
|
| 320 |
+ |
|
| 321 |
+ |
|
| 322 |
+//! @namespace AsmJit |
|
| 323 |
+//! @brief Main AsmJit library namespace. |
|
| 324 |
+//! |
|
| 325 |
+//! There are not other namespaces used in AsmJit library. |
|
| 326 |
+ |
|
| 327 |
+// ---------------------------------------------------------------------------- |
|
| 328 |
+// [Dependencies - Core] |
|
| 329 |
+// ---------------------------------------------------------------------------- |
|
| 330 |
+ |
|
| 331 |
+#include "core.h" |
|
| 332 |
+ |
|
| 333 |
+// ---------------------------------------------------------------------------- |
|
| 334 |
+// [Dependencies - X86 / X64] |
|
| 335 |
+// ---------------------------------------------------------------------------- |
|
| 336 |
+ |
|
| 337 |
+#if defined(ASMJIT_X86) || defined(ASMJIT_X64) |
|
| 338 |
+#include "x86.h" |
|
| 339 |
+#endif // ASMJIT_X86 || ASMJIT_X64 |
|
| 340 |
+ |
|
| 341 |
+// [Guard] |
|
| 342 |
+#endif // _ASMJIT_ASMJIT_H |