1 /* Automatic switching between software and hardware IEEE 128-bit
2 floating-point emulation for PowerPC.
3
4 Copyright (C) 2016-2021 Free Software Foundation, Inc.
5 This file is part of the GNU C Library.
6 Contributed by Michael Meissner (meissner@linux.vnet.ibm.com)
7 Code is based on the main soft-fp library written by:
8 Richard Henderson (rth@cygnus.com) and
9 Jakub Jelinek (jj@ultra.linux.cz).
10
11 The GNU C Library is free software; you can redistribute it and/or
12 modify it under the terms of the GNU Lesser General Public
13 License as published by the Free Software Foundation; either
14 version 2.1 of the License, or (at your option) any later version.
15
16 In addition to the permissions in the GNU Lesser General Public
17 License, the Free Software Foundation gives you unlimited
18 permission to link the compiled version of this file into
19 combinations with other programs, and to distribute those
20 combinations without any restriction coming from the use of this
21 file. (The Lesser General Public License restrictions do apply in
22 other respects; for example, they cover modification of the file,
23 and distribution when not linked into a combine executable.)
24
25 The GNU C Library is distributed in the hope that it will be useful,
26 but WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 Lesser General Public License for more details.
29
30 You should have received a copy of the GNU Lesser General Public
31 License along with the GNU C Library; if not, see
32 <http://www.gnu.org/licenses/>. */
33
34 #include <soft-fp.h>
35 #include <quad-float128.h>
36 #include <string.h>
37 #include <stdlib.h>
38 #include <ctype.h>
39
40 #ifndef FLOAT128_HW_INSNS
41 #error "float128-ifunc.c needs access to ISA 3.0 instructions and ifunc"
42 #endif
43
44 #ifdef __FLOAT128_HARDWARE__
45 #error "This module must not be compiled with IEEE 128-bit hardware support"
46 #endif
47
48 #define SW_OR_HW(SW, HW) (__builtin_cpu_supports ("ieee128") ? HW : SW)
49 #ifdef FLOAT128_HW_INSNS_ISA3_1
50 #define SW_OR_HW_ISA3_1(SW, HW) (__builtin_cpu_supports ("arch_3_1") ? HW : SW)
51 #endif
52
53 /* Resolvers. */
__typeof__(__addkf3_sw)54 static __typeof__ (__addkf3_sw) *
55 __addkf3_resolve (void)
56 {
57 return SW_OR_HW (__addkf3_sw, __addkf3_hw);
58 }
59
__typeof__(__subkf3_sw)60 static __typeof__ (__subkf3_sw) *
61 __subkf3_resolve (void)
62 {
63 return SW_OR_HW (__subkf3_sw, __subkf3_hw);
64 }
65
__typeof__(__mulkf3_sw)66 static __typeof__ (__mulkf3_sw) *
67 __mulkf3_resolve (void)
68 {
69 return SW_OR_HW (__mulkf3_sw, __mulkf3_hw);
70 }
71
__typeof__(__divkf3_sw)72 static __typeof__ (__divkf3_sw) *
73 __divkf3_resolve (void)
74 {
75 return SW_OR_HW (__divkf3_sw, __divkf3_hw);
76 }
77
__typeof__(__negkf2_sw)78 static __typeof__ (__negkf2_sw) *
79 __negkf2_resolve (void)
80 {
81 return SW_OR_HW (__negkf2_sw, __negkf2_hw);
82 }
83
__typeof__(__powikf2_sw)84 static __typeof__ (__powikf2_sw) *
85 __powikf2_resolve (void)
86 {
87 return SW_OR_HW (__powikf2_sw, __powikf2_hw);
88 }
89
__typeof__(__floatsikf_sw)90 static __typeof__ (__floatsikf_sw) *
91 __floatsikf_resolve (void)
92 {
93 return SW_OR_HW (__floatsikf_sw, __floatsikf_hw);
94 }
95
__typeof__(__floatdikf_sw)96 static __typeof__ (__floatdikf_sw) *
97 __floatdikf_resolve (void)
98 {
99 return SW_OR_HW (__floatdikf_sw, __floatdikf_hw);
100 }
101
102 #ifdef FLOAT128_HW_INSNS_ISA3_1
__typeof__(__floattikf_sw)103 static __typeof__ (__floattikf_sw) *
104 __floattikf_resolve (void)
105 {
106 return SW_OR_HW_ISA3_1 (__floattikf_sw, __floattikf_hw);
107 }
108
__typeof__(__floatuntikf_sw)109 static __typeof__ (__floatuntikf_sw) *
110 __floatuntikf_resolve (void)
111 {
112 return SW_OR_HW_ISA3_1 (__floatuntikf_sw, __floatuntikf_hw);
113 }
114 #endif
115
__typeof__(__floatunsikf_sw)116 static __typeof__ (__floatunsikf_sw) *
117 __floatunsikf_resolve (void)
118 {
119 return SW_OR_HW (__floatunsikf_sw, __floatunsikf_hw);
120 }
121
__typeof__(__floatundikf_sw)122 static __typeof__ (__floatundikf_sw) *
123 __floatundikf_resolve (void)
124 {
125 return SW_OR_HW (__floatundikf_sw, __floatundikf_hw);
126 }
127
128 #ifdef FLOAT128_HW_INSNS_ISA3_1
__typeof__(__fixkfti_sw)129 static __typeof__ (__fixkfti_sw) *
130 __fixkfti_resolve (void)
131 {
132 return SW_OR_HW_ISA3_1 (__fixkfti_sw, __fixkfti_hw);
133 }
134
__typeof__(__fixunskfti_sw)135 static __typeof__ (__fixunskfti_sw) *
136 __fixunskfti_resolve (void)
137 {
138 return SW_OR_HW_ISA3_1 (__fixunskfti_sw, __fixunskfti_hw);
139 }
140 #endif
141
__typeof__(__fixkfsi_sw)142 static __typeof__ (__fixkfsi_sw) *
143 __fixkfsi_resolve (void)
144 {
145 return SW_OR_HW (__fixkfsi_sw, __fixkfsi_hw);
146 }
147
__typeof__(__fixkfdi_sw)148 static __typeof__ (__fixkfdi_sw) *
149 __fixkfdi_resolve (void)
150 {
151 return SW_OR_HW (__fixkfdi_sw, __fixkfdi_hw);
152 }
153
__typeof__(__fixunskfsi_sw)154 static __typeof__ (__fixunskfsi_sw) *
155 __fixunskfsi_resolve (void)
156 {
157 return SW_OR_HW (__fixunskfsi_sw, __fixunskfsi_hw);
158 }
159
__typeof__(__fixunskfdi_sw)160 static __typeof__ (__fixunskfdi_sw) *
161 __fixunskfdi_resolve (void)
162 {
163 return SW_OR_HW (__fixunskfdi_sw, __fixunskfdi_hw);
164 }
165
__typeof__(__extendsfkf2_sw)166 static __typeof__ (__extendsfkf2_sw) *
167 __extendsfkf2_resolve (void)
168 {
169 return SW_OR_HW (__extendsfkf2_sw, __extendsfkf2_hw);
170 }
171
__typeof__(__extenddfkf2_sw)172 static __typeof__ (__extenddfkf2_sw) *
173 __extenddfkf2_resolve (void)
174 {
175 return SW_OR_HW (__extenddfkf2_sw, __extenddfkf2_hw);
176 }
177
__typeof__(__trunckfsf2_sw)178 static __typeof__ (__trunckfsf2_sw) *
179 __trunckfsf2_resolve (void)
180 {
181 return SW_OR_HW (__trunckfsf2_sw, __trunckfsf2_hw);
182 }
183
__typeof__(__trunckfdf2_sw)184 static __typeof__ (__trunckfdf2_sw) *
185 __trunckfdf2_resolve (void)
186 {
187 return (void *) SW_OR_HW (__trunckfdf2_sw, __trunckfdf2_hw);
188 }
189
__typeof__(__extendkftf2_sw)190 static __typeof__ (__extendkftf2_sw) *
191 __extendkftf2_resolve (void)
192 {
193 return SW_OR_HW (__extendkftf2_sw, __extendkftf2_hw);
194 }
195
__typeof__(__trunctfkf2_sw)196 static __typeof__ (__trunctfkf2_sw) *
197 __trunctfkf2_resolve (void)
198 {
199 return SW_OR_HW (__trunctfkf2_sw, __trunctfkf2_hw);
200 }
201
__typeof__(__mulkc3_sw)202 static __typeof__ (__mulkc3_sw) *
203 __mulkc3_resolve (void)
204 {
205 return SW_OR_HW (__mulkc3_sw, __mulkc3_hw);
206 }
207
__typeof__(__divkc3_sw)208 static __typeof__ (__divkc3_sw) *
209 __divkc3_resolve (void)
210 {
211 return SW_OR_HW (__divkc3_sw, __divkc3_hw);
212 }
213
__typeof__(__eqkf2_sw)214 static __typeof__ (__eqkf2_sw) *
215 __eqkf2_resolve (void)
216 {
217 return SW_OR_HW (__eqkf2_sw, __eqkf2_hw);
218 }
219
__typeof__(__gekf2_sw)220 static __typeof__ (__gekf2_sw) *
221 __gekf2_resolve (void)
222 {
223 return SW_OR_HW (__gekf2_sw, __gekf2_hw);
224 }
225
__typeof__(__lekf2_sw)226 static __typeof__ (__lekf2_sw) *
227 __lekf2_resolve (void)
228 {
229 return SW_OR_HW (__lekf2_sw, __lekf2_hw);
230 }
231
__typeof__(__unordkf2_sw)232 static __typeof__ (__unordkf2_sw) *
233 __unordkf2_resolve (void)
234 {
235 return SW_OR_HW (__unordkf2_sw, __unordkf2_hw);
236 }
237
238 /* Resolve __nekf2, __gtkf2, __ltkf2 like __eqkf2, __gekf2, and __lekf2, since
239 the functions return the same values. */
240
__typeof__(__eqkf2_sw)241 static __typeof__ (__eqkf2_sw) *
242 __nekf2_resolve (void)
243 {
244 return SW_OR_HW (__eqkf2_sw, __eqkf2_hw);
245 }
246
__typeof__(__eqkf2_sw)247 static __typeof__ (__eqkf2_sw) *
248 __gtkf2_resolve (void)
249 {
250 return SW_OR_HW (__gekf2_sw, __gekf2_hw);
251 }
252
__typeof__(__eqkf2_sw)253 static __typeof__ (__eqkf2_sw) *
254 __ltkf2_resolve (void)
255 {
256 return SW_OR_HW (__lekf2_sw, __lekf2_hw);
257 }
258
259
260
261 /* Ifunc definitions. */
262 TFtype __addkf3 (TFtype, TFtype)
263 __attribute__ ((__ifunc__ ("__addkf3_resolve")));
264
265 TFtype __subkf3 (TFtype, TFtype)
266 __attribute__ ((__ifunc__ ("__subkf3_resolve")));
267
268 TFtype __mulkf3 (TFtype, TFtype)
269 __attribute__ ((__ifunc__ ("__mulkf3_resolve")));
270
271 TFtype __divkf3 (TFtype, TFtype)
272 __attribute__ ((__ifunc__ ("__divkf3_resolve")));
273
274 TFtype __negkf2 (TFtype)
275 __attribute__ ((__ifunc__ ("__negkf2_resolve")));
276
277 TFtype __powikf2 (TFtype, SItype_ppc)
278 __attribute__ ((__ifunc__ ("__powikf2_resolve")));
279
280 CMPtype __eqkf2 (TFtype, TFtype)
281 __attribute__ ((__ifunc__ ("__eqkf2_resolve")));
282
283 CMPtype __nekf2 (TFtype, TFtype)
284 __attribute__ ((__ifunc__ ("__nekf2_resolve")));
285
286 CMPtype __gekf2 (TFtype, TFtype)
287 __attribute__ ((__ifunc__ ("__gekf2_resolve")));
288
289 CMPtype __gtkf2 (TFtype, TFtype)
290 __attribute__ ((__ifunc__ ("__gtkf2_resolve")));
291
292 CMPtype __lekf2 (TFtype, TFtype)
293 __attribute__ ((__ifunc__ ("__lekf2_resolve")));
294
295 CMPtype __ltkf2 (TFtype, TFtype)
296 __attribute__ ((__ifunc__ ("__ltkf2_resolve")));
297
298 CMPtype __unordkf2 (TFtype, TFtype)
299 __attribute__ ((__ifunc__ ("__unordkf2_resolve")));
300
301 TFtype __extendsfkf2 (float)
302 __attribute__ ((__ifunc__ ("__extendsfkf2_resolve")));
303
304 TFtype __extenddfkf2 (double)
305 __attribute__ ((__ifunc__ ("__extenddfkf2_resolve")));
306
307 float __trunckfsf2 (TFtype)
308 __attribute__ ((__ifunc__ ("__trunckfsf2_resolve")));
309
310 double __trunckfdf2 (TFtype)
311 __attribute__ ((__ifunc__ ("__trunckfdf2_resolve")));
312
313 SItype_ppc __fixkfsi (TFtype)
314 __attribute__ ((__ifunc__ ("__fixkfsi_resolve")));
315
316 DItype_ppc __fixkfdi (TFtype)
317 __attribute__ ((__ifunc__ ("__fixkfdi_resolve")));
318
319 USItype_ppc __fixunskfsi (TFtype)
320 __attribute__ ((__ifunc__ ("__fixunskfsi_resolve")));
321
322 UDItype_ppc __fixunskfdi (TFtype)
323 __attribute__ ((__ifunc__ ("__fixunskfdi_resolve")));
324
325 TFtype __floatsikf (SItype_ppc)
326 __attribute__ ((__ifunc__ ("__floatsikf_resolve")));
327
328 TFtype __floatdikf (DItype_ppc)
329 __attribute__ ((__ifunc__ ("__floatdikf_resolve")));
330
331 #ifdef FLOAT128_HW_INSNS_ISA3_1
332 TFtype __floattikf (TItype_ppc)
333 __attribute__ ((__ifunc__ ("__floattikf_resolve")));
334
335 TFtype __floatuntikf (UTItype_ppc)
336 __attribute__ ((__ifunc__ ("__floatuntikf_resolve")));
337
338 TItype_ppc __fixkfti (TFtype)
339 __attribute__ ((__ifunc__ ("__fixkfti_resolve")));
340
341 UTItype_ppc __fixunskfti (TFtype)
342 __attribute__ ((__ifunc__ ("__fixunskfti_resolve")));
343 #endif
344
345 TFtype __floatunsikf (USItype_ppc)
346 __attribute__ ((__ifunc__ ("__floatunsikf_resolve")));
347
348 TFtype __floatundikf (UDItype_ppc)
349 __attribute__ ((__ifunc__ ("__floatundikf_resolve")));
350
351 IBM128_TYPE __extendkftf2 (TFtype)
352 __attribute__ ((__ifunc__ ("__extendkftf2_resolve")));
353
354 TFtype __trunctfkf2 (IBM128_TYPE)
355 __attribute__ ((__ifunc__ ("__trunctfkf2_resolve")));
356
357 TCtype __mulkc3 (TFtype, TFtype, TFtype, TFtype)
358 __attribute__ ((__ifunc__ ("__mulkc3_resolve")));
359
360 TCtype __divkc3 (TFtype, TFtype, TFtype, TFtype)
361 __attribute__ ((__ifunc__ ("__divkc3_resolve")));
362