aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/common/config/riscv/riscv-common.cc3
-rwxr-xr-xgcc/config/riscv/arch-canonicalize1
-rw-r--r--gcc/config/riscv/riscv.opt2
-rw-r--r--gcc/config/riscv/sync.md111
-rw-r--r--gcc/doc/sourcebuild.texi10
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zabha-zacas-preferred-over-zalrsc.c21
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-char-requires-zabha.c17
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-char-requires-zacas.c17
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-preferred-over-zalrsc.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-acq-rel.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-acquire.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-relaxed.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-release.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-seq-cst.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-compatability-mapping-no-fence.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-compatability-mapping.cc58
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-acq-rel.c19
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-acquire.c19
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-relaxed.c19
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-release.c19
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-seq-cst.c19
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-acq-rel.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-acquire.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-relaxed.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-release.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-seq-cst.c20
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-char-seq-cst.c19
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-char.c49
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-compatability-mapping-no-fence.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-compatability-mapping.cc58
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-int-seq-cst.c18
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-int.c48
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-short-seq-cst.c19
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-short.c49
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-acquire-release.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-acquire.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-consume.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-relaxed.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-release.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-seq-cst-relaxed.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-seq-cst.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-acquire-release.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-acquire.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-consume.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-relaxed.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-release.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-seq-cst-relaxed.c1
-rw-r--r--gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-seq-cst.c1
-rw-r--r--gcc/testsuite/lib/target-supports.exp25
49 files changed, 901 insertions, 13 deletions
diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc
index d291287..0c12e12 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -95,6 +95,7 @@ static const riscv_implied_info_t riscv_implied_info[] =
}},
{"zabha", "zaamo"},
+ {"zacas", "zaamo"},
{"b", "zba"},
{"b", "zbb"},
@@ -283,6 +284,7 @@ static const struct riscv_ext_version riscv_ext_version_table[] =
{"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},
@@ -1584,6 +1586,7 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] =
{"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},
diff --git a/gcc/config/riscv/arch-canonicalize b/gcc/config/riscv/arch-canonicalize
index 2ea514d..35e0f46 100755
--- a/gcc/config/riscv/arch-canonicalize
+++ b/gcc/config/riscv/arch-canonicalize
@@ -43,6 +43,7 @@ IMPLIED_EXT = {
"a" : ["zaamo", "zalrsc"],
"zabha" : ["zaamo"],
+ "zacas" : ["zaamo"],
"f" : ["zicsr"],
"b" : ["zba", "zbb", "zbs"],
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index edf1c6d..2e340e5 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -264,6 +264,8 @@ Mask(ZALRSC) Var(riscv_za_subext)
Mask(ZABHA) Var(riscv_za_subext)
+Mask(ZACAS) Var(riscv_za_subext)
+
Mask(ZA64RS) Var(riscv_za_subext)
Mask(ZA128RS) Var(riscv_za_subext)
diff --git a/gcc/config/riscv/sync.md b/gcc/config/riscv/sync.md
index 0470e2c..0c493fe 100644
--- a/gcc/config/riscv/sync.md
+++ b/gcc/config/riscv/sync.md
@@ -503,7 +503,7 @@
; 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)
@@ -530,16 +530,48 @@
[(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)
{
@@ -550,9 +582,20 @@
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)
@@ -573,20 +616,64 @@
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)
@@ -619,7 +706,7 @@
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
diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
index 66c4206..d5c48e6 100644
--- a/gcc/doc/sourcebuild.texi
+++ b/gcc/doc/sourcebuild.texi
@@ -2530,6 +2530,9 @@ Test target architecture has support for the zaamo extension.
@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.
@@ -3298,6 +3301,9 @@ 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_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.
@@ -3345,6 +3351,10 @@ extension is present downgrade it to zalrsc.
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.
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zabha-zacas-preferred-over-zalrsc.c b/gcc/testsuite/gcc.target/riscv/amo/zabha-zacas-preferred-over-zalrsc.c
new file mode 100644
index 0000000..a06e195
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zabha-zacas-preferred-over-zalrsc.c
@@ -0,0 +1,21 @@
+/* { 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-char-requires-zabha.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-char-requires-zabha.c
new file mode 100644
index 0000000..c7d6e7c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-char-requires-zabha.c
@@ -0,0 +1,17 @@
+/* { 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-char-requires-zacas.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-char-requires-zacas.c
new file mode 100644
index 0000000..d0cf144
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-char-requires-zacas.c
@@ -0,0 +1,17 @@
+/* { 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-preferred-over-zalrsc.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-preferred-over-zalrsc.c
new file mode 100644
index 0000000..9a995cc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-preferred-over-zalrsc.c
@@ -0,0 +1,20 @@
+/* { 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-acq-rel.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-acq-rel.c
new file mode 100644
index 0000000..b76385b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-acq-rel.c
@@ -0,0 +1,20 @@
+/* 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-acquire.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-acquire.c
new file mode 100644
index 0000000..62ecf7b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-acquire.c
@@ -0,0 +1,20 @@
+/* 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-relaxed.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-relaxed.c
new file mode 100644
index 0000000..21c960c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-relaxed.c
@@ -0,0 +1,20 @@
+/* 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-release.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-release.c
new file mode 100644
index 0000000..6b40833
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-release.c
@@ -0,0 +1,20 @@
+/* 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-seq-cst.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-seq-cst.c
new file mode 100644
index 0000000..289bdf4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-seq-cst.c
@@ -0,0 +1,20 @@
+/* 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-compatability-mapping-no-fence.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-compatability-mapping-no-fence.c
new file mode 100644
index 0000000..99fd757
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-compatability-mapping-no-fence.c
@@ -0,0 +1,30 @@
+/*
+** 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-compatability-mapping.cc b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-compatability-mapping.cc
new file mode 100644
index 0000000..c8d8129
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-compatability-mapping.cc
@@ -0,0 +1,58 @@
+/*
+** 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-acq-rel.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-acq-rel.c
new file mode 100644
index 0000000..1b55c93
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-acq-rel.c
@@ -0,0 +1,19 @@
+/* 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-acquire.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-acquire.c
new file mode 100644
index 0000000..8182360
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-acquire.c
@@ -0,0 +1,19 @@
+/* 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-relaxed.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-relaxed.c
new file mode 100644
index 0000000..fb2a7b4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-relaxed.c
@@ -0,0 +1,19 @@
+/* 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-release.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-release.c
new file mode 100644
index 0000000..756f5cb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-release.c
@@ -0,0 +1,19 @@
+/* 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-seq-cst.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-seq-cst.c
new file mode 100644
index 0000000..1c5b4ac
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-seq-cst.c
@@ -0,0 +1,19 @@
+/* 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-acq-rel.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-acq-rel.c
new file mode 100644
index 0000000..2987eb3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-acq-rel.c
@@ -0,0 +1,20 @@
+/* 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-acquire.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-acquire.c
new file mode 100644
index 0000000..5057910
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-acquire.c
@@ -0,0 +1,20 @@
+/* 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-relaxed.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-relaxed.c
new file mode 100644
index 0000000..a85694e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-relaxed.c
@@ -0,0 +1,20 @@
+/* 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-release.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-release.c
new file mode 100644
index 0000000..e8e9aae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-release.c
@@ -0,0 +1,20 @@
+/* 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-seq-cst.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-seq-cst.c
new file mode 100644
index 0000000..d676d37
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-seq-cst.c
@@ -0,0 +1,20 @@
+/* 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-char-seq-cst.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-char-seq-cst.c
new file mode 100644
index 0000000..e219bd1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-char-seq-cst.c
@@ -0,0 +1,19 @@
+/* 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-char.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-char.c
new file mode 100644
index 0000000..183dc40
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-char.c
@@ -0,0 +1,49 @@
+/* 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-compatability-mapping-no-fence.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-compatability-mapping-no-fence.c
new file mode 100644
index 0000000..2712eff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-compatability-mapping-no-fence.c
@@ -0,0 +1,30 @@
+/*
+** 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-compatability-mapping.cc b/gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-compatability-mapping.cc
new file mode 100644
index 0000000..560172b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-compatability-mapping.cc
@@ -0,0 +1,58 @@
+/*
+** 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-int-seq-cst.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-int-seq-cst.c
new file mode 100644
index 0000000..1ee6cc2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-int-seq-cst.c
@@ -0,0 +1,18 @@
+/* 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-int.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-int.c
new file mode 100644
index 0000000..2c33262
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-int.c
@@ -0,0 +1,48 @@
+/* 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-short-seq-cst.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-short-seq-cst.c
new file mode 100644
index 0000000..1938448
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-short-seq-cst.c
@@ -0,0 +1,19 @@
+/* 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-short.c b/gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-short.c
new file mode 100644
index 0000000..69fe5ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-short.c
@@ -0,0 +1,49 @@
+/* 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);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-acquire-release.c b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-acquire-release.c
index 49eeda9..9a5616f 100644
--- a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-acquire-release.c
+++ b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-acquire-release.c
@@ -2,6 +2,7 @@
/* 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 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-acquire.c b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-acquire.c
index b9e3ade..a242348 100644
--- a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-acquire.c
+++ b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-acquire.c
@@ -2,6 +2,7 @@
/* 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 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-consume.c b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-consume.c
index 11839d8..18f53c8 100644
--- a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-consume.c
+++ b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-consume.c
@@ -2,6 +2,7 @@
/* 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 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-relaxed.c b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-relaxed.c
index 852ec99..c7a43ec 100644
--- a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-relaxed.c
+++ b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-relaxed.c
@@ -2,6 +2,7 @@
/* 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 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-release.c b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-release.c
index 9c51a08..302fca2 100644
--- a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-release.c
+++ b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-release.c
@@ -2,6 +2,7 @@
/* 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 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-seq-cst-relaxed.c b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-seq-cst-relaxed.c
index d985e2c..e62002d 100644
--- a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-seq-cst-relaxed.c
+++ b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-seq-cst-relaxed.c
@@ -3,6 +3,7 @@
/* 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 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-seq-cst.c b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-seq-cst.c
index 6efd232..c047d50 100644
--- a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-seq-cst.c
+++ b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-seq-cst.c
@@ -2,6 +2,7 @@
/* 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 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-acquire-release.c b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-acquire-release.c
index 9761a95..496af8b 100644
--- a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-acquire-release.c
+++ b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-acquire-release.c
@@ -3,6 +3,7 @@
/* 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 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-acquire.c b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-acquire.c
index 3303f80..737e3eb 100644
--- a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-acquire.c
+++ b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-acquire.c
@@ -2,6 +2,7 @@
/* 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 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-consume.c b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-consume.c
index 7474e83..51b3b5a 100644
--- a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-consume.c
+++ b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-consume.c
@@ -2,6 +2,7 @@
/* 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 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-relaxed.c b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-relaxed.c
index e431938..9a41410 100644
--- a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-relaxed.c
+++ b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-relaxed.c
@@ -2,6 +2,7 @@
/* 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 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-release.c b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-release.c
index a0d5872..ee778a7 100644
--- a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-release.c
+++ b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-release.c
@@ -2,6 +2,7 @@
/* 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 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-seq-cst-relaxed.c b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-seq-cst-relaxed.c
index fc464ab..6fbe943 100644
--- a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-seq-cst-relaxed.c
+++ b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-seq-cst-relaxed.c
@@ -3,6 +3,7 @@
/* 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 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-seq-cst.c b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-seq-cst.c
index 152806c..a361c10 100644
--- a/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-seq-cst.c
+++ b/gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-seq-cst.c
@@ -2,6 +2,7 @@
/* 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 } } */
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index d368251..f8e5f5f 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -1922,6 +1922,17 @@ proc check_effective_target_riscv_zabha { } {
}]
}
+# 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.
@@ -2140,7 +2151,7 @@ proc check_effective_target_riscv_v_misalign_ok { } {
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"
@@ -2308,6 +2319,9 @@ proc remove_options_for_riscv_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 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]
@@ -2343,6 +2357,15 @@ proc remove_options_for_riscv_zabha { 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]
}