18 #if defined(__x86_64__) || defined(__i386__) || defined(_M_X64) || defined(_M_IX86)
21 #elif defined(__GNUC__) || defined(__clang__)
23 #include <immintrin.h>
25 #define TRLC_HAS_X86_INTRINSICS 1
27 #define TRLC_HAS_X86_INTRINSICS 0
30 #if defined(__ARM_NEON) || defined(__aarch64__)
31 #if defined(__GNUC__) || defined(__clang__)
34 #define TRLC_HAS_ARM_INTRINSICS 1
36 #define TRLC_HAS_ARM_INTRINSICS 0
197 #ifdef __cpp_exceptions
199 #elif defined(__EXCEPTIONS) || defined(_CPPUNWIND)
213 #elif defined(__GXX_RTTI) || defined(_CPPRTTI)
215 #elif defined(__has_feature)
216 #if __has_feature(cxx_rtti)
231 #ifdef __STDCPP_THREADS__
232 return __STDCPP_THREADS__ == 1;
233 #elif defined(_REENTRANT) || defined(_MT)
245 #ifdef __cpp_lib_atomic_shared_ptr
247 #elif defined(__ATOMIC_RELAXED)
249 #elif defined(_MSC_VER)
261 #if defined(__GNUC__) || defined(__clang__)
263 #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
283 #ifdef __STACK_CHK_FAIL
285 #elif defined(__SSP__) || defined(__SSP_ALL__)
287 #elif defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0
300 #if __has_feature(address_sanitizer)
304 #ifdef __SANITIZE_ADDRESS__
317 #if __has_feature(thread_sanitizer)
321 #ifdef __SANITIZE_THREAD__
334 #if __has_feature(memory_sanitizer)
338 #ifdef __SANITIZE_MEMORY__
351 #if __has_feature(undefined_behavior_sanitizer)
355 #ifdef __SANITIZE_UNDEFINED__
366 #if TRLC_HAS_X86_INTRINSICS
376 inline void cpuid(uint32_t leaf, uint32_t subleaf, uint32_t regs[4]) noexcept {
377 #if defined(_MSC_VER)
378 __cpuidex(
reinterpret_cast<int*
>(regs),
static_cast<int>(leaf),
static_cast<int>(subleaf));
379 #elif defined(__GNUC__) || defined(__clang__)
380 __cpuid_count(leaf, subleaf, regs[0], regs[1], regs[2], regs[3]);
382 regs[0] = regs[1] = regs[2] = regs[3] = 0;
394 inline bool checkCpuFeature(uint32_t leaf, uint32_t subleaf,
int reg,
int bit) noexcept {
396 cpuid(leaf, subleaf, regs);
397 return (regs[reg] & (1u << bit)) != 0;
409 #if TRLC_HAS_X86_INTRINSICS
410 return detail::checkCpuFeature(1, 0, 3, 25);
421 #if TRLC_HAS_X86_INTRINSICS
422 return detail::checkCpuFeature(1, 0, 3, 26);
433 #if TRLC_HAS_X86_INTRINSICS
434 return detail::checkCpuFeature(1, 0, 2, 0);
445 #if TRLC_HAS_X86_INTRINSICS
446 return detail::checkCpuFeature(1, 0, 2, 19);
457 #if TRLC_HAS_X86_INTRINSICS
458 return detail::checkCpuFeature(1, 0, 2, 20);
469 #if TRLC_HAS_X86_INTRINSICS
470 return detail::checkCpuFeature(1, 0, 2, 28);
481 #if TRLC_HAS_X86_INTRINSICS
482 return detail::checkCpuFeature(7, 0, 1, 5);
493 #if TRLC_HAS_X86_INTRINSICS
494 return detail::checkCpuFeature(7, 0, 1, 16);
505 #if TRLC_HAS_ARM_INTRINSICS
508 #elif defined(__aarch64__)
523 #if TRLC_HAS_X86_INTRINSICS
524 return detail::checkCpuFeature(1, 0, 2, 25);
525 #elif TRLC_HAS_ARM_INTRINSICS && defined(__ARM_FEATURE_AES)
537 #if TRLC_HAS_X86_INTRINSICS
538 return detail::checkCpuFeature(1, 0, 2, 30);
658 template <LanguageFeature TFeature>
671 #define TRLC_HAS_EXCEPTIONS (trlc::platform::hasExceptions())
674 #define TRLC_HAS_RTTI (trlc::platform::hasRtti())
677 #define TRLC_HAS_THREADS (trlc::platform::hasThreads())
680 #define TRLC_HAS_ATOMIC (trlc::platform::hasAtomicOperations())
683 #define TRLC_HAS_INLINE_ASM (trlc::platform::hasInlineAssembly())
686 #define TRLC_HAS_VECTOR_INTRINSICS (trlc::platform::hasVectorIntrinsics())
689 #define TRLC_HAS_STACK_PROTECTION (trlc::platform::hasStackProtection())
692 #define TRLC_HAS_ADDRESS_SANITIZER (trlc::platform::hasAddressSanitizer())
695 #define TRLC_HAS_THREAD_SANITIZER (trlc::platform::hasThreadSanitizer())
698 #define TRLC_HAS_MEMORY_SANITIZER (trlc::platform::hasMemorySanitizer())
701 #define TRLC_HAS_UNDEFINED_BEHAVIOR_SANITIZER (trlc::platform::hasUndefinedBehaviorSanitizer())
704 #define TRLC_HAS_FEATURE(X) (trlc::platform::hasFeature<trlc::platform::LanguageFeature::X>())
711 #define TRLC_HAS_SSE_RUNTIME() (trlc::platform::hasSseSupport())
714 #define TRLC_HAS_SSE2_RUNTIME() (trlc::platform::hasSse2Support())
717 #define TRLC_HAS_SSE3_RUNTIME() (trlc::platform::hasSse3Support())
720 #define TRLC_HAS_SSE41_RUNTIME() (trlc::platform::hasSse41Support())
723 #define TRLC_HAS_SSE42_RUNTIME() (trlc::platform::hasSse42Support())
726 #define TRLC_HAS_AVX_RUNTIME() (trlc::platform::hasAvxSupport())
729 #define TRLC_HAS_AVX2_RUNTIME() (trlc::platform::hasAvx2Support())
732 #define TRLC_HAS_AVX512F_RUNTIME() (trlc::platform::hasAvx512fSupport())
735 #define TRLC_HAS_NEON_RUNTIME() (trlc::platform::hasNeonSupport())
738 #define TRLC_HAS_HARDWARE_AES_RUNTIME() (trlc::platform::hasHardwareAes())
741 #define TRLC_HAS_HARDWARE_RANDOM_RUNTIME() (trlc::platform::hasHardwareRandom())
748 #ifdef __cpp_exceptions
749 #define TRLC_IF_EXCEPTIONS(code) code
750 #elif defined(__EXCEPTIONS) || defined(_CPPUNWIND)
751 #define TRLC_IF_EXCEPTIONS(code) code
753 #define TRLC_IF_EXCEPTIONS(code) ((void)0)
758 #define TRLC_IF_RTTI(code) code
759 #elif defined(__GXX_RTTI) || defined(_CPPRTTI)
760 #define TRLC_IF_RTTI(code) code
762 #define TRLC_IF_RTTI(code) ((void)0)
766 #ifdef __STDCPP_THREADS__
767 #if __STDCPP_THREADS__ == 1
768 #define TRLC_IF_THREADS(code) code
770 #define TRLC_IF_THREADS(code) ((void)0)
772 #elif defined(_REENTRANT) || defined(_MT)
773 #define TRLC_IF_THREADS(code) code
775 #define TRLC_IF_THREADS(code) ((void)0)
#define TRLC_HAS_ARM_INTRINSICS
#define TRLC_HAS_X86_INTRINSICS