diff options
author | Tom Fogal <[email protected]> | 2010-09-26 18:57:59 -0600 |
---|---|---|
committer | Tom Fogal <[email protected]> | 2010-09-30 13:20:51 -0600 |
commit | 76a60faf529e6107e3f50406c0d40e64bc484686 (patch) | |
tree | b2210e433ec2276467603ca556777bec2e241145 /src/gallium/auxiliary/util/u_atomic.h | |
parent | 0c86e1f29483d9557f30796c03b94a34d965c095 (diff) |
Implement x86_64 atomics for compilers w/o intrinsics.
Really old gcc's (3.3, at least) don't have support for the
intrinsics we need. This implements a fallback for that case.
Diffstat (limited to 'src/gallium/auxiliary/util/u_atomic.h')
-rw-r--r-- | src/gallium/auxiliary/util/u_atomic.h | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/gallium/auxiliary/util/u_atomic.h b/src/gallium/auxiliary/util/u_atomic.h index a1568233906..8434491a421 100644 --- a/src/gallium/auxiliary/util/u_atomic.h +++ b/src/gallium/auxiliary/util/u_atomic.h @@ -29,6 +29,8 @@ #define PIPE_ATOMIC_ASM_MSVC_X86 #elif (defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86)) #define PIPE_ATOMIC_ASM_GCC_X86 +#elif (defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86_64)) +#define PIPE_ATOMIC_ASM_GCC_X86_64 #elif defined(PIPE_CC_GCC) && (PIPE_CC_GCC_VERSION >= 401) #define PIPE_ATOMIC_GCC_INTRINSIC #else @@ -36,6 +38,51 @@ #endif +#if defined(PIPE_ATOMIC_ASM_GCC_X86_64) +#define PIPE_ATOMIC "GCC x86_64 assembly" + +#ifdef __cplusplus +extern "C" { +#endif + +#define p_atomic_set(_v, _i) (*(_v) = (_i)) +#define p_atomic_read(_v) (*(_v)) + +static INLINE boolean +p_atomic_dec_zero(int32_t *v) +{ + unsigned char c; + + __asm__ __volatile__("lock; decl %0; sete %1":"+m"(*v), "=qm"(c) + ::"memory"); + + return c != 0; +} + +static INLINE void +p_atomic_inc(int32_t *v) +{ + __asm__ __volatile__("lock; incl %0":"+m"(*v)); +} + +static INLINE void +p_atomic_dec(int32_t *v) +{ + __asm__ __volatile__("lock; decl %0":"+m"(*v)); +} + +static INLINE int32_t +p_atomic_cmpxchg(int32_t *v, int32_t old, int32_t _new) +{ + return __sync_val_compare_and_swap(v, old, _new); +} + +#ifdef __cplusplus +} +#endif + +#endif /* PIPE_ATOMIC_ASM_GCC_X86_64 */ + #if defined(PIPE_ATOMIC_ASM_GCC_X86) |