1; RUN: llc -mcpu=pwr9 -mtriple=powerpc64le-unknown-unknown \
2; RUN:   -enable-ppc-quad-precision -verify-machineinstrs \
3; RUN:   -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | FileCheck %s
4
5; Function Attrs: norecurse nounwind
6define void @qpAdd(fp128* nocapture readonly %a, fp128* nocapture %res) {
7entry:
8  %0 = load fp128, fp128* %a, align 16
9  %add = fadd fp128 %0, %0
10  store fp128 %add, fp128* %res, align 16
11  ret void
12; CHECK-LABEL: qpAdd
13; CHECK-NOT: bl __addtf3
14; CHECK: xsaddqp
15; CHECK: stxv
16; CHECK: blr
17}
18
19; Function Attrs: norecurse nounwind
20define void @qpSub(fp128* nocapture readonly %a, fp128* nocapture %res) {
21entry:
22  %0 = load fp128, fp128* %a, align 16
23  %sub = fsub fp128 %0, %0
24  store fp128 %sub, fp128* %res, align 16
25  ret void
26; CHECK-LABEL: qpSub
27; CHECK-NOT: bl __subtf3
28; CHECK: xssubqp
29; CHECK: stxv
30; CHECK: blr
31}
32
33; Function Attrs: norecurse nounwind
34define void @qpMul(fp128* nocapture readonly %a, fp128* nocapture %res) {
35entry:
36  %0 = load fp128, fp128* %a, align 16
37  %mul = fmul fp128 %0, %0
38  store fp128 %mul, fp128* %res, align 16
39  ret void
40; CHECK-LABEL: qpMul
41; CHECK-NOT: bl __multf3
42; CHECK: xsmulqp
43; CHECK: stxv
44; CHECK: blr
45}
46
47; Function Attrs: norecurse nounwind
48define void @qpDiv(fp128* nocapture readonly %a, fp128* nocapture %res) {
49entry:
50  %0 = load fp128, fp128* %a, align 16
51  %div = fdiv fp128 %0, %0
52  store fp128 %div, fp128* %res, align 16
53  ret void
54; CHECK-LABEL: qpDiv
55; CHECK-NOT: bl __divtf3
56; CHECK: xsdivqp
57; CHECK: stxv
58; CHECK: blr
59}
60
61define void @testLdNSt(i8* nocapture readonly %PtrC, fp128* nocapture %PtrF) {
62entry:
63  %add.ptr = getelementptr inbounds i8, i8* %PtrC, i64 4
64  %0 = bitcast i8* %add.ptr to fp128*
65  %1 = load fp128, fp128* %0, align 16
66  %2 = bitcast fp128* %PtrF to i8*
67  %add.ptr1 = getelementptr inbounds i8, i8* %2, i64 8
68  %3 = bitcast i8* %add.ptr1 to fp128*
69  store fp128 %1, fp128* %3, align 16
70  ret void
71; CHECK-LABEL: testLdNSt
72; CHECK: lxvx
73; CHECK: stxvx
74; CHECK-NEXT: blr
75}
76
77define void @qpSqrt(fp128* nocapture readonly %a, fp128* nocapture %res) {
78entry:
79  %0 = load fp128, fp128* %a, align 16
80  %1 = tail call fp128 @llvm.sqrt.f128(fp128 %0)
81  store fp128 %1, fp128* %res, align 16
82  ret void
83
84; CHECK-LABEL: qpSqrt
85; CHECK-NOT: bl sqrtl
86; CHECK: xssqrtqp
87; CHECK: stxv
88; CHECK: blr
89}
90declare fp128 @llvm.sqrt.f128(fp128 %Val)
91
92define void @qpCpsgn(fp128* nocapture readonly %a, fp128* nocapture readonly %b,
93                     fp128* nocapture %res) {
94entry:
95  %0 = load fp128, fp128* %a, align 16
96  %1 = load fp128, fp128* %b, align 16
97  %2 = tail call fp128 @llvm.copysign.f128(fp128 %0, fp128 %1)
98  store fp128 %2, fp128* %res, align 16
99  ret void
100
101; CHECK-LABEL: qpCpsgn
102; CHECK-NOT: rldimi
103; CHECK: xscpsgnqp
104; CHECK: stxv
105; CHECK: blr
106}
107declare fp128 @llvm.copysign.f128(fp128 %Mag, fp128 %Sgn)
108
109define void @qpAbs(fp128* nocapture readonly %a, fp128* nocapture %res) {
110entry:
111  %0 = load fp128, fp128* %a, align 16
112  %1 = tail call fp128 @llvm.fabs.f128(fp128 %0)
113  store fp128 %1, fp128* %res, align 16
114  ret void
115
116; CHECK-LABEL: qpAbs
117; CHECK-NOT: clrldi
118; CHECK: xsabsqp
119; CHECK: stxv
120; CHECK: blr
121}
122declare fp128 @llvm.fabs.f128(fp128 %Val)
123
124define void @qpNAbs(fp128* nocapture readonly %a, fp128* nocapture %res) {
125entry:
126  %0 = load fp128, fp128* %a, align 16
127  %1 = tail call fp128 @llvm.fabs.f128(fp128 %0)
128  %neg = fsub fp128 0xL00000000000000008000000000000000, %1
129  store fp128 %neg, fp128* %res, align 16
130  ret void
131
132; CHECK-LABEL: qpNAbs
133; CHECK-NOT: bl __subtf3
134; CHECK: xsnabsqp
135; CHECK: stxv
136; CHECK: blr
137}
138
139define void @qpNeg(fp128* nocapture readonly %a, fp128* nocapture %res) {
140entry:
141  %0 = load fp128, fp128* %a, align 16
142  %sub = fsub fp128 0xL00000000000000008000000000000000, %0
143  store fp128 %sub, fp128* %res, align 16
144  ret void
145
146; CHECK-LABEL: qpNeg
147; CHECK-NOT: bl __subtf3
148; CHECK: xsnegqp
149; CHECK: stxv
150; CHECK: blr
151}
152
153define fp128 @qp_sin(fp128* nocapture readonly %a) {
154; CHECK-LABEL: qp_sin:
155; CHECK:         lxv v2, 0(r3)
156; CHECK:         bl sinf128
157; CHECK:         blr
158entry:
159  %0 = load fp128, fp128* %a, align 16
160  %1 = tail call fp128 @llvm.sin.f128(fp128 %0)
161  ret fp128 %1
162}
163declare fp128 @llvm.sin.f128(fp128 %Val)
164
165define fp128 @qp_cos(fp128* nocapture readonly %a) {
166; CHECK-LABEL: qp_cos:
167; CHECK:         lxv v2, 0(r3)
168; CHECK:         bl cosf128
169; CHECK:         blr
170entry:
171  %0 = load fp128, fp128* %a, align 16
172  %1 = tail call fp128 @llvm.cos.f128(fp128 %0)
173  ret fp128 %1
174}
175declare fp128 @llvm.cos.f128(fp128 %Val)
176
177define fp128 @qp_log(fp128* nocapture readonly %a) {
178; CHECK-LABEL: qp_log:
179; CHECK:         lxv v2, 0(r3)
180; CHECK:         bl logf128
181; CHECK:         blr
182entry:
183  %0 = load fp128, fp128* %a, align 16
184  %1 = tail call fp128 @llvm.log.f128(fp128 %0)
185  ret fp128 %1
186}
187declare fp128     @llvm.log.f128(fp128 %Val)
188
189define fp128 @qp_log10(fp128* nocapture readonly %a) {
190; CHECK-LABEL: qp_log10:
191; CHECK:         lxv v2, 0(r3)
192; CHECK:         bl log10f128
193; CHECK:         blr
194entry:
195  %0 = load fp128, fp128* %a, align 16
196  %1 = tail call fp128 @llvm.log10.f128(fp128 %0)
197  ret fp128 %1
198}
199declare fp128     @llvm.log10.f128(fp128 %Val)
200
201define fp128 @qp_log2(fp128* nocapture readonly %a) {
202; CHECK-LABEL: qp_log2:
203; CHECK:         lxv v2, 0(r3)
204; CHECK:         bl log2f128
205; CHECK:         blr
206entry:
207  %0 = load fp128, fp128* %a, align 16
208  %1 = tail call fp128 @llvm.log2.f128(fp128 %0)
209  ret fp128 %1
210}
211declare fp128     @llvm.log2.f128(fp128 %Val)
212
213define fp128 @qp_minnum(fp128* nocapture readonly %a,
214                        fp128* nocapture readonly %b) {
215; CHECK-LABEL: qp_minnum:
216; CHECK:         lxv v2, 0(r3)
217; CHECK:         lxv v3, 0(r4)
218; CHECK:         bl fminf128
219; CHECK:         blr
220entry:
221  %0 = load fp128, fp128* %a, align 16
222  %1 = load fp128, fp128* %b, align 16
223  %2 = tail call fp128 @llvm.minnum.f128(fp128 %0, fp128 %1)
224  ret fp128 %2
225}
226declare fp128     @llvm.minnum.f128(fp128 %Val0, fp128 %Val1)
227
228define fp128 @qp_maxnum(fp128* nocapture readonly %a,
229                        fp128* nocapture readonly %b) {
230; CHECK-LABEL: qp_maxnum:
231; CHECK:         lxv v2, 0(r3)
232; CHECK:         lxv v3, 0(r4)
233; CHECK:         bl fmaxf128
234; CHECK:         blr
235entry:
236  %0 = load fp128, fp128* %a, align 16
237  %1 = load fp128, fp128* %b, align 16
238  %2 = tail call fp128 @llvm.maxnum.f128(fp128 %0, fp128 %1)
239  ret fp128 %2
240}
241declare fp128     @llvm.maxnum.f128(fp128 %Val0, fp128 %Val1)
242
243define fp128 @qp_pow(fp128* nocapture readonly %a,
244                     fp128* nocapture readonly %b) {
245; CHECK-LABEL: qp_pow:
246; CHECK:         lxv v2, 0(r3)
247; CHECK:         lxv v3, 0(r4)
248; CHECK:         bl powf128
249; CHECK:         blr
250entry:
251  %0 = load fp128, fp128* %a, align 16
252  %1 = load fp128, fp128* %b, align 16
253  %2 = tail call fp128 @llvm.pow.f128(fp128 %0, fp128 %1)
254  ret fp128 %2
255}
256declare fp128 @llvm.pow.f128(fp128 %Val, fp128 %Power)
257
258define fp128 @qp_exp(fp128* nocapture readonly %a) {
259; CHECK-LABEL: qp_exp:
260; CHECK:         lxv v2, 0(r3)
261; CHECK:         bl expf128
262; CHECK:         blr
263entry:
264  %0 = load fp128, fp128* %a, align 16
265  %1 = tail call fp128 @llvm.exp.f128(fp128 %0)
266  ret fp128 %1
267}
268declare fp128     @llvm.exp.f128(fp128 %Val)
269
270define fp128 @qp_exp2(fp128* nocapture readonly %a) {
271; CHECK-LABEL: qp_exp2:
272; CHECK:         lxv v2, 0(r3)
273; CHECK:         bl exp2f128
274; CHECK:         blr
275entry:
276  %0 = load fp128, fp128* %a, align 16
277  %1 = tail call fp128 @llvm.exp2.f128(fp128 %0)
278  ret fp128 %1
279}
280declare fp128     @llvm.exp2.f128(fp128 %Val)
281
282define void @qp_powi(fp128* nocapture readonly %a, i32* nocapture readonly %b,
283                     fp128* nocapture %res) {
284; CHECK-LABEL: qp_powi:
285; CHECK:         lxv v2, 0(r3)
286; CHECK:         lwz r5, 0(r4)
287; CHECK:         bl __powikf2
288; CHECK:         blr
289entry:
290  %0 = load fp128, fp128* %a, align 16
291  %1 = load i32, i32* %b, align 8
292  %2 = tail call fp128 @llvm.powi.f128(fp128 %0, i32 %1)
293  store fp128 %2, fp128* %res, align 16
294  ret void
295}
296declare fp128 @llvm.powi.f128(fp128 %Val, i32 %power)
297
298@a = common global fp128 0xL00000000000000000000000000000000, align 16
299@b = common global fp128 0xL00000000000000000000000000000000, align 16
300
301define fp128 @qp_frem() #0 {
302entry:
303  %0 = load fp128, fp128* @a, align 16
304  %1 = load fp128, fp128* @b, align 16
305  %rem = frem fp128 %0, %1
306  ret fp128 %rem
307; CHECK-LABEL: qp_frem
308; CHECK: bl fmodf128
309; CHECK: blr
310}
311