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