This patch adds atomic test and set support for the microblaze arch.

Fixes: pr118280 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118280

Test case added to testsuite/gcc.dg/atomic/atomic-pr118280.c

Signed-off-by: Aayush Misra <aayush.mi...@amd.com>
Signed-off-by: Neal Frager <neal.fra...@amd.com>
---
 gcc/ChangeLog                                 |   6 +
 gcc/config/microblaze/microblaze.md           |   6 +-
 gcc/config/microblaze/sync.md                 | 103 +++++++++++++++---
 gcc/testsuite/ChangeLog                       |   5 +
 gcc/testsuite/gcc.dg/atomic/atomic-pr118280.c |  41 +++++++
 5 files changed, 142 insertions(+), 19 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/atomic/atomic-pr118280.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 78239f08f1b..a4462c87851 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2025-07-01  Neal Frager <neal.fra...@amd.com>
+
+       PR atomic/118280
+       * microblaze.md: added atomic_test_and_set support
+       * microblaze/sync.md: ditto
+
 2025-06-30  Jeff Law  <j...@ventanamicro.com>
 
        PR rtl-optimization/120242
diff --git a/gcc/config/microblaze/microblaze.md 
b/gcc/config/microblaze/microblaze.md
index 45c48a71e8d..387784504fc 100644
--- a/gcc/config/microblaze/microblaze.md
+++ b/gcc/config/microblaze/microblaze.md
@@ -43,6 +43,10 @@
   (UNSPEC_TLS           106)    ;; jump table
   (UNSPEC_SET_TEXT      107)    ;; set text start
   (UNSPEC_TEXT          108)    ;; data text relative
