The MPC8xx PowerQUICC family only implements full 'sync', 'lwsync'
is not yet supported. The CPU actually checks that the
should-be-zero bits of the sync instruction are zero, and faults
otherwise - same situation as for E500 cores.

Fix emitting 'lwsync' instructions by adding PROCESSOR_MPCCORE
to the TARGET_NO_LWSYNC define.

Encountered an illegal instruction crash (in libstdc++ atomics) and
verified the fix on actual MPC860 hardware.

Minimal test:

  $ cat test.c
  #include <stdatomic.h>
  atomic_int counter;
  void store_release(int val) {
      atomic_store_explicit(&counter, val, memory_order_release);
  }

  $ powerpc-linux-gnu-gcc -mcpu=860 -O2 -S -o- test.c | grep sync
  lwsync     <-- should be sync

  $ powerpc-linux-gnu-gcc -mcpu=8540 -O2 -S -o- test.c | grep sync
  sync       <-- correct (TARGET_NO_LWSYNC already covers E500/8540)

gcc/ChangeLog:

        * config/rs6000/rs6000.h (TARGET_NO_LWSYNC): Add PROCESSOR_MPCCORE.

gcc/testsuite/ChangeLog:

        * gcc.target/powerpc/mpc860_no_lwsync.c: New test.
---
 gcc/config/rs6000/rs6000.h                          |  8 ++++++--
 gcc/testsuite/gcc.target/powerpc/mpc860_no_lwsync.c | 13 +++++++++++++
 2 files changed, 19 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/mpc860_no_lwsync.c

diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 2d3016db5..af233a049 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -533,9 +533,13 @@ extern int rs6000_vector_align[];
                                 || TARGET_VSX                           \
                                 || TARGET_HARD_FLOAT)
 
-/* E500 cores only support plain "sync", not lwsync.  */
+/* E500 and MPC8xx cores require all should-be-zero bits in sync to
+   actually be zero; using lwsync (L=1) causes a fault on these cores.
+   Classic cores (601, 603, 604, 750 etc.) simply ignore the L field
+   and always do a full hwsync.  */
 #define TARGET_NO_LWSYNC (rs6000_cpu == PROCESSOR_PPC8540 \
-                         || rs6000_cpu == PROCESSOR_PPC8548)
+                         || rs6000_cpu == PROCESSOR_PPC8548 \
+                         || rs6000_cpu == PROCESSOR_MPCCORE)
 
 
 /* Which machine supports the various reciprocal estimate instructions.  */
diff --git a/gcc/testsuite/gcc.target/powerpc/mpc860_no_lwsync.c 
b/gcc/testsuite/gcc.target/powerpc/mpc860_no_lwsync.c
new file mode 100644
index 000000000..575d35e18
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/mpc860_no_lwsync.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target powerpc*-*-* } } */
+/* { dg-options "-mcpu=860 -O2" } */
+
+/* Check that we do not emit lwsync when targeting MPC8xx (MPCCORE),
+   since the MPC8xx core does not support and faults on this instruction.  */
+
+void
+store_release (int *ptr, int val)
+{
+  __atomic_store_n (ptr, val, __ATOMIC_RELEASE);
+}
+
+/* { dg-final { scan-assembler-not "\mlwsync\M" } } */
-- 
2.53.0

Reply via email to