On 7/23/24 6:15 PM, Patrick O'Neill wrote:
From: Gianluca Guida <gianl...@rivosinc.com>

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
        (riscv_subset_list::to_string): Skip zacas when not supported by
        the assembler.
        * config.in: Regenerate.
        * 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.
        * configure: Regenerate.
        * configure.ac: Regenerate.
        * 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 <patr...@rivosinc.com>
---
V2 Changelog
* Fix functional bug where expected amocas value wasn't initialized.
* Add leading fence to zacas with seq_cst failure mode for PSABI
compatability (and corresponding testcases).
* Rename atomic_cas_value_strong to zalrsc_atomic_cas_value_strong.
* Remove unneeded zabha from int testcases.
* Add testcase functions that test weak compxchng.
* Add testcase for non-zabha zacas preferred over lrsc.

Tested locally with zaamo, zalrsc, ztso, and zacas with amo.exp.
---


@@ -530,16 +530,47 @@
    [(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") (const_int 4))])
Doesn't the length need adjusting when we need to emit the leading fence?


;
  })
+;; 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") (const_int 4))])
Similarly here.


Otherwise I'm good with this patch. I know Kito raised some concerns. So with the length fixes you just need to come to an agreement with Kito on how to handle the out-of-date binutils scenario.

jeff



Reply via email to