From: Chao-ying Fu <[email protected]>

Fix subword address selection on big-endian RISC-V targets. 

Signed-off-by: Aleksa Paunovic <[email protected]>

gcc/ChangeLog:

        * config/riscv/riscv.cc (riscv_subword_address): Add emit_move_insn for 
big-endian.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/amo/big-endian-subword-amo-hi.c: New test.
        * gcc.target/riscv/amo/big-endian-subword-amo-qi.c: New test.
---
 gcc/config/riscv/riscv.cc                                | 5 +++++
 .../gcc.target/riscv/amo/big-endian-subword-amo-hi.c     | 9 +++++++++
 .../gcc.target/riscv/amo/big-endian-subword-amo-qi.c     | 9 +++++++++
 3 files changed, 23 insertions(+)
 create mode 100644 
gcc/testsuite/gcc.target/riscv/amo/big-endian-subword-amo-hi.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/amo/big-endian-subword-amo-qi.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index d5de76c342e0..a99d52c3efa7 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -12825,6 +12825,11 @@ riscv_subword_address (rtx mem, rtx *aligned_mem, rtx 
*shift, rtx *mask,
   /* Calculate the shift amount.  */
   emit_move_insn (*shift, gen_rtx_AND (SImode, gen_lowpart (SImode, addr),
                                       gen_int_mode (3, SImode)));
+  if (TARGET_BIG_ENDIAN)
+    emit_move_insn (*shift, gen_rtx_XOR (SImode, *shift,
+                                       gen_int_mode (GET_MODE (mem) == QImode
+                                                     ? 3 : 2, SImode)));
+
   emit_move_insn (*shift, gen_rtx_ASHIFT (SImode, *shift,
                                          gen_int_mode (3, SImode)));
 
diff --git a/gcc/testsuite/gcc.target/riscv/amo/big-endian-subword-amo-hi.c 
b/gcc/testsuite/gcc.target/riscv/amo/big-endian-subword-amo-hi.c
new file mode 100644
index 000000000000..3e2e0a6b9845
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/big-endian-subword-amo-hi.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { ! riscv_v } } } */
+/* { dg-options "-mbig-endian -O2" } */
+/* Verify that subword atomic operations use XOR for big-endian halfword 
alignment.  */
+/* { dg-final { scan-assembler "xori\\s+\[a-z0-9\]+,\[a-z0-9\]+,2" } } */
+
+void atomic_fetch_add_hi(short *ptr, short val)
+{
+  __atomic_fetch_add(ptr, val, __ATOMIC_RELAXED);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/big-endian-subword-amo-qi.c 
b/gcc/testsuite/gcc.target/riscv/amo/big-endian-subword-amo-qi.c
new file mode 100644
index 000000000000..af29b33a2014
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/big-endian-subword-amo-qi.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { ! riscv_v } } } */
+/* { dg-options "-mbig-endian -O2" } */
+/* Verify that subword atomic operations use XOR for big-endian byte 
alignment.  */
+/* { dg-final { scan-assembler "xori\\s+\[a-z0-9\]+,\[a-z0-9\]+,3" } } */
+
+void atomic_fetch_add_qi(char *ptr, char val)
+{
+  __atomic_fetch_add(ptr, val, __ATOMIC_RELAXED);
+}
-- 
2.43.0

Reply via email to