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_