Re: [PATCH 07/10] local_t : powerpc extension
On Feb 15, 2007, at 1:20 AM, Mathieu Desnoyers wrote: * Andrew Morton ([EMAIL PROTECTED]) wrote: On Sun, 11 Feb 2007 14:18:12 -0500 Mathieu Desnoyers <[EMAIL PROTECTED]> wrote: local_t : powerpc extension This diff contains changes which are also present in "[PATCH 07/10] atomic.h : Add atomic64 cmpxchg, xchg and add_unless to powerpc", resulting in rather a mess. I dropped the duplicated hunks from the later patch rather than this one, but I haven't tried to compile the result yet. Yes, sorry about that : the atomic.h diff has been duplicated in both the local and atomic changes. The change to system.h for local.h is to add the xchg_local and cmpxchg_local, while the change for atomic.h is to simply remove the #include from system.h. Here is a proper local.h diff, if it happens to become necessary, but simply removing the duplicated asm-powerpc/system.h hunks will be ok. Thanks, Signed-off-by: Mathieu Desnoyers <[EMAIL PROTECTED]> --- a/include/asm-powerpc/local.h +++ b/include/asm-powerpc/local.h @@ -1 +1,342 @@ -#include +#ifndef _ARCH_POWERPC_LOCAL_H +#define _ARCH_POWERPC_LOCAL_H + +#include +#include + +typedef struct +{ + atomic_long_t a; +} local_t; + +#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) } + +#define local_read(l) atomic_long_read(&(l)->a) +#define local_set(l,i) atomic_long_set(&(l)->a, (i)) + +#define local_add(i,l) atomic_long_add((i),(&(l)->a)) +#define local_sub(i,l) atomic_long_sub((i),(&(l)->a)) +#define local_inc(l) atomic_long_inc(&(l)->a) +#define local_dec(l) atomic_long_dec(&(l)->a) + +#ifndef __powerpc64__ + +static __inline__ int local_add_return(int a, local_t *l) +{ is there a reason this isn't local_add_return(long a, local_t *l) on ppc32? (same comment for other functions) - k - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 07/10] local_t : powerpc extension
* Andrew Morton ([EMAIL PROTECTED]) wrote: > On Sun, 11 Feb 2007 14:18:12 -0500 Mathieu Desnoyers <[EMAIL PROTECTED]> > wrote: > > > local_t : powerpc extension > > This diff contains changes which are also present in "[PATCH 07/10] > atomic.h : Add atomic64 cmpxchg, xchg and add_unless to powerpc", resulting > in rather a mess. > > I dropped the duplicated hunks from the later patch rather than this one, > but I haven't tried to compile the result yet. > Yes, sorry about that : the atomic.h diff has been duplicated in both the local and atomic changes. The change to system.h for local.h is to add the xchg_local and cmpxchg_local, while the change for atomic.h is to simply remove the #include from system.h. Here is a proper local.h diff, if it happens to become necessary, but simply removing the duplicated asm-powerpc/system.h hunks will be ok. Thanks, Signed-off-by: Mathieu Desnoyers <[EMAIL PROTECTED]> --- a/include/asm-powerpc/local.h +++ b/include/asm-powerpc/local.h @@ -1 +1,342 @@ -#include +#ifndef _ARCH_POWERPC_LOCAL_H +#define _ARCH_POWERPC_LOCAL_H + +#include +#include + +typedef struct +{ + atomic_long_t a; +} local_t; + +#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) } + +#define local_read(l) atomic_long_read(&(l)->a) +#define local_set(l,i) atomic_long_set(&(l)->a, (i)) + +#define local_add(i,l) atomic_long_add((i),(&(l)->a)) +#define local_sub(i,l) atomic_long_sub((i),(&(l)->a)) +#define local_inc(l) atomic_long_inc(&(l)->a) +#define local_dec(l) atomic_long_dec(&(l)->a) + +#ifndef __powerpc64__ + +static __inline__ int local_add_return(int a, local_t *l) +{ + int t; + + __asm__ __volatile__( +"1:lwarx %0,0,%2 # local_add_return\n\ + add %0,%1,%0\n" + PPC405_ERR77(0,%2) +" stwcx. %0,0,%2 \n\ + bne-1b" + : "=&r" (t) + : "r" (a), "r" (&(l->a.counter)) + : "cc", "memory"); + + return t; +} + +#define local_add_negative(a, l) (local_add_return((a), (l)) < 0) + +static __inline__ int local_sub_return(int a, local_t *l) +{ + int t; + + __asm__ __volatile__( +"1:lwarx %0,0,%2 # local_sub_return\n\ + subf%0,%1,%0\n" + PPC405_ERR77(0,%2) +" stwcx. %0,0,%2 \n\ + bne-1b" + : "=&r" (t) + : "r" (a), "r" (&(l->a.counter)) + : "cc", "memory"); + + return t; +} + +static __inline__ int local_inc_return(local_t *l) +{ + int t; + + __asm__ __volatile__( +"1:lwarx %0,0,%1 # local_inc_return\n\ + addic %0,%0,1\n" + PPC405_ERR77(0,%1) +" stwcx. %0,0,%1 \n\ + bne-1b" + : "=&r" (t) + : "r" (&(l->a.counter)) + : "cc", "memory"); + + return t; +} + +/* + * local_inc_and_test - increment and test + * @l: pointer of type local_t + * + * Atomically increments @l by 1 + * and returns true if the result is zero, or false for all + * other cases. + */ +#define local_inc_and_test(l) (local_inc_return(l) == 0) + +static __inline__ int local_dec_return(local_t *l) +{ + int t; + + __asm__ __volatile__( +"1:lwarx %0,0,%1 # local_dec_return\n\ + addic %0,%0,-1\n" + PPC405_ERR77(0,%1) +" stwcx. %0,0,%1\n\ + bne-1b" + : "=&r" (t) + : "r" (&(l->a.counter)) + : "cc", "memory"); + + return t; +} + +#define local_cmpxchg(l, o, n) \ + (cmpxchg_local(&((l)->a.counter), (o), (n))) +#define local_xchg(l, n) (xchg_local(&((l)->a.counter), (n))) + +/** + * local_add_unless - add unless the number is a given value + * @l: pointer of type local_t + * @a: the amount to add to v... + * @u: ...unless v is equal to u. + * + * Atomically adds @a to @l, so long as it was not @u. + * Returns non-zero if @l was not @u, and zero otherwise. + */ +static __inline__ int local_add_unless(local_t *l, int a, int u) +{ + int t; + + __asm__ __volatile__ ( +"1:lwarx %0,0,%1 # local_add_unless\n\ + cmpw0,%0,%3 \n\ + beq-2f \n\ + add %0,%2,%0 \n" + PPC405_ERR77(0,%2) +" stwcx. %0,0,%1 \n\ + bne-1b \n" +" subf%0,%2,%0 \n\ +2:" + : "=&r" (t) + : "r" (&(l->a.counter)), "r" (a), "r" (u) + : "cc", "memory"); + + return t != u; +} + +#define local_inc_not_zero(l) local_add_unless((l), 1, 0) + +#define local_sub_and_test(a, l) (local_sub_return((a), (l)) == 0) +#define local_dec_and_test(l) (local_dec_return((l)) == 0) + +/* + * Atomically test *l and decrement if it is greater than 0. + * The function returns the old value of *l minus 1. + */ +static __inline__ int local_dec_if_positive(local_t *l) +{ + int t; + + __asm__ __volatile__( +"1:lwarx %0,0,%1 # local_dec_if_positive\n\ + cmpwi %0,1\n\ + addi%0,%0,-1\n\ + blt-2f\n" + PPC405_ERR77(0,%1) +" stwcx. %0,0,%1\n\ + bne-1b" + "\n\ +2:": "=&b" (t) +
Re: [PATCH 07/10] local_t : powerpc extension
On Sun, 11 Feb 2007 14:18:12 -0500 Mathieu Desnoyers <[EMAIL PROTECTED]> wrote: > local_t : powerpc extension This diff contains changes which are also present in "[PATCH 07/10] atomic.h : Add atomic64 cmpxchg, xchg and add_unless to powerpc", resulting in rather a mess. I dropped the duplicated hunks from the later patch rather than this one, but I haven't tried to compile the result yet. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 07/10] local_t : powerpc extension
local_t : powerpc extension Signed-off-by: Mathieu Desnoyers <[EMAIL PROTECTED]> --- a/include/asm-powerpc/local.h +++ b/include/asm-powerpc/local.h @@ -1 +1,342 @@ -#include +#ifndef _ARCH_POWERPC_LOCAL_H +#define _ARCH_POWERPC_LOCAL_H + +#include +#include + +typedef struct +{ + atomic_long_t a; +} local_t; + +#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) } + +#define local_read(l) atomic_long_read(&(l)->a) +#define local_set(l,i) atomic_long_set(&(l)->a, (i)) + +#define local_add(i,l) atomic_long_add((i),(&(l)->a)) +#define local_sub(i,l) atomic_long_sub((i),(&(l)->a)) +#define local_inc(l) atomic_long_inc(&(l)->a) +#define local_dec(l) atomic_long_dec(&(l)->a) + +#ifndef __powerpc64__ + +static __inline__ int local_add_return(int a, local_t *l) +{ + int t; + + __asm__ __volatile__( +"1:lwarx %0,0,%2 # local_add_return\n\ + add %0,%1,%0\n" + PPC405_ERR77(0,%2) +" stwcx. %0,0,%2 \n\ + bne-1b" + : "=&r" (t) + : "r" (a), "r" (&(l->a.counter)) + : "cc", "memory"); + + return t; +} + +#define local_add_negative(a, l) (local_add_return((a), (l)) < 0) + +static __inline__ int local_sub_return(int a, local_t *l) +{ + int t; + + __asm__ __volatile__( +"1:lwarx %0,0,%2 # local_sub_return\n\ + subf%0,%1,%0\n" + PPC405_ERR77(0,%2) +" stwcx. %0,0,%2 \n\ + bne-1b" + : "=&r" (t) + : "r" (a), "r" (&(l->a.counter)) + : "cc", "memory"); + + return t; +} + +static __inline__ int local_inc_return(local_t *l) +{ + int t; + + __asm__ __volatile__( +"1:lwarx %0,0,%1 # local_inc_return\n\ + addic %0,%0,1\n" + PPC405_ERR77(0,%1) +" stwcx. %0,0,%1 \n\ + bne-1b" + : "=&r" (t) + : "r" (&(l->a.counter)) + : "cc", "memory"); + + return t; +} + +/* + * local_inc_and_test - increment and test + * @l: pointer of type local_t + * + * Atomically increments @l by 1 + * and returns true if the result is zero, or false for all + * other cases. + */ +#define local_inc_and_test(l) (local_inc_return(l) == 0) + +static __inline__ int local_dec_return(local_t *l) +{ + int t; + + __asm__ __volatile__( +"1:lwarx %0,0,%1 # local_dec_return\n\ + addic %0,%0,-1\n" + PPC405_ERR77(0,%1) +" stwcx. %0,0,%1\n\ + bne-1b" + : "=&r" (t) + : "r" (&(l->a.counter)) + : "cc", "memory"); + + return t; +} + +#define local_cmpxchg(l, o, n) \ + (cmpxchg_local(&((l)->a.counter), (o), (n))) +#define local_xchg(l, n) (xchg_local(&((l)->a.counter), (n))) + +/** + * local_add_unless - add unless the number is a given value + * @l: pointer of type local_t + * @a: the amount to add to v... + * @u: ...unless v is equal to u. + * + * Atomically adds @a to @l, so long as it was not @u. + * Returns non-zero if @l was not @u, and zero otherwise. + */ +static __inline__ int local_add_unless(local_t *l, int a, int u) +{ + int t; + + __asm__ __volatile__ ( +"1:lwarx %0,0,%1 # local_add_unless\n\ + cmpw0,%0,%3 \n\ + beq-2f \n\ + add %0,%2,%0 \n" + PPC405_ERR77(0,%2) +" stwcx. %0,0,%1 \n\ + bne-1b \n" +" subf%0,%2,%0 \n\ +2:" + : "=&r" (t) + : "r" (&(l->a.counter)), "r" (a), "r" (u) + : "cc", "memory"); + + return t != u; +} + +#define local_inc_not_zero(l) local_add_unless((l), 1, 0) + +#define local_sub_and_test(a, l) (local_sub_return((a), (l)) == 0) +#define local_dec_and_test(l) (local_dec_return((l)) == 0) + +/* + * Atomically test *l and decrement if it is greater than 0. + * The function returns the old value of *l minus 1. + */ +static __inline__ int local_dec_if_positive(local_t *l) +{ + int t; + + __asm__ __volatile__( +"1:lwarx %0,0,%1 # local_dec_if_positive\n\ + cmpwi %0,1\n\ + addi%0,%0,-1\n\ + blt-2f\n" + PPC405_ERR77(0,%1) +" stwcx. %0,0,%1\n\ + bne-1b" + "\n\ +2:": "=&b" (t) + : "r" (&(l->a.counter)) + : "cc", "memory"); + + return t; +} + +#else /* __powerpc64__ */ + +static __inline__ long local_add_return(long a, local_t *l) +{ + long t; + + __asm__ __volatile__( +"1:ldarx %0,0,%2 # local_add_return\n\ + add %0,%1,%0\n\ + stdcx. %0,0,%2 \n\ + bne-1b" + : "=&r" (t) + : "r" (a), "r" (&(l->a.counter)) + : "cc", "memory"); + + return t; +} + +#define local_add_negative(a, l) (local_add_return((a), (l)) < 0) + +static __inline__ long local_sub_return(long a, local_t *l) +{ + long t; + + __asm__ __volatile__( +"1:ldarx %0,0,%2 # local_sub_return\n\ + subf%0,%1,%0\n\ + stdcx. %0,0,%2 \n\ + bne-1b" + : "=&r" (t) + : "r" (a), "r" (&(l->a.counter)) +
[PATCH 07/10] local_t : powerpc extension
local_t : powerpc extension Signed-off-by: Mathieu Desnoyers <[EMAIL PROTECTED]> --- a/include/asm-powerpc/local.h +++ b/include/asm-powerpc/local.h @@ -1 +1,342 @@ -#include +#ifndef _ARCH_POWERPC_LOCAL_H +#define _ARCH_POWERPC_LOCAL_H + +#include +#include + +typedef struct +{ + atomic_long_t a; +} local_t; + +#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) } + +#define local_read(l) atomic_long_read(&(l)->a) +#define local_set(l,i) atomic_long_set(&(l)->a, (i)) + +#define local_add(i,l) atomic_long_add((i),(&(l)->a)) +#define local_sub(i,l) atomic_long_sub((i),(&(l)->a)) +#define local_inc(l) atomic_long_inc(&(l)->a) +#define local_dec(l) atomic_long_dec(&(l)->a) + +#ifndef __powerpc64__ + +static __inline__ int local_add_return(int a, local_t *l) +{ + int t; + + __asm__ __volatile__( +"1:lwarx %0,0,%2 # local_add_return\n\ + add %0,%1,%0\n" + PPC405_ERR77(0,%2) +" stwcx. %0,0,%2 \n\ + bne-1b" + : "=&r" (t) + : "r" (a), "r" (&(l->a.counter)) + : "cc", "memory"); + + return t; +} + +#define local_add_negative(a, l) (local_add_return((a), (l)) < 0) + +static __inline__ int local_sub_return(int a, local_t *l) +{ + int t; + + __asm__ __volatile__( +"1:lwarx %0,0,%2 # local_sub_return\n\ + subf%0,%1,%0\n" + PPC405_ERR77(0,%2) +" stwcx. %0,0,%2 \n\ + bne-1b" + : "=&r" (t) + : "r" (a), "r" (&(l->a.counter)) + : "cc", "memory"); + + return t; +} + +static __inline__ int local_inc_return(local_t *l) +{ + int t; + + __asm__ __volatile__( +"1:lwarx %0,0,%1 # local_inc_return\n\ + addic %0,%0,1\n" + PPC405_ERR77(0,%1) +" stwcx. %0,0,%1 \n\ + bne-1b" + : "=&r" (t) + : "r" (&(l->a.counter)) + : "cc", "memory"); + + return t; +} + +/* + * local_inc_and_test - increment and test + * @l: pointer of type local_t + * + * Atomically increments @l by 1 + * and returns true if the result is zero, or false for all + * other cases. + */ +#define local_inc_and_test(l) (local_inc_return(l) == 0) + +static __inline__ int local_dec_return(local_t *l) +{ + int t; + + __asm__ __volatile__( +"1:lwarx %0,0,%1 # local_dec_return\n\ + addic %0,%0,-1\n" + PPC405_ERR77(0,%1) +" stwcx. %0,0,%1\n\ + bne-1b" + : "=&r" (t) + : "r" (&(l->a.counter)) + : "cc", "memory"); + + return t; +} + +#define local_cmpxchg(l, o, n) \ + ((long)cmpxchg(&((l)->a.counter), (o), (n))) +#define local_xchg(l, new) (xchg(&((l)->a.counter), new)) + +/** + * local_add_unless - add unless the number is a given value + * @l: pointer of type local_t + * @a: the amount to add to v... + * @u: ...unless v is equal to u. + * + * Atomically adds @a to @l, so long as it was not @u. + * Returns non-zero if @l was not @u, and zero otherwise. + */ +static __inline__ int local_add_unless(local_t *l, int a, int u) +{ + int t; + + __asm__ __volatile__ ( +"1:lwarx %0,0,%1 # local_add_unless\n\ + cmpw0,%0,%3 \n\ + beq-2f \n\ + add %0,%2,%0 \n" + PPC405_ERR77(0,%2) +" stwcx. %0,0,%1 \n\ + bne-1b \n" +" subf%0,%2,%0 \n\ +2:" + : "=&r" (t) + : "r" (&(l->a.counter)), "r" (a), "r" (u) + : "cc", "memory"); + + return t != u; +} + +#define local_inc_not_zero(l) local_add_unless((l), 1, 0) + +#define local_sub_and_test(a, l) (local_sub_return((a), (l)) == 0) +#define local_dec_and_test(l) (local_dec_return((l)) == 0) + +/* + * Atomically test *l and decrement if it is greater than 0. + * The function returns the old value of *l minus 1. + */ +static __inline__ int local_dec_if_positive(local_t *l) +{ + int t; + + __asm__ __volatile__( +"1:lwarx %0,0,%1 # local_dec_if_positive\n\ + cmpwi %0,1\n\ + addi%0,%0,-1\n\ + blt-2f\n" + PPC405_ERR77(0,%1) +" stwcx. %0,0,%1\n\ + bne-1b" + "\n\ +2:": "=&b" (t) + : "r" (&(l->a.counter)) + : "cc", "memory"); + + return t; +} + +#else /* __powerpc64__ */ + +static __inline__ long local_add_return(long a, local_t *l) +{ + long t; + + __asm__ __volatile__( +"1:ldarx %0,0,%2 # local_add_return\n\ + add %0,%1,%0\n\ + stdcx. %0,0,%2 \n\ + bne-1b" + : "=&r" (t) + : "r" (a), "r" (&(l->a.counter)) + : "cc", "memory"); + + return t; +} + +#define local_add_negative(a, l) (local_add_return((a), (l)) < 0) + +static __inline__ long local_sub_return(long a, local_t *l) +{ + long t; + + __asm__ __volatile__( +"1:ldarx %0,0,%2 # local_sub_return\n\ + subf%0,%1,%0\n\ + stdcx. %0,0,%2 \n\ + bne-1b" + : "=&r" (t) + : "r" (a), "r" (&(l->a.counter)) + : "cc
[PATCH 07/10] local_t : powerpc extension
local_t : powerpc extension Signed-off-by: Mathieu Desnoyers <[EMAIL PROTECTED]> --- a/include/asm-powerpc/local.h +++ b/include/asm-powerpc/local.h @@ -1 +1,344 @@ -#include +#ifndef _ARCH_POWERPC_LOCAL_H +#define _ARCH_POWERPC_LOCAL_H + +#include +#include + +typedef struct +{ + atomic_long_t a; +} local_t; + +#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) } + +#define local_read(l) atomic_long_read(&(l)->a) +#define local_set(l,i) atomic_long_set(&(l)->a, (i)) + +#define local_add(i,l) atomic_long_add((i),(&(l)->a)) +#define local_sub(i,l) atomic_long_sub((i),(&(l)->a)) +#define local_inc(l) atomic_long_inc(&(l)->a) +#define local_dec(l) atomic_long_dec(&(l)->a) + +#ifndef __powerpc64__ + +static __inline__ int local_add_return(int a, local_t *l) +{ + int t; + + __asm__ __volatile__( +"1:lwarx %0,0,%2 # local_add_return\n\ + add %0,%1,%0\n" + PPC405_ERR77(0,%2) +" stwcx. %0,0,%2 \n\ + bne-1b" + : "=&r" (t) + : "r" (a), "r" (&(l->a.counter)) + : "cc", "memory"); + + return t; +} + +#define local_add_negative(a, l) (local_add_return((a), (l)) < 0) + +static __inline__ int local_sub_return(int a, local_t *l) +{ + int t; + + __asm__ __volatile__( +"1:lwarx %0,0,%2 # local_sub_return\n\ + subf%0,%1,%0\n" + PPC405_ERR77(0,%2) +" stwcx. %0,0,%2 \n\ + bne-1b" + : "=&r" (t) + : "r" (a), "r" (&(l->a.counter)) + : "cc", "memory"); + + return t; +} + +static __inline__ int local_inc_return(local_t *l) +{ + int t; + + __asm__ __volatile__( +"1:lwarx %0,0,%1 # local_inc_return\n\ + addic %0,%0,1\n" + PPC405_ERR77(0,%1) +" stwcx. %0,0,%1 \n\ + bne-1b" + : "=&r" (t) + : "r" (&(l->a.counter)) + : "cc", "memory"); + + return t; +} + +/* + * local_inc_and_test - increment and test + * @l: pointer of type local_t + * + * Atomically increments @l by 1 + * and returns true if the result is zero, or false for all + * other cases. + */ +#define local_inc_and_test(l) (local_inc_return(l) == 0) + +static __inline__ int local_dec_return(local_t *l) +{ + int t; + + __asm__ __volatile__( +"1:lwarx %0,0,%1 # local_dec_return\n\ + addic %0,%0,-1\n" + PPC405_ERR77(0,%1) +" stwcx. %0,0,%1\n\ + bne-1b" + : "=&r" (t) + : "r" (&(l->a.counter)) + : "cc", "memory"); + + return t; +} + +#define local_cmpxchg(l, o, n) \ + ((long)cmpxchg(&((l)->a.counter), (o), (n))) +#define local_xchg(l, new) (xchg(&((l)->a.counter), new)) + +/** + * local_add_unless - add unless the number is a given value + * @l: pointer of type local_t + * @a: the amount to add to v... + * @u: ...unless v is equal to u. + * + * Atomically adds @a to @l, so long as it was not @u. + * Returns non-zero if @l was not @u, and zero otherwise. + */ +static __inline__ int local_add_unless(local_t *l, int a, int u) +{ + int t; + + __asm__ __volatile__ ( +"1:lwarx %0,0,%1 # local_add_unless\n\ + cmpw0,%0,%3 \n\ + beq-2f \n\ + add %0,%2,%0 \n" + PPC405_ERR77(0,%2) +" stwcx. %0,0,%1 \n\ + bne-1b \n" +" subf%0,%2,%0 \n\ +2:" + : "=&r" (t) + : "r" (&(l->a.counter)), "r" (a), "r" (u) + : "cc", "memory"); + + return t != u; +} + +#define local_inc_not_zero(l) local_add_unless((l), 1, 0) + +#define local_sub_and_test(a, l) (local_sub_return((a), (l)) == 0) +#define local_dec_and_test(l) (local_dec_return((l)) == 0) + +/* + * Atomically test *l and decrement if it is greater than 0. + * The function returns the old value of *l minus 1. + */ +static __inline__ int local_dec_if_positive(local_t *l) +{ + int t; + + __asm__ __volatile__( +"1:lwarx %0,0,%1 # local_dec_if_positive\n\ + addic. %0,%0,-1\n\ + blt-2f\n" + PPC405_ERR77(0,%1) +" stwcx. %0,0,%1\n\ + bne-1b" + "\n\ +2:": "=&r" (t) + : "r" (&(l->a.counter)) + : "cc", "memory"); + + return t; +} + +#else /* __powerpc64__ */ + +static __inline__ long local_add_return(long a, local_t *l) +{ + long t; + + __asm__ __volatile__( +"1:ldarx %0,0,%2 # local_add_return\n\ + add %0,%1,%0\n\ + stdcx. %0,0,%2 \n\ + bne-1b" + : "=&r" (t) + : "r" (a), "r" (&(l->a.counter)) + : "cc", "memory"); + + return t; +} + +#define local_add_negative(a, l) (local_add_return((a), (l)) < 0) + +static __inline__ long local_sub_return(long a, local_t *l) +{ + long t; + + __asm__ __volatile__( +"1:ldarx %0,0,%2 # local_sub_return\n\ + subf%0,%1,%0\n\ + stdcx. %0,0,%2 \n\ + bne-1b" + : "=&r" (t) + : "r" (a), "r" (&(l->a.counter)) + : "cc", "memory"); + +