1; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips64 -soft-float -O1 \
2; RUN: -disable-mips-delay-filler < %s | FileCheck %s
3
4@gld0 = external global fp128
5@gld1 = external global fp128
6@gld2 = external global fp128
7@gf1 = external global float
8@gd1 = external global double
9
10; CHECK-LABEL: addLD:
11; CHECK: ld $25, %call16(__addtf3)
12
13define fp128 @addLD() {
14entry:
15  %0 = load fp128* @gld0, align 16
16  %1 = load fp128* @gld1, align 16
17  %add = fadd fp128 %0, %1
18  ret fp128 %add
19}
20
21; CHECK-LABEL: subLD:
22; CHECK: ld $25, %call16(__subtf3)
23
24define fp128 @subLD() {
25entry:
26  %0 = load fp128* @gld0, align 16
27  %1 = load fp128* @gld1, align 16
28  %sub = fsub fp128 %0, %1
29  ret fp128 %sub
30}
31
32; CHECK-LABEL: mulLD:
33; CHECK: ld $25, %call16(__multf3)
34
35define fp128 @mulLD() {
36entry:
37  %0 = load fp128* @gld0, align 16
38  %1 = load fp128* @gld1, align 16
39  %mul = fmul fp128 %0, %1
40  ret fp128 %mul
41}
42
43; CHECK-LABEL: divLD:
44; CHECK: ld $25, %call16(__divtf3)
45
46define fp128 @divLD() {
47entry:
48  %0 = load fp128* @gld0, align 16
49  %1 = load fp128* @gld1, align 16
50  %div = fdiv fp128 %0, %1
51  ret fp128 %div
52}
53
54; CHECK-LABEL: conv_LD_char:
55; CHECK: ld $25, %call16(__floatsitf)
56
57define fp128 @conv_LD_char(i8 signext %a) {
58entry:
59  %conv = sitofp i8 %a to fp128
60  ret fp128 %conv
61}
62
63; CHECK-LABEL: conv_LD_short:
64; CHECK: ld $25, %call16(__floatsitf)
65
66define fp128 @conv_LD_short(i16 signext %a) {
67entry:
68  %conv = sitofp i16 %a to fp128
69  ret fp128 %conv
70}
71
72; CHECK-LABEL: conv_LD_int:
73; CHECK: ld $25, %call16(__floatsitf)
74
75define fp128 @conv_LD_int(i32 %a) {
76entry:
77  %conv = sitofp i32 %a to fp128
78  ret fp128 %conv
79}
80
81; CHECK-LABEL: conv_LD_LL:
82; CHECK: ld $25, %call16(__floatditf)
83
84define fp128 @conv_LD_LL(i64 %a) {
85entry:
86  %conv = sitofp i64 %a to fp128
87  ret fp128 %conv
88}
89
90; CHECK-LABEL: conv_LD_UChar:
91; CHECK: ld $25, %call16(__floatunsitf)
92
93define fp128 @conv_LD_UChar(i8 zeroext %a) {
94entry:
95  %conv = uitofp i8 %a to fp128
96  ret fp128 %conv
97}
98
99; CHECK-LABEL: conv_LD_UShort:
100; CHECK: ld $25, %call16(__floatunsitf)
101
102define fp128 @conv_LD_UShort(i16 zeroext %a) {
103entry:
104  %conv = uitofp i16 %a to fp128
105  ret fp128 %conv
106}
107
108; CHECK-LABEL: conv_LD_UInt:
109; CHECK: ld $25, %call16(__floatunsitf)
110
111define fp128 @conv_LD_UInt(i32 %a) {
112entry:
113  %conv = uitofp i32 %a to fp128
114  ret fp128 %conv
115}
116
117; CHECK-LABEL: conv_LD_ULL:
118; CHECK: ld $25, %call16(__floatunditf)
119
120define fp128 @conv_LD_ULL(i64 %a) {
121entry:
122  %conv = uitofp i64 %a to fp128
123  ret fp128 %conv
124}
125
126; CHECK-LABEL: conv_char_LD:
127; CHECK: ld $25, %call16(__fixtfsi)
128
129define signext i8 @conv_char_LD(fp128 %a) {
130entry:
131  %conv = fptosi fp128 %a to i8
132  ret i8 %conv
133}
134
135; CHECK-LABEL: conv_short_LD:
136; CHECK: ld $25, %call16(__fixtfsi)
137
138define signext i16 @conv_short_LD(fp128 %a) {
139entry:
140  %conv = fptosi fp128 %a to i16
141  ret i16 %conv
142}
143
144; CHECK-LABEL: conv_int_LD:
145; CHECK: ld $25, %call16(__fixtfsi)
146
147define i32 @conv_int_LD(fp128 %a) {
148entry:
149  %conv = fptosi fp128 %a to i32
150  ret i32 %conv
151}
152
153; CHECK-LABEL: conv_LL_LD:
154; CHECK: ld $25, %call16(__fixtfdi)
155
156define i64 @conv_LL_LD(fp128 %a) {
157entry:
158  %conv = fptosi fp128 %a to i64
159  ret i64 %conv
160}
161
162; CHECK-LABEL: conv_UChar_LD:
163; CHECK: ld $25, %call16(__fixtfsi)
164
165define zeroext i8 @conv_UChar_LD(fp128 %a) {
166entry:
167  %conv = fptoui fp128 %a to i8
168  ret i8 %conv
169}
170
171; CHECK-LABEL: conv_UShort_LD:
172; CHECK: ld $25, %call16(__fixtfsi)
173
174define zeroext i16 @conv_UShort_LD(fp128 %a) {
175entry:
176  %conv = fptoui fp128 %a to i16
177  ret i16 %conv
178}
179
180; CHECK-LABEL: conv_UInt_LD:
181; CHECK: ld $25, %call16(__fixunstfsi)
182
183define i32 @conv_UInt_LD(fp128 %a) {
184entry:
185  %conv = fptoui fp128 %a to i32
186  ret i32 %conv
187}
188
189; CHECK-LABEL: conv_ULL_LD:
190; CHECK: ld $25, %call16(__fixunstfdi)
191
192define i64 @conv_ULL_LD(fp128 %a) {
193entry:
194  %conv = fptoui fp128 %a to i64
195  ret i64 %conv
196}
197
198; CHECK-LABEL: conv_LD_float:
199; CHECK: ld $25, %call16(__extendsftf2)
200
201define fp128 @conv_LD_float(float %a) {
202entry:
203  %conv = fpext float %a to fp128
204  ret fp128 %conv
205}
206
207; CHECK-LABEL: conv_LD_double:
208; CHECK: ld $25, %call16(__extenddftf2)
209
210define fp128 @conv_LD_double(double %a) {
211entry:
212  %conv = fpext double %a to fp128
213  ret fp128 %conv
214}
215
216; CHECK-LABEL: conv_float_LD:
217; CHECK: ld $25, %call16(__trunctfsf2)
218
219define float @conv_float_LD(fp128 %a) {
220entry:
221  %conv = fptrunc fp128 %a to float
222  ret float %conv
223}
224
225; CHECK-LABEL: conv_double_LD:
226; CHECK: ld $25, %call16(__trunctfdf2)
227
228define double @conv_double_LD(fp128 %a) {
229entry:
230  %conv = fptrunc fp128 %a to double
231  ret double %conv
232}
233
234; CHECK-LABEL:             libcall1_fabsl:
235; CHECK-DAG: ld      $[[R0:[0-9]+]], 8($[[R4:[0-9]+]])
236; CHECK-DAG: daddiu  $[[R1:[0-9]+]], $zero, 1
237; CHECK-DAG: dsll    $[[R2:[0-9]+]], $[[R1]], 63
238; CHECK-DAG: daddiu  $[[R3:[0-9]+]], $[[R2]], -1
239; CHECK-DAG: and     $4, $[[R0]], $[[R3]]
240; CHECK-DAG: ld      $2, 0($[[R4]])
241
242define fp128 @libcall1_fabsl() {
243entry:
244  %0 = load fp128* @gld0, align 16
245  %call = tail call fp128 @fabsl(fp128 %0) nounwind readnone
246  ret fp128 %call
247}
248
249declare fp128 @fabsl(fp128) #1
250
251; CHECK-LABEL: libcall1_ceill:
252; CHECK: ld $25, %call16(ceill)
253
254define fp128 @libcall1_ceill() {
255entry:
256  %0 = load fp128* @gld0, align 16
257  %call = tail call fp128 @ceill(fp128 %0) nounwind readnone
258  ret fp128 %call
259}
260
261declare fp128 @ceill(fp128) #1
262
263; CHECK-LABEL: libcall1_sinl:
264; CHECK: ld $25, %call16(sinl)
265
266define fp128 @libcall1_sinl() {
267entry:
268  %0 = load fp128* @gld0, align 16
269  %call = tail call fp128 @sinl(fp128 %0) nounwind
270  ret fp128 %call
271}
272
273declare fp128 @sinl(fp128) #2
274
275; CHECK-LABEL: libcall1_cosl:
276; CHECK: ld $25, %call16(cosl)
277
278define fp128 @libcall1_cosl() {
279entry:
280  %0 = load fp128* @gld0, align 16
281  %call = tail call fp128 @cosl(fp128 %0) nounwind
282  ret fp128 %call
283}
284
285declare fp128 @cosl(fp128) #2
286
287; CHECK-LABEL: libcall1_expl:
288; CHECK: ld $25, %call16(expl)
289
290define fp128 @libcall1_expl() {
291entry:
292  %0 = load fp128* @gld0, align 16
293  %call = tail call fp128 @expl(fp128 %0) nounwind
294  ret fp128 %call
295}
296
297declare fp128 @expl(fp128) #2
298
299; CHECK-LABEL: libcall1_exp2l:
300; CHECK: ld $25, %call16(exp2l)
301
302define fp128 @libcall1_exp2l() {
303entry:
304  %0 = load fp128* @gld0, align 16
305  %call = tail call fp128 @exp2l(fp128 %0) nounwind
306  ret fp128 %call
307}
308
309declare fp128 @exp2l(fp128) #2
310
311; CHECK-LABEL: libcall1_logl:
312; CHECK: ld $25, %call16(logl)
313
314define fp128 @libcall1_logl() {
315entry:
316  %0 = load fp128* @gld0, align 16
317  %call = tail call fp128 @logl(fp128 %0) nounwind
318  ret fp128 %call
319}
320
321declare fp128 @logl(fp128) #2
322
323; CHECK-LABEL: libcall1_log2l:
324; CHECK: ld $25, %call16(log2l)
325
326define fp128 @libcall1_log2l() {
327entry:
328  %0 = load fp128* @gld0, align 16
329  %call = tail call fp128 @log2l(fp128 %0) nounwind
330  ret fp128 %call
331}
332
333declare fp128 @log2l(fp128) #2
334
335; CHECK-LABEL: libcall1_log10l:
336; CHECK: ld $25, %call16(log10l)
337
338define fp128 @libcall1_log10l() {
339entry:
340  %0 = load fp128* @gld0, align 16
341  %call = tail call fp128 @log10l(fp128 %0) nounwind
342  ret fp128 %call
343}
344
345declare fp128 @log10l(fp128) #2
346
347; CHECK-LABEL: libcall1_nearbyintl:
348; CHECK: ld $25, %call16(nearbyintl)
349
350define fp128 @libcall1_nearbyintl() {
351entry:
352  %0 = load fp128* @gld0, align 16
353  %call = tail call fp128 @nearbyintl(fp128 %0) nounwind readnone
354  ret fp128 %call
355}
356
357declare fp128 @nearbyintl(fp128) #1
358
359; CHECK-LABEL: libcall1_floorl:
360; CHECK: ld $25, %call16(floorl)
361
362define fp128 @libcall1_floorl() {
363entry:
364  %0 = load fp128* @gld0, align 16
365  %call = tail call fp128 @floorl(fp128 %0) nounwind readnone
366  ret fp128 %call
367}
368
369declare fp128 @floorl(fp128) #1
370
371; CHECK-LABEL: libcall1_sqrtl:
372; CHECK: ld $25, %call16(sqrtl)
373
374define fp128 @libcall1_sqrtl() {
375entry:
376  %0 = load fp128* @gld0, align 16
377  %call = tail call fp128 @sqrtl(fp128 %0) nounwind
378  ret fp128 %call
379}
380
381declare fp128 @sqrtl(fp128) #2
382
383; CHECK-LABEL: libcall1_rintl:
384; CHECK: ld $25, %call16(rintl)
385
386define fp128 @libcall1_rintl() {
387entry:
388  %0 = load fp128* @gld0, align 16
389  %call = tail call fp128 @rintl(fp128 %0) nounwind readnone
390  ret fp128 %call
391}
392
393declare fp128 @rintl(fp128) #1
394
395; CHECK-LABEL: libcall_powil:
396; CHECK: ld $25, %call16(__powitf2)
397
398define fp128 @libcall_powil(fp128 %a, i32 %b) {
399entry:
400  %0 = tail call fp128 @llvm.powi.f128(fp128 %a, i32 %b)
401  ret fp128 %0
402}
403
404declare fp128 @llvm.powi.f128(fp128, i32) #3
405
406; CHECK-LABEL:     libcall2_copysignl:
407; CHECK-DAG: daddiu $[[R2:[0-9]+]], $zero, 1
408; CHECK-DAG: dsll   $[[R3:[0-9]+]], $[[R2]], 63
409; CHECK-DAG: ld     $[[R0:[0-9]+]], %got_disp(gld1)
410; CHECK-DAG: ld     $[[R1:[0-9]+]], 8($[[R0]])
411; CHECK-DAG: and    $[[R4:[0-9]+]], $[[R1]], $[[R3]]
412; CHECK-DAG: ld     $[[R5:[0-9]+]], %got_disp(gld0)
413; CHECK-DAG: ld     $[[R6:[0-9]+]], 8($[[R5]])
414; CHECK-DAG: daddiu $[[R7:[0-9]+]], $[[R3]], -1
415; CHECK-DAG: and    $[[R8:[0-9]+]], $[[R6]], $[[R7]]
416; CHECK-DAG: or     $4, $[[R8]], $[[R4]]
417; CHECK-DAG: ld     $2, 0($[[R5]])
418
419define fp128 @libcall2_copysignl() {
420entry:
421  %0 = load fp128* @gld0, align 16
422  %1 = load fp128* @gld1, align 16
423  %call = tail call fp128 @copysignl(fp128 %0, fp128 %1) nounwind readnone
424  ret fp128 %call
425}
426
427declare fp128 @copysignl(fp128, fp128) #1
428
429; CHECK-LABEL: libcall2_powl:
430; CHECK: ld $25, %call16(powl)
431
432define fp128 @libcall2_powl() {
433entry:
434  %0 = load fp128* @gld0, align 16
435  %1 = load fp128* @gld1, align 16
436  %call = tail call fp128 @powl(fp128 %0, fp128 %1) nounwind
437  ret fp128 %call
438}
439
440declare fp128 @powl(fp128, fp128) #2
441
442; CHECK-LABEL: libcall2_fmodl:
443; CHECK: ld $25, %call16(fmodl)
444
445define fp128 @libcall2_fmodl() {
446entry:
447  %0 = load fp128* @gld0, align 16
448  %1 = load fp128* @gld1, align 16
449  %call = tail call fp128 @fmodl(fp128 %0, fp128 %1) nounwind
450  ret fp128 %call
451}
452
453declare fp128 @fmodl(fp128, fp128) #2
454
455; CHECK-LABEL: libcall3_fmal:
456; CHECK: ld $25, %call16(fmal)
457
458define fp128 @libcall3_fmal() {
459entry:
460  %0 = load fp128* @gld0, align 16
461  %1 = load fp128* @gld2, align 16
462  %2 = load fp128* @gld1, align 16
463  %3 = tail call fp128 @llvm.fma.f128(fp128 %0, fp128 %2, fp128 %1)
464  ret fp128 %3
465}
466
467declare fp128 @llvm.fma.f128(fp128, fp128, fp128) #4
468
469; CHECK-LABEL: cmp_lt:
470; CHECK: ld $25, %call16(__lttf2)
471
472define i32 @cmp_lt(fp128 %a, fp128 %b) {
473entry:
474  %cmp = fcmp olt fp128 %a, %b
475  %conv = zext i1 %cmp to i32
476  ret i32 %conv
477}
478
479; CHECK-LABEL: cmp_le:
480; CHECK: ld $25, %call16(__letf2)
481
482define i32 @cmp_le(fp128 %a, fp128 %b) {
483entry:
484  %cmp = fcmp ole fp128 %a, %b
485  %conv = zext i1 %cmp to i32
486  ret i32 %conv
487}
488
489; CHECK-LABEL: cmp_gt:
490; CHECK: ld $25, %call16(__gttf2)
491
492define i32 @cmp_gt(fp128 %a, fp128 %b) {
493entry:
494  %cmp = fcmp ogt fp128 %a, %b
495  %conv = zext i1 %cmp to i32
496  ret i32 %conv
497}
498
499; CHECK-LABEL: cmp_ge:
500; CHECK: ld $25, %call16(__getf2)
501
502define i32 @cmp_ge(fp128 %a, fp128 %b) {
503entry:
504  %cmp = fcmp oge fp128 %a, %b
505  %conv = zext i1 %cmp to i32
506  ret i32 %conv
507}
508
509; CHECK-LABEL: cmp_eq:
510; CHECK: ld $25, %call16(__eqtf2)
511
512define i32 @cmp_eq(fp128 %a, fp128 %b) {
513entry:
514  %cmp = fcmp oeq fp128 %a, %b
515  %conv = zext i1 %cmp to i32
516  ret i32 %conv
517}
518
519; CHECK-LABEL: cmp_ne:
520; CHECK: ld $25, %call16(__netf2)
521
522define i32 @cmp_ne(fp128 %a, fp128 %b) {
523entry:
524  %cmp = fcmp une fp128 %a, %b
525  %conv = zext i1 %cmp to i32
526  ret i32 %conv
527}
528
529; CHECK-LABEL: load_LD_LD:
530; CHECK: ld $[[R0:[0-9]+]], %got_disp(gld1)
531; CHECK: ld $2, 0($[[R0]])
532; CHECK: ld $4, 8($[[R0]])
533
534define fp128 @load_LD_LD() {
535entry:
536  %0 = load fp128* @gld1, align 16
537  ret fp128 %0
538}
539
540; CHECK-LABEL: load_LD_float:
541; CHECK: ld   $[[R0:[0-9]+]], %got_disp(gf1)
542; CHECK: lw   $4, 0($[[R0]])
543; CHECK: ld   $25, %call16(__extendsftf2)
544; CHECK: jalr $25
545
546define fp128 @load_LD_float() {
547entry:
548  %0 = load float* @gf1, align 4
549  %conv = fpext float %0 to fp128
550  ret fp128 %conv
551}
552
553; CHECK-LABEL: load_LD_double:
554; CHECK: ld   $[[R0:[0-9]+]], %got_disp(gd1)
555; CHECK: ld   $4, 0($[[R0]])
556; CHECK: ld   $25, %call16(__extenddftf2)
557; CHECK: jalr $25
558
559define fp128 @load_LD_double() {
560entry:
561  %0 = load double* @gd1, align 8
562  %conv = fpext double %0 to fp128
563  ret fp128 %conv
564}
565
566; CHECK-LABEL: store_LD_LD:
567; CHECK: ld $[[R0:[0-9]+]], %got_disp(gld1)
568; CHECK: ld $[[R1:[0-9]+]], 0($[[R0]])
569; CHECK: ld $[[R2:[0-9]+]], 8($[[R0]])
570; CHECK: ld $[[R3:[0-9]+]], %got_disp(gld0)
571; CHECK: sd $[[R2]], 8($[[R3]])
572; CHECK: sd $[[R1]], 0($[[R3]])
573
574define void @store_LD_LD() {
575entry:
576  %0 = load fp128* @gld1, align 16
577  store fp128 %0, fp128* @gld0, align 16
578  ret void
579}
580
581; CHECK-LABEL: store_LD_float:
582; CHECK: ld   $[[R0:[0-9]+]], %got_disp(gld1)
583; CHECK: ld   $4, 0($[[R0]])
584; CHECK: ld   $5, 8($[[R0]])
585; CHECK: ld   $25, %call16(__trunctfsf2)
586; CHECK: jalr $25
587; CHECK: ld   $[[R1:[0-9]+]], %got_disp(gf1)
588; CHECK: sw   $2, 0($[[R1]])
589
590define void @store_LD_float() {
591entry:
592  %0 = load fp128* @gld1, align 16
593  %conv = fptrunc fp128 %0 to float
594  store float %conv, float* @gf1, align 4
595  ret void
596}
597
598; CHECK-LABEL: store_LD_double:
599; CHECK: ld   $[[R0:[0-9]+]], %got_disp(gld1)
600; CHECK: ld   $4, 0($[[R0]])
601; CHECK: ld   $5, 8($[[R0]])
602; CHECK: ld   $25, %call16(__trunctfdf2)
603; CHECK: jalr $25
604; CHECK: ld   $[[R1:[0-9]+]], %got_disp(gd1)
605; CHECK: sd   $2, 0($[[R1]])
606
607define void @store_LD_double() {
608entry:
609  %0 = load fp128* @gld1, align 16
610  %conv = fptrunc fp128 %0 to double
611  store double %conv, double* @gd1, align 8
612  ret void
613}
614
615; CHECK-LABEL: select_LD:
616; CHECK: movn $8, $6, $4
617; CHECK: movn $9, $7, $4
618; CHECK: move $2, $8
619; CHECK: move $4, $9
620
621define fp128 @select_LD(i32 %a, i64, fp128 %b, fp128 %c) {
622entry:
623  %tobool = icmp ne i32 %a, 0
624  %cond = select i1 %tobool, fp128 %b, fp128 %c
625  ret fp128 %cond
626}
627
628; CHECK-LABEL: selectCC_LD:
629; CHECK: move $[[R0:[0-9]+]], $11
630; CHECK: move $[[R1:[0-9]+]], $10
631; CHECK: move $[[R2:[0-9]+]], $9
632; CHECK: move $[[R3:[0-9]+]], $8
633; CHECK: ld   $25, %call16(__gttf2)($gp)
634; CHECK: jalr $25
635; CHECK: slti $1, $2, 1
636; CHECK: movz $[[R1]], $[[R3]], $1
637; CHECK: movz $[[R0]], $[[R2]], $1
638; CHECK: move $2, $[[R1]]
639; CHECK: move $4, $[[R0]]
640
641define fp128 @selectCC_LD(fp128 %a, fp128 %b, fp128 %c, fp128 %d) {
642entry:
643  %cmp = fcmp ogt fp128 %a, %b
644  %cond = select i1 %cmp, fp128 %c, fp128 %d
645  ret fp128 %cond
646}
647