This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Don't use lwsync on E500
- From: "Joseph S. Myers" <joseph at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 17 Nov 2006 12:56:28 +0000 (UTC)
- Subject: 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