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