}},
{"zabha", "zaamo"},
+ {"zacas", "zaamo"},
{"b", "zba"},
{"b", "zbb"},
{"zaamo", ISA_SPEC_CLASS_NONE, 1, 0},
{"zalrsc", ISA_SPEC_CLASS_NONE, 1, 0},
{"zabha", ISA_SPEC_CLASS_NONE, 1, 0},
+ {"zacas", ISA_SPEC_CLASS_NONE, 1, 0},
{"zba", ISA_SPEC_CLASS_NONE, 1, 0},
{"zbb", ISA_SPEC_CLASS_NONE, 1, 0},
{"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},
+ {"zacas", &gcc_options::x_riscv_za_subext, MASK_ZACAS},
{"zba", &gcc_options::x_riscv_zb_subext, MASK_ZBA},
{"zbb", &gcc_options::x_riscv_zb_subext, MASK_ZBB},
"a" : ["zaamo", "zalrsc"],
"zabha" : ["zaamo"],
+ "zacas" : ["zaamo"],
"f" : ["zicsr"],
"b" : ["zba", "zbb", "zbs"],
Mask(ZABHA) Var(riscv_za_subext)
+Mask(ZACAS) Var(riscv_za_subext)
+
Mask(ZA64RS) Var(riscv_za_subext)
Mask(ZA128RS) Var(riscv_za_subext)
; Atomic CAS ops
-(define_insn "atomic_cas_value_strong<mode>"
+(define_insn "zalrsc_atomic_cas_value_strong<mode>"
[(set (match_operand:GPR 0 "register_operand" "=&r")
(match_operand:GPR 1 "memory_operand" "+A"))
(set (match_dup 1)
[(set_attr "type" "multi")
(set (attr "length") (const_int 16))])
+;; Implement compare_exchange with a conservative leading fence when
+;; model_failure is seq_cst.
+;; This allows us to be compatible with the ISA manual Table A.6 and Table A.7
+;; (A6C and A7).
+;; More details: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/444
+(define_insn "zacas_atomic_cas_value_strong<mode>"
+ [(set (match_operand:GPR 0 "register_operand" "=&r") ;; val output
+ (match_operand:GPR 1 "memory_operand" "+A")) ;; memory
+ (set (match_dup 1)
+ (unspec_volatile:GPR [(match_operand:GPR 2 "register_operand" "0") ;; expected val
+ (match_operand:GPR 3 "reg_or_0_operand" "rJ") ;; desired val
+ (match_operand:SI 4 "const_int_operand") ;; mod_s
+ (match_operand:SI 5 "const_int_operand")] ;; mod_f
+ UNSPEC_COMPARE_AND_SWAP))]
+ "TARGET_ZACAS"
+ {
+ enum memmodel model_success = (enum memmodel) INTVAL (operands[4]);
+ enum memmodel model_failure = (enum memmodel) INTVAL (operands[5]);
+ /* Find the union of the two memory models so we can satisfy both success
+ and failure memory models. */
+ operands[4] = GEN_INT (riscv_union_memmodels (model_success, model_failure));
+
+ if (model_failure == MEMMODEL_SEQ_CST)
+ return "fence\trw,rw\;"
+ "amocas.<amo>%A4\t%0,%z3,%1";
+ else
+ return "amocas.<amo>%A4\t%0,%z3,%1";
+ }
+ [(set_attr "type" "atomic")
+ (set (attr "length")
+ (symbol_ref "is_mm_seq_cst(memmodel_from_int(INTVAL (operands[5]))) ? 8 : 4"))])
+
(define_expand "atomic_compare_and_swap<mode>"
[(match_operand:SI 0 "register_operand" "") ;; bool output
(match_operand:GPR 1 "register_operand" "") ;; val output
(match_operand:GPR 2 "memory_operand" "") ;; memory
- (match_operand:GPR 3 "reg_or_0_operand" "") ;; expected value
+ (match_operand:GPR 3 "register_operand" "") ;; expected value
(match_operand:GPR 4 "reg_or_0_operand" "") ;; desired value
(match_operand:SI 5 "const_int_operand" "") ;; is_weak
(match_operand:SI 6 "const_int_operand" "") ;; mod_s
(match_operand:SI 7 "const_int_operand" "")] ;; mod_f
- "TARGET_ZALRSC"
+ "TARGET_ZALRSC || TARGET_ZACAS"
{
if (word_mode != <MODE>mode && operands[3] != const0_rtx)
{
operands[3] = simplify_gen_subreg (<MODE>mode, tmp0, word_mode, 0);
}
- emit_insn (gen_atomic_cas_value_strong<mode> (operands[1], operands[2],
- operands[3], operands[4],
- operands[6], operands[7]));
+ if (TARGET_ZACAS)
+ emit_insn (gen_zacas_atomic_cas_value_strong<mode> (operands[1],
+ operands[2],
+ operands[3],
+ operands[4],
+ operands[6],
+ operands[7]));
+ else
+ emit_insn (gen_zalrsc_atomic_cas_value_strong<mode> (operands[1],
+ operands[2],
+ operands[3],
+ operands[4],
+ operands[6],
+ operands[7]));
rtx compare = operands[1];
if (operands[3] != const0_rtx)
DONE;
})
+;; Implement compare_exchange with a conservative leading fence when
+;; model_failure is seq_cst.
+;; This allows us to be compatible with the ISA manual Table A.6 and Table A.7
+;; (A6C and A7).
+;; More details: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/444
+(define_insn "zacas_atomic_cas_value_strong<mode>"
+ [(set (match_operand:SHORT 0 "register_operand" "=&r") ;; val output
+ (match_operand:SHORT 1 "memory_operand" "+A")) ;; memory
+ (set (match_dup 1)
+ (unspec_volatile:SHORT [(match_operand:SHORT 2 "register_operand" "0") ;; expected_val
+ (match_operand:SHORT 3 "register_operand" "rJ") ;; desired_val
+ (match_operand:SI 4 "const_int_operand") ;; mod_s
+ (match_operand:SI 5 "const_int_operand")] ;; mod_f
+ UNSPEC_COMPARE_AND_SWAP))]
+ "TARGET_ZACAS && TARGET_ZABHA"
+ {
+ enum memmodel model_success = (enum memmodel) INTVAL (operands[4]);
+ enum memmodel model_failure = (enum memmodel) INTVAL (operands[5]);
+ /* Find the union of the two memory models so we can satisfy both success
+ and failure memory models. */
+ operands[4] = GEN_INT (riscv_union_memmodels (model_success, model_failure));
+
+ if (model_failure == MEMMODEL_SEQ_CST)
+ return "fence\trw,rw\;"
+ "amocas.<amobh>%A4\t%0,%z3,%1";
+ else
+ return "amocas.<amobh>%A4\t%0,%z3,%1";
+ }
+ [(set_attr "type" "atomic")
+ (set (attr "length")
+ (symbol_ref "is_mm_seq_cst(memmodel_from_int(INTVAL (operands[5]))) ? 8 : 4"))])
+
(define_expand "atomic_compare_and_swap<mode>"
[(match_operand:SI 0 "register_operand") ;; bool output
(match_operand:SHORT 1 "register_operand") ;; val output
(match_operand:SHORT 2 "memory_operand") ;; memory
- (match_operand:SHORT 3 "reg_or_0_operand") ;; expected value
+ (match_operand:SHORT 3 "register_operand") ;; expected value
(match_operand:SHORT 4 "reg_or_0_operand") ;; desired value
(match_operand:SI 5 "const_int_operand") ;; is_weak
(match_operand:SI 6 "const_int_operand") ;; mod_s
(match_operand:SI 7 "const_int_operand")] ;; mod_f
- "TARGET_ZALRSC && TARGET_INLINE_SUBWORD_ATOMIC"
+ "(TARGET_ZALRSC && TARGET_INLINE_SUBWORD_ATOMIC) || (TARGET_ZACAS && TARGET_ZABHA)"
{
- emit_insn (gen_atomic_cas_value_strong<mode> (operands[1], operands[2],
- operands[3], operands[4],
- operands[6], operands[7]));
+
+ if (TARGET_ZACAS && TARGET_ZABHA)
+ emit_insn (gen_zacas_atomic_cas_value_strong<mode> (operands[1],
+ operands[2],
+ operands[3],
+ operands[4],
+ operands[6],
+ operands[7]));
+ else
+ emit_insn (gen_zalrsc_atomic_cas_value_strong<mode> (operands[1],
+ operands[2],
+ operands[3],
+ operands[4],
+ operands[6],
+ operands[7]));
rtx val = gen_reg_rtx (SImode);
if (operands[1] != const0_rtx)
DONE;
})
-(define_expand "atomic_cas_value_strong<mode>"
+(define_expand "zalrsc_atomic_cas_value_strong<mode>"
[(match_operand:SHORT 0 "register_operand") ;; val output
(match_operand:SHORT 1 "memory_operand") ;; memory
(match_operand:SHORT 2 "reg_or_0_operand") ;; expected value
@item riscv_zabha
Test target architecture has support for the zabha extension.
+@item riscv_zacas
+Test target architecture has support for the zacas extension.
+
@item riscv_zalrsc
Test target architecture has support for the zalrsc extension.
@item riscv_zabha
Add the zabha extension to the -march string on RISC-V targets.
+@item riscv_zacas
+Add the zacas 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 zabha extension and implied zaamo extension from the -march string
on RISC-V.
+@item riscv_zacas
+Remove the zacas 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.
--- /dev/null
+/* { dg-do compile } */
+/* Ensure that AMO ops are emitted for subword cas when both zalrsc and
+ zacas/zabha are enabled. */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_zalrsc } */
+/* { dg-add-options riscv_zacas } */
+/* { dg-add-options riscv_zabha } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-times "amocas\.b\t" 2 } } */
+
+
+void atomic_compare_exchange_weak_char_relaxed (char *bar, char *baz, char qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_strong_char_relaxed (char *bar, char *baz, char qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+}
--- /dev/null
+/* { dg-do compile } */
+/* Ensure subword zacas is not emitted unless both zacas and zabha are
+ present. */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_zacas } */
+/* { dg-remove-options riscv_zabha } */
+/* { dg-remove-options riscv_zalrsc } */
+/* { dg-final { scan-assembler "\tcall\t" } } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-not "amocas\.b\t" } } */
+
+
+void atomic_compare_exchange_char_relaxed (char *bar, char *baz, char qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+}
--- /dev/null
+/* { dg-do compile } */
+/* Ensure subword zacas is not emitted unless both zacas and zabha are
+ present. */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_zabha } */
+/* { dg-remove-options riscv_zacas } */
+/* { dg-remove-options riscv_zalrsc } */
+/* { dg-final { scan-assembler "\tcall\t" } } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-not "amocas\.b\t" } } */
+
+
+void atomic_compare_exchange_char_relaxed (char *bar, char *baz, char qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+}
--- /dev/null
+/* { dg-do compile } */
+/* Ensure that AMO ops are emitted for subword cas when both zalrsc and
+ zacas/zabha are enabled. */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_zalrsc } */
+/* { dg-add-options riscv_zacas } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-times "amocas\.w\t" 2 } } */
+
+
+void atomic_compare_exchange_weak_int_relaxed (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_strong_int_relaxed (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+}
--- /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-add-options riscv_zacas } */
+/* { dg-remove-options riscv_ztso } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-times "amocas\.b\.aqrl\t" 2 } } */
+
+
+void atomic_compare_exchange_weak_char_acq_rel (char *bar, char *baz, char qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_strong_char_acq_rel (char *bar, char *baz, char qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED);
+}
--- /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-add-options riscv_zacas } */
+/* { dg-remove-options riscv_ztso } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-times "amocas\.b\.aq\t" 2 } } */
+
+
+void atomic_compare_exchange_weak_char_acquire (char *bar, char *baz, char qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
+}
+
+void atomic_compare_exchange_strong_char_acquire (char *bar, char *baz, char qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
+}
--- /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-add-options riscv_zacas } */
+/* { dg-remove-options riscv_ztso } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-times "amocas\.b\t" 2 } } */
+
+
+void atomic_compare_exchange_weak_char_relaxed (char *bar, char *baz, char qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_strong_char_relaxed (char *bar, char *baz, char qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+}
--- /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-add-options riscv_zacas } */
+/* { dg-remove-options riscv_ztso } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-times "amocas\.b\.rl\t" 2 } } */
+
+
+void atomic_compare_exchange_weak_char_release (char *bar, char *baz, char qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_RELEASE, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_strong_char_release (char *bar, char *baz, char qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_RELEASE, __ATOMIC_RELAXED);
+}
--- /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-add-options riscv_zacas } */
+/* { dg-remove-options riscv_ztso } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-times "amocas\.b\.aqrl\t" 2 } } */
+
+
+void atomic_compare_exchange_weak_char_seq_cst (char *bar, char *baz, char qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+}
+
+void atomic_compare_exchange_strong_char_seq_cst (char *bar, char *baz, char qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+}
--- /dev/null
+/*
+** Verify that atomic op mappings match the PSABI doc's recommended mapping.
+** compare_exchange ops without a seq_cst failure ordering do *not* need a
+** leading fence.
+*/
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_zacas } */
+/* { dg-remove-options riscv_ztso } */
+/* { dg-final { scan-assembler-not "\tfence" } } */
+
+void atomic_compare_exchange_weak_int_seq_cst_relaxed (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_weak_int_seq_cst_acquire (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE);
+}
+
+void atomic_compare_exchange_strong_int_seq_cst_relaxed (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_strong_int_seq_cst_acquire (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE);
+}
--- /dev/null
+/*
+** Verify that atomic op mappings match the PSABI doc's recommended mapping.
+** compare_exchange ops with seq_cst failure ordering need a leading fence
+** to remain compatible with Table A.6 (A6C).
+*/
+/* { dg-do compile } */
+/* { dg-options "-O3 -std=c++17" } */
+/* { dg-add-options riscv_zacas } */
+/* { dg-remove-options riscv_ztso } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/*
+** atomic_compare_exchange_weak_int_relaxed_seq_cst:
+** ...
+** fence\trw,rw
+** amoadd\.w\.aqrl\t[atx][0-9]+,a2,0\(a0\)
+** ...
+*/
+void atomic_compare_exchange_weak_int_relaxed_seq_cst (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_RELAXED, __ATOMIC_SEQ_CST);
+}
+
+/*
+** atomic_compare_exchange_weak_int_seq_cst_seq_cst:
+** ...
+** fence\trw,rw
+** amoadd\.w\.aqrl\t[atx][0-9]+,a2,0\(a0\)
+** ...
+*/
+void atomic_compare_exchange_weak_int_seq_cst_seq_cst (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+}
+
+/*
+** atomic_compare_exchange_strong_int_relaxed_seq_cst:
+** ...
+** fence\trw,rw
+** amoadd\.w\.aqrl\t[atx][0-9]+,a2,0\(a0\)
+** ...
+*/
+void atomic_compare_exchange_strong_int_relaxed_seq_cst (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_RELAXED, __ATOMIC_SEQ_CST);
+}
+
+/*
+** atomic_compare_exchange_strong_int_seq_cst_seq_cst:
+** ...
+** fence\trw,rw
+** amoadd\.w\.aqrl\t[atx][0-9]+,a2,0\(a0\)
+** ...
+*/
+void atomic_compare_exchange_strong_int_seq_cst_seq_cst (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_SEQ_CST, __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_zacas } */
+/* { dg-remove-options riscv_ztso } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-times "amocas\.w\.aqrl\t" 2 } } */
+
+
+void atomic_compare_exchange_weak_int_acq_rel (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_strong_int_acq_rel (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED);
+}
--- /dev/null
+/* Verify that atomic op mappings match the PSABI doc's recommended mapping. */
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_zacas } */
+/* { dg-remove-options riscv_ztso } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-times "amocas\.w\.aq\t" 2 } } */
+
+
+void atomic_compare_exchange_weak_int_acquire (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
+}
+
+void atomic_compare_exchange_strong_int_acquire (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
+}
--- /dev/null
+/* Verify that atomic op mappings match the PSABI doc's recommended mapping. */
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_zacas } */
+/* { dg-remove-options riscv_ztso } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-times "amocas\.w\t" 2 } } */
+
+
+void atomic_compare_exchange_weak_int_relaxed (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_strong_int_relaxed (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+}
--- /dev/null
+/* Verify that atomic op mappings match the PSABI doc's recommended mapping. */
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_zacas } */
+/* { dg-remove-options riscv_ztso } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-times "amocas\.w\.rl\t" 2 } } */
+
+
+void atomic_compare_exchange_weak_int_release (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_RELEASE, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_strong_int_release (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_RELEASE, __ATOMIC_RELAXED);
+}
--- /dev/null
+/* Verify that atomic op mappings match the PSABI doc's recommended mapping. */
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_zacas } */
+/* { dg-remove-options riscv_ztso } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-times "amocas\.w\.aqrl\t" 2 } } */
+
+
+void atomic_compare_exchange_weak_int_seq_cst (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+}
+
+void atomic_compare_exchange_strong_int_seq_cst (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_SEQ_CST, __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-add-options riscv_zacas } */
+/* { dg-remove-options riscv_ztso } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-times "amocas\.h\.aqrl\t" 2 } } */
+
+
+void atomic_compare_exchange_weak_short_acq_rel (short *bar, short *baz, short qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_strong_short_acq_rel (short *bar, short *baz, short qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED);
+}
--- /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-add-options riscv_zacas } */
+/* { dg-remove-options riscv_ztso } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-times "amocas\.h\.aq\t" 2 } } */
+
+
+void atomic_compare_exchange_weak_short_acquire (short *bar, short *baz, short qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
+}
+
+void atomic_compare_exchange_strong_short_acquire (short *bar, short *baz, short qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
+}
--- /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-add-options riscv_zacas } */
+/* { dg-remove-options riscv_ztso } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-times "amocas\.h\t" 2 } } */
+
+
+void atomic_compare_exchange_weak_short_relaxed (short *bar, short *baz, short qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_strong_short_relaxed (short *bar, short *baz, short qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+}
--- /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-add-options riscv_zacas } */
+/* { dg-remove-options riscv_ztso } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-times "amocas\.h\.rl\t" 2 } } */
+
+
+void atomic_compare_exchange_weak_short_release (short *bar, short *baz, short qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_RELEASE, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_strong_short_release (short *bar, short *baz, short qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_RELEASE, __ATOMIC_RELAXED);
+}
--- /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-add-options riscv_zacas } */
+/* { dg-remove-options riscv_ztso } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-times "amocas\.h\.aqrl\t" 2 } } */
+
+
+void atomic_compare_exchange_weak_short_seq_cst (short *bar, short *baz, short qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+}
+
+void atomic_compare_exchange_strong_short_seq_cst (short *bar, short *baz, short qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_SEQ_CST, __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-add-options riscv_zacas } */
+/* { dg-add-options riscv_ztso } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-times "amocas\.b\t" 2 } } */
+
+void atomic_compare_exchange_weak_char_seq_cst (char *bar, char *baz, char qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+}
+
+void atomic_compare_exchange_strong_char_seq_cst (char *bar, char *baz, char qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_SEQ_CST, __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-add-options riscv_zacas } */
+/* { dg-add-options riscv_ztso } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-times "amocas\.b\t" 8 } } */
+
+void atomic_compare_exchange_weak_char_relaxed (char *bar, char *baz, char qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_strong_char_relaxed (char *bar, char *baz, char qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_weak_char_acquire (char *bar, char *baz, char qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
+}
+
+void atomic_compare_exchange_strong_char_acquire (char *bar, char *baz, char qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
+}
+
+void atomic_compare_exchange_weak_char_release (char *bar, char *baz, char qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_RELEASE, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_strong_char_release (char *bar, char *baz, char qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_RELEASE, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_weak_char_acq_rel (char *bar, char *baz, char qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_strong_char_acq_rel (char *bar, char *baz, char qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED);
+}
--- /dev/null
+/*
+** Verify that atomic op mappings match the PSABI doc's recommended mapping.
+** compare_exchange ops without a seq_cst failure ordering do *not* need a
+** leading fence.
+*/
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-add-options riscv_zacas } */
+/* { dg-add-options riscv_ztso } */
+/* { dg-final { scan-assembler-not "\tfence" } } */
+
+void atomic_compare_exchange_weak_int_seq_cst_relaxed (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_weak_int_seq_cst_acquire (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE);
+}
+
+void atomic_compare_exchange_strong_int_seq_cst_relaxed (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_strong_int_seq_cst_acquire (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE);
+}
--- /dev/null
+/*
+** Verify that atomic op mappings match the PSABI doc's recommended mapping.
+** compare_exchange ops with seq_cst failure ordering need a leading fence
+** to remain compatible with Table A.6 (A6C).
+*/
+/* { dg-do compile } */
+/* { dg-options "-O3 -std=c++17" } */
+/* { dg-add-options riscv_zacas } */
+/* { dg-add-options riscv_ztso } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/*
+** atomic_compare_exchange_weak_int_relaxed_seq_cst:
+** ...
+** fence\trw,rw
+** amoadd\.w\t[atx][0-9]+,a2,0\(a0\)
+** ...
+*/
+void atomic_compare_exchange_weak_int_relaxed_seq_cst (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_RELAXED, __ATOMIC_SEQ_CST);
+}
+
+/*
+** atomic_compare_exchange_weak_int_seq_cst_seq_cst:
+** ...
+** fence\trw,rw
+** amoadd\.w\t[atx][0-9]+,a2,0\(a0\)
+** ...
+*/
+void atomic_compare_exchange_weak_int_seq_cst_seq_cst (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+}
+
+/*
+** atomic_compare_exchange_strong_int_relaxed_seq_cst:
+** ...
+** fence\trw,rw
+** amoadd\.w\t[atx][0-9]+,a2,0\(a0\)
+** ...
+*/
+void atomic_compare_exchange_strong_int_relaxed_seq_cst (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_RELAXED, __ATOMIC_SEQ_CST);
+}
+
+/*
+** atomic_compare_exchange_strong_int_seq_cst_seq_cst:
+** ...
+** fence\trw,rw
+** amoadd\.w\t[atx][0-9]+,a2,0\(a0\)
+** ...
+*/
+void atomic_compare_exchange_strong_int_seq_cst_seq_cst (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_SEQ_CST, __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_zacas } */
+/* { dg-add-options riscv_ztso } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-times "amocas\.w\t" 2 } } */
+
+void atomic_compare_exchange_weak_int_seq_cst (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+}
+
+void atomic_compare_exchange_strong_int_seq_cst (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_SEQ_CST, __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_zacas } */
+/* { dg-add-options riscv_ztso } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-times "amocas\.w\t" 8 } } */
+
+void atomic_compare_exchange_weak_int_relaxed (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_strong_int_relaxed (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_weak_int_acquire (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
+}
+
+void atomic_compare_exchange_strong_int_acquire (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
+}
+
+void atomic_compare_exchange_weak_int_release (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_RELEASE, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_strong_int_release (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_RELEASE, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_weak_int_acq_rel (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_strong_int_acq_rel (int *bar, int *baz, int qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED);
+}
--- /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-add-options riscv_zacas } */
+/* { dg-add-options riscv_ztso } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-times "amocas\.h\t" 2 } } */
+
+void atomic_compare_exchange_weak_short_seq_cst (short *bar, short *baz, short qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+}
+
+void atomic_compare_exchange_strong_short_seq_cst (short *bar, short *baz, short qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_SEQ_CST, __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-add-options riscv_zacas } */
+/* { dg-add-options riscv_ztso } */
+/* { dg-final { scan-assembler-not "\tlr\.w" } } */
+/* { dg-final { scan-assembler-not "\tsc\.w" } } */
+/* { dg-final { scan-assembler-times "amocas\.h\t" 8 } } */
+
+void atomic_compare_exchange_weak_short_relaxed (short *bar, short *baz, short qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_strong_short_relaxed (short *bar, short *baz, short qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_weak_short_acquire (short *bar, short *baz, short qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
+}
+
+void atomic_compare_exchange_strong_short_acquire (short *bar, short *baz, short qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
+}
+
+void atomic_compare_exchange_weak_short_release (short *bar, short *baz, short qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_RELEASE, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_strong_short_release (short *bar, short *baz, short qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_RELEASE, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_weak_short_acq_rel (short *bar, short *baz, short qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 0, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED);
+}
+
+void atomic_compare_exchange_strong_short_acq_rel (short *bar, short *baz, short qux)
+{
+ __atomic_compare_exchange_n(bar, baz, qux, 1, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED);
+}
/* Verify that compare exchange mappings match the PSABI doc's recommended mapping. */
/* { dg-add-options riscv_zalrsc } */
/* { dg-remove-options riscv_ztso } */
+/* { dg-remove-options riscv_zacas } */
/* Mixed mappings need to be unioned. */
/* { dg-final { scan-assembler-times "lr.w.aq\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w.rl\t" 1 } } */
/* Verify that compare exchange mappings match the PSABI doc's recommended mapping. */
/* { dg-add-options riscv_zalrsc } */
/* { dg-remove-options riscv_ztso } */
+/* { dg-remove-options riscv_zacas } */
/* { dg-final { scan-assembler-times "lr.w.aq\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
/* Verify that compare exchange mappings match the PSABI doc's recommended mapping. */
/* { dg-add-options riscv_zalrsc } */
/* { dg-remove-options riscv_ztso } */
+/* { dg-remove-options riscv_zacas } */
/* { dg-final { scan-assembler-times "lr.w.aq\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
/* Verify that compare exchange mappings match the PSABI doc's recommended mapping. */
/* { dg-add-options riscv_zalrsc } */
/* { dg-remove-options riscv_ztso } */
+/* { dg-remove-options riscv_zacas } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
/* Verify that compare exchange mappings match the PSABI doc's recommended mapping. */
/* { dg-add-options riscv_zalrsc } */
/* { dg-remove-options riscv_ztso } */
+/* { dg-remove-options riscv_zacas } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w.rl\t" 1 } } */
/* Mixed mappings need to be unioned. */
/* { dg-add-options riscv_zalrsc } */
/* { dg-remove-options riscv_ztso } */
+/* { dg-remove-options riscv_zacas } */
/* { dg-final { scan-assembler-times "lr.w.aqrl\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w.rl\t" 1 } } */
/* Verify that compare exchange mappings match the PSABI doc's recommended mapping. */
/* { dg-add-options riscv_zalrsc } */
/* { dg-remove-options riscv_ztso } */
+/* { dg-remove-options riscv_zacas } */
/* { dg-final { scan-assembler-times "lr.w.aqrl\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w.rl\t" 1 } } */
/* Mixed mappings need to be unioned. */
/* { dg-add-options riscv_zalrsc } */
/* { dg-add-options riscv_ztso } */
+/* { dg-remove-options riscv_zacas } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
/* Verify that compare exchange mappings match the PSABI doc's recommended mapping. */
/* { dg-add-options riscv_zalrsc } */
/* { dg-add-options riscv_ztso } */
+/* { dg-remove-options riscv_zacas } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
/* Verify that compare exchange mappings match the PSABI doc's recommended mapping. */
/* { dg-add-options riscv_zalrsc } */
/* { dg-add-options riscv_ztso } */
+/* { dg-remove-options riscv_zacas } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
/* Verify that compare exchange mappings match the PSABI doc's recommended mapping. */
/* { dg-add-options riscv_zalrsc } */
/* { dg-add-options riscv_ztso } */
+/* { dg-remove-options riscv_zacas } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
/* Verify that compare exchange mappings match the PSABI doc's recommended mapping. */
/* { dg-add-options riscv_zalrsc } */
/* { dg-add-options riscv_ztso } */
+/* { dg-remove-options riscv_zacas } */
/* { dg-final { scan-assembler-times "lr.w\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w\t" 1 } } */
/* Mixed mappings need to be unioned. */
/* { dg-add-options riscv_zalrsc } */
/* { dg-add-options riscv_ztso } */
+/* { dg-remove-options riscv_zacas } */
/* { dg-final { scan-assembler-times "lr.w.aqrl\t" 1 } } */
/* { dg-final { scan-assembler-times "sc.w.rl\t" 1 } } */
/* Verify that compare exchange mappings match the PSABI doc's recommended mapping. */
/* { dg-add-options riscv_zalrsc } */
/* { dg-add-options riscv_ztso } */
+/* { dg-remove-options riscv_zacas } */
/* { 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 CAS extension, 0 otherwise.
+# Cache the result.
+
+proc check_effective_target_riscv_zacas { } {
+ return [check_no_compiler_messages riscv_ext_zacas assembly {
+ #ifndef __riscv_zacas
+ #error "Not __riscv_zacas"
+ #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 b v zicsr zifencei zfh zba zbb zbc zbs zvbb zvfh ztso zaamo zalrsc zabha } {
+ foreach ext { i m a f d q c b v zicsr zifencei zfh zba zbb zbc zbs zvbb zvfh ztso zaamo zalrsc zabha zacas } {
if { [check_no_compiler_messages riscv_ext_$ext assembly [string map [list DEF __riscv_$ext] {
#ifndef DEF
#error "Not DEF"
# 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 zacas is set then zaamo will be implied. We need to remove zacas
+ # as well.
+ set modified_flags [remove_options_for_riscv_z_ext zacas $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 $modified_flags]
return [remove_options_for_riscv_z_ext zabha $modified_flags]
}
+proc add_options_for_riscv_zacas { flags } {
+ return [add_options_for_riscv_z_ext zacas $flags]
+}
+
+proc remove_options_for_riscv_zacas { flags } {
+ set modified_flags [remove_options_for_riscv_zaamo $flags]
+ return [remove_options_for_riscv_z_ext zacas $modified_flags]
+}
+
proc add_options_for_riscv_zfh { flags } {
return [add_options_for_riscv_z_ext zfh $flags]
}