xref: /llvm-project/llvm/test/CodeGen/SPARC/fp128.ll (revision 728490257ecc09ada707a0390303bd3c61027a53)
1; RUN: llc < %s -mtriple=sparc -mattr=hard-quad-float | FileCheck %s --check-prefix=CHECK --check-prefix=HARD --check-prefix=BE
2; RUN: llc < %s -mtriple=sparcel -mattr=hard-quad-float | FileCheck %s --check-prefix=CHECK --check-prefix=HARD --check-prefix=EL
3; RUN: llc < %s -mtriple=sparc -mattr=-hard-quad-float -verify-machineinstrs | FileCheck %s --check-prefix=CHECK --check-prefix=SOFT --check-prefix=BE
4; RUN: llc < %s -mtriple=sparcel -mattr=-hard-quad-float | FileCheck %s --check-prefix=CHECK --check-prefix=SOFT --check-prefix=EL
5
6; CHECK-LABEL: f128_ops:
7; CHECK:      ldd
8; CHECK:      ldd
9; CHECK:      ldd
10; CHECK:      ldd
11; HARD:       faddq [[R0:.+]],  [[R1:.+]],  [[R2:.+]]
12; HARD:       fsubq [[R2]], [[R3:.+]], [[R4:.+]]
13; HARD:       fmulq [[R4]], [[R5:.+]], [[R6:.+]]
14; HARD:       fdivq [[R6]], [[R2]]
15; SOFT:       call _Q_add
16; SOFT:       unimp 16
17; SOFT:       call _Q_sub
18; SOFT:       unimp 16
19; SOFT:       call _Q_mul
20; SOFT:       unimp 16
21; SOFT:       call _Q_div
22; SOFT:       unimp 16
23; CHECK:      std
24; CHECK:      std
25
26define void @f128_ops(ptr noalias sret(fp128) %scalar.result, ptr byval(fp128) %a, ptr byval(fp128) %b, ptr byval(fp128) %c, ptr byval(fp128) %d) {
27entry:
28  %0 = load fp128, ptr %a, align 8
29  %1 = load fp128, ptr %b, align 8
30  %2 = load fp128, ptr %c, align 8
31  %3 = load fp128, ptr %d, align 8
32  %4 = fadd fp128 %0, %1
33  %5 = fsub fp128 %4, %2
34  %6 = fmul fp128 %5, %3
35  %7 = fdiv fp128 %6, %4
36  store fp128 %7, ptr %scalar.result, align 8
37  ret void
38}
39
40; CHECK-LABEL: f128_spill:
41; CHECK:       std %f{{.+}}, [%[[S0:.+]]]
42; CHECK:       std %f{{.+}}, [%[[S1:.+]]]
43; CHECK-DAG:   ldd [%[[S0]]], %f{{.+}}
44; CHECK-DAG:   ldd [%[[S1]]], %f{{.+}}
45; CHECK:       jmp {{%[oi]7}}+12
46
47define void @f128_spill(ptr noalias sret(fp128) %scalar.result, ptr byval(fp128) %a) {
48entry:
49  %0 = load fp128, ptr %a, align 8
50  call void asm sideeffect "", "~{f0},~{f1},~{f2},~{f3},~{f4},~{f5},~{f6},~{f7},~{f8},~{f9},~{f10},~{f11},~{f12},~{f13},~{f14},~{f15},~{f16},~{f17},~{f18},~{f19},~{f20},~{f21},~{f22},~{f23},~{f24},~{f25},~{f26},~{f27},~{f28},~{f29},~{f30},~{f31}"()
51  store fp128 %0, ptr %scalar.result, align 8
52  ret void
53}
54
55; CHECK-LABEL: f128_spill_large:
56; CHECK:       sethi 4, %g1
57; CHECK:       std %f{{.+}}, [%fp+-16]
58; CHECK-NEXT:  std %f{{.+}}, [%fp+-8]
59; CHECK:       ldd [%fp+-16], %f{{.+}}
60; CHECK-NEXT:  ldd [%fp+-8], %f{{.+}}
61
62define void @f128_spill_large(ptr noalias sret(<251 x fp128>) %scalar.result, ptr byval(<251 x fp128>) %a) {
63entry:
64  %0 = load <251 x fp128>, ptr %a, align 8
65  call void asm sideeffect "", "~{f0},~{f1},~{f2},~{f3},~{f4},~{f5},~{f6},~{f7},~{f8},~{f9},~{f10},~{f11},~{f12},~{f13},~{f14},~{f15},~{f16},~{f17},~{f18},~{f19},~{f20},~{f21},~{f22},~{f23},~{f24},~{f25},~{f26},~{f27},~{f28},~{f29},~{f30},~{f31}"()
66  store <251 x fp128> %0, ptr %scalar.result, align 8
67  ret void
68}
69
70; CHECK-LABEL: f128_compare:
71; HARD:       fcmpq
72; HARD-NEXT:  nop
73; SOFT:       _Q_cmp
74
75define i32 @f128_compare(ptr byval(fp128) %f0, ptr byval(fp128) %f1, i32 %a, i32 %b) {
76entry:
77   %0 = load fp128, ptr %f0, align 8
78   %1 = load fp128, ptr %f1, align 8
79   %cond = fcmp ult fp128 %0, %1
80   %ret = select i1 %cond, i32 %a, i32 %b
81   ret i32 %ret
82}
83
84; CHECK-LABEL: f128_compare2:
85; HARD:        fcmpq
86; HARD:        fb{{ule|g}}
87; SOFT:       _Q_cmp
88; SOFT:       cmp
89
90define i32 @f128_compare2(ptr byval(fp128) %f0) {
91entry:
92  %0 = load fp128, ptr %f0, align 8
93  %1 = fcmp ogt fp128 %0, 0xL00000000000000000000000000000000
94  br i1 %1, label %"5", label %"7"
95
96"5":                                              ; preds = %entry
97  ret i32 0
98
99"7":                                              ; preds = %entry
100  ret i32 1
101}
102
103
104; CHECK-LABEL: f128_abs:
105; CHECK:       ldd [%o0], %f0
106; CHECK:       ldd [%o0+8], %f2
107; BE:          fabss %f0, %f0
108; EL:          fabss %f3, %f3
109
110define void @f128_abs(ptr noalias sret(fp128) %scalar.result, ptr byval(fp128) %a) {
111entry:
112  %0 = load fp128, ptr %a, align 8
113  %1 = tail call fp128 @llvm.fabs.f128(fp128 %0)
114  store fp128 %1, ptr %scalar.result, align 8
115  ret void
116}
117
118declare fp128 @llvm.fabs.f128(fp128) nounwind readonly
119
120; CHECK-LABEL: int_to_f128:
121; HARD:       fitoq
122; SOFT:       _Q_itoq
123; SOFT:       unimp 16
124
125define void @int_to_f128(ptr noalias sret(fp128) %scalar.result, i32 %i) {
126entry:
127  %0 = sitofp i32 %i to fp128
128  store fp128 %0, ptr %scalar.result, align 8
129  ret void
130}
131
132; CHECK-LABEL: fp128_unaligned:
133; CHECK:       ldub
134; HARD:        faddq
135; SOFT:       call _Q_add
136; SOFT:       unimp 16
137; CHECK:       stb
138; CHECK:       ret
139
140define void @fp128_unaligned(ptr %a, ptr %b, ptr %c) {
141entry:
142  %0 = load fp128, ptr %a, align 1
143  %1 = load fp128, ptr %b, align 1
144  %2 = fadd fp128 %0, %1
145  store fp128 %2, ptr %c, align 1
146  ret void
147}
148
149; CHECK-LABEL: uint_to_f128:
150; HARD:       fdtoq
151; SOFT:       _Q_utoq
152; SOFT:       unimp 16
153
154define void @uint_to_f128(ptr noalias sret(fp128) %scalar.result, i32 %i) {
155entry:
156  %0 = uitofp i32 %i to fp128
157  store fp128 %0, ptr %scalar.result, align 8
158  ret void
159}
160
161; CHECK-LABEL: f128_to_i32:
162; HARD:       fqtoi
163; HARD:       fqtoi
164; SOFT:       call _Q_qtou
165; SOFT:       call _Q_qtoi
166
167
168define i32 @f128_to_i32(ptr %a, ptr %b) {
169entry:
170  %0 = load fp128, ptr %a, align 8
171  %1 = load fp128, ptr %b, align 8
172  %2 = fptoui fp128 %0 to i32
173  %3 = fptosi fp128 %1 to i32
174  %4 = add i32 %2, %3
175  ret i32 %4
176}
177
178; CHECK-LABEL:   test_itoq_qtoi
179; HARD-DAG:      call _Q_lltoq
180; HARD-DAG:      call _Q_qtoll
181; HARD-DAG:      fitoq
182; HARD-DAG:      fqtoi
183; SOFT-DAG:      call _Q_lltoq
184; SOFT-DAG:      unimp 16
185; SOFT-DAG:      call _Q_qtoll
186; SOFT-DAG:      call _Q_itoq
187; SOFT-DAG:      unimp 16
188; SOFT-DAG:      call _Q_qtoi
189
190define void @test_itoq_qtoi(i64 %a, i32 %b, ptr %c, ptr %d, ptr %ptr0, ptr %ptr1) {
191entry:
192  %0 = sitofp i64 %a to fp128
193  store  fp128 %0, ptr %ptr1, align 8
194  %cval = load fp128, ptr %c, align 8
195  %1 = fptosi fp128 %cval to i64
196  store  i64 %1, ptr %ptr0, align 8
197  %2 = sitofp i32 %b to fp128
198  store  fp128 %2, ptr %ptr1, align 8
199  %dval = load fp128, ptr %d, align 8
200  %3 = fptosi fp128 %dval to i32
201  %4 = bitcast ptr %ptr0 to ptr
202  store  i32 %3, ptr %4, align 8
203  ret void
204}
205
206; CHECK-LABEL:   test_utoq_qtou:
207; CHECK-DAG:     call _Q_ulltoq
208; CHECK-DAG:     call _Q_qtoull
209; HARD-DAG:      fdtoq
210; HARD-DAG:      fqtoi
211; SOFT-DAG:      call _Q_utoq
212; SOFT-DAG:      unimp 16
213; SOFT-DAG:      call _Q_qtou
214
215define void @test_utoq_qtou(i64 %a, i32 %b, ptr %c, ptr %d, ptr %ptr0, ptr %ptr1) {
216entry:
217  %0 = uitofp i64 %a to fp128
218  store  fp128 %0, ptr %ptr1, align 8
219  %cval = load fp128, ptr %c, align 8
220  %1 = fptoui fp128 %cval to i64
221  store  i64 %1, ptr %ptr0, align 8
222  %2 = uitofp i32 %b to fp128
223  store  fp128 %2, ptr %ptr1, align 8
224  %dval = load fp128, ptr %d, align 8
225  %3 = fptoui fp128 %dval to i32
226  %4 = bitcast ptr %ptr0 to ptr
227  store  i32 %3, ptr %4, align 8
228  ret void
229}
230
231; CHECK-LABEL: f128_neg:
232; CHECK:       ldd [%o0], %f0
233; CHECK:       ldd [%o0+8], %f2
234; BE:          fnegs %f0, %f0
235; EL:          fnegs %f3, %f3
236
237define void @f128_neg(ptr noalias sret(fp128) %scalar.result, ptr byval(fp128) %a) {
238entry:
239  %0 = load fp128, ptr %a, align 8
240  %1 = fsub fp128 0xL00000000000000008000000000000000, %0
241  store fp128 %1, ptr %scalar.result, align 8
242  ret void
243}
244