[ARC] Add support for atomic memory built-in. Add atomic.md file.
authorClaudiu Zissulescu <claziss@synopsys.com>
Thu, 10 Dec 2015 13:40:21 +0000 (14:40 +0100)
committerClaudiu Zissulescu <claziss@gcc.gnu.org>
Thu, 10 Dec 2015 13:40:21 +0000 (14:40 +0100)
gcc/

2015-12-10  Claudiu Zissulescu  <claziss@synopsys.com>

* config/arc/atomic.md: Add new file.

From-SVN: r231510

gcc/ChangeLog
gcc/config/arc/atomic.md [new file with mode: 0644]

index 5683811..d2854be 100644 (file)
@@ -1,5 +1,9 @@
 2015-12-10  Claudiu Zissulescu  <claziss@synopsys.com>
 
+       * config/arc/atomic.md: Add new file.
+
+2015-12-10  Claudiu Zissulescu  <claziss@synopsys.com>
+
        * config/arc/arc-protos.h (arc_expand_atomic_op): Prototype.
        (arc_split_compare_and_swap): Likewise.
        (arc_expand_compare_and_swap): Likewise.
diff --git a/gcc/config/arc/atomic.md b/gcc/config/arc/atomic.md
new file mode 100644 (file)
index 0000000..665cab5
--- /dev/null
@@ -0,0 +1,218 @@
+;; GCC machine description for ARC atomic instructions.
+;; Copyright (C) 2015 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; GCC is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
+
+(define_mode_iterator QHSI [QI HI SI])
+(define_code_iterator atomicop [plus minus ior xor and])
+(define_code_attr atomic_optab
+  [(ior "or") (xor "xor") (and "and") (plus "add") (minus "sub")])
+
+(define_expand "memory_barrier"
+  [(set (match_dup 0)
+       (unspec:BLK [(match_dup 0)] UNSPEC_ARC_MEMBAR))]
+  ""
+{
+  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
+  MEM_VOLATILE_P (operands[0]) = 1;
+})
+
+;; A compiler-only memory barrier for ARC700.  Generic code, when
+;; checking for the existence of various named patterns, uses
+;; asm("":::"memory") when we don't need an actual instruction.  For
+;; ARCHS, we use a hardware data memory barrier that waits for
+;; completion of current data memory operations before initiating
+;; similar data memory operations.
+(define_insn "*memory_barrier"
+  [(set (match_operand:BLK 0 "" "")
+       (unspec:BLK [(match_dup 0)] UNSPEC_ARC_MEMBAR))]
+  ""
+  {
+   if (TARGET_HS)
+      {
+       return "dmb";
+      }
+    else
+      {
+       return "";
+      }
+  }
+  [(set_attr "type" "multi")
+   (set_attr "length" "4")])
+
+(define_expand "atomic_compare_and_swap<mode>"
+  [(match_operand:SI 0 "register_operand" "")  ;; bool out
+   (match_operand:QHSI 1 "register_operand" "")        ;; val out
+   (match_operand:QHSI 2 "mem_noofs_operand" "");; memory
+   (match_operand:QHSI 3 "register_operand" "")        ;; expected
+   (match_operand:QHSI 4 "register_operand" "")        ;; desired
+   (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_ATOMIC"
+{
+  arc_expand_compare_and_swap (operands);
+  DONE;
+})
+
+(define_insn_and_split "atomic_compare_and_swapsi_1"
+  [(set (reg:CC_Z CC_REG)                                      ;; bool out
+       (unspec_volatile:CC_Z [(const_int 0)] VUNSPEC_ARC_CAS))
+   (set (match_operand:SI 0 "register_operand"      "=&r")     ;; val out
+       (match_operand:SI 1 "mem_noofs_operand"      "+ATO"))   ;; memory
+   (set (match_dup 1)
+       (unspec_volatile:SI
+         [(match_operand:SI 2 "register_operand"     "r") ;; expect
+          (match_operand:SI 3 "register_operand"     "r") ;; desired
+          (match_operand:SI 4 "const_int_operand")        ;; is_weak
+          (match_operand:SI 5 "const_int_operand")        ;; mod_s
+          (match_operand:SI 6 "const_int_operand")]       ;; mod_f
+         VUNSPEC_ARC_CAS))]
+  "TARGET_ATOMIC"
+  "#"
+  "&& reload_completed"
+  [(const_int 0)]
+  {
+    arc_split_compare_and_swap (operands);
+    DONE;
+  })
+
+(define_insn "arc_load_exclusivesi"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (unspec_volatile:SI
+         [(match_operand:SI 1 "mem_noofs_operand" "ATO")]
+         VUNSPEC_ARC_LL))]
+  "TARGET_ATOMIC"
+  "llock %0,%1"
+  [(set_attr "type" "load")
+   (set_attr "iscompact" "false")
+   (set_attr "predicable" "no")
+   (set_attr "length" "*")])
+
+(define_insn "arc_store_exclusivesi"
+  [(set (match_operand:SI 0 "mem_noofs_operand"     "=ATO")
+       (unspec_volatile:SI[(match_operand:SI 1 "register_operand" "r")]
+                          VUNSPEC_ARC_SC))
+   (clobber (reg:CC_Z CC_REG))]
+  "TARGET_ATOMIC"
+  "scond %1,%0"
+  [(set_attr "type" "store")
+   (set_attr "iscompact" "false")
+   (set_attr "predicable" "no")
+   (set_attr "length" "*")])
+
+(define_expand "atomic_exchangesi"
+  [(match_operand:SI 0 "register_operand" "")
+   (match_operand:SI 1 "mem_noofs_operand" "")
+   (match_operand:SI 2 "register_operand" "")
+   (match_operand:SI 3 "const_int_operand" "")]
+  "TARGET_ATOMIC"
+{
+  enum memmodel model = (enum memmodel) INTVAL (operands[3]);
+
+  if (model == MEMMODEL_SEQ_CST)
+    emit_insn (gen_sync (const1_rtx));
+  emit_insn (gen_exchangesi (operands[0], operands[1], operands[2]));
+  DONE;
+})
+
+(define_insn "exchangesi"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (unspec_volatile:SI [(match_operand:SI 1 "mem_noofs_operand" "+ATO")]
+                           VUNSPEC_ARC_EX))
+   (set (match_dup 1)
+       (match_operand:SI 2 "register_operand" "0"))]
+  ""
+  "ex %0,%1"
+  [(set_attr "type" "load")
+   (set_attr "iscompact" "false")
+   (set_attr "predicable" "no")
+   (set_attr "length" "*")])
+
+(define_expand "atomic_<atomic_optab>si"
+  [(match_operand:SI 0 "mem_noofs_operand" "")  ;; memory
+   (atomicop:SI (match_dup 0)
+               (match_operand:SI 1 "register_operand" "")) ;; operand
+   (match_operand:SI 2 "const_int_operand" "")] ;; model
+  "TARGET_ATOMIC"
+{
+  arc_expand_atomic_op (<CODE>, operands[0], operands[1],
+                               NULL_RTX, NULL_RTX, operands[2]);
+  DONE;
+})
+
+(define_expand "atomic_nandsi"
+  [(match_operand:SI 0 "mem_noofs_operand" "") ;; memory
+   (match_operand:SI 1 "register_operand" "")  ;; operand
+   (match_operand:SI 2 "const_int_operand" "")]        ;; model
+  "TARGET_ATOMIC"
+{
+ arc_expand_atomic_op (NOT, operands[0], operands[1],
+                           NULL_RTX, NULL_RTX, operands[2]);
+ DONE;
+})
+
+(define_expand "atomic_fetch_<atomic_optab>si"
+  [(match_operand:SI 0 "register_operand" "")  ;; output
+   (match_operand:SI 1 "mem_noofs_operand" "") ;; memory
+   (atomicop:SI (match_dup 1)
+               (match_operand:SI 2 "register_operand" "")) ;; operand
+   (match_operand:SI 3 "const_int_operand" "")]        ;; model
+  "TARGET_ATOMIC"
+{
+  arc_expand_atomic_op (<CODE>, operands[1], operands[2],
+                               operands[0], NULL_RTX, operands[3]);
+  DONE;
+})
+
+(define_expand "atomic_fetch_nandsi"
+  [(match_operand:SI 0 "register_operand" "")  ;; output
+   (match_operand:SI 1 "mem_noofs_operand" "") ;; memory
+   (match_operand:SI 2 "register_operand" "")  ;; operand
+   (match_operand:SI 3 "const_int_operand" "")]        ;; model
+  "TARGET_ATOMIC"
+{
+  arc_expand_atomic_op (NOT, operands[1], operands[2],
+                            operands[0], NULL_RTX, operands[3]);
+  DONE;
+})
+
+(define_expand "atomic_<atomic_optab>_fetchsi"
+  [(match_operand:SI 0 "register_operand" "")  ;; output
+   (match_operand:SI 1 "mem_noofs_operand" "") ;; memory
+   (atomicop:SI (match_dup 1)
+               (match_operand:SI 2 "register_operand" "")) ;; operand
+   (match_operand:SI 3 "const_int_operand" "")]        ;; model
+  "TARGET_ATOMIC"
+{
+  arc_expand_atomic_op (<CODE>, operands[1], operands[2],
+                               NULL_RTX, operands[0], operands[3]);
+  DONE;
+})
+
+(define_expand "atomic_nand_fetchsi"
+  [(match_operand:SI 0 "register_operand" "")  ;; output
+   (match_operand:SI 1 "mem_noofs_operand" "") ;; memory
+   (match_operand:SI 2 "register_operand" "")  ;; operand
+   (match_operand:SI 3 "const_int_operand" "")]        ;; model
+  "TARGET_ATOMIC"
+{
+  arc_expand_atomic_op (NOT, operands[1], operands[2],
+                            NULL_RTX, operands[0], operands[3]);
+  DONE;
+})
+