re PR target/64851 ([SH] Add atomic not)
authorOleg Endo <olegendo@gcc.gnu.org>
Sun, 1 Feb 2015 11:12:47 +0000 (11:12 +0000)
committerOleg Endo <olegendo@gcc.gnu.org>
Sun, 1 Feb 2015 11:12:47 +0000 (11:12 +0000)
gcc/
PR target/64851
* config/sh/sync.md (atomic_fetch_notsi_hard,
atomic_fetch_not<mode>_hard, atomic_fetch_not<mode>_soft_gusa,
atomic_fetch_not<mode>_soft_tcb, atomic_fetch_not<mode>_soft_imask,
atomic_not_fetchsi_hard, atomic_not_fetch<mode>_hard,
atomic_not_fetch<mode>_soft_gusa, atomic_not_fetch<mode>_soft_tcb,
atomic_not_fetch<mode>_soft_imask): New insns.

gcc/testsuite/
PR target/64851
* gcc.target/sh/pr64851-0.h: New
* gcc.target/sh/pr64851-1.c: New
* gcc.target/sh/pr64851-2.c: New
* gcc.target/sh/pr64851-3.c: New
* gcc.target/sh/pr64851-4.c: New

From-SVN: r220317

gcc/ChangeLog
gcc/config/sh/sync.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/sh/pr64851-0.h [new file with mode: 0644]
gcc/testsuite/gcc.target/sh/pr64851-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/sh/pr64851-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/sh/pr64851-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/sh/pr64851-4.c [new file with mode: 0644]

index 504c741b3be2cee89ae45e329d05ec6256b5b9ab..dca250c0ec7a939dbae1418956f0b1e2886f2023 100644 (file)
@@ -1,3 +1,13 @@
+2015-02-01  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/64851
+       * config/sh/sync.md (atomic_fetch_notsi_hard,
+       atomic_fetch_not<mode>_hard, atomic_fetch_not<mode>_soft_gusa,
+       atomic_fetch_not<mode>_soft_tcb, atomic_fetch_not<mode>_soft_imask,
+       atomic_not_fetchsi_hard, atomic_not_fetch<mode>_hard,
+       atomic_not_fetch<mode>_soft_gusa, atomic_not_fetch<mode>_soft_tcb,
+       atomic_not_fetch<mode>_soft_imask): New insns.
+
 2015-02-01  Maxim Kuvyrkov  <maxim.kuvyrkov@linaro.org>
 
        * haifa-sched.c (INSN_RFS_DEBUG_ORIG_ORDER): New access macro.
@@ -32,7 +42,7 @@
 
 2015-01-31  Uros Bizjak  <ubizjak@gmail.com>
 
-        PR target/64882
+       PR target/64882
        * config/i386/predicates.md (address_no_seg_operand): Reject
        non-CONST_INT_P operands in invalid mode.
 
index b3ff70ce171dc55ee135eba11dfc6a65967ca0e4..089a6283a47dd68fb814ae62313c0db81921ce14 100644 (file)
 }
   [(set_attr "length" "10")])
 
+;; Combine pattern for xor (val, -1) / nand (val, -1).
+(define_insn "atomic_fetch_notsi_hard"
+  [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
+       (mem:SI (match_operand:SI 1 "arith_reg_operand" "r")))
+   (set (mem:SI (match_dup 1))
+       (unspec:SI [(not:SI (mem:SI (match_dup 1)))] UNSPEC_ATOMIC))
+   (set (reg:SI T_REG) (const_int 1))
+   (clobber (reg:SI R0_REG))]
+  "TARGET_ATOMIC_HARD_LLCS
+   || (TARGET_SH4A && TARGET_ATOMIC_ANY && !TARGET_ATOMIC_STRICT)"
+{
+  return "\r0: movli.l @%1,r0"         "\n"
+        "      mov     r0,%0"          "\n"
+        "      not     r0,r0"          "\n"
+        "      movco.l r0,@%1"         "\n"
+        "      bf      0b";
+}
+  [(set_attr "length" "10")])
+
 (define_insn "atomic_fetch_<fetchop_name><mode>_hard"
   [(set (match_operand:QIHI 0 "arith_reg_dest" "=&r")
        (mem:QIHI (match_operand:SI 1 "arith_reg_operand" "r")))
 }
   [(set_attr "length" "28")])
 
