]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: Add basic support for the Zacas extension
authorGianluca Guida <gianluca@rivosinc.com>
Mon, 29 Jul 2024 22:13:46 +0000 (15:13 -0700)
committerPatrick O'Neill <patrick@rivosinc.com>
Tue, 30 Jul 2024 15:22:40 +0000 (08:22 -0700)
This patch adds support for amocas.{b|h|w|d}. Support for amocas.q
(64/128 bit cas for rv32/64) will be added in a future patch.

Extension: https://github.com/riscv/riscv-zacas
Ratification: https://jira.riscv.org/browse/RVS-680

gcc/ChangeLog:

* common/config/riscv/riscv-common.cc: Add zacas extension.
* config/riscv/arch-canonicalize: Make zacas imply zaamo.
* config/riscv/riscv.opt: Add zacas.
* config/riscv/sync.md (zacas_atomic_cas_value<mode>): New pattern.
(atomic_compare_and_swap<mode>): Use new pattern for compare-and-swap ops.
(zalrsc_atomic_cas_value_strong<mode>): Rename atomic_cas_value_strong.
* doc/sourcebuild.texi: Add Zacas documentation.

gcc/testsuite/ChangeLog:

* lib/target-supports.exp: Add zacas testsuite infra support.
* gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-acquire-release.c:
Remove zacas to continue to test the lr/sc pairs.
* gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-acquire.c: Ditto.
* gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-consume.c: Ditto.
* gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-relaxed.c: Ditto.
* gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-release.c: Ditto.
* gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-seq-cst-relaxed.c: Ditto.
* gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-seq-cst.c: Ditto.
* gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-acquire-release.c: Ditto.
* gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-acquire.c: Ditto.
* gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-consume.c: Ditto.
* gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-relaxed.c: Ditto.
* gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-release.c: Ditto.
* gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-seq-cst-relaxed.c: Ditto.
* gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-seq-cst.c: Ditto.
* gcc.target/riscv/amo/zabha-zacas-preferred-over-zalrsc.c: New test.
* gcc.target/riscv/amo/zacas-char-requires-zabha.c: New test.
* gcc.target/riscv/amo/zacas-char-requires-zacas.c: New test.
* gcc.target/riscv/amo/zacas-preferred-over-zalrsc.c: New test.
* gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-acq-rel.c: New test.
* gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-acquire.c: New test.
* gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-relaxed.c: New test.
* gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-release.c: New test.
* gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-seq-cst.c: New test.
* gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-compatability-mapping-no-fence.c:
New test.
* gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-compatability-mapping.cc: New test.
* gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-acq-rel.c: New test.
* gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-acquire.c: New test.
* gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-relaxed.c: New test.
* gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-release.c: New test.
* gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-seq-cst.c: New test.
* gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-acq-rel.c: New test.
* gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-acquire.c: New test.
* gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-relaxed.c: New test.
* gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-release.c: New test.
* gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-seq-cst.c: New test.
* gcc.target/riscv/amo/zacas-ztso-compare-exchange-char-seq-cst.c: New test.
* gcc.target/riscv/amo/zacas-ztso-compare-exchange-char.c: New test.
* gcc.target/riscv/amo/zacas-ztso-compare-exchange-compatability-mapping-no-fence.c:
New test.
* gcc.target/riscv/amo/zacas-ztso-compare-exchange-compatability-mapping.cc: New test.
* gcc.target/riscv/amo/zacas-ztso-compare-exchange-int-seq-cst.c: New test.
* gcc.target/riscv/amo/zacas-ztso-compare-exchange-int.c: New test.
* gcc.target/riscv/amo/zacas-ztso-compare-exchange-short-seq-cst.c: New test.
* gcc.target/riscv/amo/zacas-ztso-compare-exchange-short.c: New test.

