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