]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arc/atomic.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / arc / atomic.md
CommitLineData
daf9817c 1;; GCC machine description for ARC atomic instructions.
7adcbafe 2;; Copyright (C) 2015-2022 Free Software Foundation, Inc.
daf9817c
CZ
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 {
b3e5901b 47 return "dmb\\t3";
daf9817c
CZ
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" "")]
adea5023 123 "TARGET_ARC700 || TARGET_V2"
daf9817c
CZ
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