This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: powerpc64 libstdc++
On Sun, Jul 28, 2002 at 03:00:20PM -0700, dank@kegel.com wrote:
> David Edelsohn wrote:
> >
> > Personally, I prefer a patch like the following for libstdc++
> > atomicity.h and Java locks.h:
> >
> > *** atomicity.h.~1.3.~ Mon Jun 24 01:48:14 2002
> > --- atomicity.h Sun Jul 28 17:07:22 2002
>
> That looks beautiful, go for it!
No, it's wrong on two counts. We don't want ldarx/stdcx in
atomicity.h because __exchange_and_add and __atomic_add operate on
32-bit ints. Also, the stwcx. in __atomic_add uses different args.
David did say "like the following", so I suppose that lets him off the
hook. ;-)
I get the impression Dan likes the #ifdef __PPC405__. Here's another
libstdc++ and libjava patch. David, are the extra ppc405 syncs really
needed for libjava? The functions in locks.h are already doing syncs.
libstdc++-v3/ChangeLog
* config/cpu/powerpc/cpu_limits.h (__glibcpp_long_bits): Define.
* configure.target (cpu_include_dir): Use cpu/powerpc for powerpc64.
* config/cpu/powerpc/atomicity.h (__always_swap): Remove.
(__test_and_set): Remove.
(_STWCX): Define and use.
libjava/ChangeLog
* sysdep/powerpc/locks.h: Formatting.
(_LARX): Define.
(_STCX): Define.
(compare_and_swap): Use _LARX and _STCX.
(compare_and_swap_release): Likewise.
Index: libstdc++-v3/configure.target
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/configure.target,v
retrieving revision 1.47
diff -u -p -r1.47 configure.target
--- libstdc++-v3/configure.target 11 Jul 2002 18:56:58 -0000 1.47
+++ libstdc++-v3/configure.target 29 Jul 2002 00:31:36 -0000
@@ -85,7 +85,7 @@ case "${target_cpu}" in
mmix)
ATOMICITYH="cpu/generic"
;;
- powerpc | rs6000)
+ powerpc* | rs6000)
cpu_include_dir="cpu/powerpc"
;;
s390 | s390x)
Index: libstdc++-v3/config/cpu/powerpc/atomicity.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/config/cpu/powerpc/atomicity.h,v
retrieving revision 1.3
diff -u -p -r1.3 atomicity.h
--- libstdc++-v3/config/cpu/powerpc/atomicity.h 24 Jun 2002 05:48:14 -0000 1.3
+++ libstdc++-v3/config/cpu/powerpc/atomicity.h 29 Jul 2002 00:31:36 -0000
@@ -30,6 +30,12 @@
#ifndef _BITS_ATOMICITY_H
#define _BITS_ATOMICITY_H 1
+#ifdef __PPC405__
+#define _STWCX "sync \n\tstwcx. "
+#else
+#define _STWCX "stwcx. "
+#endif
+
typedef int _Atomic_word;
static inline _Atomic_word
@@ -42,7 +48,7 @@ __exchange_and_add (volatile _Atomic_wor
"0:\t"
"lwarx %0,0,%2 \n\t"
"add%I3 %1,%0,%3 \n\t"
- "stwcx. %1,0,%2 \n\t"
+ _STWCX " %1,0,%2 \n\t"
"bne- 0b \n\t"
"/* End exchange & add */"
: "=&b"(__res), "=&r"(__tmp)
@@ -61,7 +67,7 @@ __atomic_add (volatile _Atomic_word *__m
"0:\t"
"lwarx %0,0,%1 \n\t"
"add%I2 %0,%0,%2 \n\t"
- "stwcx. %0,0,%1 \n\t"
+ _STWCX " %0,0,%1 \n\t"
"bne- 0b \n\t"
"/* End atomic add */"
: "=&b"(__tmp)
@@ -69,44 +75,4 @@ __atomic_add (volatile _Atomic_word *__m
: "cr0", "memory");
}
-static inline long
-__attribute__ ((__unused__))
-__always_swap (volatile long *__p, long int __newval)
-{
- long __res;
- __asm__ __volatile__ (
- "/* Inline always swap */\n"
- "0:\t"
- "lwarx %0,0,%1 \n\t"
- "stwcx. %2,0,%1 \n\t"
- "bne- 0b \n\t"
- "/* End always swap */"
- : "=&r"(__res)
- : "r"(__p), "r"(__newval)
- : "cr0", "memory");
- return __res;
-}
-
-static inline int
-__attribute__ ((__unused__))
-__test_and_set (volatile long *__p, long int __newval)
-{
- int __res;
- __asm__ __volatile__ (
- "/* Inline test & set */\n"
- "0:\t"
- "lwarx %0,0,%1 \n\t"
- "cmpwi %0,0 \n\t"
- "bne- 1f \n\t"
- "stwcx. %2,0,%1 \n\t"
- "bne- 0b \n"
- "1:\n\t"
- "/* End test & set */"
- : "=&r"(__res)
- : "r"(__p), "r"(__newval)
- : "cr0", "memory");
- return __res;
-}
-
#endif /* atomicity.h */
-
Index: libstdc++-v3/config/cpu/powerpc/cpu_limits.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/config/cpu/powerpc/cpu_limits.h,v
retrieving revision 1.1
diff -u -p -r1.1 cpu_limits.h
--- libstdc++-v3/config/cpu/powerpc/cpu_limits.h 24 Jun 2002 05:48:14 -0000 1.1
+++ libstdc++-v3/config/cpu/powerpc/cpu_limits.h 29 Jul 2002 00:31:36 -0000
@@ -28,6 +28,10 @@
#ifndef _GLIBCPP_CPU_LIMITS
#define _GLIBCPP_CPU_LIMITS 1
+#ifdef __powerpc64__
+#define __glibcpp_long_bits 64
+#endif
+
#ifndef __LONG_DOUBLE_128__
#define __glibcpp_long_double_bits 64
#endif
Index: libjava/sysdep/powerpc/locks.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/sysdep/powerpc/locks.h,v
retrieving revision 1.2
diff -u -p -r1.2 locks.h
--- libjava/sysdep/powerpc/locks.h 21 Mar 2002 00:26:45 -0000 1.2
+++ libjava/sysdep/powerpc/locks.h 29 Jul 2002 00:31:43 -0000
@@ -11,26 +11,38 @@ details. */
#ifndef __SYSDEP_LOCKS_H__
#define __SYSDEP_LOCKS_H__
+#ifdef __powerpc64__
+#define _LARX "ldarx "
+#define _STCX "stdcx. "
+#else
+#define _LARX "lwarx "
+#ifdef __PPC405__
+#define _STCX "sync; stwcx. "
+#else
+#define _STCX "stwcx. "
+#endif
+#endif
+
typedef size_t obj_addr_t; /* Integer type big enough for object */
/* address. */
inline static bool
-compare_and_swap(volatile obj_addr_t *addr,
- obj_addr_t old,
- obj_addr_t new_val)
+compare_and_swap (volatile obj_addr_t *addr, obj_addr_t old,
+ obj_addr_t new_val)
{
int ret;
__asm__ __volatile__ (
- "0: lwarx %0,0,%1 ;"
+ "0: " _LARX "%0,0,%1 ;"
" xor. %0,%3,%0;"
" bne 1f;"
- " stwcx. %2,0,%1;"
+ " " _STCX "%2,0,%1;"
" bne- 0b;"
"1: "
- : "=&r"(ret)
- : "r"(addr), "r"(new_val), "r"(old)
+ : "=&r" (ret)
+ : "r" (addr), "r" (new_val), "r" (old)
: "cr0", "memory");
+
/* This version of __compare_and_swap is to be used when acquiring
a lock, so we don't need to worry about whether other memory
operations have completed, but we do need to be sure that any loads
@@ -40,37 +52,38 @@ compare_and_swap(volatile obj_addr_t *ad
}
inline static void
-release_set(volatile obj_addr_t *addr, obj_addr_t new_val)
+release_set (volatile obj_addr_t *addr, obj_addr_t new_val)
{
__asm__ __volatile__ ("sync" : : : "memory");
- *(addr) = new_val;
+ *addr = new_val;
}
inline static bool
-compare_and_swap_release(volatile obj_addr_t *addr,
- obj_addr_t old,
- obj_addr_t new_val)
+compare_and_swap_release (volatile obj_addr_t *addr, obj_addr_t old,
+ obj_addr_t new_val)
{
int ret;
__asm__ __volatile__ ("sync" : : : "memory");
+
__asm__ __volatile__ (
- "0: lwarx %0,0,%1 ;"
+ "0: " _LARX "%0,0,%1 ;"
" xor. %0,%3,%0;"
" bne 1f;"
- " stwcx. %2,0,%1;"
+ " " _STCX "%2,0,%1;"
" bne- 0b;"
"1: "
- : "=&r"(ret)
- : "r"(addr), "r"(new_val), "r"(old)
+ : "=&r" (ret)
+ : "r" (addr), "r" (new_val), "r" (old)
: "cr0", "memory");
+
return ret == 0;
}
// Ensure that subsequent instructions do not execute on stale
// data that was loaded from memory before the barrier.
inline static void
-read_barrier()
+read_barrier ()
{
__asm__ __volatile__ ("isync" : : : "memory");
}
@@ -78,7 +91,7 @@ read_barrier()
// Ensure that prior stores to memory are completed with respect to other
// processors.
inline static void
-write_barrier()
+write_barrier ()
{
__asm__ __volatile__ ("sync" : : : "memory");
}
--
Alan Modra
IBM OzLabs - Linux Technology Centre