1 /* Automatic switching between software and hardware IEEE 128-bit
2 floating-point emulation for PowerPC.
3
4 Copyright (C) 2016-2018 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
50 /* Resolvers. */
51
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. */
56
__typeof__(__addkf3_sw)57 static __typeof__ (__addkf3_sw) *
58 __addkf3_resolve (void)
59 {
60 return SW_OR_HW (__addkf3_sw, __addkf3_hw);
61 }
62
__typeof__(__subkf3_sw)63 static __typeof__ (__subkf3_sw) *
64 __subkf3_resolve (void)
65 {
66 return SW_OR_HW (__subkf3_sw, __subkf3_hw);
67 }
68
__typeof__(__mulkf3_sw)69 static __typeof__ (__mulkf3_sw) *
70 __mulkf3_resolve (void)
71 {
72 return SW_OR_HW (__mulkf3_sw, __mulkf3_hw);
73 }
74
__typeof__(__divkf3_sw)75 static __typeof__ (__divkf3_sw) *
76 __divkf3_resolve (void)
77 {
78 return SW_OR_HW (__divkf3_sw, __divkf3_hw);
79 }
80
__typeof__(__negkf2_sw)81 static __typeof__ (__negkf2_sw) *
82 __negkf2_resolve (void)
83 {
84 return SW_OR_HW (__negkf2_sw, __negkf2_hw);
85 }
86
__typeof__(__powikf2_sw)87 static __typeof__ (__powikf2_sw) *
88 __powikf2_resolve (void)
89 {
90 return SW_OR_HW (__powikf2_sw, __powikf2_hw);
91 }
92
__typeof__(__floatsikf_sw)93 static __typeof__ (__floatsikf_sw) *
94 __floatsikf_resolve (void)
95 {
96 return SW_OR_HW (__floatsikf_sw, __floatsikf_hw);
97 }
98
__typeof__(__floatdikf_sw)99 static __typeof__ (__floatdikf_sw) *
100 __floatdikf_resolve (void)
101 {
102 return SW_OR_HW (__floatdikf_sw, __floatdikf_hw);
103 }
104
__typeof__(__floatunsikf_sw)105 static __typeof__ (__floatunsikf_sw) *
106 __floatunsikf_resolve (void)
107 {
108 return SW_OR_HW (__floatunsikf_sw, __floatunsikf_hw);
109 }
110
__typeof__(__floatundikf_sw)111 static __typeof__ (__floatundikf_sw) *
112 __floatundikf_resolve (void)
113 {
114 return SW_OR_HW (__floatundikf_sw, __floatundikf_hw);
115 }
116
__typeof__(__fixkfsi_sw)117 static __typeof__ (__fixkfsi_sw) *
118 __fixkfsi_resolve (void)
119 {
120 return SW_OR_HW (__fixkfsi_sw, __fixkfsi_hw);
121 }
122
__typeof__(__fixkfdi_sw)123 static __typeof__ (__fixkfdi_sw) *
124 __fixkfdi_resolve (void)
125 {
126 return SW_OR_HW (__fixkfdi_sw, __fixkfdi_hw);
127 }
128
__typeof__(__fixunskfsi_sw)129 static __typeof__ (__fixunskfsi_sw) *
130 __fixunskfsi_resolve (void)
131 {
132 return SW_OR_HW (__fixunskfsi_sw, __fixunskfsi_hw);
133 }
134
__typeof__(__fixunskfdi_sw)135 static __typeof__ (__fixunskfdi_sw) *
136 __fixunskfdi_resolve (void)
137 {
138 return SW_OR_HW (__fixunskfdi_sw, __fixunskfdi_hw);
139 }
140
__typeof__(__extendsfkf2_sw)141 static __typeof__ (__extendsfkf2_sw) *
142 __extendsfkf2_resolve (void)
143 {
144 return SW_OR_HW (__extendsfkf2_sw, __extendsfkf2_hw);
145 }
146
__typeof__(__extenddfkf2_sw)147 static __typeof__ (__extenddfkf2_sw) *
148 __extenddfkf2_resolve (void)
149 {
150 return SW_OR_HW (__extenddfkf2_sw, __extenddfkf2_hw);
151 }
152
__typeof__(__trunckfsf2_sw)153 static __typeof__ (__trunckfsf2_sw) *
154 __trunckfsf2_resolve (void)
155 {
156 return SW_OR_HW (__trunckfsf2_sw, __trunckfsf2_hw);
157 }
158
__typeof__(__trunckfdf2_sw)159 static __typeof__ (__trunckfdf2_sw) *
160 __trunckfdf2_resolve (void)
161 {
162 return (void *) SW_OR_HW (__trunckfdf2_sw, __trunckfdf2_hw);
163 }
164
__typeof__(__extendkftf2_sw)165 static __typeof__ (__extendkftf2_sw) *
166 __extendkftf2_resolve (void)
167 {
168 return SW_OR_HW (__extendkftf2_sw, __extendkftf2_hw);
169 }
170
__typeof__(__trunctfkf2_sw)171 static __typeof__ (__trunctfkf2_sw) *
172 __trunctfkf2_resolve (void)
173 {
174 return SW_OR_HW (__trunctfkf2_sw, __trunctfkf2_hw);
175 }
176
__typeof__(__mulkc3_sw)177 static __typeof__ (__mulkc3_sw) *
178 __mulkc3_resolve (void)
179 {
180 return SW_OR_HW (__mulkc3_sw, __mulkc3_hw);
181 }
182
__typeof__(__divkc3_sw)183 static __typeof__ (__divkc3_sw) *
184 __divkc3_resolve (void)
185 {
186 return SW_OR_HW (__divkc3_sw, __divkc3_hw);
187 }
188
__typeof__(__eqkf2_sw)189 static __typeof__ (__eqkf2_sw) *
190 __eqkf2_resolve (void)
191 {
192 return SW_OR_HW (__eqkf2_sw, __eqkf2_hw);
193 }
194
__typeof__(__gekf2_sw)195 static __typeof__ (__gekf2_sw) *
196 __gekf2_resolve (void)
197 {
198 return SW_OR_HW (__gekf2_sw, __gekf2_hw);
199 }
200
__typeof__(__lekf2_sw)201 static __typeof__ (__lekf2_sw) *
202 __lekf2_resolve (void)
203 {
204 return SW_OR_HW (__lekf2_sw, __lekf2_hw);
205 }
206
__typeof__(__unordkf2_sw)207 static __typeof__ (__unordkf2_sw) *
208 __unordkf2_resolve (void)
209 {
210 return SW_OR_HW (__unordkf2_sw, __unordkf2_hw);
211 }
212
213 /* Resolve __nekf2, __gtkf2, __ltkf2 like __eqkf2, __gekf2, and __lekf2, since
214 the functions return the same values. */
215
__typeof__(__eqkf2_sw)216 static __typeof__ (__eqkf2_sw) *
217 __nekf2_resolve (void)
218 {
219 return SW_OR_HW (__eqkf2_sw, __eqkf2_hw);
220 }
221
__typeof__(__eqkf2_sw)222 static __typeof__ (__eqkf2_sw) *
223 __gtkf2_resolve (void)
224 {
225 return SW_OR_HW (__gekf2_sw, __gekf2_hw);
226 }
227
__typeof__(__eqkf2_sw)228 static __typeof__ (__eqkf2_sw) *
229 __ltkf2_resolve (void)
230 {
231 return SW_OR_HW (__lekf2_sw, __lekf2_hw);
232 }
233
234
235
236 /* Ifunc definitions. */
237 TFtype __addkf3 (TFtype, TFtype)
238 __attribute__ ((__ifunc__ ("__addkf3_resolve")));
239
240 TFtype __subkf3 (TFtype, TFtype)
241 __attribute__ ((__ifunc__ ("__subkf3_resolve")));
242
243 TFtype __mulkf3 (TFtype, TFtype)
244 __attribute__ ((__ifunc__ ("__mulkf3_resolve")));
245
246 TFtype __divkf3 (TFtype, TFtype)
247 __attribute__ ((__ifunc__ ("__divkf3_resolve")));
248
249 TFtype __negkf2 (TFtype)
250 __attribute__ ((__ifunc__ ("__negkf2_resolve")));
251
252 TFtype __powikf2 (TFtype, SItype_ppc)
253 __attribute__ ((__ifunc__ ("__powikf2_resolve")));
254
255 CMPtype __eqkf2 (TFtype, TFtype)
256 __attribute__ ((__ifunc__ ("__eqkf2_resolve")));
257
258 CMPtype __nekf2 (TFtype, TFtype)
259 __attribute__ ((__ifunc__ ("__nekf2_resolve")));
260
261 CMPtype __gekf2 (TFtype, TFtype)
262 __attribute__ ((__ifunc__ ("__gekf2_resolve")));
263
264 CMPtype __gtkf2 (TFtype, TFtype)
265 __attribute__ ((__ifunc__ ("__gtkf2_resolve")));
266
267 CMPtype __lekf2 (TFtype, TFtype)
268 __attribute__ ((__ifunc__ ("__lekf2_resolve")));
269
270 CMPtype __ltkf2 (TFtype, TFtype)
271 __attribute__ ((__ifunc__ ("__ltkf2_resolve")));
272
273 CMPtype __unordkf2 (TFtype, TFtype)
274 __attribute__ ((__ifunc__ ("__unordkf2_resolve")));
275
276 TFtype __extendsfkf2 (float)
277 __attribute__ ((__ifunc__ ("__extendsfkf2_resolve")));
278
279 TFtype __extenddfkf2 (double)
280 __attribute__ ((__ifunc__ ("__extenddfkf2_resolve")));
281
282 float __trunckfsf2 (TFtype)
283 __attribute__ ((__ifunc__ ("__trunckfsf2_resolve")));
284
285 double __trunckfdf2 (TFtype)
286 __attribute__ ((__ifunc__ ("__trunckfdf2_resolve")));
287
288 SItype_ppc __fixkfsi (TFtype)
289 __attribute__ ((__ifunc__ ("__fixkfsi_resolve")));
290
291 DItype_ppc __fixkfdi (TFtype)
292 __attribute__ ((__ifunc__ ("__fixkfdi_resolve")));
293
294 USItype_ppc __fixunskfsi (TFtype)
295 __attribute__ ((__ifunc__ ("__fixunskfsi_resolve")));
296
297 UDItype_ppc __fixunskfdi (TFtype)
298 __attribute__ ((__ifunc__ ("__fixunskfdi_resolve")));
299
300 TFtype __floatsikf (SItype_ppc)
301 __attribute__ ((__ifunc__ ("__floatsikf_resolve")));
302
303 TFtype __floatdikf (DItype_ppc)
304 __attribute__ ((__ifunc__ ("__floatdikf_resolve")));
305
306 TFtype __floatunsikf (USItype_ppc)
307 __attribute__ ((__ifunc__ ("__floatunsikf_resolve")));
308
309 TFtype __floatundikf (UDItype_ppc)
310 __attribute__ ((__ifunc__ ("__floatundikf_resolve")));
311
312 IBM128_TYPE __extendkftf2 (TFtype)
313 __attribute__ ((__ifunc__ ("__extendkftf2_resolve")));
314
315 TFtype __trunctfkf2 (IBM128_TYPE)
316 __attribute__ ((__ifunc__ ("__trunctfkf2_resolve")));
317
318 TCtype __mulkc3 (TFtype, TFtype, TFtype, TFtype)
319 __attribute__ ((__ifunc__ ("__mulkc3_resolve")));
320
321 TCtype __divkc3 (TFtype, TFtype, TFtype, TFtype)
322 __attribute__ ((__ifunc__ ("__divkc3_resolve")));
323