Define CLANG/GNUC_PREREQ macros to check gcc/clang minimum version
authorIvan Maidanski <ivmai@mail.ru>
Mon, 6 Mar 2017 04:32:19 +0000 (07:32 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Mon, 6 Mar 2017 04:32:19 +0000 (07:32 +0300)
(code refactoring)

* src/atomic_ops.h (AO_GNUC_PREREQ, AO_CLANG_PREREQ): New internal
macro.
* src/atomic_ops.h (AO_EXPECT_FALSE): Use AO_GNUC_PREREQ() instead of
direct use of __GNUC[_MINOR]__.
* src/atomic_ops.h [__x86_64__] (AO_USE_SYNC_CAS_BUILTIN): Likewise.
* src/atomic_ops/sysdeps/gcc/arm.h (AO_GCC_ATOMIC_TEST_AND_SET):
Likewise.
* src/atomic_ops/sysdeps/gcc/mips.h: Likewise.
* src/atomic_ops/sysdeps/gcc/tile.h: Likewise.
* src/atomic_ops/sysdeps/gcc/x86.h (AO_GCC_ATOMIC_TEST_AND_SET):
Likewise.
* src/atomic_ops/sysdeps/standard_ao_double_t.h (pragma GCC,
double_ptr_storage): Likewise.
* src/atomic_ops.h [!AO_ATTR_NO_SANITIZE_MEMORY]
(AO_ATTR_NO_SANITIZE_MEMORY): Use AO_CLANG_PREREQ() instead of direct
use __clang_major__ and __clang_minor__.
* src/atomic_ops/sysdeps/gcc/arm.h (AO_GCC_ATOMIC_TEST_AND_SET,
AO_ARM_HAVE_LDREXD): Likewise.
* src/atomic_ops/sysdeps/gcc/mips.h: Likewise.
* src/atomic_ops/sysdeps/gcc/tile.h: Likewise.
* src/atomic_ops/sysdeps/gcc/x86.h (AO_GCC_ATOMIC_TEST_AND_SET,
AO_SKIPATOMIC_double_load): Likewise.
* src/atomic_ops/sysdeps/standard_ao_double_t.h (pragma GCC): Likewise.

src/atomic_ops.h
src/atomic_ops/sysdeps/gcc/arm.h
src/atomic_ops/sysdeps/gcc/mips.h
src/atomic_ops/sysdeps/gcc/tile.h
src/atomic_ops/sysdeps/gcc/x86.h
src/atomic_ops/sysdeps/standard_ao_double_t.h

index 1057136..92b4e3d 100644 (file)
 
 #define AO_TS_INITIALIZER ((AO_TS_t)AO_TS_CLEAR)
 
+/* Convenient internal macro to test version of GCC.    */
+#if defined(__GNUC__) && defined(__GNUC_MINOR__)
+# define AO_GNUC_PREREQ(major, minor) \
+            ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((major) << 16) + (minor))
+#else
+# define AO_GNUC_PREREQ(major, minor) 0 /* false */
+#endif
+
+/* Convenient internal macro to test version of Clang.  */
+#if defined(__clang__) && defined(__clang_major__)
+# define AO_CLANG_PREREQ(major, minor) \
+    ((__clang_major__ << 16) + __clang_minor__ >= ((major) << 16) + (minor))
+#else
+# define AO_CLANG_PREREQ(major, minor) 0 /* false */
+#endif
+
 /* Platform-dependent stuff:                                    */
 #if (defined(__GNUC__) || defined(_MSC_VER) || defined(__INTEL_COMPILER) \
         || defined(__DMC__) || defined(__WATCOMC__)) && !defined(AO_NO_INLINE)
 # define AO_INLINE static
 #endif
 
-#if __GNUC__ >= 3 && !defined(LINT2)
+#if AO_GNUC_PREREQ(3, 0) && !defined(LINT2)
 # define AO_EXPECT_FALSE(expr) __builtin_expect(expr, 0)
   /* Equivalent to (expr) but predict that usually (expr) == 0. */
 #else
 
 #ifndef AO_ATTR_NO_SANITIZE_MEMORY
 # if defined(AO_MEMORY_SANITIZER) \
-        && (!defined(__clang__) || __clang_major__ > 3 \
-            || (__clang_major__ == 3 && __clang_minor__ >= 8))
+        && (!defined(__clang__) || AO_CLANG_PREREQ(3, 8))
 #   define AO_ATTR_NO_SANITIZE_MEMORY __attribute__((no_sanitize("memory")))
 # else
 #   define AO_ATTR_NO_SANITIZE_MEMORY /* empty */
 #   include "atomic_ops/sysdeps/gcc/x86.h"
 # endif /* __i386__ */
 # if defined(__x86_64__)
-#   if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)) \
-       && !defined(AO_USE_SYNC_CAS_BUILTIN)
+#   if AO_GNUC_PREREQ(4, 2) && !defined(AO_USE_SYNC_CAS_BUILTIN)
       /* It is safe to use __sync CAS built-in on this architecture.    */
 #     define AO_USE_SYNC_CAS_BUILTIN
 #   endif
