1 ;; GCC machine description for ARC atomic instructions.
2 ;; Copyright (C) 2015-2016 Free Software Foundation, Inc.
4 ;; This file is part of GCC.
6 ;; GCC is free software; you can redistribute it and/or modify
7 ;; it under the terms of the GNU General Public License as published by
8 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; GCC is distributed in the hope that it will be useful,
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ;; GNU General Public License for more details.
16 ;; You should have received a copy of the GNU General Public License
17 ;; along with GCC; see the file COPYING3. If not see
18 ;; <http://www.gnu.org/licenses/>.
20 (define_mode_iterator QHSI [QI HI SI])
21 (define_code_iterator atomicop [plus minus ior xor and])
22 (define_code_attr atomic_optab
23 [(ior "or") (xor "xor") (and "and") (plus "add") (minus "sub")])
25 (define_expand "memory_barrier"
27 (unspec:BLK [(match_dup 0)] UNSPEC_ARC_MEMBAR))]
30 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
31 MEM_VOLATILE_P (operands[0]) = 1;
34 ;; A compiler-only memory barrier for ARC700. Generic code, when
35 ;; checking for the existence of various named patterns, uses
36 ;; asm("":::"memory") when we don't need an actual instruction. For
37 ;; ARCHS, we use a hardware data memory barrier that waits for
38 ;; completion of current data memory operations before initiating
39 ;; similar data memory operations.
40 (define_insn "*memory_barrier"
41 [(set (match_operand:BLK 0 "" "")
42 (unspec:BLK [(match_dup 0)] UNSPEC_ARC_MEMBAR))]
54 [(set_attr "type" "multi")
55 (set_attr "length" "4")])
57 (define_expand "atomic_compare_and_swap<mode>"
58 [(match_operand:SI 0 "register_operand" "") ;; bool out
59 (match_operand:QHSI 1 "register_operand" "") ;; val out
60 (match_operand:QHSI 2 "mem_noofs_operand" "");; memory
61 (match_operand:QHSI 3 "register_operand" "") ;; expected
62 (match_operand:QHSI 4 "register_operand" "") ;; desired
63 (match_operand:SI 5 "const_int_operand") ;; is_weak
64 (match_operand:SI 6 "const_int_operand") ;; mod_s
65 (match_operand:SI 7 "const_int_operand")] ;; mod_f
68 arc_expand_compare_and_swap (operands);
72 (define_insn_and_split "atomic_compare_and_swapsi_1"
73 [(set (reg:CC_Z CC_REG) ;; bool out
74 (unspec_volatile:CC_Z [(const_int 0)] VUNSPEC_ARC_CAS))
75 (set (match_operand:SI 0 "register_operand" "=&r") ;; val out
76 (match_operand:SI 1 "mem_noofs_operand" "+ATO")) ;; memory
79 [(match_operand:SI 2 "register_operand" "r") ;; expect
80 (match_operand:SI 3 "register_operand" "r") ;; desired
81 (match_operand:SI 4 "const_int_operand") ;; is_weak
82 (match_operand:SI 5 "const_int_operand") ;; mod_s
83 (match_operand:SI 6 "const_int_operand")] ;; mod_f
90 arc_split_compare_and_swap (operands);
94 (define_insn "arc_load_exclusivesi"
95 [(set (match_operand:SI 0 "register_operand" "=r")
97 [(match_operand:SI 1 "mem_noofs_operand" "ATO")]
101 [(set_attr "type" "load")
102 (set_attr "iscompact" "false")
103 (set_attr "predicable" "no")
104 (set_attr "length" "*")])
106 (define_insn "arc_store_exclusivesi"
107 [(set (match_operand:SI 0 "mem_noofs_operand" "=ATO")
108 (unspec_volatile:SI[(match_operand:SI 1 "register_operand" "r")]
110 (clobber (reg:CC_Z CC_REG))]
113 [(set_attr "type" "store")
114 (set_attr "iscompact" "false")
115 (set_attr "predicable" "no")
116 (set_attr "length" "*")])
118 (define_expand "atomic_exchangesi"
119 [(match_operand:SI 0 "register_operand" "")
120 (match_operand:SI 1 "mem_noofs_operand" "")
121 (match_operand:SI 2 "register_operand" "")
122 (match_operand:SI 3 "const_int_operand" "")]
125 enum memmodel model = (enum memmodel) INTVAL (operands[3]);
127 if (model == MEMMODEL_SEQ_CST)
128 emit_insn (gen_sync (const1_rtx));
129 emit_insn (gen_exchangesi (operands[0], operands[1], operands[2]));
133 (define_insn "exchangesi"
134 [(set (match_operand:SI 0 "register_operand" "=r")
135 (unspec_volatile:SI [(match_operand:SI 1 "mem_noofs_operand" "+ATO")]
138 (match_operand:SI 2 "register_operand" "0"))]
141 [(set_attr "type" "load")
142 (set_attr "iscompact" "false")
143 (set_attr "predicable" "no")
144 (set_attr "length" "*")])
146 (define_expand "atomic_<atomic_optab>si"
147 [(match_operand:SI 0 "mem_noofs_operand" "") ;; memory
148 (atomicop:SI (match_dup 0)
149 (match_operand:SI 1 "register_operand" "")) ;; operand
150 (match_operand:SI 2 "const_int_operand" "")] ;; model
153 arc_expand_atomic_op (<CODE>, operands[0], operands[1],
154 NULL_RTX, NULL_RTX, operands[2]);
158 (define_expand "atomic_nandsi"
159 [(match_operand:SI 0 "mem_noofs_operand" "") ;; memory
160 (match_operand:SI 1 "register_operand" "") ;; operand
161 (match_operand:SI 2 "const_int_operand" "")] ;; model
164 arc_expand_atomic_op (NOT, operands[0], operands[1],
165 NULL_RTX, NULL_RTX, operands[2]);
169 (define_expand "atomic_fetch_<atomic_optab>si"
170 [(match_operand:SI 0 "register_operand" "") ;; output
171 (match_operand:SI 1 "mem_noofs_operand" "") ;; memory
172 (atomicop:SI (match_dup 1)
173 (match_operand:SI 2 "register_operand" "")) ;; operand
174 (match_operand:SI 3 "const_int_operand" "")] ;; model
177 arc_expand_atomic_op (<CODE>, operands[1], operands[2],
178 operands[0], NULL_RTX, operands[3]);
182 (define_expand "atomic_fetch_nandsi"
183 [(match_operand:SI 0 "register_operand" "") ;; output
184 (match_operand:SI 1 "mem_noofs_operand" "") ;; memory
185 (match_operand:SI 2 "register_operand" "") ;; operand
186 (match_operand:SI 3 "const_int_operand" "")] ;; model
189 arc_expand_atomic_op (NOT, operands[1], operands[2],
190 operands[0], NULL_RTX, operands[3]);
194 (define_expand "atomic_<atomic_optab>_fetchsi"
195 [(match_operand:SI 0 "register_operand" "") ;; output
196 (match_operand:SI 1 "mem_noofs_operand" "") ;; memory
197 (atomicop:SI (match_dup 1)
198 (match_operand:SI 2 "register_operand" "")) ;; operand
199 (match_operand:SI 3 "const_int_operand" "")] ;; model
202 arc_expand_atomic_op (<CODE>, operands[1], operands[2],
203 NULL_RTX, operands[0], operands[3]);
207 (define_expand "atomic_nand_fetchsi"
208 [(match_operand:SI 0 "register_operand" "") ;; output
209 (match_operand:SI 1 "mem_noofs_operand" "") ;; memory
210 (match_operand:SI 2 "register_operand" "") ;; operand
211 (match_operand:SI 3 "const_int_operand" "")] ;; model
214 arc_expand_atomic_op (NOT, operands[1], operands[2],
215 NULL_RTX, operands[0], operands[3]);