]>
Commit | Line | Data |
---|---|---|
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 |