+;; Combine pattern for xor (val, -1) / nand (val, -1).
+(define_insn "atomic_fetch_not<mode>_hard"
+  [(set (match_operand:QIHI 0 "arith_reg_dest" "=&r")
+       (mem:QIHI (match_operand:SI 1 "arith_reg_operand" "r")))
+   (set (mem:QIHI (match_dup 1))
+       (unspec:QIHI [(not:QIHI (mem:QIHI (match_dup 1)))] UNSPEC_ATOMIC))
+   (set (reg:SI T_REG) (const_int 1))
+   (clobber (reg:SI R0_REG))
+   (clobber (match_scratch:SI 2 "=&r"))
+   (clobber (match_scratch:SI 3 "=1"))]
+  "TARGET_ATOMIC_HARD_LLCS"
+{
+  return "\r   mov     #-4,%2"                 "\n"
+        "      and     %1,%2"                  "\n"
+        "      xor     %2,%1"                  "\n"
+        "      add     r15,%1"                 "\n"
+        "      add     #-4,%1"                 "\n"
+        "0:    movli.l @%2,r0"                 "\n"
+        "      mov.l   r0,@-r15"               "\n"
+        "      mov.<bw>        @%1,%0"         "\n"
+        "      not     %0,r0"                  "\n"
+        "      mov.<bw>        r0,@%1"         "\n"
+        "      mov.l   @r15+,r0"               "\n"
+        "      movco.l r0,@%2"                 "\n"
+        "      bf      0b";
+}
+  [(set_attr "length" "26")])
+
 (define_insn "atomic_fetch_<fetchop_name><mode>_soft_gusa"
   [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&u")
        (mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "u")))
 }
   [(set_attr "length" "18")])
 