+  (UNSPECV_CAS_BOOL     201)    ;; compare and swap (bool)
+  (UNSPECV_CAS_VAL      202)    ;; compare and swap (val)
+  (UNSPECV_CAS_MEM      203)    ;; compare and swap (mem)
+  (UNSPECV_ATS          204)    ;; atomic test and set
 ])
 
 (define_c_enum "unspec" [
@@ -79,7 +83,7 @@
 ;; bshift      Shift operations
 
 (define_attr "type"
-  
"unknown,branch,jump,call,load,store,move,arith,darith,imul,idiv,icmp,multi,nop,no_delay_arith,no_delay_load,no_delay_store,no_delay_imul,no_delay_move,bshift,fadd,frsub,fmul,fdiv,fcmp,fsl,fsqrt,fcvt,trap"
+  
"unknown,branch,jump,call,load,store,move,arith,darith,imul,idiv,icmp,multi,nop,no_delay_arith,no_delay_load,no_delay_store,no_delay_imul,no_delay_move,bshift,fadd,frsub,fmul,fdiv,fcmp,fsl,fsqrt,fcvt,trap,atomic"
   (const_string "unknown"))
 
 ;; Main data type used by the insn
diff --git a/gcc/config/microblaze/sync.md b/gcc/config/microblaze/sync.md
index db7b11e5379..ebf07eb67f5 100644
--- a/gcc/config/microblaze/sync.md
+++ b/gcc/config/microblaze/sync.md
@@ -18,26 +18,93 @@
 ;; <http://www.gnu.org/licenses/>.
 
 (define_insn "atomic_compare_and_swapsi"
-  [(match_operand:SI 0 "register_operand" "=&d")       ;; bool output
-   (match_operand:SI 1 "register_operand" "=&d")       ;; val output
-   (match_operand:SI 2 "nonimmediate_operand" "+Q")    ;; memory
-   (match_operand:SI 3 "register_operand" "d")         ;; expected value
-   (match_operand:SI 4 "register_operand" "d")         ;; 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
+  [(set (match_operand:SI 0 "register_operand" "=&d")          ;; bool output
+        (unspec_volatile:SI
+          [(match_operand:SI 2 "nonimmediate_operand" "+Q")    ;; memory
+           (match_operand:SI 3 "register_operand" "d")         ;; expected 
value
+           (match_operand:SI 4 "register_operand" "d")]                ;; 
desired value
+          UNSPECV_CAS_BOOL))
+   (set (match_operand:SI 1 "register_operand" "=&d")          ;; val output
+        (unspec_volatile:SI [(const_int 0)] UNSPECV_CAS_VAL))
+   (set (match_dup 2)
+        (unspec_volatile:SI [(const_int 0)] UNSPECV_CAS_MEM))
+   (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
    (clobber (match_scratch:SI 8 "=&d"))]
   ""
   {
-    output_asm_insn ("addc \tr0,r0,r0", operands);
-    output_asm_insn ("lwx  \t%1,%y2,r0", operands);
-    output_asm_insn ("addic\t%8,r0,0", operands);
-    output_asm_insn ("bnei \t%8,.-8", operands);
-    output_asm_insn ("cmp  \t%0,%1,%3", operands);
-    output_asm_insn ("bnei \t%0,.+16", operands);
-    output_asm_insn ("swx  \t%4,%y2,r0", operands);
-    output_asm_insn ("addic\t%8,r0,0", operands);
-    output_asm_insn ("bnei \t%8,.-28", operands);
-    return "";
+    return "add  \t%0,r0,r0\n\t"
+      "lwx  \t%1,%y2,r0\n\t"
+      "addic\t%8,r0,0\n\t"
+      "bnei \t%8,.-8\n\t"
+      "cmp  \t%8,%1,%3\n\t"
+      "bnei \t%8,.+20\n\t"
+      "swx  \t%4,%y2,r0\n\t"
+      "addic\t%8,r0,0\n\t"
+      "bnei \t%8,.-28\n\t"
+      "addi \t%0,r0,1";
   }
+  [(set_attr "type"    "atomic")
+   (set_attr "mode"    "SI")
+   (set_attr "length"  "40")]
+)
+
+;;
+;; MicroBlaze has no atomic load/store instruction pair for QImode
+;;
+;; Use load/store reserved word with necessary mem align,shift,mask magic
+;;
+(define_insn "atomic_test_and_set"
+  [(set (match_operand:QI 0 "register_operand" "=&d")          ;; bool output
+        (unspec_volatile:QI
+          [(match_operand:QI 1 "nonimmediate_operand" "+Q") ;; memory
+           (match_operand:SI 2 "const_int_operand" "")   ;; model
+         ]
+       UNSPECV_ATS))
+   (clobber (match_scratch:SI 3 "=&d")) ; old word
+   (clobber (match_scratch:SI 4 "=&d")) ; tmp
+   (clobber (match_scratch:SI 5 "=&d")) ; aligned address
+   (clobber (match_scratch:SI 6 "=&d")) ; shift
+   (clobber (match_scratch:SI 7 "=&d")) ; mask
+   (clobber (match_scratch:SI 8 "=&d")) ; old value
+  ]
+  "TARGET_BARREL_SHIFT"
+  {
+    return
+      /* word align memory address, compute shift  */
+      "andi \t%5,%y1,-4\n\t"
+      "andi \t%6,%y1,3\n\t"
+      "bslli \t%6,%6,3\n\t"
+
+      /* compute set value and mask */
+      "addik \t%7,r0,1\n\t"
+      "bsll \t%7,%7,%6\n\t"
+
+      /* Load and reserve word */
+      "lwx  \t%3,%5,r0\n\t"
+      "addic\t%4,r0,0\n\t"
+      "bnei \t%4,.-8\n\t"
+
+      /* Compute old value */
+      "and \t%8,%3,%7\n\t"
+
+      /* Test Old Value */
+      "cmp \t%4,%8,r0\n\t"
+      "bnei \t%4,.+20\n\t"
+
+      /* Compute Set Word */
+      "or \t%4,%3,%7\n\t"
+
+      /* Try Reserved store */
+      "swx  \t%4,%5,r0\n\t"
+      "addic\t%4,r0,0\n\t"
+      "bnei \t%4,.-36\n\t"
+
+      /* Set result */
+      "bsrl \t%0,%8,%6\n\t";
+  }
+  [(set_attr "type"    "atomic")
+  (set_attr "mode"     "QI")
+  (set_attr "length"   "64")]
 )
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1e78e8679fa..d3fbb73059f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2025-07-01  Neal Frager <neal.fra...@amd.com>
+
+       PR atomic/118280
+       * gcc.dg/atomic/atomic-pr118280.c: New test.
+
 2025-06-30  Jeff Law  <j...@ventanamicro.com>
 
        PR rtl-optimization/120242
diff --git a/gcc/testsuite/gcc.dg/atomic/atomic-pr118280.c 
b/gcc/testsuite/gcc.dg/atomic/atomic-pr118280.c
new file mode 100644
index 00000000000..1857d14602c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/atomic/atomic-pr118280.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mcpu=v10.0 -mxl-barrel-shift" { target 
microblaze*-*-* } } */
+
+#include <stdatomic.h>
+#include <stdio.h>
+
+atomic_flag f = ATOMIC_FLAG_INIT ;
+
+int main()
+{
+       int b = 0;
+       int result = 0;
+
+       b = atomic_flag_test_and_set(&f);
+       if (b != 0) {
+         result = 1;
+         printf ("Expected <0> Received <%d>\n", (int)b);
+       }
+
+       b = atomic_flag_test_and_set(&f);
+       if (b != 1) {
+         result = 1;
+         printf ("Expected <1> Received <%d>\n", (int)b);
+       }
+
+       b = atomic_flag_test_and_set(&f);
+       if (b != 1) {
+         result = 1;
+         printf ("Expected <1> Received <%d>\n", (int)b);
+       }
+
+       atomic_flag_clear(&f);
+
+       b = atomic_flag_test_and_set(&f);
+       if (b != 0) {
+         result = 1;
+         printf ("Expected <0> Received <%d>\n", (int)b);
+       }
+
+       return result;
+}
-- 
2.25.1

Reply via email to