• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: llc < %s -mtriple=x86_64-apple-macosx10.9 -verify-machineinstrs -mattr=cx16 | FileCheck %s
2
3@var = global i128 0
4
5define i128 @val_compare_and_swap(i128* %p, i128 %oldval, i128 %newval) {
6; CHECK-LABEL: val_compare_and_swap:
7; CHECK: movq %rsi, %rax
8; CHECK: movq %rcx, %rbx
9; CHECK: movq %r8, %rcx
10; CHECK: lock
11; CHECK: cmpxchg16b (%rdi)
12
13  %pair = cmpxchg i128* %p, i128 %oldval, i128 %newval acquire acquire
14  %val = extractvalue { i128, i1 } %pair, 0
15  ret i128 %val
16}
17
18define void @fetch_and_nand(i128* %p, i128 %bits) {
19; CHECK-LABEL: fetch_and_nand:
20; CHECK-DAG:     movq %rdx, [[INCHI:%[a-z0-9]+]]
21; CHECK-DAG:     movq (%rdi), %rax
22; CHECK-DAG:     movq 8(%rdi), %rdx
23
24; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
25; CHECK:         movq %rdx, %rcx
26; CHECK:         andq [[INCHI]], %rcx
27; CHECK:         movq %rax, %rbx
28  ; INCLO equivalent comes in in %rsi, so it makes sense it stays there.
29; CHECK:         andq %rsi, %rbx
30; CHECK:         notq %rbx
31; CHECK:         notq %rcx
32; CHECK:         lock
33; CHECK:         cmpxchg16b (%rdi)
34; CHECK:         jne [[LOOP]]
35
36; CHECK:         movq %rax, _var
37; CHECK:         movq %rdx, _var+8
38  %val = atomicrmw nand i128* %p, i128 %bits release
39  store i128 %val, i128* @var, align 16
40  ret void
41}
42
43define void @fetch_and_or(i128* %p, i128 %bits) {
44; CHECK-LABEL: fetch_and_or:
45; CHECK-DAG:     movq %rdx, [[INCHI:%[a-z0-9]+]]
46; CHECK-DAG:     movq (%rdi), %rax
47; CHECK-DAG:     movq 8(%rdi), %rdx
48
49; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
50; CHECK:         movq %rax, %rbx
51  ; INCLO equivalent comes in in %rsi, so it makes sense it stays there.
52; CHECK:         orq %rsi, %rbx
53; CHECK:         movq %rdx, %rcx
54; CHECK:         orq [[INCHI]], %rcx
55; CHECK:         lock
56; CHECK:         cmpxchg16b (%rdi)
57; CHECK:         jne [[LOOP]]
58
59; CHECK:         movq %rax, _var
60; CHECK:         movq %rdx, _var+8
61
62  %val = atomicrmw or i128* %p, i128 %bits seq_cst
63  store i128 %val, i128* @var, align 16
64  ret void
65}
66
67define void @fetch_and_add(i128* %p, i128 %bits) {
68; CHECK-LABEL: fetch_and_add:
69; CHECK-DAG:     movq %rdx, [[INCHI:%[a-z0-9]+]]
70; CHECK-DAG:     movq (%rdi), %rax
71; CHECK-DAG:     movq 8(%rdi), %rdx
72
73; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
74; CHECK:         movq %rax, %rbx
75  ; INCLO equivalent comes in in %rsi, so it makes sense it stays there.
76; CHECK:         addq %rsi, %rbx
77; CHECK:         movq %rdx, %rcx
78; CHECK:         adcq [[INCHI]], %rcx
79; CHECK:         lock
80; CHECK:         cmpxchg16b (%rdi)
81; CHECK:         jne [[LOOP]]
82
83; CHECK:         movq %rax, _var
84; CHECK:         movq %rdx, _var+8
85
86  %val = atomicrmw add i128* %p, i128 %bits seq_cst
87  store i128 %val, i128* @var, align 16
88  ret void
89}
90
91define void @fetch_and_sub(i128* %p, i128 %bits) {
92; CHECK-LABEL: fetch_and_sub:
93; CHECK-DAG:     movq %rdx, [[INCHI:%[a-z0-9]+]]
94; CHECK-DAG:     movq (%rdi), %rax
95; CHECK-DAG:     movq 8(%rdi), %rdx
96
97; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
98; CHECK:         movq %rax, %rbx
99  ; INCLO equivalent comes in in %rsi, so it makes sense it stays there.
100; CHECK:         subq %rsi, %rbx
101; CHECK:         movq %rdx, %rcx
102; CHECK:         sbbq [[INCHI]], %rcx
103; CHECK:         lock
104; CHECK:         cmpxchg16b (%rdi)
105; CHECK:         jne [[LOOP]]
106
107; CHECK:         movq %rax, _var
108; CHECK:         movq %rdx, _var+8
109
110  %val = atomicrmw sub i128* %p, i128 %bits seq_cst
111  store i128 %val, i128* @var, align 16
112  ret void
113}
114
115define void @fetch_and_min(i128* %p, i128 %bits) {
116; CHECK-LABEL: fetch_and_min:
117; CHECK-DAG:     movq %rdx, [[INCHI:%[a-z0-9]+]]
118; CHECK-DAG:     movq (%rdi), %rax
119; CHECK-DAG:     movq 8(%rdi), %rdx
120
121; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
122; CHECK:         cmpq
123; CHECK:         sbbq
124; CHECK:         setg
125; CHECK:         cmovneq %rax, %rbx
126; CHECK:         movq [[INCHI]], %rcx
127; CHECK:         cmovneq %rdx, %rcx
128; CHECK:         lock
129; CHECK:         cmpxchg16b (%rdi)
130; CHECK:         jne [[LOOP]]
131
132; CHECK:         movq %rax, _var
133; CHECK:         movq %rdx, _var+8
134
135  %val = atomicrmw min i128* %p, i128 %bits seq_cst
136  store i128 %val, i128* @var, align 16
137  ret void
138}
139
140define void @fetch_and_max(i128* %p, i128 %bits) {
141; CHECK-LABEL: fetch_and_max:
142; CHECK-DAG:     movq %rdx, [[INCHI:%[a-z0-9]+]]
143; CHECK-DAG:     movq (%rdi), %rax
144; CHECK-DAG:     movq 8(%rdi), %rdx
145
146; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
147; CHECK:         cmpq
148; CHECK:         sbbq
149; CHECK:         setge
150; CHECK:         cmovneq %rax, %rbx
151; CHECK:         movq [[INCHI]], %rcx
152; CHECK:         cmovneq %rdx, %rcx
153; CHECK:         lock
154; CHECK:         cmpxchg16b (%rdi)
155; CHECK:         jne [[LOOP]]
156
157; CHECK:         movq %rax, _var
158; CHECK:         movq %rdx, _var+8
159
160  %val = atomicrmw max i128* %p, i128 %bits seq_cst
161  store i128 %val, i128* @var, align 16
162  ret void
163}
164
165define void @fetch_and_umin(i128* %p, i128 %bits) {
166; CHECK-LABEL: fetch_and_umin:
167; CHECK-DAG:     movq %rdx, [[INCHI:%[a-z0-9]+]]
168; CHECK-DAG:     movq (%rdi), %rax
169; CHECK-DAG:     movq 8(%rdi), %rdx
170
171; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
172; CHECK:         cmpq
173; CHECK:         sbbq
174; CHECK:         seta
175; CHECK:         cmovneq %rax, %rbx
176; CHECK:         movq [[INCHI]], %rcx
177; CHECK:         cmovneq %rdx, %rcx
178; CHECK:         lock
179; CHECK:         cmpxchg16b (%rdi)
180; CHECK:         jne [[LOOP]]
181
182; CHECK:         movq %rax, _var
183; CHECK:         movq %rdx, _var+8
184
185  %val = atomicrmw umin i128* %p, i128 %bits seq_cst
186  store i128 %val, i128* @var, align 16
187  ret void
188}
189
190define void @fetch_and_umax(i128* %p, i128 %bits) {
191; CHECK-LABEL: fetch_and_umax:
192; CHECK-DAG:     movq %rdx, [[INCHI:%[a-z0-9]+]]
193; CHECK-DAG:     movq (%rdi), %rax
194; CHECK-DAG:     movq 8(%rdi), %rdx
195
196; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
197; CHECK:         cmpq
198; CHECK:         sbbq
199; CHECK:         setb
200; CHECK:         cmovneq %rax, %rbx
201; CHECK:         movq [[INCHI]], %rcx
202; CHECK:         cmovneq %rdx, %rcx
203; CHECK:         lock
204; CHECK:         cmpxchg16b (%rdi)
205; CHECK:         jne [[LOOP]]
206
207; CHECK:         movq %rax, _var
208; CHECK:         movq %rdx, _var+8
209
210  %val = atomicrmw umax i128* %p, i128 %bits seq_cst
211  store i128 %val, i128* @var, align 16
212  ret void
213}
214
215define i128 @atomic_load_seq_cst(i128* %p) {
216; CHECK-LABEL: atomic_load_seq_cst:
217; CHECK: xorl %eax, %eax
218; CHECK: xorl %edx, %edx
219; CHECK: xorl %ebx, %ebx
220; CHECK: xorl %ecx, %ecx
221; CHECK: lock
222; CHECK: cmpxchg16b (%rdi)
223
224   %r = load atomic i128, i128* %p seq_cst, align 16
225   ret i128 %r
226}
227
228define i128 @atomic_load_relaxed(i128* %p) {
229; CHECK: atomic_load_relaxed:
230; CHECK: xorl %eax, %eax
231; CHECK: xorl %edx, %edx
232; CHECK: xorl %ebx, %ebx
233; CHECK: xorl %ecx, %ecx
234; CHECK: lock
235; CHECK: cmpxchg16b (%rdi)
236
237   %r = load atomic i128, i128* %p monotonic, align 16
238   ret i128 %r
239}
240
241define void @atomic_store_seq_cst(i128* %p, i128 %in) {
242; CHECK-LABEL: atomic_store_seq_cst:
243; CHECK:         movq %rdx, %rcx
244; CHECK:         movq %rsi, %rbx
245; CHECK:         movq (%rdi), %rax
246; CHECK:         movq 8(%rdi), %rdx
247
248; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
249; CHECK:         lock
250; CHECK:         cmpxchg16b (%rdi)
251; CHECK:         jne [[LOOP]]
252; CHECK-NOT:     callq ___sync_lock_test_and_set_16
253
254   store atomic i128 %in, i128* %p seq_cst, align 16
255   ret void
256}
257
258define void @atomic_store_release(i128* %p, i128 %in) {
259; CHECK-LABEL: atomic_store_release:
260; CHECK:         movq %rdx, %rcx
261; CHECK:         movq %rsi, %rbx
262; CHECK:         movq (%rdi), %rax
263; CHECK:         movq 8(%rdi), %rdx
264
265; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
266; CHECK:         lock
267; CHECK:         cmpxchg16b (%rdi)
268; CHECK:         jne [[LOOP]]
269
270   store atomic i128 %in, i128* %p release, align 16
271   ret void
272}
273
274define void @atomic_store_relaxed(i128* %p, i128 %in) {
275; CHECK-LABEL: atomic_store_relaxed:
276; CHECK:         movq %rdx, %rcx
277; CHECK:         movq %rsi, %rbx
278; CHECK:         movq (%rdi), %rax
279; CHECK:         movq 8(%rdi), %rdx
280
281; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
282; CHECK:         lock
283; CHECK:         cmpxchg16b (%rdi)
284; CHECK:         jne [[LOOP]]
285
286   store atomic i128 %in, i128* %p unordered, align 16
287   ret void
288}
289