+;; Combine pattern for xor (val, -1) / nand (val, -1).
+(define_insn "atomic_fetch_not<mode>_soft_gusa"
+  [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&u")
+       (mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "u")))
+   (set (mem:QIHISI (match_dup 1))
+       (unspec:QIHISI [(not:QIHISI (mem:QIHISI (match_dup 1)))] UNSPEC_ATOMIC))
+   (clobber (match_scratch:QIHISI 2 "=&u"))
+   (clobber (reg:SI R0_REG))
+   (clobber (reg:SI R1_REG))]
+  "TARGET_ATOMIC_SOFT_GUSA"
+{
+  return "\r   mova    1f,r0"                  "\n"
+        "      mov     r15,r1"                 "\n"
+        "      .align 2"                       "\n"
+        "      mov     #(0f-1f),r15"           "\n"
+        "0:    mov.<bwl>       @%1,%0"         "\n"
+        "      not     %0,%2"                  "\n"
+        "      mov.<bwl>       %2,@%1"         "\n"
+        "1:    mov     r1,r15";
+}
+  [(set_attr "length" "16")])
+
 (define_insn "atomic_fetch_<fetchop_name><mode>_soft_tcb"
   [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&r")
        (mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r")))
 }
   [(set_attr "length" "20")])
 
+;; Combine pattern for xor (val, -1) / nand (val, -1).
+(define_insn "atomic_fetch_not<mode>_soft_tcb"
+  [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&r")
+       (mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r")))
+   (set (mem:QIHISI (match_dup 1))
+       (unspec:QIHISI [(not:QIHISI (mem:QIHISI (match_dup 1)))] UNSPEC_ATOMIC))
+   (use (match_operand:SI 2 "gbr_displacement"))
+   (clobber (reg:SI R0_REG))
+   (clobber (reg:SI R1_REG))]
+  "TARGET_ATOMIC_SOFT_TCB"
+{
+  return "\r   mova    1f,r0"                  "\n"
+        "      .align 2"                       "\n"
+        "      mov     #(0f-1f),r1"            "\n"
+        "      mov.l   r0,@(%O2,gbr)"          "\n"
+        "0:    mov.<bwl>       @%1,r0"         "\n"
+        "      mov     r0,%0"                  "\n"
+        "      not     r0,r0"                  "\n"
+        "      mov.<bwl>       r0,@%1"         "\n"
+        "1:    mov     #0,r0"                  "\n"
+        "      mov.l   r0,@(%O2,gbr)";
+}
+  [(set_attr "length" "20")])
+
 (define_insn "atomic_fetch_<fetchop_name><mode>_soft_imask"
   [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&r")
        (mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r")))
 }
   [(set_attr "length" "18")])
 
+;; Combine pattern for xor (val, -1) / nand (val, -1).
+(define_insn "atomic_fetch_not<mode>_soft_imask"
+  [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&r")
+       (mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r")))
+   (set (mem:QIHISI (match_dup 1))
+       (unspec:QIHISI [(not:QIHISI (mem:QIHISI (match_dup 1)))] UNSPEC_ATOMIC))
+   (clobber (reg:SI R0_REG))
+   (clobber (match_scratch:QIHISI 2 "=&r"))]
+  "TARGET_ATOMIC_SOFT_IMASK"
+{
+  return "\r   stc     sr,r0"                  "\n"
+        "      mov     r0,%2"                  "\n"
+        "      or      #0xF0,r0"               "\n"
+        "      ldc     r0,sr"                  "\n"
+        "      mov.<bwl>       @%1,r0"         "\n"
+        "      mov     r0,%0"                  "\n"
+        "      not     r0,r0"                  "\n"
+        "      mov.<bwl>       r0,@%1"         "\n"
+        "      ldc     %2,sr";
+}
+  [(set_attr "length" "18")])
+
 (define_expand "atomic_fetch_nand<mode>"
   [(set (match_operand:QIHISI 0 "arith_reg_dest")
        (match_operand:QIHISI 1 "memory_operand"))
 }
   [(set_attr "length" "8")])
 
+;; Combine pattern for xor (val, -1) / nand (val, -1).
+(define_insn "atomic_not_fetchsi_hard"
+  [(set (match_operand:SI 0 "arith_reg_dest" "=&z")
+       (not:SI (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))))
+   (set (mem:SI (match_dup 1))
+       (unspec:SI [(not:SI (mem:SI (match_dup 1)))] UNSPEC_ATOMIC))
+   (set (reg:SI T_REG) (const_int 1))]
+  "TARGET_ATOMIC_HARD_LLCS
+   || (TARGET_SH4A && TARGET_ATOMIC_ANY && !TARGET_ATOMIC_STRICT)"
+{
+  return "\r0: movli.l @%1,%0"         "\n"
+        "      not     %0,%0"          "\n"
+        "      movco.l %0,@%1"         "\n"
+        "      bf      0b";
+}
+  [(set_attr "length" "8")])
+
 (define_insn "atomic_<fetchop_name>_fetch<mode>_hard"
   [(set (match_operand:QIHI 0 "arith_reg_dest" "=&r")
        (FETCHOP:QIHI
 }
   [(set_attr "length" "28")])
 
+;; Combine pattern for xor (val, -1) / nand (val, -1).
+(define_insn "atomic_not_fetch<mode>_hard"
+  [(set (match_operand:QIHI 0 "arith_reg_dest" "=&r")
+       (not:QIHI (mem:QIHI (match_operand:SI 1 "arith_reg_operand" "r"))))
+   (set (mem:QIHI (match_dup 1))
+       (unspec:QIHI [(not:QIHI (mem:QIHI (match_dup 1)))] UNSPEC_ATOMIC))
+   (set (reg:SI T_REG) (const_int 1))
+   (clobber (reg:SI R0_REG))
+   (clobber (match_scratch:SI 2 "=&r"))
+   (clobber (match_scratch:SI 3 "=1"))]
+  "TARGET_ATOMIC_HARD_LLCS"
+{
+  return "\r   mov     #-4,%2"                 "\n"
+        "      and     %1,%2"                  "\n"
+        "      xor     %2,%1"                  "\n"
+        "      add     r15,%1"                 "\n"
+        "      add     #-4,%1"                 "\n"
+        "0:    movli.l @%2,r0"                 "\n"
+        "      mov.l   r0,@-r15"               "\n"
+        "      mov.<bw>        @%1,r0"         "\n"
+        "      not     r0,r0"                  "\n"
+        "      mov.<bw>        r0,@%1"         "\n"
+        "      mov     r0,%0"                  "\n"
+        "      mov.l   @r15+,r0"               "\n"
+        "      movco.l r0,@%2"                 "\n"
+        "      bf      0b";
+}
+  [(set_attr "length" "28")])
+
 (define_insn "atomic_<fetchop_name>_fetch<mode>_soft_gusa"
   [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&u")
        (FETCHOP:QIHISI
 }
   [(set_attr "length" "16")])
 
+;; Combine pattern for xor (val, -1) / nand (val, -1).
+(define_insn "atomic_not_fetch<mode>_soft_gusa"
+  [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&u")
+       (not:QIHISI (mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "u"))))
+   (set (mem:QIHISI (match_dup 1))
+       (unspec:QIHISI [(not:QIHISI (mem:QIHISI (match_dup 1)))] UNSPEC_ATOMIC))
+   (clobber (reg:SI R0_REG))
+   (clobber (reg:SI R1_REG))]
+  "TARGET_ATOMIC_SOFT_GUSA"
+{
+  return "\r   mova    1f,r0"                  "\n"
+        "      mov     r15,r1"                 "\n"
+        "      .align 2"                       "\n"
+        "      mov     #(0f-1f),r15"           "\n"
+        "0:    mov.<bwl>       @%1,%0"         "\n"
+        "      not     %0,%0"          "\n"
+        "      mov.<bwl>       %0,@%1"         "\n"
+        "1:    mov     r1,r15";
+}
+  [(set_attr "length" "16")])
+
 (define_insn "atomic_<fetchop_name>_fetch<mode>_soft_tcb"
   [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&r")
        (FETCHOP:QIHISI
 }
   [(set_attr "length" "20")])
 
+;; Combine pattern for xor (val, -1) / nand (val, -1).
+(define_insn "atomic_not_fetch<mode>_soft_tcb"
+  [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&r")
+       (not:QIHISI (mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r"))))
+   (set (mem:QIHISI (match_dup 1))
+       (unspec:QIHISI [(not:QIHISI (mem:QIHISI (match_dup 1)))] UNSPEC_ATOMIC))
+   (clobber (reg:SI R0_REG))
+   (clobber (reg:SI R1_REG))
+   (use (match_operand:SI 2 "gbr_displacement"))]
+  "TARGET_ATOMIC_SOFT_TCB"
+{
+  return "\r   mova    1f,r0"                  "\n"
+        "      mov     #(0f-1f),r1"            "\n"
+        "      .align 2"                       "\n"
+        "      mov.l   r0,@(%O2,gbr)"          "\n"
+        "0:    mov.<bwl>       @%1,r0"         "\n"
+        "      not     r0,r0"          "\n"
+        "      mov.<bwl>       r0,@%1"         "\n"
+        "1:    mov     r0,%0"                  "\n"
+        "      mov     #0,r0"                  "\n"
+        "      mov.l   r0,@(%O2,gbr)";
+}
+  [(set_attr "length" "20")])
+
 (define_insn "atomic_<fetchop_name>_fetch<mode>_soft_imask"
   [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&z")
        (FETCHOP:QIHISI
 }
   [(set_attr "length" "16")])
 
+;; Combine pattern for xor (val, -1) / nand (val, -1).
+(define_insn "atomic_not_fetch<mode>_soft_imask"
+  [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&z")
+       (not:QIHISI (mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r"))))
+   (set (mem:QIHISI (match_dup 1))
+       (unspec:QIHISI [(not:QIHISI (mem:QIHISI (match_dup 1)))] UNSPEC_ATOMIC))
+   (clobber (match_scratch:SI 2 "=&r"))]
+  "TARGET_ATOMIC_SOFT_IMASK"
+{
+  return "\r   stc     sr,%0"                  "\n"
+        "      mov     %0,%2"                  "\n"
+        "      or      #0xF0,%0"               "\n"
+        "      ldc     %0,sr"                  "\n"
+        "      mov.<bwl>       @%1,%0"         "\n"
+        "      not     %0,%0"          "\n"
+        "      mov.<bwl>       %0,@%1"         "\n"
+        "      ldc     %2,sr";
+}
+  [(set_attr "length" "16")])
+
 (define_expand "atomic_nand_fetch<mode>"
   [(set (match_operand:QIHISI 0 "arith_reg_dest")
        (not:QIHISI (and:QIHISI
index 54dc54380435592fd8b9fc04779f6181d0935457..3d552515f35c78c4286ebf5c4691aa19857e3bc2 100644 (file)
@@ -1,6 +1,15 @@
+2015-02-01  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/64851
+       * gcc.target/sh/pr64851-0.h: New
+       * gcc.target/sh/pr64851-1.c: New
+       * gcc.target/sh/pr64851-2.c: New
+       * gcc.target/sh/pr64851-3.c: New
+       * gcc.target/sh/pr64851-4.c: New
+
 2015-01-31  Uros Bizjak  <ubizjak@gmail.com>
 
-        PR target/64882
+       PR target/64882
        * gcc.dg/torture/pr64882.c: New test.
 
 2015-01-31  David Edelsohn  <dje.gcc@gmail.com>
diff --git a/gcc/testsuite/gcc.target/sh/pr64851-0.h b/gcc/testsuite/gcc.target/sh/pr64851-0.h
new file mode 100644 (file)
index 0000000..5d2d901
--- /dev/null
@@ -0,0 +1,21 @@
+/* Check that atomic not ops are generated.  */
+
+#define emitfuncs(name)\
+  void test_ ## name ## _0 (char* mem)\
+  {\
+    name (mem, -1, __ATOMIC_ACQ_REL);\
+  }\
+  void test_ ## name ## _1 (short* mem)\
+  {\
+    name (mem, -1, __ATOMIC_ACQ_REL);\
+  }\
+  void test_ ## name ##_2 (int* mem)\
+  {\
+    name (mem, -1, __ATOMIC_ACQ_REL);\
+  }\
+
+emitfuncs (__atomic_xor_fetch)
+emitfuncs (__atomic_fetch_xor)
+
+emitfuncs (__atomic_nand_fetch)
+emitfuncs (__atomic_fetch_nand)
diff --git a/gcc/testsuite/gcc.target/sh/pr64851-1.c b/gcc/testsuite/gcc.target/sh/pr64851-1.c
new file mode 100644 (file)
index 0000000..26e9b2a
--- /dev/null
@@ -0,0 +1,6 @@
+/* Check that atomic not ops are generated.  */
+/* { dg-do compile { target { atomic_model_soft_gusa_available } } }  */
+/* { dg-options "-O2 -matomic-model=soft-gusa,strict" }  */
+/* { dg-final { scan-assembler-times "not\t" 12 } }  */
+
+#include "pr64851-0.h"
diff --git a/gcc/testsuite/gcc.target/sh/pr64851-2.c b/gcc/testsuite/gcc.target/sh/pr64851-2.c
new file mode 100644 (file)
index 0000000..44358a5
--- /dev/null
@@ -0,0 +1,6 @@
+/* Check that atomic not ops are generated.  */
+/* { dg-do compile { target { atomic_model_soft_tcb_available } } }  */
+/* { dg-options "-O2 -matomic-model=soft-tcb,gbr-offset=0,strict" }  */
+/* { dg-final { scan-assembler-times "not\t" 12 } }  */
+
+#include "pr64851-0.h"
diff --git a/gcc/testsuite/gcc.target/sh/pr64851-3.c b/gcc/testsuite/gcc.target/sh/pr64851-3.c
new file mode 100644 (file)
index 0000000..a12fd33
--- /dev/null
@@ -0,0 +1,6 @@
+/* Check that atomic not ops are generated.  */
+/* { dg-do compile { target { atomic_model_soft_imask_available } } }  */
+/* { dg-options "-O2 -matomic-model=soft-imask,strict -mno-usermode" }  */
+/* { dg-final { scan-assembler-times "not\t" 12 } }  */
+
+#include "pr64851-0.h"
diff --git a/gcc/testsuite/gcc.target/sh/pr64851-4.c b/gcc/testsuite/gcc.target/sh/pr64851-4.c
new file mode 100644 (file)
index 0000000..4c802e2
--- /dev/null
@@ -0,0 +1,6 @@
+/* Check that atomic not ops are generated.  */
+/* { dg-do compile { target { atomic_model_hard_llcs_available } } }  */
+/* { dg-options "-O2 -matomic-model=hard-llcs,strict" }  */
+/* { dg-final { scan-assembler-times "not\t" 12 } }  */
+
+#include "pr64851-0.h"