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]

Don't use lwsync on E500


GCC generates lwsync instructions for PowerPC (both from sync.md and 
hardcoded in libstdc++'s atomicity configuration).

These generate illegal instruction errors on E500 CPUs, which only have an 
msync instruction (same bit-pattern as sync; lwsync involves setting a bit 
that's reserved in msync).  Although Power ISA 2.03 requires lwsync, an 
older Book E only has msync.

This patch makes GCC use plain sync instead of lwsync on E500 (I don't see 
a need for a separate command-line option for this at present).  This 
removes about 2500 FAILs for powerpc-none-linux-gnuspe 
--enable-e500_double.  (For some reason only one of those FAILs appears 
for me in 4.1 testing: that in ia64-sync-1.c, the others only appear in 
4.2 and 4.3 testing.  They don't appear in Edmar's results on 
gcc-testresults because those have kernel emulation enabled in order to 
use a root filesystem with ordinary PowerPC binaries.)

Tested with no regressions with a cross to powerpc-none-linux-gnuspe.  OK 
to commit to mainline, 4.2, 4.1?

2006-11-16  Joseph Myers  <joseph@codesourcery.com>

	gcc/
	* config/rs6000/rs6000.h (TARGET_NO_LWSYNC): Define.
	* config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): Define
	__NO_LWSYNC__ if TARGET_NO_LWSYNC.
	* config/rs6000/sync.md (lwsync): Emit plain sync if
	TARGET_NO_LWSYNC.

	libstdc++-v3/
	* config/cpu/powerpc/atomic_word.h (_GLIBCXX_WRITE_MEM_BARRIER):
	Use plain sync if __NO_LWSYNC__.

Index: gcc/config/rs6000/rs6000-c.c
===================================================================
--- gcc/config/rs6000/rs6000-c.c	(revision 118892)
+++ gcc/config/rs6000/rs6000-c.c	(working copy)
@@ -127,6 +127,9 @@
   /* Used by lwarx/stwcx. errata work-around.  */
   if (rs6000_cpu == PROCESSOR_PPC405)
     builtin_define ("__PPC405__");
+  /* Used by libstdc++.  */
+  if (TARGET_NO_LWSYNC)
+    builtin_define ("__NO_LWSYNC__");
 
   /* May be overridden by target configuration.  */
   RS6000_CPU_CPP_ENDIAN_BUILTINS();
Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h	(revision 118892)
+++ gcc/config/rs6000/rs6000.h	(working copy)
@@ -342,6 +342,9 @@
 #define TARGET_E500_SINGLE 0
 #define TARGET_E500_DOUBLE 0
 
+/* E500 processors only support plain "sync", not lwsync.  */
+#define TARGET_NO_LWSYNC TARGET_E500
+
 /* Sometimes certain combinations of command options do not make sense
    on a particular target machine.  You can define a macro
    `OVERRIDE_OPTIONS' to take account of this.  This macro, if
Index: gcc/config/rs6000/sync.md
===================================================================
--- gcc/config/rs6000/sync.md	(revision 118892)
+++ gcc/config/rs6000/sync.md	(working copy)
@@ -615,6 +615,11 @@
   [(set (mem:BLK (match_scratch 0 "X"))
 	(unspec_volatile:BLK [(mem:BLK (match_scratch 1 "X"))] UNSPEC_LWSYNC))]
   ""
-  ".long 0x7c2004ac"
+{
+  if (TARGET_NO_LWSYNC)
+    return "sync";
+  else
+    return ".long 0x7c2004ac";
+}
   [(set_attr "type" "sync")])
 
Index: libstdc++-v3/config/cpu/powerpc/atomic_word.h
===================================================================
--- libstdc++-v3/config/cpu/powerpc/atomic_word.h	(revision 118892)
+++ libstdc++-v3/config/cpu/powerpc/atomic_word.h	(working copy)
@@ -33,6 +33,10 @@
 typedef int _Atomic_word;
 
 #define _GLIBCXX_READ_MEM_BARRIER __asm __volatile ("isync":::"memory")
+#ifdef __NO_LWSYNC__
+#define _GLIBCXX_WRITE_MEM_BARRIER __asm __volatile ("sync":::"memory")
+#else
 #define _GLIBCXX_WRITE_MEM_BARRIER __asm __volatile ("lwsync":::"memory")
+#endif
 
 #endif 

-- 
Joseph S. Myers
joseph@codesourcery.com


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