RISC-V: Add Zalrsc amo-op patterns
All amo<op> patterns can be represented with lrsc sequences. Add these patterns as a fallback when Zaamo is not enabled. gcc/ChangeLog: * config/riscv/sync.md (atomic_<atomic_optab><mode>): New expand pattern. (amo_atomic_<atomic_optab><mode>): Rename amo pattern. (atomic_fetch_<atomic_optab><mode>): New lrsc sequence pattern. (lrsc_atomic_<atomic_optab><mode>): New expand pattern. (amo_atomic_fetch_<atomic_optab><mode>): Rename amo pattern. (lrsc_atomic_fetch_<atomic_optab><mode>): New lrsc sequence pattern. (atomic_exchange<mode>): New expand pattern. (amo_atomic_exchange<mode>): Rename amo pattern. (lrsc_atomic_exchange<mode>): New lrsc sequence pattern. gcc/testsuite/ChangeLog: * gcc.target/riscv/amo-zaamo-preferred-over-zalrsc.c: New test. * gcc.target/riscv/amo-zalrsc-amo-add-1.c: New test. * gcc.target/riscv/amo-zalrsc-amo-add-2.c: New test. * gcc.target/riscv/amo-zalrsc-amo-add-3.c: New test. * gcc.target/riscv/amo-zalrsc-amo-add-4.c: New test. * gcc.target/riscv/amo-zalrsc-amo-add-5.c: New test. Signed-off-by: Patrick O'Neill <patrick@rivosinc.com>
This commit is contained in:
parent
0fea902b1b
commit
1588983be6
7 changed files with 231 additions and 5 deletions
|
@ -86,7 +86,24 @@
|
|||
DONE;
|
||||
})
|
||||
|
||||
(define_insn "atomic_<atomic_optab><mode>"
|
||||
;; AMO ops
|
||||
|
||||
(define_expand "atomic_<atomic_optab><mode>"
|
||||
[(any_atomic:GPR (match_operand:GPR 0 "memory_operand") ;; mem location
|
||||
(match_operand:GPR 1 "reg_or_0_operand")) ;; value for op
|
||||
(match_operand:SI 2 "const_int_operand")] ;; model
|
||||
"TARGET_ZAAMO || TARGET_ZALRSC"
|
||||
{
|
||||
if (TARGET_ZAAMO)
|
||||
emit_insn (gen_amo_atomic_<atomic_optab><mode> (operands[0], operands[1],
|
||||
operands[2]));
|
||||
else
|
||||
emit_insn (gen_lrsc_atomic_<atomic_optab><mode> (operands[0], operands[1],
|
||||
operands[2]));
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_insn "amo_atomic_<atomic_optab><mode>"
|
||||
[(set (match_operand:GPR 0 "memory_operand" "+A")
|
||||
(unspec_volatile:GPR
|
||||
[(any_atomic:GPR (match_dup 0)
|
||||
|
@ -98,7 +115,44 @@
|
|||
[(set_attr "type" "atomic")
|
||||
(set (attr "length") (const_int 4))])
|
||||
|
||||
(define_insn "atomic_fetch_<atomic_optab><mode>"
|
||||
(define_insn "lrsc_atomic_<atomic_optab><mode>"
|
||||
[(set (match_operand:GPR 0 "memory_operand" "+A")
|
||||
(unspec_volatile:GPR
|
||||
[(any_atomic:GPR (match_dup 0)
|
||||
(match_operand:GPR 1 "reg_or_0_operand" "rJ"))
|
||||
(match_operand:SI 2 "const_int_operand")] ;; model
|
||||
UNSPEC_SYNC_OLD_OP))
|
||||
(clobber (match_scratch:GPR 3 "=&r"))] ;; tmp_1
|
||||
"!TARGET_ZAAMO && TARGET_ZALRSC"
|
||||
{
|
||||
return "1:\;"
|
||||
"lr.<amo>%I2\t%3, %0\;"
|
||||
"<insn>\t%3, %3, %1\;"
|
||||
"sc.<amo>%J2\t%3, %3, %0\;"
|
||||
"bnez\t%3, 1b";
|
||||
}
|
||||
[(set_attr "type" "atomic")
|
||||
(set (attr "length") (const_int 16))])
|
||||
|
||||
;; AMO fetch ops
|
||||
|
||||
(define_expand "atomic_fetch_<atomic_optab><mode>"
|
||||
[(match_operand:GPR 0 "register_operand") ;; old value at mem
|
||||
(any_atomic:GPR (match_operand:GPR 1 "memory_operand") ;; mem location
|
||||
(match_operand:GPR 2 "reg_or_0_operand")) ;; value for op
|
||||
(match_operand:SI 3 "const_int_operand")] ;; model
|
||||
"TARGET_ZAAMO || TARGET_ZALRSC"
|
||||
{
|
||||
if (TARGET_ZAAMO)
|
||||
emit_insn (gen_amo_atomic_fetch_<atomic_optab><mode> (operands[0], operands[1],
|
||||
operands[2], operands[3]));
|
||||
else
|
||||
emit_insn (gen_lrsc_atomic_fetch_<atomic_optab><mode> (operands[0], operands[1],
|
||||
operands[2], operands[3]));
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_insn "amo_atomic_fetch_<atomic_optab><mode>"
|
||||
[(set (match_operand:GPR 0 "register_operand" "=&r")
|
||||
(match_operand:GPR 1 "memory_operand" "+A"))
|
||||
(set (match_dup 1)
|
||||
|
@ -112,6 +166,27 @@
|
|||
[(set_attr "type" "atomic")
|
||||
(set (attr "length") (const_int 4))])
|
||||
|
||||
(define_insn "lrsc_atomic_fetch_<atomic_optab><mode>"
|
||||
[(set (match_operand:GPR 0 "register_operand" "=&r")
|
||||
(match_operand:GPR 1 "memory_operand" "+A"))
|
||||
(set (match_dup 1)
|
||||
(unspec_volatile:GPR
|
||||
[(any_atomic:GPR (match_dup 1)
|
||||
(match_operand:GPR 2 "reg_or_0_operand" "rJ"))
|
||||
(match_operand:SI 3 "const_int_operand")] ;; model
|
||||
UNSPEC_SYNC_OLD_OP))
|
||||
(clobber (match_scratch:GPR 4 "=&r"))] ;; tmp_1
|
||||
"!TARGET_ZAAMO && TARGET_ZALRSC"
|
||||
{
|
||||
return "1:\;"
|
||||
"lr.<amo>%I3\t%0, %1\;"
|
||||
"<insn>\t%4, %0, %2\;"
|
||||
"sc.<amo>%J3\t%4, %4, %1\;"
|
||||
"bnez\t%4, 1b";
|
||||
}
|
||||
[(set_attr "type" "atomic")
|
||||
(set (attr "length") (const_int 20))])
|
||||
|
||||
(define_insn "subword_atomic_fetch_strong_<atomic_optab>"
|
||||
[(set (match_operand:SI 0 "register_operand" "=&r") ;; old value at mem
|
||||
(match_operand:SI 1 "memory_operand" "+A")) ;; mem location
|
||||
|
@ -248,7 +323,23 @@
|
|||
DONE;
|
||||
})
|
||||
|
||||
(define_insn "atomic_exchange<mode>"
|
||||
(define_expand "atomic_exchange<mode>"
|
||||
[(match_operand:GPR 0 "register_operand") ;; old value at mem
|
||||
(match_operand:GPR 1 "memory_operand") ;; mem location
|
||||
(match_operand:GPR 2 "register_operand") ;; value for op
|
||||
(match_operand:SI 3 "const_int_operand")] ;; model
|
||||
"TARGET_ZAAMO || TARGET_ZALRSC"
|
||||
{
|
||||
if (TARGET_ZAAMO)
|
||||
emit_insn (gen_amo_atomic_exchange<mode> (operands[0], operands[1],
|
||||
operands[2], operands[3]));
|
||||
else
|
||||
emit_insn (gen_lrsc_atomic_exchange<mode> (operands[0], operands[1],
|
||||
operands[2], operands[3]));
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_insn "amo_atomic_exchange<mode>"
|
||||
[(set (match_operand:GPR 0 "register_operand" "=&r")
|
||||
(unspec_volatile:GPR
|
||||
[(match_operand:GPR 1 "memory_operand" "+A")
|
||||
|
@ -261,6 +352,26 @@
|
|||
[(set_attr "type" "atomic")
|
||||
(set (attr "length") (const_int 4))])
|
||||
|
||||
(define_insn "lrsc_atomic_exchange<mode>"
|
||||
[(set (match_operand:GPR 0 "register_operand" "=&r")
|
||||
(unspec_volatile:GPR
|
||||
[(match_operand:GPR 1 "memory_operand" "+A")
|
||||
(match_operand:SI 3 "const_int_operand")] ;; model
|
||||
UNSPEC_SYNC_EXCHANGE))
|
||||
(set (match_dup 1)
|
||||
(match_operand:GPR 2 "register_operand" "0"))
|
||||
(clobber (match_scratch:GPR 4 "=&r"))] ;; tmp_1
|
||||
"!TARGET_ZAAMO && TARGET_ZALRSC"
|
||||
{
|
||||
return "1:\;"
|
||||
"lr.<amo>%I3\t%4, %1\;"
|
||||
"sc.<amo>%J3\t%0, %0, %1\;"
|
||||
"bnez\t%0, 1b\;"
|
||||
"mv\t%0, %4";
|
||||
}
|
||||
[(set_attr "type" "atomic")
|
||||
(set (attr "length") (const_int 20))])
|
||||
|
||||
(define_expand "atomic_exchange<mode>"
|
||||
[(match_operand:SHORT 0 "register_operand") ;; old value at mem
|
||||
(match_operand:SHORT 1 "memory_operand") ;; mem location
|
||||
|
@ -516,7 +627,7 @@
|
|||
[(match_operand:QI 0 "register_operand" "") ;; bool output
|
||||
(match_operand:QI 1 "memory_operand" "+A") ;; memory
|
||||
(match_operand:SI 2 "const_int_operand" "")] ;; model
|
||||
"TARGET_ZALRSC"
|
||||
"TARGET_ZAAMO || TARGET_ZALRSC"
|
||||
{
|
||||
/* We have no QImode atomics, so use the address LSBs to form a mask,
|
||||
then use an aligned SImode atomic. */
|
||||
|
@ -537,7 +648,10 @@
|
|||
rtx shifted_set = gen_reg_rtx (SImode);
|
||||
riscv_lshift_subword (QImode, set, shift, &shifted_set);
|
||||
|
||||
emit_insn (gen_atomic_fetch_orsi (old, aligned_mem, shifted_set, model));
|
||||
if (TARGET_ZAAMO)
|
||||
emit_insn (gen_amo_atomic_fetch_orsi (old, aligned_mem, shifted_set, model));
|
||||
else if (TARGET_ZALRSC)
|
||||
emit_insn (gen_lrsc_atomic_fetch_orsi (old, aligned_mem, shifted_set, model));
|
||||
|
||||
emit_move_insn (old, gen_rtx_ASHIFTRT (SImode, old,
|
||||
gen_lowpart (QImode, shift)));
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
/* { dg-do compile } */
|
||||
/* Ensure that AMO ops are emitted when both zalrsc and zaamo are enabled. */
|
||||
/* { dg-options "-O3" } */
|
||||
/* { dg-add-options riscv_zalrsc } */
|
||||
/* { dg-add-options riscv_zaamo } */
|
||||
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
|
||||
/* { dg-final { check-function-bodies "**" "" } } */
|
||||
|
||||
/*
|
||||
** foo:
|
||||
** amoadd\.w\tzero,a1,0\(a0\)
|
||||
** ret
|
||||
*/
|
||||
void foo (int* bar, int* baz)
|
||||
{
|
||||
__atomic_add_fetch(bar, baz, __ATOMIC_RELAXED);
|
||||
}
|
19
gcc/testsuite/gcc.target/riscv/amo-zalrsc-amo-add-1.c
Normal file
19
gcc/testsuite/gcc.target/riscv/amo-zalrsc-amo-add-1.c
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* { dg-do compile } */
|
||||
/* Verify that lrsc atomic op mappings match Table A.6's recommended mapping. */
|
||||
/* { dg-options "-O3 -march=rv64id_zalrsc -mabi=lp64d" } */
|
||||
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
|
||||
/* { dg-final { check-function-bodies "**" "" } } */
|
||||
|
||||
/*
|
||||
** foo:
|
||||
** 1:
|
||||
** lr.w\t[atx][0-9]+, 0\(a0\)
|
||||
** add\t[atx][0-9]+, [atx][0-9]+, a1
|
||||
** sc.w\t[atx][0-9]+, [atx][0-9]+, 0\(a0\)
|
||||
** bnez\t[atx][0-9]+, 1b
|
||||
** ret
|
||||
*/
|
||||
void foo (int* bar, int* baz)
|
||||
{
|
||||
__atomic_add_fetch(bar, baz, __ATOMIC_RELAXED);
|
||||
}
|
19
gcc/testsuite/gcc.target/riscv/amo-zalrsc-amo-add-2.c
Normal file
19
gcc/testsuite/gcc.target/riscv/amo-zalrsc-amo-add-2.c
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* { dg-do compile } */
|
||||
/* Verify that lrsc atomic op mappings match Table A.6's recommended mapping. */
|
||||
/* { dg-options "-O3 -march=rv64id_zalrsc -mabi=lp64d" } */
|
||||
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
|
||||
/* { dg-final { check-function-bodies "**" "" } } */
|
||||
|
||||
/*
|
||||
** foo:
|
||||
** 1:
|
||||
** lr.w.aq\t[atx][0-9]+, 0\(a0\)
|
||||
** add\t[atx][0-9]+, [atx][0-9]+, a1
|
||||
** sc.w\t[atx][0-9]+, [atx][0-9]+, 0\(a0\)
|
||||
** bnez\t[atx][0-9]+, 1b
|
||||
** ret
|
||||
*/
|
||||
void foo (int* bar, int* baz)
|
||||
{
|
||||
__atomic_add_fetch(bar, baz, __ATOMIC_ACQUIRE);
|
||||
}
|
19
gcc/testsuite/gcc.target/riscv/amo-zalrsc-amo-add-3.c
Normal file
19
gcc/testsuite/gcc.target/riscv/amo-zalrsc-amo-add-3.c
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* { dg-do compile } */
|
||||
/* Verify that lrsc atomic op mappings match Table A.6's recommended mapping. */
|
||||
/* { dg-options "-O3 -march=rv64id_zalrsc -mabi=lp64d" } */
|
||||
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
|
||||
/* { dg-final { check-function-bodies "**" "" } } */
|
||||
|
||||
/*
|
||||
** foo:
|
||||
** 1:
|
||||
** lr.w\t[atx][0-9]+, 0\(a0\)
|
||||
** add\t[atx][0-9]+, [atx][0-9]+, a1
|
||||
** sc.w.rl\t[atx][0-9]+, [atx][0-9]+, 0\(a0\)
|
||||
** bnez\t[atx][0-9]+, 1b
|
||||
** ret
|
||||
*/
|
||||
void foo (int* bar, int* baz)
|
||||
{
|
||||
__atomic_add_fetch(bar, baz, __ATOMIC_RELEASE);
|
||||
}
|
19
gcc/testsuite/gcc.target/riscv/amo-zalrsc-amo-add-4.c
Normal file
19
gcc/testsuite/gcc.target/riscv/amo-zalrsc-amo-add-4.c
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* { dg-do compile } */
|
||||
/* Verify that lrsc atomic op mappings match Table A.6's recommended mapping. */
|
||||
/* { dg-options "-O3 -march=rv64id_zalrsc -mabi=lp64d" } */
|
||||
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
|
||||
/* { dg-final { check-function-bodies "**" "" } } */
|
||||
|
||||
/*
|
||||
** foo:
|
||||
** 1:
|
||||
** lr.w.aq\t[atx][0-9]+, 0\(a0\)
|
||||
** add\t[atx][0-9]+, [atx][0-9]+, a1
|
||||
** sc.w.rl\t[atx][0-9]+, [atx][0-9]+, 0\(a0\)
|
||||
** bnez\t[atx][0-9]+, 1b
|
||||
** ret
|
||||
*/
|
||||
void foo (int* bar, int* baz)
|
||||
{
|
||||
__atomic_add_fetch(bar, baz, __ATOMIC_ACQ_REL);
|
||||
}
|
19
gcc/testsuite/gcc.target/riscv/amo-zalrsc-amo-add-5.c
Normal file
19
gcc/testsuite/gcc.target/riscv/amo-zalrsc-amo-add-5.c
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* { dg-do compile } */
|
||||
/* Verify that lrsc atomic op mappings match Table A.6's recommended mapping. */
|
||||
/* { dg-options "-O3 -march=rv64id_zalrsc -mabi=lp64d" } */
|
||||
/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
|
||||
/* { dg-final { check-function-bodies "**" "" } } */
|
||||
|
||||
/*
|
||||
** foo:
|
||||
** 1:
|
||||
** lr.w.aqrl\t[atx][0-9]+, 0\(a0\)
|
||||
** add\t[atx][0-9]+, [atx][0-9]+, a1
|
||||
** sc.w.rl\t[atx][0-9]+, [atx][0-9]+, 0\(a0\)
|
||||
** bnez\t[atx][0-9]+, 1b
|
||||
** ret
|
||||
*/
|
||||
void foo (int* bar, int* baz)
|
||||
{
|
||||
__atomic_add_fetch(bar, baz, __ATOMIC_SEQ_CST);
|
||||
}
|
Loading…
Add table
Reference in a new issue