Co-authored-by: Patrick O'Neill <patrick@rivosinc.com>
Tested-by: Andrea Parri <andrea@rivosinc.com>
Signed-Off-By: Gianluca Guida <gianluca@rivosinc.com>
49 files changed:
gcc/common/config/riscv/riscv-common.cc
gcc/config/riscv/arch-canonicalize
gcc/config/riscv/riscv.opt
gcc/config/riscv/sync.md
gcc/doc/sourcebuild.texi
gcc/testsuite/gcc.target/riscv/amo/zabha-zacas-preferred-over-zalrsc.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-char-requires-zabha.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-char-requires-zacas.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-preferred-over-zalrsc.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-acq-rel.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-acquire.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-relaxed.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-release.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-char-seq-cst.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-compatability-mapping-no-fence.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-compatability-mapping.cc [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-acq-rel.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-acquire.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-relaxed.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-release.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-int-seq-cst.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-acq-rel.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-acquire.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-relaxed.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-release.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-rvwmo-compare-exchange-short-seq-cst.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-char-seq-cst.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-char.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-compatability-mapping-no-fence.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-compatability-mapping.cc [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-int-seq-cst.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-int.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-short-seq-cst.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zacas-ztso-compare-exchange-short.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-acquire-release.c
gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-acquire.c
gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-consume.c
gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-relaxed.c
gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-release.c
gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-seq-cst-relaxed.c
gcc/testsuite/gcc.target/riscv/amo/zalrsc-rvwmo-compare-exchange-int-seq-cst.c
gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-acquire-release.c
gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-acquire.c
gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-consume.c
gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-relaxed.c
gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-release.c
gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-seq-cst-relaxed.c
gcc/testsuite/gcc.target/riscv/amo/zalrsc-ztso-compare-exchange-int-seq-cst.c
gcc/testsuite/lib/target-supports.exp

index d2912877784d97b01bd310ee5b56276a4372b082..0c12e12cde51e09b568fb74a831d6536f5dd3aee 100644 (file)
@@ -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},
index 2ea514dd9869f3389dfa2ccd55a4f2708620a32a..35e0f46b6bd344cd293cf39177f754e1235b36d4 100755 (executable)
@@ -43,6 +43,7 @@ IMPLIED_EXT = {
 
   "a" : ["zaamo", "zalrsc"],
   "zabha" : ["zaamo"],
+  "zacas" : ["zaamo"],
 
   "f" : ["zicsr"],
   "b" : ["zba", "zbb", "zbs"],
index edf1c6d85f396663dc50947da8221642baeae8ed..2e340e5324ff068e050b6336be32111d8ff7f5da 100644 (file)
@@ -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)
index 0470e2ca45720a453c987f88560a38f5e537cb01..0c493fea828fb480afa09fba7d8559d5ded70ee7 100644 (file)
 
 ; 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
index 66c4206bfc2cae394583e347b1124121d8db85cd..d5c48e67b71b8b66786851b64d418c0dbe82bb44 100644 (file)
@@ -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 (file)
index 0000000..a06e195
--- /dev/null
@@ -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 (file)
index 0000000..c7d6e7c
--- /dev/null
@@ -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 (file)
index 0000000..d0cf144
--- /dev/null
@@ -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 (file)
index 0000000..9a995cc
--- /dev/null
@@ -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 (file)
index 0000000..b76385b
--- /dev/null
@@ -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 (file)
index 0000000..62ecf7b
--- /dev/null
@@ -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 (file)
index 0000000..21c960c
--- /dev/null
@@ -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 (file)
index 0000000..6b40833
--- /dev/null
@@ -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 (file)
index 0000000..289bdf4
--- /dev/null
@@ -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 (file)
index 0000000..99fd757
--- /dev/null
@@ -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 (file)
index 0000000..c8d8129
--- /dev/null
@@ -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 (file)
index 0000000..1b55c93
--- /dev/null
@@ -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 (file)
index 0000000..8182360
--- /dev/null
@@ -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 (file)
index 0000000..fb2a7b4
--- /dev/null
@@ -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 (file)
index 0000000..756f5cb
--- /dev/null
@@ -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 (file)
index 0000000..1c5b4ac
--- /dev/null
@@ -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 (file)
index 0000000..2987eb3
--- /dev/null
@@ -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 (file)
index 0000000..5057910
--- /dev/null
@@ -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 (file)
index 0000000..a85694e
--- /dev/null
@@ -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 (file)
index 0000000..e8e9aae
--- /dev/null
@@ -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 (file)
index 0000000..d676d37
--- /dev/null
@@ -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 (file)
index 0000000..e219bd1
--- /dev/null
@@ -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 (file)
index 0000000..183dc40
--- /dev/null
@@ -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 (file)
index 0000000..2712eff
--- /dev/null
@@ -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 (file)
index 0000000..560172b
--- /dev/null
@@ -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 (file)
index 0000000..1ee6cc2
--- /dev/null
@@ -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 (file)
index 0000000..2c33262
--- /dev/null
@@ -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 (file)
index 0000000..1938448
--- /dev/null
@@ -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 (file)
index 0000000..69fe5ae
--- /dev/null
@@ -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);
+}
index 49eeda9cb3383833530bea4f2c9f511133997fb0..9a5616f891663532b3dcd4f9ba374ecd4de1b04e 100644 (file)
@@ -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 } } */
index b9e3adece8d6715d03062feb2ddbb84d79641c55..a24234855e9966cd9cd46b5e7b0ce94f94c3fe02 100644 (file)
@@ -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 } } */
 
