]> git.proxmox.com Git - rustc.git/blob - src/llvm/lib/Target/AArch64/AArch64InstrAtomics.td
Imported Upstream version 1.0.0+dfsg1
[rustc.git] / src / llvm / lib / Target / AArch64 / AArch64InstrAtomics.td
1 //=- AArch64InstrAtomics.td - AArch64 Atomic codegen support -*- tablegen -*-=//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // AArch64 Atomic operand code-gen constructs.
11 //
12 //===----------------------------------------------------------------------===//
13
14 //===----------------------------------
15 // Atomic fences
16 //===----------------------------------
17 def : Pat<(atomic_fence (i64 4), (imm)), (DMB (i32 0x9))>;
18 def : Pat<(atomic_fence (imm), (imm)), (DMB (i32 0xb))>;
19
20 //===----------------------------------
21 // Atomic loads
22 //===----------------------------------
23
24 // When they're actually atomic, only one addressing mode (GPR64sp) is
25 // supported, but when they're relaxed and anything can be used, all the
26 // standard modes would be valid and may give efficiency gains.
27
28 // A atomic load operation that actually needs acquire semantics.
29 class acquiring_load<PatFrag base>
30 : PatFrag<(ops node:$ptr), (base node:$ptr), [{
31 AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getOrdering();
32 return isAtLeastAcquire(Ordering);
33 }]>;
34
35 // An atomic load operation that does not need either acquire or release
36 // semantics.
37 class relaxed_load<PatFrag base>
38 : PatFrag<(ops node:$ptr), (base node:$ptr), [{
39 AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getOrdering();
40 return !isAtLeastAcquire(Ordering);
41 }]>;
42
43 // 8-bit loads
44 def : Pat<(acquiring_load<atomic_load_8> GPR64sp:$ptr), (LDARB GPR64sp:$ptr)>;
45 def : Pat<(relaxed_load<atomic_load_8> (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
46 ro_Wextend8:$offset)),
47 (LDRBBroW GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$offset)>;
48 def : Pat<(relaxed_load<atomic_load_8> (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
49 ro_Xextend8:$offset)),
50 (LDRBBroX GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$offset)>;
51 def : Pat<(relaxed_load<atomic_load_8> (am_indexed8 GPR64sp:$Rn,
52 uimm12s1:$offset)),
53 (LDRBBui GPR64sp:$Rn, uimm12s1:$offset)>;
54 def : Pat<(relaxed_load<atomic_load_8>
55 (am_unscaled8 GPR64sp:$Rn, simm9:$offset)),
56 (LDURBBi GPR64sp:$Rn, simm9:$offset)>;
57
58 // 16-bit loads
59 def : Pat<(acquiring_load<atomic_load_16> GPR64sp:$ptr), (LDARH GPR64sp:$ptr)>;
60 def : Pat<(relaxed_load<atomic_load_16> (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
61 ro_Wextend16:$extend)),
62 (LDRHHroW GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend)>;
63 def : Pat<(relaxed_load<atomic_load_16> (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
64 ro_Xextend16:$extend)),
65 (LDRHHroX GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend)>;
66 def : Pat<(relaxed_load<atomic_load_16> (am_indexed16 GPR64sp:$Rn,
67 uimm12s2:$offset)),
68 (LDRHHui GPR64sp:$Rn, uimm12s2:$offset)>;
69 def : Pat<(relaxed_load<atomic_load_16>
70 (am_unscaled16 GPR64sp:$Rn, simm9:$offset)),
71 (LDURHHi GPR64sp:$Rn, simm9:$offset)>;
72
73 // 32-bit loads
74 def : Pat<(acquiring_load<atomic_load_32> GPR64sp:$ptr), (LDARW GPR64sp:$ptr)>;
75 def : Pat<(relaxed_load<atomic_load_32> (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
76 ro_Wextend32:$extend)),
77 (LDRWroW GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend)>;
78 def : Pat<(relaxed_load<atomic_load_32> (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
79 ro_Xextend32:$extend)),
80 (LDRWroX GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend)>;
81 def : Pat<(relaxed_load<atomic_load_32> (am_indexed32 GPR64sp:$Rn,
82 uimm12s4:$offset)),
83 (LDRWui GPR64sp:$Rn, uimm12s4:$offset)>;
84 def : Pat<(relaxed_load<atomic_load_32>
85 (am_unscaled32 GPR64sp:$Rn, simm9:$offset)),
86 (LDURWi GPR64sp:$Rn, simm9:$offset)>;
87
88 // 64-bit loads
89 def : Pat<(acquiring_load<atomic_load_64> GPR64sp:$ptr), (LDARX GPR64sp:$ptr)>;
90 def : Pat<(relaxed_load<atomic_load_64> (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
91 ro_Wextend64:$extend)),
92 (LDRXroW GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend)>;
93 def : Pat<(relaxed_load<atomic_load_64> (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
94 ro_Xextend64:$extend)),
95 (LDRXroX GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend)>;
96 def : Pat<(relaxed_load<atomic_load_64> (am_indexed64 GPR64sp:$Rn,
97 uimm12s8:$offset)),
98 (LDRXui GPR64sp:$Rn, uimm12s8:$offset)>;
99 def : Pat<(relaxed_load<atomic_load_64>
100 (am_unscaled64 GPR64sp:$Rn, simm9:$offset)),
101 (LDURXi GPR64sp:$Rn, simm9:$offset)>;
102
103 //===----------------------------------
104 // Atomic stores
105 //===----------------------------------
106
107 // When they're actually atomic, only one addressing mode (GPR64sp) is
108 // supported, but when they're relaxed and anything can be used, all the
109 // standard modes would be valid and may give efficiency gains.
110
111 // A store operation that actually needs release semantics.
112 class releasing_store<PatFrag base>
113 : PatFrag<(ops node:$ptr, node:$val), (base node:$ptr, node:$val), [{
114 AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getOrdering();
115 assert(Ordering != AcquireRelease && "unexpected store ordering");
116 return isAtLeastRelease(Ordering);
117 }]>;
118
119 // An atomic store operation that doesn't actually need to be atomic on AArch64.
120 class relaxed_store<PatFrag base>
121 : PatFrag<(ops node:$ptr, node:$val), (base node:$ptr, node:$val), [{
122 AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getOrdering();
123 return !isAtLeastRelease(Ordering);
124 }]>;
125
126 // 8-bit stores
127 def : Pat<(releasing_store<atomic_store_8> GPR64sp:$ptr, GPR32:$val),
128 (STLRB GPR32:$val, GPR64sp:$ptr)>;
129 def : Pat<(relaxed_store<atomic_store_8>
130 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
131 GPR32:$val),
132 (STRBBroW GPR32:$val, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend)>;
133 def : Pat<(relaxed_store<atomic_store_8>
134 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
135 GPR32:$val),
136 (STRBBroX GPR32:$val, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend)>;
137 def : Pat<(relaxed_store<atomic_store_8>
138 (am_indexed8 GPR64sp:$Rn, uimm12s1:$offset), GPR32:$val),
139 (STRBBui GPR32:$val, GPR64sp:$Rn, uimm12s1:$offset)>;
140 def : Pat<(relaxed_store<atomic_store_8>
141 (am_unscaled8 GPR64sp:$Rn, simm9:$offset), GPR32:$val),
142 (STURBBi GPR32:$val, GPR64sp:$Rn, simm9:$offset)>;
143
144 // 16-bit stores
145 def : Pat<(releasing_store<atomic_store_16> GPR64sp:$ptr, GPR32:$val),
146 (STLRH GPR32:$val, GPR64sp:$ptr)>;
147 def : Pat<(relaxed_store<atomic_store_16> (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
148 ro_Wextend16:$extend),
149 GPR32:$val),
150 (STRHHroW GPR32:$val, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend)>;
151 def : Pat<(relaxed_store<atomic_store_16> (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
152 ro_Xextend16:$extend),
153 GPR32:$val),
154 (STRHHroX GPR32:$val, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend)>;
155 def : Pat<(relaxed_store<atomic_store_16>
156 (am_indexed16 GPR64sp:$Rn, uimm12s2:$offset), GPR32:$val),
157 (STRHHui GPR32:$val, GPR64sp:$Rn, uimm12s2:$offset)>;
158 def : Pat<(relaxed_store<atomic_store_16>
159 (am_unscaled16 GPR64sp:$Rn, simm9:$offset), GPR32:$val),
160 (STURHHi GPR32:$val, GPR64sp:$Rn, simm9:$offset)>;
161
162 // 32-bit stores
163 def : Pat<(releasing_store<atomic_store_32> GPR64sp:$ptr, GPR32:$val),
164 (STLRW GPR32:$val, GPR64sp:$ptr)>;
165 def : Pat<(relaxed_store<atomic_store_32> (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
166 ro_Wextend32:$extend),
167 GPR32:$val),
168 (STRWroW GPR32:$val, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend)>;
169 def : Pat<(relaxed_store<atomic_store_32> (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
170 ro_Xextend32:$extend),
171 GPR32:$val),
172 (STRWroX GPR32:$val, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend)>;
173 def : Pat<(relaxed_store<atomic_store_32>
174 (am_indexed32 GPR64sp:$Rn, uimm12s4:$offset), GPR32:$val),
175 (STRWui GPR32:$val, GPR64sp:$Rn, uimm12s4:$offset)>;
176 def : Pat<(relaxed_store<atomic_store_32>
177 (am_unscaled32 GPR64sp:$Rn, simm9:$offset), GPR32:$val),
178 (STURWi GPR32:$val, GPR64sp:$Rn, simm9:$offset)>;
179
180 // 64-bit stores
181 def : Pat<(releasing_store<atomic_store_64> GPR64sp:$ptr, GPR64:$val),
182 (STLRX GPR64:$val, GPR64sp:$ptr)>;
183 def : Pat<(relaxed_store<atomic_store_64> (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
184 ro_Wextend16:$extend),
185 GPR64:$val),
186 (STRXroW GPR64:$val, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend)>;
187 def : Pat<(relaxed_store<atomic_store_64> (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
188 ro_Xextend16:$extend),
189 GPR64:$val),
190 (STRXroX GPR64:$val, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend)>;
191 def : Pat<(relaxed_store<atomic_store_64>
192 (am_indexed64 GPR64sp:$Rn, uimm12s8:$offset), GPR64:$val),
193 (STRXui GPR64:$val, GPR64sp:$Rn, uimm12s8:$offset)>;
194 def : Pat<(relaxed_store<atomic_store_64>
195 (am_unscaled64 GPR64sp:$Rn, simm9:$offset), GPR64:$val),
196 (STURXi GPR64:$val, GPR64sp:$Rn, simm9:$offset)>;
197
198 //===----------------------------------
199 // Low-level exclusive operations
200 //===----------------------------------
201
202 // Load-exclusives.
203
204 def ldxr_1 : PatFrag<(ops node:$ptr), (int_aarch64_ldxr node:$ptr), [{
205 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i8;
206 }]>;
207
208 def ldxr_2 : PatFrag<(ops node:$ptr), (int_aarch64_ldxr node:$ptr), [{
209 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16;
210 }]>;
211
212 def ldxr_4 : PatFrag<(ops node:$ptr), (int_aarch64_ldxr node:$ptr), [{
213 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32;
214 }]>;
215
216 def ldxr_8 : PatFrag<(ops node:$ptr), (int_aarch64_ldxr node:$ptr), [{
217 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i64;
218 }]>;
219
220 def : Pat<(ldxr_1 GPR64sp:$addr),
221 (SUBREG_TO_REG (i64 0), (LDXRB GPR64sp:$addr), sub_32)>;
222 def : Pat<(ldxr_2 GPR64sp:$addr),
223 (SUBREG_TO_REG (i64 0), (LDXRH GPR64sp:$addr), sub_32)>;
224 def : Pat<(ldxr_4 GPR64sp:$addr),
225 (SUBREG_TO_REG (i64 0), (LDXRW GPR64sp:$addr), sub_32)>;
226 def : Pat<(ldxr_8 GPR64sp:$addr), (LDXRX GPR64sp:$addr)>;
227
228 def : Pat<(and (ldxr_1 GPR64sp:$addr), 0xff),
229 (SUBREG_TO_REG (i64 0), (LDXRB GPR64sp:$addr), sub_32)>;
230 def : Pat<(and (ldxr_2 GPR64sp:$addr), 0xffff),
231 (SUBREG_TO_REG (i64 0), (LDXRH GPR64sp:$addr), sub_32)>;
232 def : Pat<(and (ldxr_4 GPR64sp:$addr), 0xffffffff),
233 (SUBREG_TO_REG (i64 0), (LDXRW GPR64sp:$addr), sub_32)>;
234
235 // Load-exclusives.
236
237 def ldaxr_1 : PatFrag<(ops node:$ptr), (int_aarch64_ldaxr node:$ptr), [{
238 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i8;
239 }]>;
240
241 def ldaxr_2 : PatFrag<(ops node:$ptr), (int_aarch64_ldaxr node:$ptr), [{
242 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16;
243 }]>;
244
245 def ldaxr_4 : PatFrag<(ops node:$ptr), (int_aarch64_ldaxr node:$ptr), [{
246 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32;
247 }]>;
248
249 def ldaxr_8 : PatFrag<(ops node:$ptr), (int_aarch64_ldaxr node:$ptr), [{
250 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i64;
251 }]>;
252
253 def : Pat<(ldaxr_1 GPR64sp:$addr),
254 (SUBREG_TO_REG (i64 0), (LDAXRB GPR64sp:$addr), sub_32)>;
255 def : Pat<(ldaxr_2 GPR64sp:$addr),
256 (SUBREG_TO_REG (i64 0), (LDAXRH GPR64sp:$addr), sub_32)>;
257 def : Pat<(ldaxr_4 GPR64sp:$addr),
258 (SUBREG_TO_REG (i64 0), (LDAXRW GPR64sp:$addr), sub_32)>;
259 def : Pat<(ldaxr_8 GPR64sp:$addr), (LDAXRX GPR64sp:$addr)>;
260
261 def : Pat<(and (ldaxr_1 GPR64sp:$addr), 0xff),
262 (SUBREG_TO_REG (i64 0), (LDAXRB GPR64sp:$addr), sub_32)>;
263 def : Pat<(and (ldaxr_2 GPR64sp:$addr), 0xffff),
264 (SUBREG_TO_REG (i64 0), (LDAXRH GPR64sp:$addr), sub_32)>;
265 def : Pat<(and (ldaxr_4 GPR64sp:$addr), 0xffffffff),
266 (SUBREG_TO_REG (i64 0), (LDAXRW GPR64sp:$addr), sub_32)>;
267
268 // Store-exclusives.
269
270 def stxr_1 : PatFrag<(ops node:$val, node:$ptr),
271 (int_aarch64_stxr node:$val, node:$ptr), [{
272 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i8;
273 }]>;
274
275 def stxr_2 : PatFrag<(ops node:$val, node:$ptr),
276 (int_aarch64_stxr node:$val, node:$ptr), [{
277 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16;
278 }]>;
279
280 def stxr_4 : PatFrag<(ops node:$val, node:$ptr),
281 (int_aarch64_stxr node:$val, node:$ptr), [{
282 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32;
283 }]>;
284
285 def stxr_8 : PatFrag<(ops node:$val, node:$ptr),
286 (int_aarch64_stxr node:$val, node:$ptr), [{
287 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i64;
288 }]>;
289
290
291 def : Pat<(stxr_1 GPR64:$val, GPR64sp:$addr),
292 (STXRB (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>;
293 def : Pat<(stxr_2 GPR64:$val, GPR64sp:$addr),
294 (STXRH (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>;
295 def : Pat<(stxr_4 GPR64:$val, GPR64sp:$addr),
296 (STXRW (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>;
297 def : Pat<(stxr_8 GPR64:$val, GPR64sp:$addr),
298 (STXRX GPR64:$val, GPR64sp:$addr)>;
299
300 def : Pat<(stxr_1 (zext (and GPR32:$val, 0xff)), GPR64sp:$addr),
301 (STXRB GPR32:$val, GPR64sp:$addr)>;
302 def : Pat<(stxr_2 (zext (and GPR32:$val, 0xffff)), GPR64sp:$addr),
303 (STXRH GPR32:$val, GPR64sp:$addr)>;
304 def : Pat<(stxr_4 (zext GPR32:$val), GPR64sp:$addr),
305 (STXRW GPR32:$val, GPR64sp:$addr)>;
306
307 def : Pat<(stxr_1 (and GPR64:$val, 0xff), GPR64sp:$addr),
308 (STXRB (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>;
309 def : Pat<(stxr_2 (and GPR64:$val, 0xffff), GPR64sp:$addr),
310 (STXRH (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>;
311 def : Pat<(stxr_4 (and GPR64:$val, 0xffffffff), GPR64sp:$addr),
312 (STXRW (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>;
313
314 // Store-release-exclusives.
315
316 def stlxr_1 : PatFrag<(ops node:$val, node:$ptr),
317 (int_aarch64_stlxr node:$val, node:$ptr), [{
318 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i8;
319 }]>;
320
321 def stlxr_2 : PatFrag<(ops node:$val, node:$ptr),
322 (int_aarch64_stlxr node:$val, node:$ptr), [{
323 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16;
324 }]>;
325
326 def stlxr_4 : PatFrag<(ops node:$val, node:$ptr),
327 (int_aarch64_stlxr node:$val, node:$ptr), [{
328 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32;
329 }]>;
330
331 def stlxr_8 : PatFrag<(ops node:$val, node:$ptr),
332 (int_aarch64_stlxr node:$val, node:$ptr), [{
333 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i64;
334 }]>;
335
336
337 def : Pat<(stlxr_1 GPR64:$val, GPR64sp:$addr),
338 (STLXRB (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>;
339 def : Pat<(stlxr_2 GPR64:$val, GPR64sp:$addr),
340 (STLXRH (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>;
341 def : Pat<(stlxr_4 GPR64:$val, GPR64sp:$addr),
342 (STLXRW (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>;
343 def : Pat<(stlxr_8 GPR64:$val, GPR64sp:$addr),
344 (STLXRX GPR64:$val, GPR64sp:$addr)>;
345
346 def : Pat<(stlxr_1 (zext (and GPR32:$val, 0xff)), GPR64sp:$addr),
347 (STLXRB GPR32:$val, GPR64sp:$addr)>;
348 def : Pat<(stlxr_2 (zext (and GPR32:$val, 0xffff)), GPR64sp:$addr),
349 (STLXRH GPR32:$val, GPR64sp:$addr)>;
350 def : Pat<(stlxr_4 (zext GPR32:$val), GPR64sp:$addr),
351 (STLXRW GPR32:$val, GPR64sp:$addr)>;
352
353 def : Pat<(stlxr_1 (and GPR64:$val, 0xff), GPR64sp:$addr),
354 (STLXRB (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>;
355 def : Pat<(stlxr_2 (and GPR64:$val, 0xffff), GPR64sp:$addr),
356 (STLXRH (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>;
357 def : Pat<(stlxr_4 (and GPR64:$val, 0xffffffff), GPR64sp:$addr),
358 (STLXRW (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>;
359
360
361 // And clear exclusive.
362
363 def : Pat<(int_aarch64_clrex), (CLREX 0xf)>;