#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_ao_t.h"
void AO_sync(void);
#pragma mc_func AO_sync { "7c0004ac" }
#ifdef __NO_LWSYNC__
# define AO_lwsync AO_sync
#else
void AO_lwsync(void);
#pragma mc_func AO_lwsync { "7c2004ac" }
#endif
#define AO_nop_write() AO_lwsync()
#define AO_HAVE_nop_write
#define AO_nop_read() AO_lwsync()
#define AO_HAVE_nop_read
AO_INLINE AO_t
AO_load_acquire(const volatile AO_t *addr)
{
AO_t result = *addr;
AO_lwsync();
return result;
}
#define AO_HAVE_load_acquire
AO_INLINE void
AO_store_release(volatile AO_t *addr, AO_t value)
{
AO_lwsync();
*addr = value;
}
#define AO_HAVE_store_release
#ifndef AO_PREFER_GENERALIZED
AO_INLINE AO_TS_VAL_t
AO_test_and_set(volatile AO_TS_t *addr) {
#if defined(__powerpc64__) || defined(__ppc64__) || defined(__64BIT__)
unsigned long oldval;
unsigned long temp = 1;
__asm__ __volatile__(
"1:ldarx %0,0,%1\n"
"cmpdi %0, 0\n"
"bne 2f\n"
"stdcx. %2,0,%1\n"
"bne- 1b\n"
"2:\n"
: "=&r"(oldval)
: "r"(addr), "r"(temp)
: "memory", "cr0");
#else
int oldval;
int temp = 1;
__asm__ __volatile__(
"1:lwarx %0,0,%1\n"
"cmpwi %0, 0\n"
"bne 2f\n"
"stwcx. %2,0,%1\n"
"bne- 1b\n"
"2:\n"
: "=&r"(oldval)
: "r"(addr), "r"(temp)
: "memory", "cr0");
#endif
return (AO_TS_VAL_t)oldval;
}
#define AO_HAVE_test_and_set
AO_INLINE AO_TS_VAL_t
AO_test_and_set_acquire(volatile AO_TS_t *addr) {
AO_TS_VAL_t result = AO_test_and_set(addr);
AO_lwsync();
return result;
}
#define AO_HAVE_test_and_set_acquire
AO_INLINE AO_TS_VAL_t
AO_test_and_set_release(volatile AO_TS_t *addr) {
AO_lwsync();
return AO_test_and_set(addr);
}
#define AO_HAVE_test_and_set_release
AO_INLINE AO_TS_VAL_t
AO_test_and_set_full(volatile AO_TS_t *addr) {
AO_TS_VAL_t result;
AO_lwsync();
result = AO_test_and_set(addr);
AO_lwsync();
return result;
}
#define AO_HAVE_test_and_set_full
#endif
AO_INLINE AO_t
AO_fetch_compare_and_swap(volatile AO_t *addr, AO_t old_val, AO_t new_val)
{
AO_t fetched_val;
# if defined(__powerpc64__) || defined(__ppc64__) || defined(__64BIT__)
__asm__ __volatile__(
"1:ldarx %0,0,%1\n"
"cmpd %0, %3\n"
"bne 2f\n"
"stdcx. %2,0,%1\n"
"bne- 1b\n"
"2:\n"
: "=&r"(fetched_val)
: "r"(addr), "r"(new_val), "r"(old_val)
: "memory", "cr0");
# else
__asm__ __volatile__(
"1:lwarx %0,0,%1\n"
"cmpw %0, %3\n"
"bne 2f\n"
"stwcx. %2,0,%1\n"
"bne- 1b\n"
"2:\n"
: "=&r"(fetched_val)
: "r"(addr), "r"(new_val), "r"(old_val)
: "memory", "cr0");
# endif
return fetched_val;
}
#define AO_HAVE_fetch_compare_and_swap
AO_INLINE AO_t
AO_fetch_compare_and_swap_acquire(volatile AO_t *addr, AO_t old_val,
AO_t new_val)
{
AO_t result = AO_fetch_compare_and_swap(addr, old_val, new_val);
AO_lwsync();
return result;
}
#define AO_HAVE_fetch_compare_and_swap_acquire
AO_INLINE AO_t
AO_fetch_compare_and_swap_release(volatile AO_t *addr, AO_t old_val,
AO_t new_val)
{
AO_lwsync();
return AO_fetch_compare_and_swap(addr, old_val, new_val);
}
#define AO_HAVE_fetch_compare_and_swap_release
AO_INLINE AO_t
AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val,
AO_t new_val)
{
AO_t result;
AO_lwsync();
result = AO_fetch_compare_and_swap(addr, old_val, new_val);
AO_lwsync();
return result;
}
#define AO_HAVE_fetch_compare_and_swap_full