1 /* Automatic switching between software and hardware IEEE 128-bit
2 floating-point emulation for PowerPC.
4 Copyright (C) 2016-2017 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)
52 /* We do not provide ifunc resolvers for __fixkfti, __fixunskfti, __floattikf,
53 and __floatuntikf. There is no ISA 3.0 instruction that converts between
54 128-bit integer types and 128-bit IEEE floating point, or vice versa. So
55 use the emulator functions for these conversions. */
57 static void *__addkf3_resolve (void);
58 static void *__subkf3_resolve (void);
59 static void *__mulkf3_resolve (void);
60 static void *__divkf3_resolve (void);
61 static void *__negkf2_resolve (void);
62 static void *__eqkf2_resolve (void);
63 static void *__nekf2_resolve (void);
64 static void *__gekf2_resolve (void);
65 static void *__gtkf2_resolve (void);
66 static void *__lekf2_resolve (void);
67 static void *__ltkf2_resolve (void);
68 static void *__unordkf2_resolve (void);
69 static void *__extendsfkf2_resolve (void);
70 static void *__extenddfkf2_resolve (void);
71 static void *__trunckfsf2_resolve (void);
72 static void *__trunckfdf2_resolve (void);
73 static void *__fixkfsi_resolve (void);
74 static void *__fixkfdi_resolve (void);
75 static void *__fixunskfsi_resolve (void);
76 static void *__fixunskfdi_resolve (void);
77 static void *__floatsikf_resolve (void);
78 static void *__floatdikf_resolve (void);
79 static void *__floatunsikf_resolve (void);
80 static void *__floatundikf_resolve (void);
81 static void *__extendkftf2_resolve (void);
82 static void *__trunctfkf2_resolve (void);
85 __addkf3_resolve (void)
87 return (void *) SW_OR_HW (__addkf3_sw
, __addkf3_hw
);
91 __subkf3_resolve (void)
93 return (void *) SW_OR_HW (__subkf3_sw
, __subkf3_hw
);
97 __mulkf3_resolve (void)
99 return (void *) SW_OR_HW (__mulkf3_sw
, __mulkf3_hw
);
103 __divkf3_resolve (void)
105 return (void *) SW_OR_HW (__divkf3_sw
, __divkf3_hw
);
109 __negkf2_resolve (void)
111 return (void *) SW_OR_HW (__negkf2_sw
, __negkf2_hw
);
115 __floatsikf_resolve (void)
117 return (void *) SW_OR_HW (__floatsikf_sw
, __floatsikf_hw
);
121 __floatdikf_resolve (void)
123 return (void *) SW_OR_HW (__floatdikf_sw
, __floatdikf_hw
);
127 __floatunsikf_resolve (void)
129 return (void *) SW_OR_HW (__floatunsikf_sw
, __floatunsikf_hw
);
133 __floatundikf_resolve (void)
135 return (void *) SW_OR_HW (__floatundikf_sw
, __floatundikf_hw
);
139 __fixkfsi_resolve (void)
141 return (void *) SW_OR_HW (__fixkfsi_sw
, __fixkfsi_hw
);
145 __fixkfdi_resolve (void)
147 return (void *) SW_OR_HW (__fixkfdi_sw
, __fixkfdi_hw
);
151 __fixunskfsi_resolve (void)
153 return (void *) SW_OR_HW (__fixunskfsi_sw
, __fixunskfsi_hw
);
157 __fixunskfdi_resolve (void)
159 return (void *) SW_OR_HW (__fixunskfdi_sw
, __fixunskfdi_hw
);
163 __extendsfkf2_resolve (void)
165 return (void *) SW_OR_HW (__extendsfkf2_sw
, __extendsfkf2_hw
);
169 __extenddfkf2_resolve (void)
171 return (void *) SW_OR_HW (__extenddfkf2_sw
, __extenddfkf2_hw
);
175 __trunckfsf2_resolve (void)
177 return (void *) SW_OR_HW (__trunckfsf2_sw
, __trunckfsf2_hw
);
181 __trunckfdf2_resolve (void)
183 return (void *) SW_OR_HW (__trunckfdf2_sw
, __trunckfdf2_hw
);
187 __extendkftf2_resolve (void)
189 return (void *) SW_OR_HW (__extendkftf2_sw
, __extendkftf2_hw
);
193 __trunctfkf2_resolve (void)
195 return (void *) SW_OR_HW (__trunctfkf2_sw
, __trunctfkf2_hw
);
199 __eqkf2_resolve (void)
201 return (void *) SW_OR_HW (__eqkf2_sw
, __eqkf2_hw
);
205 __gekf2_resolve (void)
207 return (void *) SW_OR_HW (__gekf2_sw
, __gekf2_hw
);
211 __lekf2_resolve (void)
213 return (void *) SW_OR_HW (__lekf2_sw
, __lekf2_hw
);
217 __unordkf2_resolve (void)
219 return (void *) SW_OR_HW (__unordkf2_sw
, __unordkf2_hw
);
222 /* Resolve __nekf2, __gtkf2, __ltkf2 like __eqkf2, __gekf2, and __lekf2, since
223 the functions return the same values. */
226 __nekf2_resolve (void)
228 return (void *) SW_OR_HW (__eqkf2_sw
, __eqkf2_hw
);
232 __gtkf2_resolve (void)
234 return (void *) SW_OR_HW (__gekf2_sw
, __gekf2_hw
);
238 __ltkf2_resolve (void)
240 return (void *) SW_OR_HW (__lekf2_sw
, __lekf2_hw
);
245 /* Ifunc definitions. */
246 TFtype
__addkf3 (TFtype
, TFtype
)
247 __attribute__ ((__ifunc__ ("__addkf3_resolve")));
249 TFtype
__subkf3 (TFtype
, TFtype
)
250 __attribute__ ((__ifunc__ ("__subkf3_resolve")));
252 TFtype
__mulkf3 (TFtype
, TFtype
)
253 __attribute__ ((__ifunc__ ("__mulkf3_resolve")));
255 TFtype
__divkf3 (TFtype
, TFtype
)
256 __attribute__ ((__ifunc__ ("__divkf3_resolve")));
258 TFtype
__negkf2 (TFtype
)
259 __attribute__ ((__ifunc__ ("__negkf2_resolve")));
261 CMPtype
__eqkf2 (TFtype
, TFtype
)
262 __attribute__ ((__ifunc__ ("__eqkf2_resolve")));
264 CMPtype
__nekf2 (TFtype
, TFtype
)
265 __attribute__ ((__ifunc__ ("__nekf2_resolve")));
267 CMPtype
__gekf2 (TFtype
, TFtype
)
268 __attribute__ ((__ifunc__ ("__gekf2_resolve")));
270 CMPtype
__gtkf2 (TFtype
, TFtype
)
271 __attribute__ ((__ifunc__ ("__gtkf2_resolve")));
273 CMPtype
__lekf2 (TFtype
, TFtype
)
274 __attribute__ ((__ifunc__ ("__lekf2_resolve")));
276 CMPtype
__ltkf2 (TFtype
, TFtype
)
277 __attribute__ ((__ifunc__ ("__ltkf2_resolve")));
279 CMPtype
__unordkf2 (TFtype
, TFtype
)
280 __attribute__ ((__ifunc__ ("__unordkf2_resolve")));
282 TFtype
__extendsfkf2 (float)
283 __attribute__ ((__ifunc__ ("__extendsfkf2_resolve")));
285 TFtype
__extenddfkf2 (double)
286 __attribute__ ((__ifunc__ ("__extenddfkf2_resolve")));
288 float __trunckfsf2 (TFtype
)
289 __attribute__ ((__ifunc__ ("__trunckfsf2_resolve")));
291 double __trunckfdf2 (TFtype
)
292 __attribute__ ((__ifunc__ ("__trunckfdf2_resolve")));
294 SItype_ppc
__fixkfsi (TFtype
)
295 __attribute__ ((__ifunc__ ("__fixkfsi_resolve")));
297 DItype_ppc
__fixkfdi (TFtype
)
298 __attribute__ ((__ifunc__ ("__fixkfdi_resolve")));
300 USItype_ppc
__fixunskfsi (TFtype
)
301 __attribute__ ((__ifunc__ ("__fixunskfsi_resolve")));
303 UDItype_ppc
__fixunskfdi (TFtype
)
304 __attribute__ ((__ifunc__ ("__fixunskfdi_resolve")));
306 TFtype
__floatsikf (SItype_ppc
)
307 __attribute__ ((__ifunc__ ("__floatsikf_resolve")));
309 TFtype
__floatdikf (DItype_ppc
)
310 __attribute__ ((__ifunc__ ("__floatdikf_resolve")));
312 TFtype
__floatunsikf (USItype_ppc
)
313 __attribute__ ((__ifunc__ ("__floatunsikf_resolve")));
315 TFtype
__floatundikf (UDItype_ppc
)
316 __attribute__ ((__ifunc__ ("__floatundikf_resolve")));
318 IBM128_TYPE
__extendkftf2 (TFtype
)
319 __attribute__ ((__ifunc__ ("__extendkftf2_resolve")));
321 TFtype
__trunctfkf2 (IBM128_TYPE
)
322 __attribute__ ((__ifunc__ ("__trunctfkf2_resolve")));