1 // AsmJit - Machine code generation for C++ 2 // 3 // * Official AsmJit Home Page: https://asmjit.com 4 // * Official Github Repository: https://github.com/asmjit/asmjit 5 // 6 // Copyright (c) 2008-2020 The AsmJit Authors 7 // 8 // This software is provided 'as-is', without any express or implied 9 // warranty. In no event will the authors be held liable for any damages 10 // arising from the use of this software. 11 // 12 // Permission is granted to anyone to use this software for any purpose, 13 // including commercial applications, and to alter it and redistribute it 14 // freely, subject to the following restrictions: 15 // 16 // 1. The origin of this software must not be misrepresented; you must not 17 // claim that you wrote the original software. If you use this software 18 // in a product, an acknowledgment in the product documentation would be 19 // appreciated but is not required. 20 // 2. Altered source versions must be plainly marked as such, and must not be 21 // misrepresented as being the original software. 22 // 3. This notice may not be removed or altered from any source distribution. 23 24 #ifndef ASMJIT_CORE_API_CONFIG_H_INCLUDED 25 #define ASMJIT_CORE_API_CONFIG_H_INCLUDED 26 27 // ============================================================================ 28 // [asmjit::Version] 29 // ============================================================================ 30 31 //! \addtogroup asmjit_core 32 //! \{ 33 34 //! AsmJit library version in `(Major << 16) | (Minor << 8) | (Patch)` format. 35 #define ASMJIT_LIBRARY_VERSION 0x010400 /* 1.4.0 */ 36 37 //! \} 38 39 // ============================================================================ 40 // [asmjit::Build - Documentation] 41 // ============================================================================ 42 43 // NOTE: Doxygen cannot document macros that are not defined, that's why we have 44 // to define them and then undefine them, so it won't use the macros with its 45 // own preprocessor. 46 #ifdef _DOXYGEN 47 namespace asmjit { 48 49 //! \addtogroup asmjit_build 50 //! \{ 51 52 //! Asmjit is embedded, implies \ref ASMJIT_STATIC. 53 #define ASMJIT_EMBED 54 55 //! Enables static-library build. 56 #define ASMJIT_STATIC 57 58 //! Defined when AsmJit's build configuration is 'Debug'. 59 //! 60 //! \note Can be defined explicitly to bypass autodetection. 61 #define ASMJIT_BUILD_DEBUG 62 63 //! Defined when AsmJit's build configuration is 'Release'. 64 //! 65 //! \note Can be defined explicitly to bypass autodetection. 66 #define ASMJIT_BUILD_RELEASE 67 68 //! Defined to build X86/X64 backend. 69 #define ASMJIT_BUILD_X86 70 71 //! Defined to build host backend autodetected at compile-time. 72 #define ASMJIT_BUILD_HOST 73 74 //! Disables deprecated API at compile time. 75 #define ASMJIT_NO_DEPRECATED 76 77 //! Disable non-host architectures entirely. 78 #define ASMJIT_NO_FOREIGN 79 80 //! Disables \ref asmjit_builder functionality completely. 81 #define ASMJIT_NO_BUILDER 82 83 //! Disables \ref asmjit_compiler functionality completely. 84 #define ASMJIT_NO_COMPILER 85 86 //! Disables JIT memory management and \ref JitRuntime. 87 #define ASMJIT_NO_JIT 88 89 //! Disables \ref Logger and \ref Formatter. 90 #define ASMJIT_NO_LOGGING 91 92 //! Disables everything that contains text. 93 #define ASMJIT_NO_TEXT 94 95 //! Disables instruction validation API. 96 #define ASMJIT_NO_VALIDATION 97 98 //! Disables instruction introspection API. 99 #define ASMJIT_NO_INTROSPECTION 100 101 // Avoid doxygen preprocessor using feature-selection definitions. 102 #undef ASMJIT_NO_BUILDER 103 #undef ASMJIT_NO_COMPILER 104 #undef ASMJIT_NO_JIT 105 #undef ASMJIT_NO_LOGGING 106 #undef ASMJIT_NO_TEXT 107 #undef ASMJIT_NO_VALIDATION 108 #undef ASMJIT_NO_INTROSPECTION 109 110 //! \} 111 112 } // {asmjit} 113 #endif // _DOXYGEN 114 115 // Enable all features at IDE level, so it's properly highlighted and indexed. 116 #ifdef __INTELLISENSE__ 117 #ifndef ASMJIT_BUILD_X86 118 #define ASMJIT_BUILD_X86 119 #endif 120 #endif 121 122 // ============================================================================ 123 // [asmjit::Dependencies] 124 // ============================================================================ 125 126 // We really want std-types as globals. 127 #include <stdarg.h> 128 #include <stddef.h> 129 #include <stdint.h> 130 #include <stdio.h> 131 #include <stdlib.h> 132 #include <string.h> 133 134 #include <iterator> 135 #include <limits> 136 #include <new> 137 #include <type_traits> 138 #include <utility> 139 140 #if !defined(_WIN32) && !defined(__EMSCRIPTEN__) 141 #include <pthread.h> 142 #endif 143 144 145 // ============================================================================ 146 // [asmjit::Options] 147 // ============================================================================ 148 149 // ASMJIT_NO_BUILDER implies ASMJIT_NO_COMPILER. 150 #if defined(ASMJIT_NO_BUILDER) && !defined(ASMJIT_NO_COMPILER) 151 #define ASMJIT_NO_COMPILER 152 #endif 153 154 // Prevent compile-time errors caused by misconfiguration. 155 #if defined(ASMJIT_NO_TEXT) && !defined(ASMJIT_NO_LOGGING) 156 #pragma "ASMJIT_NO_TEXT can only be defined when ASMJIT_NO_LOGGING is defined." 157 #undef ASMJIT_NO_TEXT 158 #endif 159 160 #if defined(ASMJIT_NO_INTROSPECTION) && !defined(ASMJIT_NO_COMPILER) 161 #pragma message("ASMJIT_NO_INTROSPECTION can only be defined when ASMJIT_NO_COMPILER is defined") 162 #undef ASMJIT_NO_INTROSPECTION 163 #endif 164 165 // ============================================================================ 166 // [asmjit::Build - Globals - Deprecated] 167 // ============================================================================ 168 169 #ifndef ASMJIT_NO_DEPRECATED 170 #if defined(ASMJIT_BUILD_EMBED) || defined(ASMJIT_BUILD_STATIC) 171 #if defined(ASMJIT_BUILD_EMBED) 172 #pragma message("'ASMJIT_BUILD_EMBED' is deprecated, use 'ASMJIT_STATIC'") 173 #endif 174 #if defined(ASMJIT_BUILD_STATIC) 175 #pragma message("'ASMJIT_BUILD_STATIC' is deprecated, use 'ASMJIT_STATIC'") 176 #endif 177 178 #if !defined(ASMJIT_STATIC) 179 #define ASMJIT_STATIC 180 #endif 181 #endif 182 #endif // !ASMJIT_NO_DEPRECATED 183 184 // ============================================================================ 185 // [asmjit::Build - Globals - Build Mode] 186 // ============================================================================ 187 188 // Detect ASMJIT_BUILD_DEBUG and ASMJIT_BUILD_RELEASE if not defined. 189 #if !defined(ASMJIT_BUILD_DEBUG) && !defined(ASMJIT_BUILD_RELEASE) 190 #if !defined(NDEBUG) 191 #define ASMJIT_BUILD_DEBUG 192 #else 193 #define ASMJIT_BUILD_RELEASE 194 #endif 195 #endif 196 197 // ============================================================================ 198 // [asmjit::Build - Globals - Target Architecture Information] 199 // ============================================================================ 200 201 #if defined(_M_X64) || defined(__x86_64__) 202 #define ASMJIT_ARCH_X86 64 203 #elif defined(_M_IX86) || defined(__X86__) || defined(__i386__) 204 #define ASMJIT_ARCH_X86 32 205 #else 206 #define ASMJIT_ARCH_X86 0 207 #endif 208 209 #if defined(__arm64__) || defined(__aarch64__) 210 # define ASMJIT_ARCH_ARM 64 211 #elif defined(_M_ARM) || defined(_M_ARMT) || defined(__arm__) || defined(__thumb__) || defined(__thumb2__) 212 #define ASMJIT_ARCH_ARM 32 213 #else 214 #define ASMJIT_ARCH_ARM 0 215 #endif 216 217 #if defined(_MIPS_ARCH_MIPS64) || defined(__mips64) 218 #define ASMJIT_ARCH_MIPS 64 219 #elif defined(_MIPS_ARCH_MIPS32) || defined(_M_MRX000) || defined(__mips__) 220 #define ASMJIT_ARCH_MIPS 32 221 #else 222 #define ASMJIT_ARCH_MIPS 0 223 #endif 224 225 #define ASMJIT_ARCH_BITS (ASMJIT_ARCH_X86 | ASMJIT_ARCH_ARM | ASMJIT_ARCH_MIPS) 226 #if ASMJIT_ARCH_BITS == 0 227 #undef ASMJIT_ARCH_BITS 228 #if defined (__LP64__) || defined(_LP64) 229 #define ASMJIT_ARCH_BITS 64 230 #else 231 #define ASMJIT_ARCH_BITS 32 232 #endif 233 #endif 234 235 #if (defined(__ARMEB__)) || \ 236 (defined(__MIPSEB__)) || \ 237 (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) 238 #define ASMJIT_ARCH_LE 0 239 #define ASMJIT_ARCH_BE 1 240 #else 241 #define ASMJIT_ARCH_LE 1 242 #define ASMJIT_ARCH_BE 0 243 #endif 244 245 // ============================================================================ 246 // [asmjit::Build - Globals - Build Architectures Definitions] 247 // ============================================================================ 248 249 #if !defined(ASMJIT_NO_FOREIGN) 250 // If 'ASMJIT_NO_FOREIGN' is not defined then all architectures will be built. 251 #if !defined(ASMJIT_BUILD_X86) 252 #define ASMJIT_BUILD_X86 253 #endif 254 #else 255 // Detect architectures to build if building only for the host architecture. 256 #if ASMJIT_ARCH_X86 && !defined(ASMJIT_BUILD_X86) 257 #define ASMJIT_BUILD_X86 258 #endif 259 #endif 260 261 // Define 'ASMJIT_BUILD_HOST' if we know that host architecture will be built. 262 #if !defined(ASMJIT_BUILD_HOST) && ASMJIT_ARCH_X86 && defined(ASMJIT_BUILD_X86) 263 #define ASMJIT_BUILD_HOST 264 #endif 265 266 // ============================================================================ 267 // [asmjit::Build - Globals - C++ Compiler and Features Detection] 268 // ============================================================================ 269 270 #define ASMJIT_CXX_GNU 0 271 #define ASMJIT_CXX_MAKE_VER(MAJOR, MINOR) ((MAJOR) * 1000 + (MINOR)) 272 273 // Intel Compiler [pretends to be GNU or MSC, so it must be checked first]: 274 // - https://software.intel.com/en-us/articles/c0x-features-supported-by-intel-c-compiler 275 // - https://software.intel.com/en-us/articles/c14-features-supported-by-intel-c-compiler 276 // - https://software.intel.com/en-us/articles/c17-features-supported-by-intel-c-compiler 277 #if defined(__INTEL_COMPILER) 278 279 // MSC Compiler: 280 // - https://msdn.microsoft.com/en-us/library/hh567368.aspx 281 // 282 // Version List: 283 // - 16.00.0 == VS2010 284 // - 17.00.0 == VS2012 285 // - 18.00.0 == VS2013 286 // - 19.00.0 == VS2015 287 // - 19.10.0 == VS2017 288 #elif defined(_MSC_VER) && defined(_MSC_FULL_VER) 289 290 // Clang Compiler [Pretends to be GNU, so it must be checked before]: 291 // - https://clang.llvm.org/cxx_status.html 292 #elif defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__) 293 294 // GNU Compiler: 295 // - https://gcc.gnu.org/projects/cxx-status.html 296 #elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) 297 298 #undef ASMJIT_CXX_GNU 299 #define ASMJIT_CXX_GNU ASMJIT_CXX_MAKE_VER(__GNUC__, __GNUC_MINOR__) 300 301 #endif 302 303 // Compiler features detection macros. 304 #if defined(__clang__) && defined(__has_attribute) 305 #define ASMJIT_CXX_HAS_ATTRIBUTE(NAME, CHECK) (__has_attribute(NAME)) 306 #else 307 #define ASMJIT_CXX_HAS_ATTRIBUTE(NAME, CHECK) (!(!(CHECK))) 308 #endif 309 310 // ============================================================================ 311 // [asmjit::Build - Globals - API Decorators & Language Extensions] 312 // ============================================================================ 313 314 // API (Export / Import). 315 #if !defined(ASMJIT_STATIC) 316 #if defined(_WIN32) && (defined(_MSC_VER) || defined(__MINGW32__)) 317 #ifdef ASMJIT_EXPORTS 318 #define ASMJIT_API __declspec(dllexport) 319 #else 320 #define ASMJIT_API __declspec(dllimport) 321 #endif 322 #elif defined(_WIN32) && defined(__GNUC__) 323 #ifdef ASMJIT_EXPORTS 324 #define ASMJIT_API __attribute__((__dllexport__)) 325 #else 326 #define ASMJIT_API __attribute__((__dllimport__)) 327 #endif 328 #elif defined(__GNUC__) 329 #define ASMJIT_API __attribute__((__visibility__("default"))) 330 #endif 331 #endif 332 333 #if !defined(ASMJIT_API) 334 #define ASMJIT_API 335 #endif 336 337 #if !defined(ASMJIT_VARAPI) 338 #define ASMJIT_VARAPI extern ASMJIT_API 339 #endif 340 341 // This is basically a workaround. When using MSVC and marking class as DLL 342 // export everything gets exported, which is unwanted in most projects. MSVC 343 // automatically exports typeinfo and vtable if at least one symbol of the 344 // class is exported. However, GCC has some strange behavior that even if 345 // one or more symbol is exported it doesn't export typeinfo unless the 346 // class itself is decorated with "visibility(default)" (i.e. ASMJIT_API). 347 #if !defined(_WIN32) && defined(__GNUC__) 348 #define ASMJIT_VIRTAPI ASMJIT_API 349 #else 350 #define ASMJIT_VIRTAPI 351 #endif 352 353 // Function attributes. 354 #if !defined(ASMJIT_BUILD_DEBUG) && defined(__GNUC__) 355 #define ASMJIT_INLINE inline __attribute__((__always_inline__)) 356 #elif !defined(ASMJIT_BUILD_DEBUG) && defined(_MSC_VER) 357 #define ASMJIT_INLINE __forceinline 358 #else 359 #define ASMJIT_INLINE inline 360 #endif 361 362 #if defined(__GNUC__) 363 #define ASMJIT_NOINLINE __attribute__((__noinline__)) 364 #define ASMJIT_NORETURN __attribute__((__noreturn__)) 365 #elif defined(_MSC_VER) 366 #define ASMJIT_NOINLINE __declspec(noinline) 367 #define ASMJIT_NORETURN __declspec(noreturn) 368 #else 369 #define ASMJIT_NOINLINE 370 #define ASMJIT_NORETURN 371 #endif 372 373 // Calling conventions. 374 #if ASMJIT_ARCH_X86 == 32 && defined(__GNUC__) 375 #define ASMJIT_CDECL __attribute__((__cdecl__)) 376 #define ASMJIT_STDCALL __attribute__((__stdcall__)) 377 #define ASMJIT_FASTCALL __attribute__((__fastcall__)) 378 #define ASMJIT_REGPARM(N) __attribute__((__regparm__(N))) 379 #elif ASMJIT_ARCH_X86 == 32 && defined(_MSC_VER) 380 #define ASMJIT_CDECL __cdecl 381 #define ASMJIT_STDCALL __stdcall 382 #define ASMJIT_FASTCALL __fastcall 383 #define ASMJIT_REGPARM(N) 384 #else 385 #define ASMJIT_CDECL 386 #define ASMJIT_STDCALL 387 #define ASMJIT_FASTCALL 388 #define ASMJIT_REGPARM(N) 389 #endif 390 391 #if ASMJIT_ARCH_X86 && defined(_WIN32) && defined(_MSC_VER) 392 #define ASMJIT_VECTORCALL __vectorcall 393 #elif ASMJIT_ARCH_X86 && defined(_WIN32) 394 #define ASMJIT_VECTORCALL __attribute__((__vectorcall__)) 395 #else 396 #define ASMJIT_VECTORCALL 397 #endif 398 399 400 // Type alignment (not allowed by C++11 'alignas' keyword). 401 #if defined(__GNUC__) 402 #define ASMJIT_ALIGN_TYPE(TYPE, N) __attribute__((__aligned__(N))) TYPE 403 #elif defined(_MSC_VER) 404 #define ASMJIT_ALIGN_TYPE(TYPE, N) __declspec(align(N)) TYPE 405 #else 406 #define ASMJIT_ALIGN_TYPE(TYPE, N) TYPE 407 #endif 408 409 //! \def ASMJIT_MAY_ALIAS 410 //! 411 //! Expands to `__attribute__((__may_alias__))` if supported. 412 #if defined(__GNUC__) 413 #define ASMJIT_MAY_ALIAS __attribute__((__may_alias__)) 414 #else 415 #define ASMJIT_MAY_ALIAS 416 #endif 417 418 //! \def ASMJIT_LIKELY(...) 419 //! 420 //! Condition is likely to be taken (mostly error handling and edge cases). 421 422 //! \def ASMJIT_UNLIKELY(...) 423 //! 424 //! Condition is unlikely to be taken (mostly error handling and edge cases). 425 #if defined(__GNUC__) 426 #define ASMJIT_LIKELY(...) __builtin_expect(!!(__VA_ARGS__), 1) 427 #define ASMJIT_UNLIKELY(...) __builtin_expect(!!(__VA_ARGS__), 0) 428 #else 429 #define ASMJIT_LIKELY(...) (__VA_ARGS__) 430 #define ASMJIT_UNLIKELY(...) (__VA_ARGS__) 431 #endif 432 433 //! \def ASMJIT_FALLTHROUGH 434 //! 435 //! Portable [[fallthrough]] attribute. 436 #if defined(__clang__) && __cplusplus >= 201103L 437 #define ASMJIT_FALLTHROUGH [[clang::fallthrough]] 438 #elif defined(__GNUC__) && __GNUC__ >= 7 439 #define ASMJIT_FALLTHROUGH __attribute__((__fallthrough__)) 440 #else 441 #define ASMJIT_FALLTHROUGH ((void)0) /* fallthrough */ 442 #endif 443 444 //! \def ASMJIT_DEPRECATED 445 //! 446 //! Marks function, class, struct, enum, or anything else as deprecated. 447 #if defined(__GNUC__) 448 #define ASMJIT_DEPRECATED(MESSAGE) __attribute__((__deprecated__(MESSAGE))) 449 #if defined(__clang__) 450 #define ASMJIT_DEPRECATED_STRUCT(MESSAGE) __attribute__((__deprecated__(MESSAGE))) 451 #else 452 #define ASMJIT_DEPRECATED_STRUCT(MESSAGE) /* not usable if a deprecated function uses it */ 453 #endif 454 #elif defined(_MSC_VER) 455 #define ASMJIT_DEPRECATED(MESSAGE) __declspec(deprecated(MESSAGE)) 456 #define ASMJIT_DEPRECATED_STRUCT(MESSAGE) /* not usable if a deprecated function uses it */ 457 #else 458 #define ASMJIT_DEPRECATED(MESSAGE) 459 #define ASMJIT_DEPRECATED_STRUCT(MESSAGE) 460 #endif 461 462 // Utilities. 463 #define ASMJIT_OFFSET_OF(STRUCT, MEMBER) ((int)(intptr_t)((const char*)&((const STRUCT*)0x100)->MEMBER) - 0x100) 464 #define ASMJIT_ARRAY_SIZE(X) uint32_t(sizeof(X) / sizeof(X[0])) 465 466 #if ASMJIT_CXX_HAS_ATTRIBUTE(no_sanitize, 0) 467 #define ASMJIT_ATTRIBUTE_NO_SANITIZE_UNDEF __attribute__((__no_sanitize__("undefined"))) 468 #elif ASMJIT_CXX_GNU >= ASMJIT_CXX_MAKE_VER(4, 9) 469 #define ASMJIT_ATTRIBUTE_NO_SANITIZE_UNDEF __attribute__((__no_sanitize_undefined__)) 470 #else 471 #define ASMJIT_ATTRIBUTE_NO_SANITIZE_UNDEF 472 #endif 473 474 // ============================================================================ 475 // [asmjit::Build - Globals - Begin-Namespace / End-Namespace] 476 // ============================================================================ 477 478 #if defined(__clang__) 479 #define ASMJIT_BEGIN_NAMESPACE \ 480 namespace asmjit { \ 481 _Pragma("clang diagnostic push") \ 482 _Pragma("clang diagnostic ignored \"-Wconstant-logical-operand\"") \ 483 _Pragma("clang diagnostic ignored \"-Wunnamed-type-template-args\"") 484 #define ASMJIT_END_NAMESPACE \ 485 _Pragma("clang diagnostic pop") \ 486 } 487 #elif defined(__GNUC__) && __GNUC__ == 4 488 #define ASMJIT_BEGIN_NAMESPACE \ 489 namespace asmjit { \ 490 _Pragma("GCC diagnostic push") \ 491 _Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") 492 #define ASMJIT_END_NAMESPACE \ 493 _Pragma("GCC diagnostic pop") \ 494 } 495 #elif defined(__GNUC__) && __GNUC__ >= 8 496 #define ASMJIT_BEGIN_NAMESPACE \ 497 namespace asmjit { \ 498 _Pragma("GCC diagnostic push") \ 499 _Pragma("GCC diagnostic ignored \"-Wclass-memaccess\"") 500 #define ASMJIT_END_NAMESPACE \ 501 _Pragma("GCC diagnostic pop") \ 502 } 503 #elif defined(_MSC_VER) && !defined(__INTEL_COMPILER) 504 #define ASMJIT_BEGIN_NAMESPACE \ 505 namespace asmjit { \ 506 __pragma(warning(push)) \ 507 __pragma(warning(disable: 4127)) /* conditional expression is const */ \ 508 __pragma(warning(disable: 4201)) /* nameless struct/union */ 509 #define ASMJIT_END_NAMESPACE \ 510 __pragma(warning(pop)) \ 511 } 512 #endif 513 514 #if !defined(ASMJIT_BEGIN_NAMESPACE) && !defined(ASMJIT_END_NAMESPACE) 515 #define ASMJIT_BEGIN_NAMESPACE namespace asmjit { 516 #define ASMJIT_END_NAMESPACE } 517 #endif 518 519 #define ASMJIT_BEGIN_SUB_NAMESPACE(NAMESPACE) \ 520 ASMJIT_BEGIN_NAMESPACE \ 521 namespace NAMESPACE { 522 523 #define ASMJIT_END_SUB_NAMESPACE \ 524 } \ 525 ASMJIT_END_NAMESPACE 526 527 // ============================================================================ 528 // [asmjit::Build - Globals - Utilities] 529 // ============================================================================ 530 531 #define ASMJIT_NONCOPYABLE(...) \ 532 private: \ 533 __VA_ARGS__(const __VA_ARGS__& other) = delete; \ 534 __VA_ARGS__& operator=(const __VA_ARGS__& other) = delete; \ 535 public: 536 537 #define ASMJIT_NONCONSTRUCTIBLE(...) \ 538 private: \ 539 __VA_ARGS__() = delete; \ 540 __VA_ARGS__(const __VA_ARGS__& other) = delete; \ 541 __VA_ARGS__& operator=(const __VA_ARGS__& other) = delete; \ 542 public: 543 544 // ============================================================================ 545 // [asmjit::Build - Globals - Cleanup] 546 // ============================================================================ 547 548 // Cleanup definitions that are only used within this header file. 549 #undef ASMJIT_CXX_GNU 550 #undef ASMJIT_CXX_MAKE_VER 551 552 #endif // ASMJIT_CORE_API_CONFIG_H_INCLUDED 553