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