index f3dc644..8ad4be2 100644 (file)
@@ -15,9 +15,7 @@
  *
  */
 
-#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) \
-     || __clang_major__ > 3 \
-     || (__clang_major__ == 3 && __clang_minor__ >= 5)) \
+#if (AO_GNUC_PREREQ(4, 8) || AO_CLANG_PREREQ(3, 5)) \
     && !defined(AO_DISABLE_GCC_ATOMICS)
   /* Probably, it could be enabled even for earlier gcc/clang versions. */
 # define AO_GCC_ATOMIC_TEST_AND_SET
@@ -82,8 +80,7 @@
 #   if (!defined(__thumb__) \
         || (defined(__thumb2__) && !defined(__ARM_ARCH_7__) \
             && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__))) \
-       && (!defined(__clang__) || (__clang_major__ > 3) \
-            || (__clang_major__ == 3 && __clang_minor__ >= 3))
+       && (!defined(__clang__) || AO_CLANG_PREREQ(3, 3))
       /* LDREXD/STREXD present in ARMv6K/M+ (see gas/config/tc-arm.c).  */
       /* In the Thumb mode, this works only starting from ARMv7 (except */
       /* for the base and 'M' models).  Clang3.2 (and earlier) does not */
index e093897..9024542 100644 (file)
@@ -23,9 +23,7 @@
 /* #include "../standard_ao_double_t.h" */
 /* TODO: Implement double-wide operations if available. */
 
-#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9) \
-     || __clang_major__ > 3 \
-     || (__clang_major__ == 3 && __clang_minor__ >= 5)) \
+#if (AO_GNUC_PREREQ(4, 9) || AO_CLANG_PREREQ(3, 5)) \
     && !defined(AO_DISABLE_GCC_ATOMICS)
   /* Probably, it could be enabled even for earlier gcc/clang versions. */
 
index 0c13180..e42be1e 100644 (file)
@@ -11,9 +11,7 @@
 
 /* Minimal support for tile.    */
 
-#if ((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) \
-     || __clang_major__ > 3 \
-     || (__clang_major__ == 3 && __clang_minor__ >= 4)) \
+#if (AO_GNUC_PREREQ(4, 8) || AO_CLANG_PREREQ(3, 4)) \
     && !defined(AO_DISABLE_GCC_ATOMICS)
 
 # include "generic.h"
index 3ab80cf..20bf77f 100644 (file)
  * Some of the machine specific code was borrowed from our GC distribution.
  */
 
-#if (((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) \
-      && !defined(__INTEL_COMPILER)) /* TODO: test and enable icc */ \
-     || __clang_major__ > 3 \
-     || (__clang_major__ == 3 && __clang_minor__ >= 4)) \
+#if (AO_GNUC_PREREQ(4, 8) || AO_CLANG_PREREQ(3, 4)) \
+    && !defined(__INTEL_COMPILER) /* TODO: test and enable icc */ \
     && !defined(AO_DISABLE_GCC_ATOMICS)
 # define AO_GCC_ATOMIC_TEST_AND_SET
 
@@ -28,8 +26,8 @@
      && (!(defined(__x86_64__) || defined(__APPLE_CC__) \
            || defined(__CYGWIN__) || defined(AO_PREFER_BUILTIN_ATOMICS)) \
          || (defined(__x86_64__) && !defined(__ILP32__) \
-             && ((__clang_major__ == 3 && __clang_minor__ == 4 \
-                   && !defined(AO_PREFER_BUILTIN_ATOMICS)) \
+             && (!(AO_CLANG_PREREQ(3, 5) \
+                   || defined(AO_PREFER_BUILTIN_ATOMICS)) \
                  || defined(AO_ADDRESS_SANITIZER))))
     /* As of clang-3.8 i686 (NDK r11c), it requires -latomic for all    */
     /* the double-wide operations.  Same for clang-3.4/x64.  For now,   */
index 316b07a..a80a236 100644 (file)
@@ -25,8 +25,7 @@
 #if ((defined(__x86_64__) && defined(AO_GCC_ATOMIC_TEST_AND_SET)) \
      || defined(__aarch64__)) && !defined(__ILP32__)
   /* x86-64: __m128 is not applicable to atomic intrinsics.     */
-# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) \
-     || __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 6)
+# if AO_GNUC_PREREQ(4, 7) || AO_CLANG_PREREQ(3, 6)
 #   pragma GCC diagnostic push
     /* Suppress warning about __int128 type.      */
 #   if defined(__clang__)
@@ -40,7 +39,7 @@
 # else /* pragma diagnostic is not supported */
     typedef unsigned __int128 double_ptr_storage;
 # endif
-#elif ((defined(__x86_64__) && __GNUC__ >= 4) || defined(_WIN64)) \
+#elif ((defined(__x86_64__) && AO_GNUC_PREREQ(4, 0)) || defined(_WIN64)) \
       && !defined(__ILP32__)
   /* x86-64 (except for x32): __m128 serves as a placeholder which also */
   /* requires the compiler to align it on 16-byte boundary (as required */