This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
[PATCH] PPC64 bits/atomic.h
- From: Steven Munroe <sjmunroe at us dot ibm dot com>
- To: libc-alpha <libc-alpha at sources dot redhat dot com>
- Date: Mon, 24 Mar 2003 16:12:45 -0600
- Subject: [PATCH] PPC64 bits/atomic.h
- Organization: IBM Linux Developement
- Reply-to: sjmunroe at vnet dot ibm dot com
For PPC64, NPTL only seems to need 32 bit atomic_exchange,
atomic_exchange_and_add, and atomic_decrement_if_positive, but make check
(csu/tst-atomic.c, csu/tst-atomic-long.c) requires both 32-bit and 64-bit forms
(sizeof(int) != sizeof(long)).
So I updated powerpc/bits/atomic.h so PPC64 can handle both 32- and 64-bit
forms.
2003-03-24 Steven Munroe <sjmunroe at us dot ibm dot com>
* sysdeps/powerpc/bits/atomic.h [__powerpc64__] (atomic_exchange): Support
32- and 64-bit mem targets.
* sysdeps/powerpc/bits/atomic.h [__powerpc64__] (atomic_exchange_and_add):
Support 32- and 64-bit mem targets.
* sysdeps/powerpc/bits/atomic.h [__powerpc64__]
(atomic_decrement_if_positive):
Support 32- and 64-bit mem targets.
--
Steven Munroe
sjmunroe at us dot ibm dot com
Linux on PowerPC-64 Development
GLIBC for PowerPC-64 Development
diff -urN libc23-cvstip-20030324/sysdeps/powerpc/bits/atomic.h libc23/sysdeps/powerpc/bits/atomic.h
--- libc23-cvstip-20030324/sysdeps/powerpc/bits/atomic.h 2003-03-21 01:43:14.000000000 -0600
+++ libc23/sysdeps/powerpc/bits/atomic.h 2003-03-24 14:56:49.000000000 -0600
@@ -108,6 +108,34 @@
#endif
+#ifdef __powerpc64__
+#define atomic_exchange(mem, value) \
+ ({ __typeof (*mem) __val; \
+ if (sizeof (*mem) == 8) \
+ { \
+ __asm __volatile (__ARCH_REL_INSTR "\n" \
+ "1: ldarx %0,0,%2\n" \
+ " stdcx. %3,0,%2\n" \
+ " bne- 1b" \
+ : "=&r" (__val), "=m" (*mem) \
+ : "r" (mem), "r" (value), "1" (*mem) \
+ : "cr0"); \
+ }\
+ else if (sizeof (*mem) == 4) \
+ { \
+ __asm __volatile (__ARCH_REL_INSTR "\n" \
+ "1: lwarx %0,0,%2\n" \
+ " stwcx. %3,0,%2\n" \
+ " bne- 1b" \
+ : "=&r" (__val), "=m" (*mem) \
+ : "r" (mem), "r" (value), "1" (*mem) \
+ : "cr0"); \
+ }\
+ else \
+ abort (); \
+ __val; })
+
+#else /* powerpc32 */
#define atomic_exchange(mem, value) \
({ if (sizeof (*mem) != 4) \
abort (); \
@@ -120,8 +148,37 @@
: "r" (mem), "r" (value), "1" (*mem) \
: "cr0"); \
__val; })
+#endif
+#ifdef __powerpc64__
+#define atomic_exchange_and_add(mem, value) \
+ ({ __typeof (*mem) __val, __tmp; \
+ if (sizeof (*mem) == 8) \
+ { \
+ __asm __volatile ("1: ldarx %0,0,%3\n" \
+ " addi %1,%0,%4\n" \
+ " stdcx. %1,0,%3\n" \
+ " bne- 1b" \
+ : "=&b" (__val), "=&r" (__tmp), "=m" (*mem) \
+ : "r" (mem), "I" (value), "2" (*mem) \
+ : "cr0"); \
+ }\
+ else if (sizeof (*mem) == 4) \
+ { \
+ __asm __volatile ("1: lwarx %0,0,%3\n" \
+ " addi %1,%0,%4\n" \
+ " stwcx. %1,0,%3\n" \
+ " bne- 1b" \
+ : "=&b" (__val), "=&r" (__tmp), "=m" (*mem) \
+ : "r" (mem), "I" (value), "2" (*mem) \
+ : "cr0"); \
+ }\
+ else \
+ abort (); \
+ __val; })
+
+#else /* powerpc32 */
#define atomic_exchange_and_add(mem, value) \
({ if (sizeof (*mem) != 4) \
abort (); \
@@ -135,9 +192,44 @@
: "cr0"); \
__val; \
})
+#endif
/* Decrement *MEM if it is > 0, and return the old value. */
+#ifdef __powerpc64__
+#define atomic_decrement_if_positive(mem) \
+ ({ __typeof (*mem) __val, __tmp; \
+ if (sizeof (*mem) == 8) \
+ { \
+ __asm __volatile ("1: ldarx %0,0,%3\n" \
+ " cmpwi 0,%0,0\n" \
+ " addi %1,%0,-1\n" \
+ " ble 2f\n" \
+ " stdcx. %1,0,%3\n" \
+ " bne- 1b\n" \
+ "2: " __ARCH_ACQ_INSTR \
+ : "=&b" (__val), "=&r" (__tmp), "=m" (*mem) \
+ : "r" (mem), "2" (*mem) \
+ : "cr0"); \
+ }\
+ else if (sizeof (*mem) == 4) \
+ { \
+ __asm __volatile ("1: lwarx %0,0,%3\n" \
+ " cmpwi 0,%0,0\n" \
+ " addi %1,%0,-1\n" \
+ " ble 2f\n" \
+ " stwcx. %1,0,%3\n" \
+ " bne- 1b\n" \
+ "2: " __ARCH_ACQ_INSTR \
+ : "=&b" (__val), "=&r" (__tmp), "=m" (*mem) \
+ : "r" (mem), "2" (*mem) \
+ : "cr0"); \
+ }\
+ else \
+ abort (); \
+ __val; })
+
+#else /* powerpc32 */
#define atomic_decrement_if_positive(mem) \
({ if (sizeof (*mem) != 4) \
abort (); \
@@ -154,7 +246,7 @@
: "cr0"); \
__val; \
})
-
+#endif
#define atomic_full_barrier() __asm ("sync" ::: "memory")