dnl Check for compiler builtins
AX_GCC_BUILTIN([__builtin_bswap32])
AX_GCC_BUILTIN([__builtin_bswap64])
+AX_GCC_BUILTIN([__builtin_clz])
+AX_GCC_BUILTIN([__builtin_clzll])
+AX_GCC_BUILTIN([__builtin_ctz])
+AX_GCC_BUILTIN([__builtin_expect])
+AX_GCC_BUILTIN([__builtin_ffs])
+AX_GCC_BUILTIN([__builtin_ffsll])
+AX_GCC_BUILTIN([__builtin_popcount])
+AX_GCC_BUILTIN([__builtin_popcountll])
+AX_GCC_BUILTIN([__builtin_unreachable])
AM_CONDITIONAL([GEN_ASM_OFFSETS], test "x$GEN_ASM_OFFSETS" = xyes)
env.Append(CCFLAGS = ['-fopenmp'])
env.Append(LIBS = ['gomp'])
+ if gcc_compat:
+ ccversion = env['CCVERSION']
+ cppdefines += [
+ 'HAVE___BUILTIN_EXPECT',
+ 'HAVE___BUILTIN_FFS',
+ 'HAVE___BUILTIN_FFSLL',
+ ]
+ if distutils.version.LooseVersion(ccversion) >= distutils.version.LooseVersion('3.4'):
+ cppdefines += [
+ 'HAVE___BUILTIN_CTZ',
+ 'HAVE___BUILTIN_POPCOUNT',
+ 'HAVE___BUILTIN_POPCOUNTLL',
+ 'HAVE___BUILTIN_CLZ',
+ 'HAVE___BUILTIN_CLZLL',
+ ]
+ if distutils.version.LooseVersion(ccversion) >= distutils.version.LooseVersion('4.5'):
+ cppdefines += ['HAVE___BUILTIN_UNREACHABLE']
+
# Load tools
env.Tool('lex')
env.Tool('yacc')
*/
inline int count_trailing_one_bits(unsigned value)
{
-#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
+#ifdef HAVE___BUILTIN_CTZ
return __builtin_ctz(~value);
#else
return _mesa_bitcount(value & ~(value + 1));
/*@{*/
-#ifndef __GNUC__
+#ifndef HAVE___BUILTIN_FFS
/**
* Find the first bit set in a word.
*/
}
return bit;
}
+#endif
-
+#ifndef HAVE___BUILTIN_FFSLL
/**
* Find position of first bit set in given value.
* XXX Warning: this function can only be used on 64-bit systems!
return 0;
}
-#endif /* __GNUC__ */
+#endif
-#if !defined(__GNUC__) ||\
- ((__GNUC__ * 100 + __GNUC_MINOR__) < 304) /* Not gcc 3.4 or later */
+#ifndef HAVE___BUILTIN_POPCOUNT
/**
* Return number of bits set in given GLuint.
*/
}
return bits;
}
+#endif
+#ifndef HAVE___BUILTIN_POPCOUNTLL
/**
* Return number of bits set in given 64-bit uint.
*/
static inline int32_t
_mesa_next_pow_two_32(uint32_t x)
{
-#if defined(__GNUC__) && \
- ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
+#ifdef HAVE___BUILTIN_CLZ
uint32_t y = (x != 1);
return (1 + y) << ((__builtin_clz(x - y) ^ 31) );
#else
static inline int64_t
_mesa_next_pow_two_64(uint64_t x)
{
-#if defined(__GNUC__) && \
- ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
+#ifdef HAVE___BUILTIN_CLZLL
uint64_t y = (x != 1);
- if (sizeof(x) == sizeof(long))
- return (1 + y) << ((__builtin_clzl(x - y) ^ 63));
- else
- return (1 + y) << ((__builtin_clzll(x - y) ^ 63));
+ STATIC_ASSERT(sizeof(x) == sizeof(long long));
+ return (1 + y) << ((__builtin_clzll(x - y) ^ 63));
#else
x--;
x |= x >> 1;
static inline GLuint
_mesa_logbase2(GLuint n)
{
-#if defined(__GNUC__) && \
- ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
+#ifdef HAVE___BUILTIN_CLZ
return (31 - __builtin_clz(n | 1));
#else
GLuint pos = 0;
#ifndef FFS_DEFINED
#define FFS_DEFINED 1
-#ifdef __GNUC__
+#ifdef HAVE___BUILTIN_FFS
#define ffs __builtin_ffs
-#define ffsll __builtin_ffsll
#else
extern int ffs(int i);
+#endif
+
+#ifdef HAVE___BUILTIN_FFSLL
+#define ffsll __builtin_ffsll
+#else
extern int ffsll(long long int i);
-#endif /*__ GNUC__ */
+#endif
#endif /* FFS_DEFINED */
-#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
+#ifdef HAVE___BUILTIN_POPCOUNT
#define _mesa_bitcount(i) __builtin_popcount(i)
-#define _mesa_bitcount_64(i) __builtin_popcountll(i)
#else
extern unsigned int
_mesa_bitcount(unsigned int n);
+#endif
+
+#ifdef HAVE___BUILTIN_POPCOUNTLL
+#define _mesa_bitcount_64(i) __builtin_popcountll(i)
+#else
extern unsigned int
_mesa_bitcount_64(uint64_t n);
#endif
static inline unsigned int
_mesa_fls(unsigned int n)
{
-#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304)
+#ifdef HAVE___BUILTIN_CLZ
return n == 0 ? 0 : 32 - __builtin_clz(n);
#else
unsigned int v = 1;
/**
* __builtin_expect macros
*/
-#if !defined(__GNUC__)
+#if !defined(HAVE___BUILTIN_EXPECT)
# define __builtin_expect(x, y) (x)
#endif
#ifndef likely
-# ifdef __GNUC__
+# ifdef HAVE___BUILTIN_EXPECT
# define likely(x) __builtin_expect(!!(x), 1)
# define unlikely(x) __builtin_expect(!!(x), 0)
# else
* Unreachable macro. Useful for suppressing "control reaches end of non-void
* function" warnings.
*/
-#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 5
+#ifdef HAVE___BUILTIN_UNREACHABLE
#define unreachable(str) \
do { \
assert(!str); \
__builtin_unreachable(); \
} while (0)
-#elif (defined(__clang__) && defined(__has_builtin))
-# if __has_builtin(__builtin_unreachable)
-# define unreachable(str) \
-do { \
- assert(!str); \
- __builtin_unreachable(); \
-} while (0)
-# endif
#endif
#ifndef unreachable