#if !defined(AO_ATOMIC_OPS_H) || defined(AO_ATOMIC_OPS_INCLUDED)
# error This file should not be included directly.
#endif
#include "../all_aligned_atomic_load_store.h"
#include "../test_and_set_t_is_char.h"
#if !defined(AO_USE_PENTIUM4_INSTRS) && !defined(__i386)
# define AO_USE_PENTIUM4_INSTRS
#endif
#if defined(AO_USE_PENTIUM4_INSTRS)
AO_INLINE void
AO_nop_full(void)
{
__asm__ __volatile__ ("mfence" : : : "memory");
}
# define AO_HAVE_nop_full
#else
#endif
#ifndef AO_PREFER_GENERALIZED
AO_INLINE AO_t
AO_fetch_and_add_full (volatile AO_t *p, AO_t incr)
{
AO_t result;
__asm__ __volatile__ ("lock; xadd %0, %1"
: "=r" (result), "+m" (*p)
: "0" (incr)
: "memory");
return result;
}
# define AO_HAVE_fetch_and_add_full
#endif
AO_INLINE unsigned char
AO_char_fetch_and_add_full (volatile unsigned char *p, unsigned char incr)
{
unsigned char result;
__asm__ __volatile__ ("lock; xaddb %0, %1"
: "=q" (result), "+m" (*p)
: "0" (incr)
: "memory");
return result;
}
#define AO_HAVE_char_fetch_and_add_full
AO_INLINE unsigned short
AO_short_fetch_and_add_full (volatile unsigned short *p, unsigned short incr)
{
unsigned short result;
__asm__ __volatile__ ("lock; xaddw %0, %1"
: "=r" (result), "+m" (*p)
: "0" (incr)
: "memory");
return result;
}
#define AO_HAVE_short_fetch_and_add_full
#ifndef AO_PREFER_GENERALIZED
AO_INLINE void
AO_and_full (volatile AO_t *p, AO_t value)
{
__asm__ __volatile__ ("lock; and %1, %0"
: "+m" (*p)
: "r" (value)
: "memory");
}
# define AO_HAVE_and_full
AO_INLINE void
AO_or_full (volatile AO_t *p, AO_t value)
{
__asm__ __volatile__ ("lock; or %1, %0"
: "+m" (*p)
: "r" (value)
: "memory");
}
# define AO_HAVE_or_full
AO_INLINE void
AO_xor_full (volatile AO_t *p, AO_t value)
{
__asm__ __volatile__ ("lock; xor %1, %0"
: "+m" (*p)
: "r" (value)
: "memory");
}
# define AO_HAVE_xor_full
#endif
AO_INLINE AO_TS_VAL_t
AO_test_and_set_full (volatile AO_TS_t *addr)
{
AO_TS_t oldval;
__asm__ __volatile__ ("xchg %b0, %1"
: "=q" (oldval), "+m" (*addr)
: "0" (0xff)
: "memory");
return (AO_TS_VAL_t)oldval;
}
#define AO_HAVE_test_and_set_full
#ifndef AO_GENERALIZE_ASM_BOOL_CAS
AO_INLINE int
AO_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val)
{
char result;
__asm__ __volatile__ ("lock; cmpxchg %2, %0; setz %1"
: "+m" (*addr), "=a" (result)
: "r" (new_val), "a" (old)
: "memory");
return (int) result;
}
# define AO_HAVE_compare_and_swap_full
#endif
AO_INLINE AO_t
AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val,
AO_t new_val)
{
AO_t fetched_val;
__asm__ __volatile__ ("lock; cmpxchg %2, %0"
: "+m" (*addr), "=a" (fetched_val)
: "r" (new_val), "a" (old_val)
: "memory");
return fetched_val;
}
#define AO_HAVE_fetch_compare_and_swap_full
#if defined(__i386)
# ifndef AO_NO_CMPXCHG8B
# include "../standard_ao_double_t.h"
# define AO_ACCESS_double_CHECK_ALIGNED
# include "../loadstore/double_atomic_load_store.h"
AO_INLINE int
AO_compare_double_and_swap_double_full(volatile AO_double_t *addr,
AO_t old_val1, AO_t old_val2,
AO_t new_val1, AO_t new_val2)
{
AO_t dummy;
char result;
__asm__ __volatile__ ("lock; cmpxchg8b %0; setz %1"
: "+m" (*addr), "=a" (result), "=d" (dummy)
: "d" (old_val2), "a" (old_val1),
"c" (new_val2), "b" (new_val1)
: "memory");
return (int) result;
}
# define AO_HAVE_compare_double_and_swap_double_full
# endif
# define AO_T_IS_INT
#else
AO_INLINE unsigned int
AO_int_fetch_and_add_full (volatile unsigned int *p, unsigned int incr)
{
unsigned int result;
__asm__ __volatile__ ("lock; xaddl %0, %1"
: "=r" (result), "+m" (*p)
: "0" (incr)
: "memory");
return result;
}
# define AO_HAVE_int_fetch_and_add_full
# ifdef AO_CMPXCHG16B_AVAILABLE
# include "../standard_ao_double_t.h"
AO_INLINE int
AO_compare_double_and_swap_double_full (volatile AO_double_t *addr,
AO_t old_val1, AO_t old_val2,
AO_t new_val1, AO_t new_val2)
{
AO_t dummy;
char result;
__asm__ __volatile__ ("lock; cmpxchg16b %0; setz %1"
: "+m" (*addr), "=a" (result), "=d" (dummy)
: "d" (old_val2), "a" (old_val1),
"c" (new_val2), "b" (new_val1)
: "memory");
return (int) result;
}
# define AO_HAVE_compare_double_and_swap_double_full
# endif
#endif
#include "../ordered_except_wr.h"