The Zabha extension adds support for subword Zaamo ops.
Extension: https://github.com/riscv/riscv-zabha.git
Ratification: https://jira.riscv.org/browse/RVS-1685
gcc/ChangeLog:
* common/config/riscv/riscv-common.cc
(riscv_subset_list::to_string): Skip zabha when not supported by
the assembler.
* config.in: Regenerate.
* config/riscv/arch-canonicalize: Make zabha imply zaamo.
* config/riscv/iterators.md (amobh): Add iterator for amo
byte/halfword.
* config/riscv/riscv.opt: Add zabha.
* config/riscv/sync.md (atomic_<atomic_optab><mode>): Add
subword atomic op pattern.
(zabha_atomic_fetch_<atomic_optab><mode>): Add subword
atomic_fetch op pattern.
(lrsc_atomic_fetch_<atomic_optab><mode>): Prefer zabha over lrsc
for subword atomic ops.
(zabha_atomic_exchange<mode>): Add subword atomic exchange
pattern.
(lrsc_atomic_exchange<mode>): Prefer zabha over lrsc for subword
atomic exchange ops.
* configure: Regenerate.
* configure.ac: Add zabha assembler check.
* doc/sourcebuild.texi: Add zabha documentation.
gcc/testsuite/ChangeLog:
* lib/target-supports.exp: Add zabha testsuite infra support.
* gcc.target/riscv/amo/inline-atomics-1.c: Remove zabha to continue to
test the lr/sc subword patterns.
* gcc.target/riscv/amo/inline-atomics-2.c: Ditto.
* gcc.target/riscv/amo/zalrsc-rvwmo-subword-amo-add-char-acq-rel.c: Ditto.
* gcc.target/riscv/amo/zalrsc-rvwmo-subword-amo-add-char-acquire.c: Ditto.
* gcc.target/riscv/amo/zalrsc-rvwmo-subword-amo-add-char-relaxed.c: Ditto.
* gcc.target/riscv/amo/zalrsc-rvwmo-subword-amo-add-char-release.c: Ditto.
* gcc.target/riscv/amo/zalrsc-rvwmo-subword-amo-add-char-seq-cst.c: Ditto.
* gcc.target/riscv/amo/zalrsc-ztso-subword-amo-add-char-acq-rel.c: Ditto.
* gcc.target/riscv/amo/zalrsc-ztso-subword-amo-add-char-acquire.c: Ditto.
* gcc.target/riscv/amo/zalrsc-ztso-subword-amo-add-char-relaxed.c: Ditto.
* gcc.target/riscv/amo/zalrsc-ztso-subword-amo-add-char-release.c: Ditto.
* gcc.target/riscv/amo/zalrsc-ztso-subword-amo-add-char-seq-cst.c: Ditto.
* gcc.target/riscv/amo/zabha-all-amo-ops-char-run.c: New test.
* gcc.target/riscv/amo/zabha-all-amo-ops-short-run.c: New test.
* gcc.target/riscv/amo/zabha-rvwmo-all-amo-ops-char.c: New test.
* gcc.target/riscv/amo/zabha-rvwmo-all-amo-ops-short.c: New test.
* gcc.target/riscv/amo/zabha-rvwmo-amo-add-char.c: New test.
* gcc.target/riscv/amo/zabha-rvwmo-amo-add-short.c: New test.
* gcc.target/riscv/amo/zabha-ztso-amo-add-char.c: New test.
* gcc.target/riscv/amo/zabha-ztso-amo-add-short.c: New test.
Co-Authored-By: Patrick O'Neill <patrick@rivosinc.com>
Signed-Off-By: Gianluca Guida <gianluca@rivosinc.com>
Tested-by: Andrea Parri <andrea@rivosinc.com>
{"a", "zaamo"},
{"a", "zalrsc"},
+ {"zabha", "zaamo"},
+
{"zdinx", "zfinx"},
{"zfinx", "zicsr"},
{"zdinx", "zicsr"},
{"zawrs", ISA_SPEC_CLASS_NONE, 1, 0},
{"zaamo", ISA_SPEC_CLASS_NONE, 1, 0},
{"zalrsc", ISA_SPEC_CLASS_NONE, 1, 0},
+ {"zabha", ISA_SPEC_CLASS_NONE, 1, 0},
{"zba", ISA_SPEC_CLASS_NONE, 1, 0},
{"zbb", ISA_SPEC_CLASS_NONE, 1, 0},
bool skip_zifencei = false;
bool skip_zaamo_zalrsc = false;
+ bool skip_zabha = false;
bool skip_zicsr = false;
bool i2p0 = false;
/* Skip since binutils 2.42 and earlier don't recognize zaamo/zalrsc. */
skip_zaamo_zalrsc = true;
#endif
+#ifndef HAVE_AS_MARCH_ZABHA
+ /* Skip since binutils 2.42 and earlier don't recognize zabha. */
+ skip_zabha = true;
+#endif
for (subset = m_head; subset != NULL; subset = subset->next)
{
if (skip_zaamo_zalrsc && subset->name == "zalrsc")
continue;
+ if (skip_zabha && subset->name == "zabha")
+ continue;
+
/* For !version_p, we only separate extension with underline for
multi-letter extension. */
if (!first &&
{"zawrs", &gcc_options::x_riscv_za_subext, MASK_ZAWRS},
{"zaamo", &gcc_options::x_riscv_za_subext, MASK_ZAAMO},
{"zalrsc", &gcc_options::x_riscv_za_subext, MASK_ZALRSC},
+ {"zabha", &gcc_options::x_riscv_za_subext, MASK_ZABHA},
{"zba", &gcc_options::x_riscv_zb_subext, MASK_ZBA},
{"zbb", &gcc_options::x_riscv_zb_subext, MASK_ZBB},
#endif
+/* Define if the assembler understands -march=rv*_zabha. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AS_MARCH_ZABHA
+#endif
+
+
/* Define if the assembler understands -march=rv*_zifencei. */
#ifndef USED_FOR_TARGET
#undef HAVE_AS_MARCH_ZIFENCEI
#
IMPLIED_EXT = {
"d" : ["f", "zicsr"],
+
"a" : ["zaamo", "zalrsc"],
+ "zabha" : ["zaamo"],
+
"f" : ["zicsr"],
"zdinx" : ["zfinx", "zicsr"],
"zfinx" : ["zicsr"],
;; This attribute gives the format suffix for atomic memory operations.
(define_mode_attr amo [(SI "w") (DI "d")])
+;; This attribute gives the format suffix for byte and halfword atomic memory operations.
+(define_mode_attr amobh [(QI "b") (HI "h")])
+
;; This attribute gives the upper-case mode name for one unit of a
;; floating-point mode.
(define_mode_attr UNITMODE [(HF "HF") (SF "SF") (DF "DF")])
Mask(ZALRSC) Var(riscv_za_subext)
+Mask(ZABHA) Var(riscv_za_subext)
+
Mask(ZA64RS) Var(riscv_za_subext)
Mask(ZA128RS) Var(riscv_za_subext)
UNSPEC_COMPARE_AND_SWAP_SUBWORD
UNSPEC_SYNC_OLD_OP
UNSPEC_SYNC_OLD_OP_SUBWORD
+ UNSPEC_SYNC_OLD_OP_ZABHA
UNSPEC_SYNC_EXCHANGE
UNSPEC_SYNC_EXCHANGE_SUBWORD
+ UNSPEC_SYNC_EXCHANGE_ZABHA
UNSPEC_ATOMIC_LOAD
UNSPEC_ATOMIC_STORE
UNSPEC_MEMORY_BARRIER
;; AMO ops
+(define_insn "atomic_<atomic_optab><mode>"
+ [(set (match_operand:SHORT 0 "memory_operand" "+A")
+ (unspec_volatile:SHORT
+ [(any_atomic:SHORT (match_dup 0)
+ (match_operand:SHORT 1 "reg_or_0_operand" "rJ"))
+ (match_operand:SI 2 "const_int_operand")] ;; model
+ UNSPEC_SYNC_OLD_OP_ZABHA))]
+ "TARGET_ZABHA"
+ "amo<insn>.<amobh>%A2\tzero,%z1,%0"
+ [(set_attr "type" "atomic")
+ (set (attr "length") (const_int 4))])
+
(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
(any_atomic:SHORT (match_operand:SHORT 1 "memory_operand") ;; mem location
(match_operand:SHORT 2 "reg_or_0_operand")) ;; value for op
(match_operand:SI 3 "const_int_operand")] ;; model
- "TARGET_ZALRSC && TARGET_INLINE_SUBWORD_ATOMIC"
+ "(TARGET_ZALRSC && TARGET_INLINE_SUBWORD_ATOMIC) || TARGET_ZABHA"
+{
+ if (TARGET_ZABHA)
+ emit_insn(gen_zabha_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 "zabha_atomic_fetch_<atomic_optab><mode>"
+ [(set (match_operand:SHORT 0 "register_operand" "=&r")
+ (match_operand:SHORT 1 "memory_operand" "+A"))
+ (set (match_dup 1)
+ (unspec_volatile:SHORT
+ [(any_atomic:SHORT (match_dup 1)
+ (match_operand:SHORT 2 "reg_or_0_operand" "rJ"))
+ (match_operand:SI 3 "const_int_operand")] ;; model
+ UNSPEC_SYNC_OLD_OP_ZABHA))]
+ "TARGET_ZABHA"
+ "amo<insn>.<amobh>%A3\t%0,%z2,%1"
+ [(set_attr "type" "atomic")
+ (set (attr "length") (const_int 4))])
+
+(define_expand "lrsc_atomic_fetch_<atomic_optab><mode>"
+ [(match_operand:SHORT 0 "register_operand") ;; old value at mem
+ (any_atomic:SHORT (match_operand:SHORT 1 "memory_operand") ;; mem location
+ (match_operand:SHORT 2 "reg_or_0_operand")) ;; value for op
+ (match_operand:SI 3 "const_int_operand")] ;; model
+ "!TARGET_ZABHA && TARGET_ZALRSC && TARGET_INLINE_SUBWORD_ATOMIC"
{
/* We have no QImode/HImode atomics, so form a mask, then use
subword_atomic_fetch_strong_<mode> to implement a LR/SC version of the
DONE;
})
+; Atomic exchange ops
+
(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:SHORT 1 "memory_operand") ;; mem location
(match_operand:SHORT 2 "register_operand") ;; value
(match_operand:SI 3 "const_int_operand")] ;; model
- "TARGET_ZALRSC && TARGET_INLINE_SUBWORD_ATOMIC"
+ "(TARGET_ZALRSC && TARGET_INLINE_SUBWORD_ATOMIC) || TARGET_ZABHA"
+{
+ if (TARGET_ZABHA)
+ emit_insn(gen_zabha_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 "zabha_atomic_exchange<mode>"
+ [(set (match_operand:SHORT 0 "register_operand" "=&r")
+ (unspec_volatile:SHORT
+ [(match_operand:SHORT 1 "memory_operand" "+A")
+ (match_operand:SI 3 "const_int_operand")] ;; model
+ UNSPEC_SYNC_EXCHANGE_ZABHA))
+ (set (match_dup 1)
+ (match_operand:SHORT 2 "register_operand" "0"))]
+ "TARGET_ZABHA"
+ "amoswap.<amobh>%A3\t%0,%z2,%1"
+ [(set_attr "type" "atomic")
+ (set (attr "length") (const_int 4))])
+
+(define_expand "lrsc_atomic_exchange<mode>"
+ [(match_operand:SHORT 0 "register_operand") ;; old value at mem
+ (match_operand:SHORT 1 "memory_operand") ;; mem location
+ (match_operand:SHORT 2 "register_operand") ;; value
+ (match_operand:SI 3 "const_int_operand")] ;; model
+ "!TARGET_ZABHA && TARGET_ZALRSC && TARGET_INLINE_SUBWORD_ATOMIC"
{
rtx old = gen_reg_rtx (SImode);
rtx mem = operands[1];
[(set_attr "type" "multi")
(set (attr "length") (const_int 20))])
+; Atomic CAS ops
+
(define_insn "atomic_cas_value_strong<mode>"
[(set (match_operand:GPR 0 "register_operand" "=&r")
(match_operand:GPR 1 "memory_operand" "+A"))
$as_echo "#define HAVE_AS_MARCH_ZAAMO_ZALRSC 1" >>confdefs.h
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for -march=rv32i_zabha support" >&5
+$as_echo_n "checking assembler for -march=rv32i_zabha support... " >&6; }
+if ${gcc_cv_as_riscv_march_zabha+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcc_cv_as_riscv_march_zabha=no
+ if test x$gcc_cv_as != x; then
+ $as_echo '' > conftest.s
+ if { ac_try='$gcc_cv_as $gcc_cv_as_flags -march=rv32i_zabha -o conftest.o conftest.s >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+ then
+ gcc_cv_as_riscv_march_zabha=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_riscv_march_zabha" >&5
+$as_echo "$gcc_cv_as_riscv_march_zabha" >&6; }
+if test $gcc_cv_as_riscv_march_zabha = yes; then
+
+$as_echo "#define HAVE_AS_MARCH_ZABHA 1" >>confdefs.h
+
fi
;;
[-march=rv32i_zaamo_zalrsc],,,
[AC_DEFINE(HAVE_AS_MARCH_ZAAMO_ZALRSC, 1,
[Define if the assembler understands -march=rv*_zaamo_zalrsc.])])
+ gcc_GAS_CHECK_FEATURE([-march=rv32i_zabha support],
+ gcc_cv_as_riscv_march_zabha,
+ [-march=rv32i_zabha],,,
+ [AC_DEFINE(HAVE_AS_MARCH_ZABHA, 1,
+ [Define if the assembler understands -march=rv*_zabha.])])
;;
loongarch*-*-*)
gcc_GAS_CHECK_FEATURE([.dtprelword support],
@item riscv_zaamo
Test target architecture has support for the zaamo extension.
-@item riscv_zlrsc
+@item riscv_zabha
+Test target architecture has support for the zabha extension.
+
+@item riscv_zalrsc
Test target architecture has support for the zalrsc extension.
@item riscv_ztso
@item riscv_zaamo
Add the zaamo extension to the -march string on RISC-V targets.
+@item riscv_zabha
+Add the zabha extension to the -march string on RISC-V targets.
+
@item riscv_zalrsc
Add the zalrsc extension to the -march string on RISC-V targets.
Remove the zaamo extension from the -march string on RISC-V. If the 'A'
extension is present downgrade it to zalrsc.
+@item riscv_zabha
+Remove the zabha extension and implied zaamo extension from the -march string
+on RISC-V.
+
@item riscv_zalrsc
Remove the zalrsc extension from the -march string on RISC-V. If the 'A'
extension is present downgrade it to zaamo.
/* { dg-do compile } */
/* { dg-options "-mno-inline-atomics" } */
+/* { dg-remove-options riscv_zabha } */
/* { dg-message "note: '__sync_fetch_and_nand' changed semantics in GCC 4.4" "fetch_and_nand" { target *-*-* } 0 } */
/* { dg-final { scan-assembler "\tcall\t__sync_fetch_and_add_1" } } */
/* { dg-final { scan-assembler "\tcall\t__sync_fetch_and_nand_1" } } */
/* Verify that subword atomics do not generate calls. */
/* { dg-options "-minline-atomics" } */
/* { dg-add-options riscv_a } */
+/* { dg-remove-options riscv_zabha } */
/* { dg-message "note: '__sync_fetch_and_nand' changed semantics in GCC 4.4" "fetch_and_nand" { target *-*-* } 0 } */
/* { dg-final { scan-assembler-not "\tcall\t__sync_fetch_and_add_1" } } */
/* { dg-final { scan-assembler-not "\tcall\t__sync_fetch_and_nand_1" } } */
--- /dev/null
+/* Test __atomic routines for existence on 1 byte values with each valid memory model. */
+/* { dg-do run { target { riscv_zabha } } } */
+/* { dg-options "-Wno-address-of-packed-member" } */
+
+#include "inline-atomics-3.c"
--- /dev/null
+/* Test __atomic routines for execution on 2 byte values with each valid memory model. */
+/* { dg-do run { target { riscv_zabha } } } */
+/* { dg-options "-Wno-address-of-packed-member" } */
+
+#include "inline-atomics-4.c"
--- /dev/null
+/* Test __atomic routines for existence on 2 byte values with each valid memory model. */
+/* { dg-compile } */
+/* { dg-options "-Wno-address-of-packed-member" } */
+/* { dg-add-options riscv_zabha } */
+/* { dg-remove-options riscv_ztso } */
+/* { dg-final { scan-assembler "\tamoadd.b" } } */
+/* { dg-final { scan-assembler "\tamoadd.b.aq" } } */
+/* { dg-final { scan-assembler "\tamoadd.b.rl" } } */
+/* { dg-final { scan-assembler "\tamoadd.b.aqrl" } } */
+/* { dg-final { scan-assembler "\tamoand.b" } } */
+/* { dg-final { scan-assembler "\tamoand.b.aq" } } */
+/* { dg-final { scan-assembler "\tamoand.b.rl" } } */
+/* { dg-final { scan-assembler "\tamoand.b.aqrl" } } */
+/* { dg-final { scan-assembler "\tamoxor.b" } } */
+/* { dg-final { scan-assembler "\tamoxor.b.aq" } } */
+/* { dg-final { scan-assembler "\tamoxor.b.rl" } } */
+/* { dg-final { scan-assembler "\tamoxor.b.aqrl" } } */
+/* { dg-final { scan-assembler "\tamoor.b" } } */
+/* { dg-final { scan-assembler "\tamoor.b.aq" } } */
+/* { dg-final { scan-assembler "\tamoor.b.rl" } } */
+/* { dg-final { scan-assembler "\tamoor.b.aqrl" } } */
+
+#include "inline-atomics-3.c"
--- /dev/null
+/* Test __atomic routines for existence on 2 byte values with each valid memory model. */
+/* { dg-compile } */
+/* { dg-options "-Wno-address-of-packed-member" } */
+/* { dg-add-options riscv_zabha } */
+/* { dg-remove-options riscv_ztso } */
+/* { dg-final { scan-assembler "\tamoadd.h" } } */
+/* { dg-final { scan-assembler "\tamoadd.h.aq" } } */
+/* { dg-final { scan-assembler "\tamoadd.h.rl" } } */
+/* { dg-final { scan-assembler "\tamoadd.h.aqrl" } } */
+/* { dg-final { scan-assembler "\tamoand.h" } } */
+/* { dg-final { scan-assembler "\tamoand.h.aq" } } */
+/* { dg-final { scan-assembler "\tamoand.h.rl" } } */
+/* { dg-final { scan-assembler "\tamoand.h.aqrl" } } */
+/* { dg-final { scan-assembler "\tamoxor.h" } } */
+/* { dg-final { scan-assembler "\tamoxor.h.aq" } } */
+/* { dg-final { scan-assembler "\tamoxor.h.rl" } } */
+/* { dg-final { scan-assembler "\tamoxor.h.aqrl" } } */
+/* { dg-final { scan-assembler "\tamoor.h" } } */
+/* { dg-final { scan-assembler "\tamoor.h.aq" } } */
+/* { dg-final { scan-assembler "\tamoor.h.rl" } } */
+/* { dg-final { scan-assembler "\tamoor.h.aqrl" } } */
+
+#include "inline-atomics-4.c"
--- /dev/null
+/* Verify that atomic op mappings match the PSABI doc's recommended mapping. */
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_zabha } */
+/* { dg-remove-options riscv_ztso } */
+/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/*
+** atomic_add_fetch_char_relaxed:
+** amoadd\.b\tzero,a1,0\(a0\)
+** ret
+*/
+void atomic_add_fetch_char_relaxed (char* bar, char baz)
+{
+ __atomic_add_fetch(bar, baz, __ATOMIC_RELAXED);
+}
+
+/*
+** atomic_add_fetch_char_acquire:
+** amoadd\.b\.aq\tzero,a1,0\(a0\)
+** ret
+*/
+void atomic_add_fetch_char_acquire (char* bar, char baz)
+{
+ __atomic_add_fetch(bar, baz, __ATOMIC_ACQUIRE);
+}
+
+/*
+** atomic_add_fetch_char_release:
+** amoadd\.b\.rl\tzero,a1,0\(a0\)
+** ret
+*/
+void atomic_add_fetch_char_release (char* bar, char baz)
+{
+ __atomic_add_fetch(bar, baz, __ATOMIC_RELEASE);
+}
+
+/*
+** atomic_add_fetch_char_acq_rel:
+** amoadd\.b\.aqrl\tzero,a1,0\(a0\)
+** ret
+*/
+void atomic_add_fetch_char_acq_rel (char* bar, char baz)
+{
+ __atomic_add_fetch(bar, baz, __ATOMIC_ACQ_REL);
+}
+
+/*
+** atomic_add_fetch_char_seq_cst:
+** amoadd\.b\.aqrl\tzero,a1,0\(a0\)
+** ret
+*/
+void atomic_add_fetch_char_seq_cst (char* bar, char baz)
+{
+ __atomic_add_fetch(bar, baz, __ATOMIC_SEQ_CST);
+}
--- /dev/null
+/* Verify that atomic op mappings match the PSABI doc's recommended mapping. */
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_zabha } */
+/* { dg-remove-options riscv_ztso } */
+/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/*
+** atomic_add_fetch_short_relaxed:
+** amoadd\.h\tzero,a1,0\(a0\)
+** ret
+*/
+void atomic_add_fetch_short_relaxed (short* bar, short baz)
+{
+ __atomic_add_fetch(bar, baz, __ATOMIC_RELAXED);
+}
+
+/*
+** atomic_add_fetch_short_acquire:
+** amoadd\.h\.aq\tzero,a1,0\(a0\)
+** ret
+*/
+void atomic_add_fetch_short_acquire (short* bar, short baz)
+{
+ __atomic_add_fetch(bar, baz, __ATOMIC_ACQUIRE);
+}
+
+/*
+** atomic_add_fetch_short_release:
+** amoadd\.h\.rl\tzero,a1,0\(a0\)
+** ret
+*/
+void atomic_add_fetch_short_release (short* bar, short baz)
+{
+ __atomic_add_fetch(bar, baz, __ATOMIC_RELEASE);
+}
+
+/*
+** atomic_add_fetch_short_acq_rel:
+** amoadd\.h\.aqrl\tzero,a1,0\(a0\)
+** ret
+*/
+void atomic_add_fetch_short_acq_rel (short* bar, short baz)
+{
+ __atomic_add_fetch(bar, baz, __ATOMIC_ACQ_REL);
+}
+
+/*
+** atomic_add_fetch_short_seq_cst:
+** amoadd\.h\.aqrl\tzero,a1,0\(a0\)
+** ret
+*/
+void atomic_add_fetch_short_seq_cst (short* bar, short baz)
+{
+ __atomic_add_fetch(bar, baz, __ATOMIC_SEQ_CST);
+}
--- /dev/null
+/* Verify that atomic op mappings match the PSABI doc's recommended mapping. */
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_ztso } */
+/* { dg-add-options riscv_zabha } */
+/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/*
+** atomic_add_fetch_char_relaxed:
+** amoadd\.b\tzero,a1,0\(a0\)
+** ret
+*/
+void atomic_add_fetch_char_relaxed (char* bar, char baz)
+{
+ __atomic_add_fetch(bar, baz, __ATOMIC_RELAXED);
+}
+
+/*
+** atomic_add_fetch_char_acquire:
+** amoadd\.b\tzero,a1,0\(a0\)
+** ret
+*/
+void atomic_add_fetch_char_acquire (char* bar, char baz)
+{
+ __atomic_add_fetch(bar, baz, __ATOMIC_ACQUIRE);
+}
+
+/*
+** atomic_add_fetch_char_release:
+** amoadd\.b\tzero,a1,0\(a0\)
+** ret
+*/
+void atomic_add_fetch_char_release (char* bar, char baz)
+{
+ __atomic_add_fetch(bar, baz, __ATOMIC_RELEASE);
+}
+
+/*
+** atomic_add_fetch_char_acq_rel:
+** amoadd\.b\tzero,a1,0\(a0\)
+** ret
+*/
+void atomic_add_fetch_char_acq_rel (char* bar, char baz)
+{
+ __atomic_add_fetch(bar, baz, __ATOMIC_ACQ_REL);
+}
+
+/*
+** atomic_add_fetch_char_seq_cst:
+** amoadd\.b\tzero,a1,0\(a0\)
+** ret
+*/
+void atomic_add_fetch_char_seq_cst (char* bar, char baz)
+{
+ __atomic_add_fetch(bar, baz, __ATOMIC_SEQ_CST);
+}
--- /dev/null
+/* Verify that atomic op mappings match the PSABI doc's recommended mapping. */
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_ztso } */
+/* { dg-add-options riscv_zabha } */
+/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/*
+** atomic_add_fetch_short_relaxed:
+** amoadd\.h\tzero,a1,0\(a0\)
+** ret
+*/
+void atomic_add_fetch_short_relaxed (short* bar, short baz)
+{
+ __atomic_add_fetch(bar, baz, __ATOMIC_RELAXED);
+}
+
+/*
+** atomic_add_fetch_short_acquire:
+** amoadd\.h\tzero,a1,0\(a0\)
+** ret
+*/
+void atomic_add_fetch_short_acquire (short* bar, short baz)
+{
+ __atomic_add_fetch(bar, baz, __ATOMIC_ACQUIRE);
+}
+
+/*
+** atomic_add_fetch_short_release:
+** amoadd\.h\tzero,a1,0\(a0\)
+** ret
+*/
+void atomic_add_fetch_short_release (short* bar, short baz)
+{
+ __atomic_add_fetch(bar, baz, __ATOMIC_RELEASE);
+}
+
+/*
+** atomic_add_fetch_short_acq_rel:
+** amoadd\.h\tzero,a1,0\(a0\)
+** ret
+*/
+void atomic_add_fetch_short_acq_rel (short* bar, short baz)
+{
+ __atomic_add_fetch(bar, baz, __ATOMIC_ACQ_REL);
+}
+
+/*
+** atomic_add_fetch_short_seq_cst:
+** amoadd\.h\tzero,a1,0\(a0\)
+** ret
+*/
+void atomic_add_fetch_short_seq_cst (short* bar, short baz)
+{
+ __atomic_add_fetch(bar, baz, __ATOMIC_SEQ_CST);
+}
/* Verify that subword atomic op mappings match the PSABI doc's recommended mapping. */
/* { dg-add-options riscv_zalrsc } */
/* { dg-remove-options riscv_ztso } */
+/* { dg-remove-options riscv_zabha } */
/* { dg-final { scan-assembler-times "lr.w.aq\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w.rl\t" 1 } } */
/* Verify that subword atomic op mappings match the PSABI doc's recommended mapping. */
/* { dg-add-options riscv_zalrsc } */
/* { dg-remove-options riscv_ztso } */
+/* { dg-remove-options riscv_zabha } */
/* { dg-final { scan-assembler-times "lr.w.aq\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
/* Verify that subword atomic op mappings match the PSABI doc's recommended mapping. */
/* { dg-add-options riscv_zalrsc } */
/* { dg-remove-options riscv_ztso } */
+/* { dg-remove-options riscv_zabha } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
/* Verify that subword atomic op mappings match the PSABI doc's recommended mapping. */
/* { dg-add-options riscv_zalrsc } */
/* { dg-remove-options riscv_ztso } */
+/* { dg-remove-options riscv_zabha } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w.rl\t" 1 } } */
/* Verify that subword atomic op mappings match the PSABI doc's recommended mapping. */
/* { dg-add-options riscv_zalrsc } */
/* { dg-remove-options riscv_ztso } */
+/* { dg-remove-options riscv_zabha } */
/* { dg-final { scan-assembler-times "lr.w.aqrl\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w.rl\t" 1 } } */
/* Verify that subword atomic op mappings match the PSABI doc's suggested mapping. */
/* { dg-add-options riscv_zalrsc } */
/* { dg-add-options riscv_ztso } */
+/* { dg-remove-options riscv_zabha } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
/* Verify that subword atomic op mappings match the PSABI doc's suggested mapping. */
/* { dg-add-options riscv_zalrsc } */
/* { dg-add-options riscv_ztso } */
+/* { dg-remove-options riscv_zabha } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
/* Verify that subword atomic op mappings match the PSABI doc's suggested mapping. */
/* { dg-add-options riscv_zalrsc } */
/* { dg-add-options riscv_ztso } */
+/* { dg-remove-options riscv_zabha } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
/* Verify that subword atomic op mappings match the PSABI doc's suggested mapping. */
/* { dg-add-options riscv_zalrsc } */
/* { dg-add-options riscv_ztso } */
+/* { dg-remove-options riscv_zabha } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
/* Verify that subword atomic op mappings match the PSABI doc's suggested mapping. */
/* { dg-add-options riscv_zalrsc } */
/* { dg-add-options riscv_ztso } */
+/* { dg-remove-options riscv_zabha } */
/* { dg-final { scan-assembler-times "lr.w.aqrl\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w.rl\t" 1 } } */
}]
}
+# Return 1 if the target arch supports the atomic BHA extension, 0 otherwise.
+# Cache the result.
+
+proc check_effective_target_riscv_zabha { } {
+ return [check_no_compiler_messages riscv_ext_zabha assembly {
+ #ifndef __riscv_zabha
+ #error "Not __riscv_zabha"
+ #endif
+ }]
+}
+
# Return 1 if the target arch supports the double precision floating point
# extension, 0 otherwise. Cache the result.
proc riscv_get_arch { } {
set gcc_march ""
# ??? do we neeed to add more extensions to the list below?
- foreach ext { i m a f d q c v zicsr zifencei zfh zba zbb zbc zbs zvbb zvfh ztso zaamo zalrsc } {
+ foreach ext { i m a f d q c v zicsr zifencei zfh zba zbb zbc zbs zvbb zvfh ztso zaamo zalrsc zabha } {
if { [check_no_compiler_messages riscv_ext_$ext assembly [string map [list DEF __riscv_$ext] {
#ifndef DEF
#error "Not DEF"
proc remove_options_for_riscv_zaamo { flags } {
set modified_flags [remove_options_for_riscv_z_ext zaamo $flags]
+ # If zabha is set then zaamo will be implied. We need to remove zabha
+ # as well.
+ set modified_flags [remove_options_for_riscv_z_ext zabha $modified_flags]
# If 'a' is set then zaamo will be implied. We need to downgrade instances
# of 'a' to 'zalrsc'
- set no_a_flags [remove_options_for_riscv_a_only [split $modified_flags]]
+ set no_a_flags [remove_options_for_riscv_a_only $modified_flags]
if {![string equal $modified_flags $no_a_flags]} {
# 'a' was removed, add 'zalrsc' since it was previously implied
- set modified_flags [add_options_for_riscv_zalrsc [split $no_a_flags]]
+ set modified_flags [add_options_for_riscv_zalrsc $no_a_flags]
}
return $modified_flags
}
set modified_flags [remove_options_for_riscv_z_ext zalrsc $flags]
# If 'a' is set then zalrsc will be implied. We need to downgrade instances
# of 'a' to 'zaamo'
- set no_a_flags [remove_options_for_riscv_a_only [split $modified_flags]]
+ set no_a_flags [remove_options_for_riscv_a_only $modified_flags]
if {![string equal $modified_flags $no_a_flags]} {
# 'a' was removed, add 'zalrsc' since it was previously implied
- set modified_flags [add_options_for_riscv_zalrsc [split $no_a_flags]]
+ set modified_flags [add_options_for_riscv_zalrsc $no_a_flags]
}
return $modified_flags
}
+proc add_options_for_riscv_zabha { flags } {
+ return [add_options_for_riscv_z_ext zabha $flags]
+}
+
+proc remove_options_for_riscv_zabha { flags } {
+ set modified_flags [remove_options_for_riscv_zaamo $flags]
+ return [remove_options_for_riscv_z_ext zabha $modified_flags]
+}
+
proc add_options_for_riscv_zfh { flags } {
return [add_options_for_riscv_z_ext zfh $flags]
}