1 /* Automatic switching between software and hardware IEEE 128-bit
2 floating-point emulation for PowerPC.
4 Copyright (C) 2016-2024 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).
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.
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.)
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.
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/>. */
35 #include <quad-float128.h>
40 #ifndef FLOAT128_HW_INSNS
41 #error "float128-ifunc.c needs access to ISA 3.0 instructions and ifunc"
44 #ifdef __FLOAT128_HARDWARE__
45 #error "This module must not be compiled with IEEE 128-bit hardware support"
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)
54 static __typeof__ (__addkf3_sw
) *
55 __addkf3_resolve (void)
57 return SW_OR_HW (__addkf3_sw
, __addkf3_hw
);
60 static __typeof__ (__subkf3_sw
) *
61 __subkf3_resolve (void)
63 return SW_OR_HW (__subkf3_sw
, __subkf3_hw
);
66 static __typeof__ (__mulkf3_sw
) *
67 __mulkf3_resolve (void)
69 return SW_OR_HW (__mulkf3_sw
, __mulkf3_hw
);
72 static __typeof__ (__divkf3_sw
) *
73 __divkf3_resolve (void)
75 return SW_OR_HW (__divkf3_sw
, __divkf3_hw
);
78 static __typeof__ (__negkf2_sw
) *
79 __negkf2_resolve (void)
81 return SW_OR_HW (__negkf2_sw
, __negkf2_hw
);
84 static __typeof__ (__powikf2_sw
) *
85 __powikf2_resolve (void)
87 return SW_OR_HW (__powikf2_sw
, __powikf2_hw
);
90 static __typeof__ (__floatsikf_sw
) *
91 __floatsikf_resolve (void)
93 return SW_OR_HW (__floatsikf_sw
, __floatsikf_hw
);
96 static __typeof__ (__floatdikf_sw
) *
97 __floatdikf_resolve (void)
99 return SW_OR_HW (__floatdikf_sw
, __floatdikf_hw
);
102 #ifdef FLOAT128_HW_INSNS_ISA3_1
103 static __typeof__ (__floattikf_sw
) *
104 __floattikf_resolve (void)
106 return SW_OR_HW_ISA3_1 (__floattikf_sw
, __floattikf_hw
);
109 static __typeof__ (__floatuntikf_sw
) *
110 __floatuntikf_resolve (void)
112 return SW_OR_HW_ISA3_1 (__floatuntikf_sw
, __floatuntikf_hw
);
116 static __typeof__ (__floatunsikf_sw
) *
117 __floatunsikf_resolve (void)
119 return SW_OR_HW (__floatunsikf_sw
, __floatunsikf_hw
);
122 static __typeof__ (__floatundikf_sw
) *
123 __floatundikf_resolve (void)
125 return SW_OR_HW (__floatundikf_sw
, __floatundikf_hw
);
128 #ifdef FLOAT128_HW_INSNS_ISA3_1
129 static __typeof__ (__fixkfti_sw
) *
130 __fixkfti_resolve (void)
132 return SW_OR_HW_ISA3_1 (__fixkfti_sw
, __fixkfti_hw
);
135 static __typeof__ (__fixunskfti_sw
) *
136 __fixunskfti_resolve (void)
138 return SW_OR_HW_ISA3_1 (__fixunskfti_sw
, __fixunskfti_hw
);
142 static __typeof__ (__fixkfsi_sw
) *
143 __fixkfsi_resolve (void)
145 return SW_OR_HW (__fixkfsi_sw
, __fixkfsi_hw
);
148 static __typeof__ (__fixkfdi_sw
) *
149 __fixkfdi_resolve (void)
151 return SW_OR_HW (__fixkfdi_sw
, __fixkfdi_hw
);
154 static __typeof__ (__fixunskfsi_sw
) *
155 __fixunskfsi_resolve (void)
157 return SW_OR_HW (__fixunskfsi_sw
, __fixunskfsi_hw
);
160 static __typeof__ (__fixunskfdi_sw
) *
161 __fixunskfdi_resolve (void)
163 return SW_OR_HW (__fixunskfdi_sw
, __fixunskfdi_hw
);
166 static __typeof__ (__extendsfkf2_sw
) *
167 __extendsfkf2_resolve (void)
169 return SW_OR_HW (__extendsfkf2_sw
, __extendsfkf2_hw
);
172 static __typeof__ (__extenddfkf2_sw
) *
173 __extenddfkf2_resolve (void)
175 return SW_OR_HW (__extenddfkf2_sw
, __extenddfkf2_hw
);
178 static __typeof__ (__trunckfsf2_sw
) *
179 __trunckfsf2_resolve (void)
181 return SW_OR_HW (__trunckfsf2_sw
, __trunckfsf2_hw
);
184 static __typeof__ (__trunckfdf2_sw
) *
185 __trunckfdf2_resolve (void)
187 return (void *) SW_OR_HW (__trunckfdf2_sw
, __trunckfdf2_hw
);
190 static __typeof__ (__extendkftf2_sw
) *
191 __extendkftf2_resolve (void)
193 return SW_OR_HW (__extendkftf2_sw
, __extendkftf2_hw
);
196 static __typeof__ (__trunctfkf2_sw
) *
197 __trunctfkf2_resolve (void)
199 return SW_OR_HW (__trunctfkf2_sw
, __trunctfkf2_hw
);
202 static __typeof__ (__mulkc3_sw
) *
203 __mulkc3_resolve (void)
205 return SW_OR_HW (__mulkc3_sw
, __mulkc3_hw
);
208 static __typeof__ (__divkc3_sw
) *
209 __divkc3_resolve (void)
211 return SW_OR_HW (__divkc3_sw
, __divkc3_hw
);
214 static __typeof__ (__eqkf2_sw
) *
215 __eqkf2_resolve (void)
217 return SW_OR_HW (__eqkf2_sw
, __eqkf2_hw
);
220 static __typeof__ (__gekf2_sw
) *
221 __gekf2_resolve (void)
223 return SW_OR_HW (__gekf2_sw
, __gekf2_hw
);
226 static __typeof__ (__lekf2_sw
) *
227 __lekf2_resolve (void)
229 return SW_OR_HW (__lekf2_sw
, __lekf2_hw
);
232 static __typeof__ (__unordkf2_sw
) *
233 __unordkf2_resolve (void)
235 return SW_OR_HW (__unordkf2_sw
, __unordkf2_hw
);
238 /* Resolve __nekf2, __gtkf2, __ltkf2 like __eqkf2, __gekf2, and __lekf2, since
239 the functions return the same values. */
241 static __typeof__ (__eqkf2_sw
) *
242 __nekf2_resolve (void)
244 return SW_OR_HW (__eqkf2_sw
, __eqkf2_hw
);
247 static __typeof__ (__eqkf2_sw
) *
248 __gtkf2_resolve (void)
250 return SW_OR_HW (__gekf2_sw
, __gekf2_hw
);
253 static __typeof__ (__eqkf2_sw
) *
254 __ltkf2_resolve (void)
256 return SW_OR_HW (__lekf2_sw
, __lekf2_hw
);
261 /* Ifunc definitions. */
262 TFtype
__addkf3 (TFtype
, TFtype
)
263 __attribute__ ((__ifunc__ ("__addkf3_resolve")));
265 TFtype
__subkf3 (TFtype
, TFtype
)
266 __attribute__ ((__ifunc__ ("__subkf3_resolve")));
268 TFtype
__mulkf3 (TFtype
, TFtype
)
269 __attribute__ ((__ifunc__ ("__mulkf3_resolve")));
271 TFtype
__divkf3 (TFtype
, TFtype
)
272 __attribute__ ((__ifunc__ ("__divkf3_resolve")));
274 TFtype
__negkf2 (TFtype
)
275 __attribute__ ((__ifunc__ ("__negkf2_resolve")));
277 TFtype
__powikf2 (TFtype
, SItype_ppc
)
278 __attribute__ ((__ifunc__ ("__powikf2_resolve")));
280 CMPtype
__eqkf2 (TFtype
, TFtype
)
281 __attribute__ ((__ifunc__ ("__eqkf2_resolve")));
283 CMPtype
__nekf2 (TFtype
, TFtype
)
284 __attribute__ ((__ifunc__ ("__nekf2_resolve")));
286 CMPtype
__gekf2 (TFtype
, TFtype
)
287 __attribute__ ((__ifunc__ ("__gekf2_resolve")));
289 CMPtype
__gtkf2 (TFtype
, TFtype
)
290 __attribute__ ((__ifunc__ ("__gtkf2_resolve")));
292 CMPtype
__lekf2 (TFtype
, TFtype
)
293 __attribute__ ((__ifunc__ ("__lekf2_resolve")));
295 CMPtype
__ltkf2 (TFtype
, TFtype
)
296 __attribute__ ((__ifunc__ ("__ltkf2_resolve")));
298 CMPtype
__unordkf2 (TFtype
, TFtype
)
299 __attribute__ ((__ifunc__ ("__unordkf2_resolve")));
301 TFtype
__extendsfkf2 (float)
302 __attribute__ ((__ifunc__ ("__extendsfkf2_resolve")));
304 TFtype
__extenddfkf2 (double)
305 __attribute__ ((__ifunc__ ("__extenddfkf2_resolve")));
307 float __trunckfsf2 (TFtype
)
308 __attribute__ ((__ifunc__ ("__trunckfsf2_resolve")));
310 double __trunckfdf2 (TFtype
)
311 __attribute__ ((__ifunc__ ("__trunckfdf2_resolve")));
313 SItype_ppc
__fixkfsi (TFtype
)
314 __attribute__ ((__ifunc__ ("__fixkfsi_resolve")));
316 DItype_ppc
__fixkfdi (TFtype
)
317 __attribute__ ((__ifunc__ ("__fixkfdi_resolve")));
319 USItype_ppc
__fixunskfsi (TFtype
)
320 __attribute__ ((__ifunc__ ("__fixunskfsi_resolve")));
322 UDItype_ppc
__fixunskfdi (TFtype
)
323 __attribute__ ((__ifunc__ ("__fixunskfdi_resolve")));
325 TFtype
__floatsikf (SItype_ppc
)
326 __attribute__ ((__ifunc__ ("__floatsikf_resolve")));
328 TFtype
__floatdikf (DItype_ppc
)
329 __attribute__ ((__ifunc__ ("__floatdikf_resolve")));
331 #ifdef FLOAT128_HW_INSNS_ISA3_1
332 TFtype
__floattikf (TItype_ppc
)
333 __attribute__ ((__ifunc__ ("__floattikf_resolve")));
335 TFtype
__floatuntikf (UTItype_ppc
)
336 __attribute__ ((__ifunc__ ("__floatuntikf_resolve")));
338 TItype_ppc
__fixkfti (TFtype
)
339 __attribute__ ((__ifunc__ ("__fixkfti_resolve")));
341 UTItype_ppc
__fixunskfti (TFtype
)
342 __attribute__ ((__ifunc__ ("__fixunskfti_resolve")));
345 TFtype
__floatunsikf (USItype_ppc
)
346 __attribute__ ((__ifunc__ ("__floatunsikf_resolve")));
348 TFtype
__floatundikf (UDItype_ppc
)
349 __attribute__ ((__ifunc__ ("__floatundikf_resolve")));
351 IBM128_TYPE
__extendkftf2 (TFtype
)
352 __attribute__ ((__ifunc__ ("__extendkftf2_resolve")));
354 TFtype
__trunctfkf2 (IBM128_TYPE
)
355 __attribute__ ((__ifunc__ ("__trunctfkf2_resolve")));
357 TCtype
__mulkc3 (TFtype
, TFtype
, TFtype
, TFtype
)
358 __attribute__ ((__ifunc__ ("__mulkc3_resolve")));
360 TCtype
__divkc3 (TFtype
, TFtype
, TFtype
, TFtype
)
361 __attribute__ ((__ifunc__ ("__divkc3_resolve")));