1; RUN: llc -verify-machineinstrs < %s -ppc-asm-full-reg-names -mtriple=ppc64-- | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-BE
2; RUN: llc -verify-machineinstrs < %s -ppc-asm-full-reg-names -mtriple=powerpc64le-unknown-linux-gnu | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-LE
3; RUN: llc -verify-machineinstrs < %s -ppc-asm-full-reg-names -mtriple=ppc64-- -mcpu=pwr7 | FileCheck %s
4; RUN: llc -verify-machineinstrs < %s -ppc-asm-full-reg-names -mtriple=ppc64-- -mcpu=pwr8 | FileCheck %s -check-prefix=CHECK-P8U
5
6define i64 @exchange_and_add(i64* %mem, i64 %val) nounwind {
7; CHECK-LABEL: exchange_and_add:
8; CHECK: ldarx
9  %tmp = atomicrmw add i64* %mem, i64 %val monotonic
10; CHECK: stdcx.
11  ret i64 %tmp
12}
13
14define i8 @exchange_and_add8(i8* %mem, i8 %val) nounwind {
15; CHECK-LABEL: exchange_and_add8:
16; CHECK-BE: xori
17; CHECK-LE-NOT: xori
18; CHECK-P8U: lbarx
19  %tmp = atomicrmw add i8* %mem, i8 %val monotonic
20; CHECK-P8U: stbcx.
21  ret i8 %tmp
22}
23
24define i16 @exchange_and_add16(i16* %mem, i16 %val) nounwind {
25; CHECK-LABEL: exchange_and_add16:
26; CHECK-BE: xori
27; CHECK-LE-NOT: xori
28; CHECK-P8U: lharx
29  %tmp = atomicrmw add i16* %mem, i16 %val monotonic
30; CHECK-P8U: sthcx.
31  ret i16 %tmp
32}
33
34define i64 @exchange_and_cmp(i64* %mem) nounwind {
35; CHECK-LABEL: exchange_and_cmp:
36; CHECK: ldarx
37  %tmppair = cmpxchg i64* %mem, i64 0, i64 1 monotonic monotonic
38  %tmp = extractvalue { i64, i1 } %tmppair, 0
39; CHECK: stdcx.
40; CHECK: stdcx.
41  ret i64 %tmp
42}
43
44define i8 @exchange_and_cmp8(i8* %mem) nounwind {
45; CHECK-LABEL: exchange_and_cmp8:
46; CHECK-BE: xori
47; CHECK-LE-NOT: xori
48; CHECK-P8U: lbarx
49  %tmppair = cmpxchg i8* %mem, i8 0, i8 1 monotonic monotonic
50  %tmp = extractvalue { i8, i1 } %tmppair, 0
51; CHECK-P8U: stbcx.
52; CHECK-P8U: stbcx.
53  ret i8 %tmp
54}
55
56define i16 @exchange_and_cmp16(i16* %mem) nounwind {
57; CHECK-LABEL: exchange_and_cmp16:
58; CHECK-BE: xori
59; CHECK-LE-NOT: xori
60; CHECK-P8U: lharx
61  %tmppair = cmpxchg i16* %mem, i16 0, i16 1 monotonic monotonic
62  %tmp = extractvalue { i16, i1 } %tmppair, 0
63; CHECK-P8U: sthcx.
64; CHECK-P8U: sthcx.
65  ret i16 %tmp
66}
67
68define i64 @exchange(i64* %mem, i64 %val) nounwind {
69; CHECK-LABEL: exchange:
70; CHECK: ldarx
71  %tmp = atomicrmw xchg i64* %mem, i64 1 monotonic
72; CHECK: stdcx.
73  ret i64 %tmp
74}
75
76define i8 @exchange8(i8* %mem, i8 %val) nounwind {
77; CHECK-LABEL: exchange8:
78; CHECK-BE: xori
79; CHECK-LE-NOT: xori
80; CHECK-P8U: lbarx
81  %tmp = atomicrmw xchg i8* %mem, i8 1 monotonic
82; CHECK-P8U: stbcx.
83  ret i8 %tmp
84}
85
86define i16 @exchange16(i16* %mem, i16 %val) nounwind {
87; CHECK-LABEL: exchange16:
88; CHECK-BE: xori
89; CHECK-LE-NOT: xori
90; CHECK-P8U: lharx
91  %tmp = atomicrmw xchg i16* %mem, i16 1 monotonic
92; CHECK-P8U: sthcx.
93  ret i16 %tmp
94}
95
96define void @atomic_store(i64* %mem, i64 %val) nounwind {
97entry:
98; CHECK: @atomic_store
99  store atomic i64 %val, i64* %mem release, align 64
100; CHECK: lwsync
101; CHECK-NOT: stdcx
102; CHECK: std
103  ret void
104}
105
106define i64 @atomic_load(i64* %mem) nounwind {
107entry:
108; CHECK: @atomic_load
109  %tmp = load atomic i64, i64* %mem acquire, align 64
110; CHECK-NOT: ldarx
111; CHECK: ld [[VAL:r[0-9]+]]
112; CHECK: cmpd [[CR:cr[0-9]+]], [[VAL]], [[VAL]]
113; CHECK: bne- [[CR]], .+4
114; CHECK: isync
115  ret i64 %tmp
116}
117
118