github.com/Schaudge/grailbase@v0.0.0-20240223061707-44c758a471c0/compress/libdeflate/compiler_gcc.h (about) 1 #ifndef GO_SRC_GITHUB_COM_GRAILBIO_BASE_COMPRESS_LIBDEFLATE_COMPILER_GCC_H_ 2 #define GO_SRC_GITHUB_COM_GRAILBIO_BASE_COMPRESS_LIBDEFLATE_COMPILER_GCC_H_ 3 /* 4 * compiler_gcc.h - definitions for the GNU C Compiler. This also handles clang 5 * and the Intel C Compiler (icc). 6 * 7 * TODO: icc is not well tested, so some things are currently disabled even 8 * though they maybe can be enabled on some icc versions. 9 */ 10 11 #if !defined(__clang__) && !defined(__INTEL_COMPILER) 12 # define GCC_PREREQ(major, minor) \ 13 (__GNUC__ > (major) || \ 14 (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) 15 #else 16 # define GCC_PREREQ(major, minor) 0 17 #endif 18 19 /* Note: only check the clang version when absolutely necessary! 20 * "Vendors" such as Apple can use different version numbers. */ 21 #ifdef __clang__ 22 # ifdef __apple_build_version__ 23 # define CLANG_PREREQ(major, minor, apple_version) \ 24 (__apple_build_version__ >= (apple_version)) 25 # else 26 # define CLANG_PREREQ(major, minor, apple_version) \ 27 (__clang_major__ > (major) || \ 28 (__clang_major__ == (major) && __clang_minor__ >= (minor))) 29 # endif 30 #else 31 # define CLANG_PREREQ(major, minor, apple_version) 0 32 #endif 33 34 #ifndef __has_attribute 35 # define __has_attribute(attribute) 0 36 #endif 37 #ifndef __has_feature 38 # define __has_feature(feature) 0 39 #endif 40 #ifndef __has_builtin 41 # define __has_builtin(builtin) 0 42 #endif 43 44 #ifdef _WIN32 45 # define LIBEXPORT __declspec(dllexport) 46 #else 47 # define LIBEXPORT __attribute__((visibility("default"))) 48 #endif 49 50 #define inline inline 51 #define forceinline inline __attribute__((always_inline)) 52 #define restrict __restrict__ 53 #define likely(expr) __builtin_expect(!!(expr), 1) 54 #define unlikely(expr) __builtin_expect(!!(expr), 0) 55 #define prefetchr(addr) __builtin_prefetch((addr), 0) 56 #define prefetchw(addr) __builtin_prefetch((addr), 1) 57 #define _aligned_attribute(n) __attribute__((aligned(n))) 58 59 #define COMPILER_SUPPORTS_TARGET_FUNCTION_ATTRIBUTE \ 60 (GCC_PREREQ(4, 4) || __has_attribute(target)) 61 62 #if COMPILER_SUPPORTS_TARGET_FUNCTION_ATTRIBUTE 63 64 # if defined(__i386__) || defined(__x86_64__) 65 66 # define COMPILER_SUPPORTS_PCLMUL_TARGET \ 67 (GCC_PREREQ(4, 4) || __has_builtin(__builtin_ia32_pclmulqdq128)) 68 69 # define COMPILER_SUPPORTS_AVX_TARGET \ 70 (GCC_PREREQ(4, 6) || __has_builtin(__builtin_ia32_maxps256)) 71 72 # define COMPILER_SUPPORTS_BMI2_TARGET \ 73 (GCC_PREREQ(4, 7) || __has_builtin(__builtin_ia32_pdep_di)) 74 75 # define COMPILER_SUPPORTS_AVX2_TARGET \ 76 (GCC_PREREQ(4, 7) || __has_builtin(__builtin_ia32_pmaddwd256)) 77 78 /* 79 * Prior to gcc 4.9 (r200349) and clang 3.8 (r239883), x86 intrinsics 80 * not available in the main target could not be used in 'target' 81 * attribute functions. Unfortunately clang has no feature test macro 82 * for this so we have to check its version. 83 */ 84 # if GCC_PREREQ(4, 9) || CLANG_PREREQ(3, 8, 7030000) 85 # define COMPILER_SUPPORTS_SSE2_TARGET_INTRINSICS 1 86 # define COMPILER_SUPPORTS_PCLMUL_TARGET_INTRINSICS \ 87 COMPILER_SUPPORTS_PCLMUL_TARGET 88 # define COMPILER_SUPPORTS_AVX2_TARGET_INTRINSICS \ 89 COMPILER_SUPPORTS_AVX2_TARGET 90 # endif 91 # elif defined(__arm__) || defined(__aarch64__) 92 /* 93 * Prior to gcc 6.1 (r230411 for arm, r226563 for aarch64), NEON 94 * and crypto intrinsics not available in the main target could not be 95 * used in 'target' attribute functions. 96 * 97 * clang as of 5.0.1 still doesn't allow it. But, it does seem to allow 98 * the pmull intrinsics if only __ARM_NEON is enabled. 99 */ 100 # define COMPILER_SUPPORTS_NEON_TARGET_INTRINSICS GCC_PREREQ(6, 1) 101 # ifdef __ARM_NEON 102 # define COMPILER_SUPPORTS_PMULL_TARGET_INTRINSICS \ 103 (GCC_PREREQ(6, 1) || __has_builtin(__builtin_neon_vmull_p64)) 104 # else 105 # define COMPILER_SUPPORTS_PMULL_TARGET_INTRINSICS \ 106 (GCC_PREREQ(6, 1)) 107 # endif 108 # endif 109 #endif /* COMPILER_SUPPORTS_TARGET_FUNCTION_ATTRIBUTE */ 110 111 /* Newer gcc supports __BYTE_ORDER__. Older gcc doesn't. */ 112 #ifdef __BYTE_ORDER__ 113 # define CPU_IS_LITTLE_ENDIAN() (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) 114 #endif 115 116 #if GCC_PREREQ(4, 8) || __has_builtin(__builtin_bswap16) 117 # define bswap16 __builtin_bswap16 118 #endif 119 120 #if GCC_PREREQ(4, 3) || __has_builtin(__builtin_bswap32) 121 # define bswap32 __builtin_bswap32 122 #endif 123 124 #if GCC_PREREQ(4, 3) || __has_builtin(__builtin_bswap64) 125 # define bswap64 __builtin_bswap64 126 #endif 127 128 #if defined(__x86_64__) || defined(__i386__) || defined(__ARM_FEATURE_UNALIGNED) || defined(__powerpc64__) 129 # define UNALIGNED_ACCESS_IS_FAST 1 130 #endif 131 132 /* With gcc, we can access unaligned memory through 'packed' structures. */ 133 #define DEFINE_UNALIGNED_TYPE(type) \ 134 \ 135 struct type##unaligned { \ 136 type v; \ 137 } __attribute__((packed)); \ 138 \ 139 static forceinline type \ 140 load_##type##_unaligned(const void *p) \ 141 { \ 142 return ((const struct type##unaligned *)p)->v; \ 143 } \ 144 \ 145 static forceinline void \ 146 store_##type##_unaligned(type v, void *p) \ 147 { \ 148 ((struct type##unaligned *)p)->v = v; \ 149 } 150 151 #define bsr32(n) (31 - __builtin_clz(n)) 152 #define bsr64(n) (63 - __builtin_clzll(n)) 153 #define bsf32(n) __builtin_ctz(n) 154 #define bsf64(n) __builtin_ctzll(n) 155 156 #endif // GO_SRC_GITHUB_COM_GRAILBIO_BASE_COMPRESS_LIBDEFLATE_COMPILER_GCC_H_