]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/arc/atomic.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / arc / atomic.md
1 ;; GCC machine description for ARC atomic instructions.
2 ;; Copyright (C) 2015-2020 Free Software Foundation, Inc.
3 ;;
4 ;; This file is part of GCC.
5 ;;
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)
9 ;; any later version.
10 ;;
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.
15 ;;
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/>.
19
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")])
24
25 (define_expand "memory_barrier"
26 [(set (match_dup 0)
27 (unspec:BLK [(match_dup 0)] UNSPEC_ARC_MEMBAR))]
28 ""
29 {
30 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
31 MEM_VOLATILE_P (operands[0]) = 1;
32 })
33
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))]
43 ""
44 {
45 if (TARGET_HS)
46 {
47 return "dmb\\t3";
48 }
49 else
50 {
51 return "";
52 }
53 }
54 [(set_attr "type" "multi")
55 (set_attr "length" "4")])
56
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
66 "TARGET_ATOMIC"
67 {
68 arc_expand_compare_and_swap (operands);
69 DONE;
70 })
71
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
77 (set (match_dup 1)
78 (unspec_volatile:SI
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
84 VUNSPEC_ARC_CAS))]
85 "TARGET_ATOMIC"
86 "#"
87 "&& reload_completed"
88 [(const_int 0)]
89 {
90 arc_split_compare_and_swap (operands);
91 DONE;
92 })
93
94 (define_insn "arc_load_exclusivesi"
95 [(set (match_operand:SI 0 "register_operand" "=r")
96 (unspec_volatile:SI
97 [(match_operand:SI 1 "mem_noofs_operand" "ATO")]
98 VUNSPEC_ARC_LL))]
99 "TARGET_ATOMIC"
100 "llock %0,%1"
101 [(set_attr "type" "load")
102 (set_attr "iscompact" "false")
103 (set_attr "predicable" "no")
104 (set_attr "length" "*")])
105
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")]
109 VUNSPEC_ARC_SC))
110 (clobber (reg:CC_Z CC_REG))]
111 "TARGET_ATOMIC"
112 "scond %1,%0"
113 [(set_attr "type" "store")
114 (set_attr "iscompact" "false")
115 (set_attr "predicable" "no")
116 (set_attr "length" "*")])
117
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" "")]
123 "TARGET_ARC700 || TARGET_V2"
124 {
125 enum memmodel model = (enum memmodel) INTVAL (operands[3]);
126
127 if (model == MEMMODEL_SEQ_CST)
128 emit_insn (gen_sync (const1_rtx));
129 emit_insn (gen_exchangesi (operands[0], operands[1], operands[2]));
130 DONE;
131 })
132
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")]
136 VUNSPEC_ARC_EX))
137 (set (match_dup 1)
138 (match_operand:SI 2 "register_operand" "0"))]
139 ""
140 "ex %0,%1"
141 [(set_attr "type" "load")
142 (set_attr "iscompact" "false")
143 (set_attr "predicable" "no")
144 (set_attr "length" "*")])
145
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
151 "TARGET_ATOMIC"
152 {
153 arc_expand_atomic_op (<CODE>, operands[0], operands[1],
154 NULL_RTX, NULL_RTX, operands[2]);
155 DONE;
156 })
157
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
162 "TARGET_ATOMIC"
163 {
164 arc_expand_atomic_op (NOT, operands[0], operands[1],
165 NULL_RTX, NULL_RTX, operands[2]);
166 DONE;
167 })
168
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
175 "TARGET_ATOMIC"
176 {
177 arc_expand_atomic_op (<CODE>, operands[1], operands[2],
178 operands[0], NULL_RTX, operands[3]);
179 DONE;
180 })
181
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
187 "TARGET_ATOMIC"
188 {
189 arc_expand_atomic_op (NOT, operands[1], operands[2],
190 operands[0], NULL_RTX, operands[3]);
191 DONE;
192 })
193
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
200 "TARGET_ATOMIC"
201 {
202 arc_expand_atomic_op (<CODE>, operands[1], operands[2],
203 NULL_RTX, operands[0], operands[3]);
204 DONE;
205 })
206
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
212 "TARGET_ATOMIC"
213 {
214 arc_expand_atomic_op (NOT, operands[1], operands[2],
215 NULL_RTX, operands[0], operands[3]);
216 DONE;
217 })
218