|
| 1 | +// AsmJit - Complete JIT Assembler for C++ Language. |
| 2 | + |
| 3 | +// Copyright (c) 2008-2009, Petr Kobalicek <kobalicek.petr@gmail.com> |
| 4 | +// |
| 5 | +// Permission is hereby granted, free of charge, to any person |
| 6 | +// obtaining a copy of this software and associated documentation |
| 7 | +// files (the "Software"), to deal in the Software without |
| 8 | +// restriction, including without limitation the rights to use, |
| 9 | +// copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 10 | +// copies of the Software, and to permit persons to whom the |
| 11 | +// Software is furnished to do so, subject to the following |
| 12 | +// conditions: |
| 13 | +// |
| 14 | +// The above copyright notice and this permission notice shall be |
| 15 | +// included in all copies or substantial portions of the Software. |
| 16 | +// |
| 17 | +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| 18 | +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
| 19 | +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| 20 | +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
| 21 | +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
| 22 | +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| 23 | +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| 24 | +// OTHER DEALINGS IN THE SOFTWARE. |
| 25 | + |
| 26 | +// [Guard] |
| 27 | +#ifndef _ASMJIT_H |
| 28 | +#define _ASMJIT_H |
| 29 | + |
| 30 | +//! @mainpage |
| 31 | +//! |
| 32 | +//! @brief AsmJit is complete x86/x64 JIT Assembler for C++ language |
| 33 | +//! |
| 34 | +//! It supports FPU, MMX, 3dNow, SSE, SSE2, SSE3 and SSE4 intrinsics, powerful |
| 35 | +//! compiler that helps to write portable functions for 32-bit (x86) and 64-bit |
| 36 | +//! (x64) architectures. AsmJit can be used to create functions at runtime that |
| 37 | +//! can be called from existing (but also generated) C/C++ code. |
| 38 | +//! |
| 39 | +//! AsmJit is crossplatform library that supports various compilers and |
| 40 | +//! operating systems. Currently only limitation is x86 (32-bit) or x64 (64-bit) |
| 41 | +//! processor. Currently tested operating systems are Windows (32 bit and 64 bit), |
| 42 | +//! Linux (32 bit and 64 bit) and MacOSX (32 bit). |
| 43 | +//! |
| 44 | +//! <b>Introduction</b> |
| 45 | +//! |
| 46 | +//! AsmJit library contains two main classes for code generation with different |
| 47 | +//! goals. First main code generation class is called @c AsmJit::Assembler and |
| 48 | +//! contains low level API that can be used to generate JIT binary code. It |
| 49 | +//! directly emits binary stream that represents encoded x86/x64 assembler |
| 50 | +//! opcodes. Together with operands and labels it can be used to generate |
| 51 | +//! complete code. For details look to @ref AsmJit_Serializer and |
| 52 | +//! @ref AsmJit_Assembler sections. |
| 53 | +//! |
| 54 | +//! There is also class named @c AsmJit::Compiler that allows to develop |
| 55 | +//! crossplatform assembler code without worring about function calling |
| 56 | +//! conventions and registers allocation. It can be also used to write 32 |
| 57 | +//! bit and 64 bit portable code. Compiler is recommended class to use for |
| 58 | +//! code generation. If you want to use pure @c AsmJit::Compiler solution, |
| 59 | +//! it's needed also to look at @c AsmJit::Assembler and @c AsmJit::Serializer |
| 60 | +//! classes to understand how AsmJit library works and how you should use |
| 61 | +//! its API. |
| 62 | +//! |
| 63 | +//! Everything in AsmJit library is in @c AsmJit namespace. |
| 64 | +//! |
| 65 | +//! <b>Code generation sections:</b> |
| 66 | +//! |
| 67 | +//! - @ref AsmJit_Serializer "Serializer" - Intrinsics, operands and labels. |
| 68 | +//! - @ref AsmJit_Assembler "Assembler" - Low level code generation. |
| 69 | +//! - @ref AsmJit_Compiler "Compiler" - High level code generation. |
| 70 | +//! - @ref AsmJit_CpuInfo "Cpu Informations" - Get informations about host processor. |
| 71 | +//! - @ref AsmJit_Logging "Logging" - Logging and error handling. |
| 72 | +//! - @ref AsmJit_MemoryManagement "Memory Management" - Virtual memory management. |
| 73 | +//! |
| 74 | +//! <b>Configuration, definitions and utilities:</b> |
| 75 | +//! |
| 76 | +//! - @ref AsmJit_Config "Configuration" - Macros used to configure AsmJit. |
| 77 | +//! - @ref AsmJit_Defs "Definitions" - Constants and macros. |
| 78 | +//! - @ref AsmJit_Util "Utilities" - Utilities and helper classes. |
| 79 | +//! |
| 80 | +//! <b>AsmJit homepage:</b> |
| 81 | +//! - http://code.google.com/p/asmjit/ |
| 82 | +//! |
| 83 | +//! <b>External resources:</b> |
| 84 | +//! - http://www.agner.org/optimize/ |
| 85 | +//! - http://www.mark.masmcode.com/ (Assembler Tips) |
| 86 | +//! - http://avisynth.org/mediawiki/Filter_SDK/Assembler_optimizing (Optimizing) |
| 87 | +//! - http://www.ragestorm.net/distorm/ (Disassembling) |
| 88 | + |
| 89 | + |
| 90 | +//! @defgroup AsmJit_Assembler Assembler - low level code generation. |
| 91 | +//! |
| 92 | +//! Contains classes related to @c AsmJit::Assembler that is directly used |
| 93 | +//! to generate machine code stream. It's one of oldest and fastest method |
| 94 | +//! to generate machine code through AsmJit library. |
| 95 | +//! |
| 96 | +//! - See @c AsmJit::Serializer class for intrinsics and operands |
| 97 | +//! documentation. |
| 98 | +//! - See @c AsmJit::Assembler class for low level code generation |
| 99 | +//! documentation. |
| 100 | + |
| 101 | + |
| 102 | +//! @defgroup AsmJit_Compiler Compiler - high level code generation. |
| 103 | +//! |
| 104 | +//! Contains classes related to @c AsmJit::Compiler that is high level code |
| 105 | +//! generation class. |
| 106 | +//! |
| 107 | +//! - See @c AsmJit::Serializer class for intrinsics and operands |
| 108 | +//! documentation. |
| 109 | +//! - See @c AsmJit::Assembler class for low level code generation |
| 110 | +//! and documentation for assembler operands. |
| 111 | +//! - See @c AsmJit::Compiler class for high level code generation |
| 112 | +//! documentation - calling conventions, function declaration |
| 113 | +//! and variables management. |
| 114 | + |
| 115 | +//! @defgroup AsmJit_Config Configuration - macros used to configure AsmJit. |
| 116 | +//! library. |
| 117 | +//! |
| 118 | +//! Contains macros that can be redefined to fit into any project. |
| 119 | + |
| 120 | + |
| 121 | +//! @defgroup AsmJit_CpuInfo Cpu informations - Get informations about host |
| 122 | +//! processor. |
| 123 | +//! |
| 124 | +//! X86 or x64 cpuid instruction allows to get information about processor |
| 125 | +//! vendor and it's features. It's always used to detect features like MMX, |
| 126 | +//! SSE and other newer ones. |
| 127 | +//! |
| 128 | +//! AsmJit library supports low level cpuid call implemented internally as |
| 129 | +//! C++ function using inline assembler or intrinsics and also higher level |
| 130 | +//! CPU features detection. The low level function (also used by higher level |
| 131 | +//! one) is @c AsmJit::cpuid(). |
| 132 | +//! |
| 133 | +//! AsmJit library also contains higher level function @c AsmJit::cpuInfo() |
| 134 | +//! that returns features detected by the library. The detection process is |
| 135 | +//! done only once and it's cached for all next calls. @c AsmJit::CpuInfo |
| 136 | +//! structure not contains only informations through @c AsmJit::cpuid(), but |
| 137 | +//! there is also small multiplatform code to detect number of processors |
| 138 | +//! (or cores) throught operating system API. |
| 139 | +//! |
| 140 | +//! It's recommended to use @c AsmJit::cpuInfo to detect and check for |
| 141 | +//! host processor features. |
| 142 | +//! |
| 143 | +//! Example how to use AsmJit::cpuid(): |
| 144 | +//! |
| 145 | +//! @code |
| 146 | +//! // All functions and structures are in AsmJit namesapce. |
| 147 | +//! using namespace AsmJit; |
| 148 | +//! |
| 149 | +//! // Here will be retrieved result of cpuid call. |
| 150 | +//! CpuId out; |
| 151 | +//! |
| 152 | +//! // Use cpuid function to do the job. |
| 153 | +//! cpuid(0 /* eax */, &out /* eax, ebx, ecx, edx */); |
| 154 | +//! |
| 155 | +//! // Id eax argument to cpuid is 0, ebx, ecx and edx registers |
| 156 | +//! // are filled with cpu vendor. |
| 157 | +//! char vendor[13]; |
| 158 | +//! memcpy(i->vendor, &out.ebx, 4); |
| 159 | +//! memcpy(i->vendor + 4, &out.edx, 4); |
| 160 | +//! memcpy(i->vendor + 8, &out.ecx, 4); |
| 161 | +//! vendor[12] = '\0'; |
| 162 | +//! |
| 163 | +//! // Print vendor |
| 164 | +//! puts(vendor); |
| 165 | +//! @endcode |
| 166 | +//! |
| 167 | +//! If you want to use AsmJit::cpuid() function instead of higher level |
| 168 | +//! @c AsmJit::cpuInfo(), please read processor manuals provided by Intel, |
| 169 | +//! AMD or other manufacturers for cpuid instruction details. |
| 170 | +//! |
| 171 | +//! Example of using @c AsmJit::cpuInfo(): |
| 172 | +//! |
| 173 | +//! @code |
| 174 | +//! // All functions and structures are in AsmJit namesapce. |
| 175 | +//! using namespace AsmJit; |
| 176 | +//! |
| 177 | +//! // Call to cpuInfo return CpuInfo structure that shouldn't be modified. |
| 178 | +//! // Make it const by default. |
| 179 | +//! const CpuInfo *i = cpuInfo(); |
| 180 | +//! |
| 181 | +//! // Now you are able to get specific features |
| 182 | +//! |
| 183 | +//! // Processor has SSE2 |
| 184 | +//! if (i->features & CpuInfo::Feature_SSE2) |
| 185 | +//! { |
| 186 | +//! // your code... |
| 187 | +//! } |
| 188 | +//! // Processor has MMX |
| 189 | +//! else if (i->features & CpuInfo::Feature_MMX) |
| 190 | +//! { |
| 191 | +//! // your code... |
| 192 | +//! } |
| 193 | +//! // Processor is old, no SSE2 or MMX support |
| 194 | +//! else |
| 195 | +//! { |
| 196 | +//! // your code... |
| 197 | +//! } |
| 198 | +//! @endcode |
| 199 | +//! |
| 200 | +//! Better example is in AsmJit/test/testcpu.cpp file. |
| 201 | +//! |
| 202 | +//! @sa AsmJit::cpuid, @c AsmJit::cpuInfo. |
| 203 | + |
| 204 | + |
| 205 | +//! @defgroup AsmJit_Defs Definitions - registers and instructions constants. |
| 206 | +//! |
| 207 | +//! Contains constants used in AsmJit library. |
| 208 | + |
| 209 | + |
| 210 | +//! @defgroup AsmJit_Logging Logging - logging and error handling. |
| 211 | +//! |
| 212 | +//! Contains classes related to loging assembler output. Currently logging |
| 213 | +//! is implemented in @c AsmJit::Logger class.You can override |
| 214 | +//! @c AsmJit::Logger::log() to log messages into your stream. There is also |
| 215 | +//! @c FILE based logger implemented in @c AsmJit::FileLogger class. |
| 216 | +//! |
| 217 | +//! To log your assembler output to FILE stream use this code: |
| 218 | +//! |
| 219 | +//! @code |
| 220 | +//! // Create assembler |
| 221 | +//! Assembler a; |
| 222 | +//! |
| 223 | +//! // Create and set file based logger |
| 224 | +//! FileLogger logger(stderr); |
| 225 | +//! a.setLogger(&logger); |
| 226 | +//! @endcode |
| 227 | +//! |
| 228 | +//! You can see that logging goes through @c AsmJit::Assembler. If you are |
| 229 | +//! using @c AsmJit::Compiler and you want to log messages in correct assembler |
| 230 | +//! order, you should look at @c AsmJit::Compiler::comment() method. It allows |
| 231 | +//! you to insert text message into @c AsmJit::Emittable list and |
| 232 | +//! @c AsmJit::Compiler will send your message to @c AsmJit::Assembler in |
| 233 | +//! correct order. |
| 234 | +//! |
| 235 | +//! @sa @c AsmJit::Logger, @c AsmJit::FileLogger. |
| 236 | + |
| 237 | + |
| 238 | +//! @defgroup AsmJit_Serializer Serializer - code generation intrinsics. |
| 239 | +//! |
| 240 | +//! Serializer implements assembler intrinsics that's used by @c Assembler |
| 241 | +//! and @c Compiler classes. Intrinsics are implemented as overloaded methods |
| 242 | +//! of @c AsmJit::Serializer class. This section also contains all assembler |
| 243 | +//! primitives used to generate machine code. |
| 244 | +//! |
| 245 | +//! <b>Registers</b> |
| 246 | +//! |
| 247 | +//! There are static objects that represents X86 and X64 registers. They can |
| 248 | +//! be used directly (like @c eax, @c mm, @c xmm, ...) or created through |
| 249 | +//! these functions: |
| 250 | +//! |
| 251 | +//! - @c AsmJit::mk_gpb() - make general purpose byte register |
| 252 | +//! - @c AsmJit::mk_gpw() - make general purpose word register |
| 253 | +//! - @c AsmJit::mk_gpd() - make general purpose dword register |
| 254 | +//! - @c AsmJit::mk_gpq() - make general purpose qword register |
| 255 | +//! - @c AsmJit::mk_mm() - make mmx register |
| 256 | +//! - @c AsmJit::mk_xmm() - make sse register |
| 257 | +//! - @c AsmJit::st() - make x87 register |
| 258 | +//! |
| 259 | +//! <b>Addressing</b> |
| 260 | +//! |
| 261 | +//! X86 and x64 architectures contains several addressing modes and most ones |
| 262 | +//! are possible with AsmJit library. Memory represents are represented by |
| 263 | +//! @c AsmJit::Mem class. These functions are used to make operands that |
| 264 | +//! represents memory addresses: |
| 265 | +//! |
| 266 | +//! - @c AsmJit::ptr() |
| 267 | +//! - @c AsmJit::byte_ptr() |
| 268 | +//! - @c AsmJit::word_ptr() |
| 269 | +//! - @c AsmJit::dword_ptr() |
| 270 | +//! - @c AsmJit::qword_ptr() |
| 271 | +//! - @c AsmJit::tword_ptr() |
| 272 | +//! - @c AsmJit::dqword_ptr() |
| 273 | +//! - @c AsmJit::mmword_ptr() |
| 274 | +//! - @c AsmJit::xmmword_ptr() |
| 275 | +//! - @c AsmJit::sysint_ptr() |
| 276 | +//! |
| 277 | +//! Most useful function to make pointer should be @c AsmJit::ptr(). It creates |
| 278 | +//! pointer to the target with unspecified size. Unspecified size works in all |
| 279 | +//! intrinsics where are used registers (this means that size is specified by |
| 280 | +//! register operand or by instruction itself). For example @c AsmJit::ptr() |
| 281 | +//! can't be used with @c AsmJit::Serializer::inc() instruction. In this case |
| 282 | +//! size must be specified and it's also reason to make difference between |
| 283 | +//! pointer sizes. |
| 284 | +//! |
| 285 | +//! Supported are simple address forms (register + displacement) and complex |
| 286 | +//! address forms (register + (register << shift) + displacement). |
| 287 | +//! |
| 288 | +//! <b>Immediates</b> |
| 289 | +//! |
| 290 | +//! Immediate values are constants thats passed directly after instruction |
| 291 | +//! opcode. To create such value use @c AsmJit::imm() or @c AsmJit::uimm() |
| 292 | +//! methods to create signed or unsigned immediate value. |
| 293 | +//! |
| 294 | +//! @sa @c AsmJit::Serializer. |
| 295 | + |
| 296 | + |
| 297 | +//! @defgroup AsmJit_Util Utilities - Utilities and helper classes. |
| 298 | +//! |
| 299 | +//! Contains some helper classes that's used by AsmJit library. |
| 300 | + |
| 301 | + |
| 302 | +//! @defgroup AsmJit_MemoryManagement Virtual memory management. |
| 303 | +//! |
| 304 | +//! Using @c AsmJit::Assembler or @c AsmJit::Compiler to generate machine |
| 305 | +//! code is not final step. Each generated code needs to run in memory |
| 306 | +//! that is not protected against code execution. To alloc this code it's |
| 307 | +//! needed to use operating system functions provided to enable execution |
| 308 | +//! code in specified memory block or to allocate memory that is not |
| 309 | +//! protected. The solution is always to use @c See AsmJit::Assembler::make() |
| 310 | +//! and @c AsmJit::Compiler::make() functions that can allocate memory and |
| 311 | +//! relocate code for you. But AsmJit also contains classes for manual memory |
| 312 | +//! management thats internally used by AsmJit but can be used by programmers |
| 313 | +//! too. |
| 314 | +//! |
| 315 | +//! Memory management contains low level and high level classes related to |
| 316 | +//! allocating and freeing virtual memory. Low level class is |
| 317 | +//! @c AsmJit::VirtualMemory that can allocate and free full pages of |
| 318 | +//! virtual memory provided by operating system. Higher level class is |
| 319 | +//! @c AsmJit::MemoryManager that is able to manage complete allocation and |
| 320 | +//! free mechanism. It internally uses larger chunks of memory to make |
| 321 | +//! allocation fast and effective. |
| 322 | +//! |
| 323 | +//! Using @c AsmJit::VirtualMemory::alloc() is crossplatform way how to |
| 324 | +//! allocate this kind of memory without worrying about operating system |
| 325 | +//! and it's API. Each memory block that is no longer needed should be |
| 326 | +//! freed by @c AsmJit::VirtualMemory::free() method. If you want better |
| 327 | +//! comfort and malloc()/free() interface, look at the |
| 328 | +//! @c AsmJit::MemoryManager class. |
| 329 | +//! |
| 330 | +//! @sa @c AsmJit::VirtualMemory, @ AsmJit::MemoryManager. |
| 331 | + |
| 332 | + |
| 333 | +//! @addtogroup AsmJit_Config |
| 334 | +//! @{ |
| 335 | + |
| 336 | +//! @def ASMJIT_WINDOWS |
| 337 | +//! @brief Macro that is declared if AsmJit is compiled for Windows. |
| 338 | + |
| 339 | +//! @def ASMJIT_POSIX |
| 340 | +//! @brief Macro that is declared if AsmJit is compiled for unix like |
| 341 | +//! operating system. |
| 342 | + |
| 343 | +//! @def ASMJIT_API |
| 344 | +//! @brief Attribute that's added to classes that can be exported if AsmJit |
| 345 | +//! is compiled as a dll library. |
| 346 | + |
| 347 | +//! @def ASMJIT_MALLOC |
| 348 | +//! @brief Function to call to allocate dynamic memory. |
| 349 | + |
| 350 | +//! @def ASMJIT_REALLOC |
| 351 | +//! @brief Function to call to reallocate dynamic memory. |
| 352 | + |
| 353 | +//! @def ASMJIT_FREE |
| 354 | +//! @brief Function to call to free dynamic memory. |
| 355 | + |
| 356 | +//! @def ASMJIT_CRASH |
| 357 | +//! @brief Code that is execute if an one or more operands are invalid. |
| 358 | + |
| 359 | +//! @def ASMJIT_ASSERT |
| 360 | +//! @brief Assertion macro. Default implementation calls @c ASMJIT_CRASH |
| 361 | +//! if assert fails. |
| 362 | + |
| 363 | +//! @} |
| 364 | + |
| 365 | + |
| 366 | +//! @namespace AsmJit |
| 367 | +//! @brief Main AsmJit library namespace. |
| 368 | +//! |
| 369 | +//! There are not other namespaces used in AsmJit library. |
| 370 | + |
| 371 | + |
| 372 | +// [Includes] |
| 373 | +#include "Build.h" |
| 374 | +#include "Assembler.h" |
| 375 | +#include "Compiler.h" |
| 376 | +#include "CpuInfo.h" |
| 377 | +#include "Defs.h" |
| 378 | +#include "Logger.h" |
| 379 | +#include "MemoryManager.h" |
| 380 | +#include "Serializer.h" |
| 381 | +#include "Util.h" |
| 382 | +#include "VirtualMemory.h" |
| 383 | + |
| 384 | + |
| 385 | +// [Guard] |
| 386 | +#endif // _ASMJIT_H |
0 commit comments