[SPARC64]: __atomic_{add,sub}() must sign-extend return value.
Linux Kernel Mailing List <[email protected]>
| Newsgroups | gmane.linux.kernel.commits.2-4 |
|---|---|
| Message-ID | <[email protected]> |
ChangeSet 1.1521.19.2, 2005/02/01 12:26:07-08:00, [email protected] [SPARC64]: __atomic_{add,sub}() must sign-extend return value. Even though we declare these functions as returning a 32-bit signed integer, the sparc64 ABI states that such functions must properly sign-extend the return value to the full 64-bits. Due to this bug, parts of mm/rmap.c were misbehaving when compiled with gcc-3.4 on sparc64. gcc-3.4 was legally using a 64-bit comparison against zero with the return value of __atomic_add(). I would like to thank Hugh Daniels and others for helping to track down this peculiar bug. Signed-off-by: David S. Miller <[email protected]> atomic.S | 29 +++++++++++++++++++++-------- 1 files changed, 21 insertions(+), 8 deletions(-) diff -Nru a/arch/sparc64/lib/atomic.S b/arch/sparc64/lib/atomic.S --- a/arch/sparc64/lib/atomic.S 2005-02-01 16:04:25 -08:00 +++ b/arch/sparc64/lib/atomic.S 2005-02-01 16:04:25 -08:00 @@ -7,21 +7,34 @@ #include <asm/asi.h> .text - .align 64 .globl atomic_impl_begin, atomic_impl_end +atomic_impl_begin: + /* We use these stubs for the uncommon case + * of contention on the atomic value. This is + * so that we can keep the main fast path 8 + * instructions long and thus fit into a single + * L2 cache line. + */ +__atomic_add_membar: + ba,pt %xcc, __atomic_add + membar #StoreLoad | #StoreStore + +__atomic_sub_membar: + ba,pt %xcc, __atomic_sub + membar #StoreLoad | #StoreStore + .align 64 .globl __atomic_add -atomic_impl_begin: __atomic_add: /* %o0 = increment, %o1 = atomic_ptr */ lduw [%o1], %g5 add %g5, %o0, %g7 cas [%o1], %g5, %g7 cmp %g5, %g7 - bne,pn %icc, __atomic_add - membar #StoreLoad | #StoreStore + bne,pn %icc, __atomic_add_membar + add %g7, %o0, %g7 retl - add %g7, %o0, %o0 + sra %g7, 0, %o0 .globl __atomic_sub __atomic_sub: /* %o0 = increment, %o1 = atomic_ptr */ @@ -29,8 +42,8 @@ sub %g5, %o0, %g7 cas [%o1], %g5, %g7 cmp %g5, %g7 - bne,pn %icc, __atomic_sub - membar #StoreLoad | #StoreStore + bne,pn %icc, __atomic_sub_membar + sub %g7, %o0, %g7 retl - sub %g7, %o0, %o0 + sra %g7, 0, %o0 atomic_impl_end: