This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]