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