#ifndef _ALPHA_RWSEM_XCHGADD_H #define _ALPHA_RWSEM_XCHGADD_H #include /* BITS_PER_LONG */ static inline void __down_read(struct rw_semaphore *sem) { long count, temp; __asm__ __volatile__( "1: ldq_l %0,%1\n" " addq %0,1,%2\n" " stq_c %2,%1\n" " beq %2,2f\n" #ifdef CONFIG_SMP " mb\n" #endif ".subsection 2\n" "2: br 1b\n" ".previous" :"=&r" (count), "=m" (sem->count), "=&r" (temp) :"m" (sem->count) : "memory"); if (count < 0) rwsem_down_failed(sem, RWSEM_READ_BLOCKING_BIAS); } static inline void __down_write(struct rw_semaphore *sem) { long granted, temp = RWSEM_WRITE_BIAS + RWSEM_READ_BIAS; __asm__ __volatile__( "1: ldq_l %0,%1\n" " addq %0,%2,%2\n" " stq_c %2,%1\n" " beq %2,2f\n" #ifdef CONFIG_SMP " mb\n" #endif " cmpeq %0,0,%0\n" ".subsection 2\n" "2: br 1b\n" ".previous" :"=&r" (granted), "=m" (sem->count), "=&r" (temp) :"2" (temp),"m" (sem->count) : "memory"); if (!granted) rwsem_down_failed(sem, RWSEM_WRITE_BLOCKING_BIAS); } static inline void __up_read(struct rw_semaphore *sem) { long oldcount, temp; __asm__ __volatile__( #ifdef CONFIG_SMP " mb\n" #endif "1: ldq_l %0,%1\n" " subq %0,1,%2\n" " stq_c %2,%1\n" " beq %2,2f\n" " subl %0,1,%2\n" ".subsection 2\n" "2: br 1b\n" ".previous" :"=&r" (oldcount), "=m" (sem->count), "=&r" (temp) :"m" (sem->count) : "memory"); if (oldcount < 0 && temp == 0) rwsem_wake(sem); } static inline void __up_write(struct rw_semaphore *sem) { long count, temp = RWSEM_READ_BIAS + RWSEM_WRITE_BIAS; __asm__ __volatile__( #ifdef CONFIG_SMP " mb\n" #endif "1: ldq_l %0,%1\n" " subq %0,%2,%2\n" " mov %2,%0\n" " stq_c %2,%1\n" " beq %2,2f\n" ".subsection 2\n" "2: br 1b\n" ".previous" :"=&r" (count), "=m" (sem->count), "=&r" (temp) :"2" (temp), "m" (sem->count) : "memory"); if (count < 0) rwsem_wake(sem); } static inline long rwsem_xchgadd(long value, long * count) { long ret, temp; __asm__ __volatile__( "1: ldq_l %0,%1\n" " addq %0,%3,%2\n" " stq_c %2,%1\n" " beq %2,2f\n" ".subsection 2\n" "2: br 1b\n" ".previous" :"=&r" (ret), "=m" (count), "=&r" (temp) :"Ir" (value), "m" (count) : "memory"); return ret; } #endif