#ifndef _MACHINE_ATOMIC_H_
#define _MACHINE_ATOMIC_H_
#if defined(_KERNEL)
static __inline void
atomic_setbits_ulong(volatile unsigned long *ulp, unsigned long v)
{
unsigned long t0;
__asm volatile(
"# BEGIN atomic_setbits_ulong\n"
"1: ldq_l %0, %1 \n"
" or %0, %2, %0 \n"
" stq_c %0, %1 \n"
" beq %0, 2f \n"
" mb \n"
" br 3f \n"
"2: br 1b \n"
"3: \n"
" # END atomic_setbits_ulong"
: "=&r" (t0), "=m" (*ulp)
: "r" (v)
: "memory");
}
static __inline void
atomic_clearbits_ulong(volatile unsigned long *ulp, unsigned long v)
{
unsigned long t0;
__asm volatile(
"# BEGIN atomic_clearbits_ulong\n"
"1: ldq_l %0, %1 \n"
" and %0, %2, %0 \n"
" stq_c %0, %1 \n"
" beq %0, 2f \n"
" mb \n"
" br 3f \n"
"2: br 1b \n"
"3: \n"
" # END atomic_clearbits_ulong"
: "=&r" (t0), "=m" (*ulp)
: "r" (~v)
: "memory");
}
static __inline void
atomic_add_ulong(volatile unsigned long *ulp, unsigned long v)
{
unsigned long t0;
__asm volatile(
"# BEGIN atomic_add_ulong\n"
"1: ldq_l %0, %1 \n"
" addq %0, %2, %0 \n"
" stq_c %0, %1 \n"
" beq %0, 2f \n"
" mb \n"
" br 3f \n"
"2: br 1b \n"
"3: \n"
" # END atomic_add_ulong"
: "=&r" (t0), "=m" (*ulp)
: "r" (v)
: "memory");
}
static __inline void
atomic_sub_ulong(volatile unsigned long *ulp, unsigned long v)
{
unsigned long t0;
__asm volatile(
"# BEGIN atomic_sub_ulong\n"
"1: ldq_l %0, %1 \n"
" subq %0, %2, %0 \n"
" stq_c %0, %1 \n"
" beq %0, 2f \n"
" mb \n"
" br 3f \n"
"2: br 1b \n"
"3: \n"
" # END atomic_sub_ulong"
: "=&r" (t0), "=m" (*ulp)
: "r" (v)
: "memory");
}
static __inline unsigned long
atomic_loadlatch_ulong(volatile unsigned long *ulp, unsigned long v)
{
unsigned long t0, v0;
__asm volatile(
"# BEGIN atomic_loadlatch_ulong\n"
"1: mov %3, %0 \n"
" ldq_l %1, %2 \n"
" stq_c %0, %2 \n"
" beq %0, 2f \n"
" mb \n"
" br 3f \n"
"2: br 1b \n"
"3: \n"
" # END atomic_loadlatch_ulong"
: "=&r" (t0), "=r" (v0), "=m" (*ulp)
: "r" (v)
: "memory");
return (v0);
}
static __inline void
atomic_setbits_int(volatile unsigned int *uip, unsigned int v)
{
unsigned int t0;
__asm volatile(
"# BEGIN atomic_setbits_ulong\n"
"1: ldl_l %0, %1 \n"
" or %0, %2, %0 \n"
" stl_c %0, %1 \n"
" beq %0, 2f \n"
" mb \n"
" br 3f \n"
"2: br 1b \n"
"3: \n"
" # END atomic_setbits_int"
: "=&r" (t0), "=m" (*uip)
: "r" (v)
: "memory");
}
static __inline void
atomic_clearbits_int(volatile unsigned int *uip, unsigned int v)
{
unsigned int t0;
__asm volatile(
"# BEGIN atomic_clearbits_int\n"
"1: ldl_l %0, %1 \n"
" and %0, %2, %0 \n"
" stl_c %0, %1 \n"
" beq %0, 2f \n"
" mb \n"
" br 3f \n"
"2: br 1b \n"
"3: \n"
" # END atomic_clearbits_int"
: "=&r" (t0), "=m" (*uip)
: "r" (~v)
: "memory");
}
static __inline void
atomic_add_int(volatile int *ulp, int v)
{
unsigned long t0;
__asm volatile(
"# BEGIN atomic_add_int\n"
"1: ldl_l %0, %1 \n"
" addl %0, %2, %0 \n"
" stl_c %0, %1 \n"
" beq %0, 2f \n"
" mb \n"
" br 3f \n"
"2: br 1b \n"
"3: \n"
" # END atomic_add_ulong"
: "=&r" (t0), "=m" (*ulp)
: "r" (v)
: "memory");
}
#endif
#endif