aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorClaudiu Zissulescu <claziss@synopsys.com>2015-12-10 14:40:21 +0100
committerClaudiu Zissulescu <claziss@gcc.gnu.org>2015-12-10 14:40:21 +0100
commitdaf9817c1c929cdc23a520c5d6d599f52a5ed99c (patch)
treef908859abb404ad8b9e9cc44e7665ac666bea058 /gcc
parentb8a64b7f5d699776983eab2c07125523e96bc6ea (diff)
downloadgcc-daf9817c1c929cdc23a520c5d6d599f52a5ed99c.zip
gcc-daf9817c1c929cdc23a520c5d6d599f52a5ed99c.tar.gz
gcc-daf9817c1c929cdc23a520c5d6d599f52a5ed99c.tar.bz2
[ARC] Add support for atomic memory built-in. Add atomic.md file.
gcc/ 2015-12-10 Claudiu Zissulescu <claziss@synopsys.com> * config/arc/atomic.md: Add new file. From-SVN: r231510
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/config/arc/atomic.md218
2 files changed, 222 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5683811..d2854be 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
index 0000000..665cab5
--- /dev/null
+++ b/gcc/config/arc/atomic.md
@@ -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;
+})
+