1; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc-unknown-linux-gnu \
2; RUN:          -mattr=+spe |  FileCheck %s
3
4declare float @llvm.fabs.float(float)
5define float @test_float_abs(float %a) #0 {
6  entry:
7    %0 = tail call float @llvm.fabs.float(float %a)
8    ret float %0
9; CHECK-LABEL: test_float_abs
10; CHECK: efsabs 3, 3
11; CHECK: blr
12}
13
14define float @test_fnabs(float %a) #0 {
15  entry:
16    %0 = tail call float @llvm.fabs.float(float %a)
17    %sub = fsub float -0.000000e+00, %0
18    ret float %sub
19; CHECK-LABEL: @test_fnabs
20; CHECK: efsnabs
21; CHECK: blr
22}
23
24define float @test_fdiv(float %a, float %b) {
25entry:
26  %v = fdiv float %a, %b
27  ret float %v
28
29; CHECK-LABEL: test_fdiv
30; CHECK: efsdiv
31; CHECK: blr
32}
33
34define float @test_fmul(float %a, float %b) {
35  entry:
36  %v = fmul float %a, %b
37  ret float %v
38; CHECK-LABEL @test_fmul
39; CHECK: efsmul
40; CHECK: blr
41}
42
43define float @test_fadd(float %a, float %b) {
44  entry:
45  %v = fadd float %a, %b
46  ret float %v
47; CHECK-LABEL @test_fadd
48; CHECK: efsadd
49; CHECK: blr
50}
51
52define float @test_fsub(float %a, float %b) {
53  entry:
54  %v = fsub float %a, %b
55  ret float %v
56; CHECK-LABEL @test_fsub
57; CHECK: efssub
58; CHECK: blr
59}
60
61define float @test_fneg(float %a) {
62  entry:
63  %v = fsub float -0.0, %a
64  ret float %v
65
66; CHECK-LABEL @test_fneg
67; CHECK: efsneg
68; CHECK: blr
69}
70
71define float @test_dtos(double %a) {
72  entry:
73  %v = fptrunc double %a to float
74  ret float %v
75; CHECK-LABEL: test_dtos
76; CHECK: efscfd
77; CHECK: blr
78}
79
80define i1 @test_fcmpgt(float %a, float %b) {
81  entry:
82  %r = fcmp ogt float %a, %b
83  ret i1 %r
84; CHECK-LABEL: test_fcmpgt
85; CHECK: efscmpgt
86; CHECK: blr
87}
88
89define i1 @test_fcmpugt(float %a, float %b) {
90  entry:
91  %r = fcmp ugt float %a, %b
92  ret i1 %r
93; CHECK-LABEL: test_fcmpugt
94; CHECK: efscmpgt
95; CHECK: blr
96}
97
98define i1 @test_fcmple(float %a, float %b) {
99  entry:
100  %r = fcmp ole float %a, %b
101  ret i1 %r
102; CHECK-LABEL: test_fcmple
103; CHECK: efscmpgt
104; CHECK: blr
105}
106
107define i1 @test_fcmpule(float %a, float %b) {
108  entry:
109  %r = fcmp ule float %a, %b
110  ret i1 %r
111; CHECK-LABEL: test_fcmpule
112; CHECK: efscmpgt
113; CHECK: blr
114}
115
116define i1 @test_fcmpeq(float %a, float %b) {
117  entry:
118  %r = fcmp oeq float %a, %b
119  ret i1 %r
120; CHECK-LABEL: test_fcmpeq
121; CHECK: efscmpeq
122; CHECK: blr
123}
124
125; (un)ordered tests are expanded to une and oeq so verify
126define i1 @test_fcmpuno(float %a, float %b) {
127  entry:
128  %r = fcmp uno float %a, %b
129  ret i1 %r
130; CHECK-LABEL: test_fcmpuno
131; CHECK: efscmpeq
132; CHECK: efscmpeq
133; CHECK: crand
134; CHECK: blr
135}
136
137define i1 @test_fcmpord(float %a, float %b) {
138  entry:
139  %r = fcmp ord float %a, %b
140  ret i1 %r
141; CHECK-LABEL: test_fcmpord
142; CHECK: efscmpeq
143; CHECK: efscmpeq
144; CHECK: crnand
145; CHECK: blr
146}
147
148define i1 @test_fcmpueq(float %a, float %b) {
149  entry:
150  %r = fcmp ueq float %a, %b
151  ret i1 %r
152; CHECK-LABEL: test_fcmpueq
153; CHECK: efscmpeq
154; CHECK: blr
155}
156
157define i1 @test_fcmpne(float %a, float %b) {
158  entry:
159  %r = fcmp one float %a, %b
160  ret i1 %r
161; CHECK-LABEL: test_fcmpne
162; CHECK: efscmpeq
163; CHECK: blr
164}
165
166define i1 @test_fcmpune(float %a, float %b) {
167  entry:
168  %r = fcmp une float %a, %b
169  ret i1 %r
170; CHECK-LABEL: test_fcmpune
171; CHECK: efscmpeq
172; CHECK: blr
173}
174
175define i1 @test_fcmplt(float %a, float %b) {
176  entry:
177  %r = fcmp olt float %a, %b
178  ret i1 %r
179; CHECK-LABEL: test_fcmplt
180; CHECK: efscmplt
181; CHECK: blr
182}
183
184define i1 @test_fcmpult(float %a, float %b) {
185  entry:
186  %r = fcmp ult float %a, %b
187  ret i1 %r
188; CHECK-LABEL: test_fcmpult
189; CHECK: efscmplt
190; CHECK: blr
191}
192
193define i1 @test_fcmpge(float %a, float %b) {
194  entry:
195  %r = fcmp oge float %a, %b
196  ret i1 %r
197; CHECK-LABEL: test_fcmpge
198; CHECK: efscmplt
199; CHECK: blr
200}
201
202define i1 @test_fcmpuge(float %a, float %b) {
203  entry:
204  %r = fcmp uge float %a, %b
205  ret i1 %r
206; CHECK-LABEL: test_fcmpuge
207; CHECK: efscmplt
208; CHECK: blr
209}
210
211define i32 @test_ftoui(float %a) {
212  %v = fptoui float %a to i32
213  ret i32 %v
214; CHECK-LABEL: test_ftoui
215; CHECK: efsctuiz
216}
217
218define i32 @test_ftosi(float %a) {
219  %v = fptosi float %a to i32
220  ret i32 %v
221; CHECK-LABEL: test_ftosi
222; CHECK: efsctsiz
223}
224
225define float @test_ffromui(i32 %a) {
226  %v = uitofp i32 %a to float
227  ret float %v
228; CHECK-LABEL: test_ffromui
229; CHECK: efscfui
230}
231
232define float @test_ffromsi(i32 %a) {
233  %v = sitofp i32 %a to float
234  ret float %v
235; CHECK-LABEL: test_ffromsi
236; CHECK: efscfsi
237}
238
239define i32 @test_fasmconst(float %x) {
240entry:
241  %x.addr = alloca float, align 8
242  store float %x, float* %x.addr, align 8
243  %0 = load float, float* %x.addr, align 8
244  %1 = call i32 asm sideeffect "efsctsi $0, $1", "=f,f"(float %0)
245  ret i32 %1
246; CHECK-LABEL: test_fasmconst
247; Check that it's not loading a double
248; CHECK-NOT: evldd
249; CHECK: #APP
250; CHECK: efsctsi
251; CHECK: #NO_APP
252}
253
254; Double tests
255
256define void @test_double_abs(double * %aa) #0 {
257  entry:
258    %0 = load double, double * %aa
259    %1 = tail call double @llvm.fabs.f64(double %0) #2
260    store double %1, double * %aa
261    ret void
262; CHECK-LABEL: test_double_abs
263; CHECK: efdabs
264; CHECK: blr
265}
266
267; Function Attrs: nounwind readnone
268declare double @llvm.fabs.f64(double) #1
269
270define void @test_dnabs(double * %aa) #0 {
271  entry:
272    %0 = load double, double * %aa
273    %1 = tail call double @llvm.fabs.f64(double %0) #2
274    %sub = fsub double -0.000000e+00, %1
275    store double %sub, double * %aa
276    ret void
277}
278; CHECK-LABEL: @test_dnabs
279; CHECK: efdnabs
280; CHECK: blr
281
282define double @test_ddiv(double %a, double %b) {
283entry:
284  %v = fdiv double %a, %b
285  ret double %v
286
287; CHECK-LABEL: test_ddiv
288; CHECK: efddiv
289; CHECK: blr
290}
291
292define double @test_dmul(double %a, double %b) {
293  entry:
294  %v = fmul double %a, %b
295  ret double %v
296; CHECK-LABEL @test_dmul
297; CHECK: efdmul
298; CHECK: blr
299}
300
301define double @test_dadd(double %a, double %b) {
302  entry:
303  %v = fadd double %a, %b
304  ret double %v
305; CHECK-LABEL @test_dadd
306; CHECK: efdadd
307; CHECK: blr
308}
309
310define double @test_dsub(double %a, double %b) {
311  entry:
312  %v = fsub double %a, %b
313  ret double %v
314; CHECK-LABEL @test_dsub
315; CHECK: efdsub
316; CHECK: blr
317}
318
319define double @test_dneg(double %a) {
320  entry:
321  %v = fsub double -0.0, %a
322  ret double %v
323
324; CHECK-LABEL @test_dneg
325; CHECK: blr
326}
327
328define double @test_stod(float %a) {
329  entry:
330  %v = fpext float %a to double
331  ret double %v
332; CHECK-LABEL: test_stod
333; CHECK: efdcfs
334; CHECK: blr
335}
336
337; (un)ordered tests are expanded to une and oeq so verify
338define i1 @test_dcmpuno(double %a, double %b) {
339  entry:
340  %r = fcmp uno double %a, %b
341  ret i1 %r
342; CHECK-LABEL: test_dcmpuno
343; CHECK: efdcmpeq
344; CHECK: efdcmpeq
345; CHECK: crand
346; CHECK: blr
347}
348
349define i1 @test_dcmpord(double %a, double %b) {
350  entry:
351  %r = fcmp ord double %a, %b
352  ret i1 %r
353; CHECK-LABEL: test_dcmpord
354; CHECK: efdcmpeq
355; CHECK: efdcmpeq
356; CHECK: crnand
357; CHECK: blr
358}
359
360define i1 @test_dcmpgt(double %a, double %b) {
361  entry:
362  %r = fcmp ogt double %a, %b
363  ret i1 %r
364; CHECK-LABEL: test_dcmpgt
365; CHECK: efdcmpgt
366; CHECK: blr
367}
368
369define i1 @test_dcmpugt(double %a, double %b) {
370  entry:
371  %r = fcmp ugt double %a, %b
372  ret i1 %r
373; CHECK-LABEL: test_dcmpugt
374; CHECK: efdcmpgt
375; CHECK: blr
376}
377
378define i1 @test_dcmple(double %a, double %b) {
379  entry:
380  %r = fcmp ole double %a, %b
381  ret i1 %r
382; CHECK-LABEL: test_dcmple
383; CHECK: efdcmpgt
384; CHECK: blr
385}
386
387define i1 @test_dcmpule(double %a, double %b) {
388  entry:
389  %r = fcmp ule double %a, %b
390  ret i1 %r
391; CHECK-LABEL: test_dcmpule
392; CHECK: efdcmpgt
393; CHECK: blr
394}
395
396define i1 @test_dcmpeq(double %a, double %b) {
397  entry:
398  %r = fcmp oeq double %a, %b
399  ret i1 %r
400; CHECK-LABEL: test_dcmpeq
401; CHECK: efdcmpeq
402; CHECK: blr
403}
404
405define i1 @test_dcmpueq(double %a, double %b) {
406  entry:
407  %r = fcmp ueq double %a, %b
408  ret i1 %r
409; CHECK-LABEL: test_dcmpueq
410; CHECK: efdcmpeq
411; CHECK: blr
412}
413
414define i1 @test_dcmpne(double %a, double %b) {
415  entry:
416  %r = fcmp one double %a, %b
417  ret i1 %r
418; CHECK-LABEL: test_dcmpne
419; CHECK: efdcmpeq
420; CHECK: blr
421}
422
423define i1 @test_dcmpune(double %a, double %b) {
424  entry:
425  %r = fcmp une double %a, %b
426  ret i1 %r
427; CHECK-LABEL: test_dcmpune
428; CHECK: efdcmpeq
429; CHECK: blr
430}
431
432define i1 @test_dcmplt(double %a, double %b) {
433  entry:
434  %r = fcmp olt double %a, %b
435  ret i1 %r
436; CHECK-LABEL: test_dcmplt
437; CHECK: efdcmplt
438; CHECK: blr
439}
440
441define i1 @test_dcmpult(double %a, double %b) {
442  entry:
443  %r = fcmp ult double %a, %b
444  ret i1 %r
445; CHECK-LABEL: test_dcmpult
446; CHECK: efdcmplt
447; CHECK: blr
448}
449
450define i1 @test_dcmpge(double %a, double %b) {
451  entry:
452  %r = fcmp oge double %a, %b
453  ret i1 %r
454; CHECK-LABEL: test_dcmpge
455; CHECK: efdcmplt
456; CHECK: blr
457}
458
459define i1 @test_dcmpuge(double %a, double %b) {
460  entry:
461  %r = fcmp uge double %a, %b
462  ret i1 %r
463; CHECK-LABEL: test_dcmpuge
464; CHECK: efdcmplt
465; CHECK: blr
466}
467
468define double @test_dselect(double %a, double %b, i1 %c) {
469entry:
470  %r = select i1 %c, double %a, double %b
471  ret double %r
472; CHECK-LABEL: test_dselect
473; CHECK: andi.
474; CHECK: bc
475; CHECK: evldd
476; CHECK: b
477; CHECK: evldd
478; CHECK: evstdd
479; CHECK: blr
480}
481
482define i32 @test_dtoui(double %a) {
483entry:
484  %v = fptoui double %a to i32
485  ret i32 %v
486; CHECK-LABEL: test_dtoui
487; CHECK: efdctuiz
488}
489
490define i32 @test_dtosi(double %a) {
491entry:
492  %v = fptosi double %a to i32
493  ret i32 %v
494; CHECK-LABEL: test_dtosi
495; CHECK: efdctsiz
496}
497
498define double @test_dfromui(i32 %a) {
499entry:
500  %v = uitofp i32 %a to double
501  ret double %v
502; CHECK-LABEL: test_dfromui
503; CHECK: efdcfui
504}
505
506define double @test_dfromsi(i32 %a) {
507entry:
508  %v = sitofp i32 %a to double
509  ret double %v
510; CHECK-LABEL: test_dfromsi
511; CHECK: efdcfsi
512}
513
514define i32 @test_dasmconst(double %x) {
515entry:
516  %x.addr = alloca double, align 8
517  store double %x, double* %x.addr, align 8
518  %0 = load double, double* %x.addr, align 8
519  %1 = call i32 asm sideeffect "efdctsi $0, $1", "=d,d"(double %0)
520  ret i32 %1
521; CHECK-LABEL: test_dasmconst
522; CHECK: evldd
523; CHECK: #APP
524; CHECK: efdctsi
525; CHECK: #NO_APP
526}
527
528define double @test_spill(double %a) nounwind {
529entry:
530  %0 = fadd double %a, %a
531  call void asm sideeffect "","~{r0},~{r3},~{s4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{r16},~{r17},~{r18},~{r19},~{r20},~{r21},~{r22},~{r23},~{r24},~{r25},~{r26},~{r27},~{r28},~{r29},~{r30},~{r31}"() nounwind
532  %1 = fadd double %0, 3.14159
533  br label %return
534
535return:
536  ret double %1
537
538; CHECK-LABEL: test_spill
539; CHECK: efdadd
540; CHECK: evstdd
541; CHECK: evldd
542}
543