index 11839d84f140de30f1a93eb2fb027b1441b9eb3e..18f53c83a387f771f021be9da66bf2d8e5390734 100644 (file)
@@ -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 } } */
 
index 852ec99df7689f33466231a0f1720d0c28cab224..c7a43ecd323a565aa534b6733989359e918a6435 100644 (file)
@@ -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 } } */
 
index 9c51a082d0bab9347c34a699841b24dc8387aa89..302fca2ca1711f47d2cdb68984ac14758ee63e97 100644 (file)
@@ -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 } } */
 
index d985e2cef8b4339ec93a9c6165708c04d068cf73..e62002d267ac91fa2de343a65df7759870d2408e 100644 (file)
@@ -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 } } */
 
index 6efd232ce21122c8941d1736674a3cea6b28f255..c047d509aafed7d67ef90bc321c6346d7bbf95d5 100644 (file)
@@ -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 } } */
 
index 9761a955ede53330697a72b6e7fe2edf44a6d6f1..496af8bfd7df6528c555d42302c5ee92e3857f09 100644 (file)
@@ -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 } } */
 
index 3303f8021e1e2a3a4956e38fe1634151c6364bca..737e3eb3d684749a7faa7aa6e8888ffcdf712d84 100644 (file)
@@ -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 } } */
 
index 7474e832bb153d5c01da140a491191c306839473..51b3b5a8dc7332854a9514d849781472432d5270 100644 (file)
@@ -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 } } */
 
index e43193820f256601e3f87ecdccf0b222c1816113..9a41410a57bf59280d06cda5bde6534f7f59b398 100644 (file)
@@ -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 } } */
 
index a0d5872e1bd20b25e8acbd3d65e52442ff4e597f..ee778a760d12cb350711007ab28e7a0ba4993fff 100644 (file)
@@ -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 } } */
 
index fc464ab1ff5391b579c23e8f7ea2d5eaa4a8dea5..6fbe943b31692f180b3efc0f57d027664f5e0d26 100644 (file)
@@ -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 } } */
 
index 152806cfde3383f204d175c0673d68335eb5acd5..a361c10086d57e40681e241154e14f86758b1a17 100644 (file)
@@ -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 } } */
 
index d368251ef9a46bd4e0f22ac4bac2ce7c6394112a..f8e5f5f36d034f179ddc58aa5c24217d045d509d 100644 (file)
@@ -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]
 }