]>
Commit | Line | Data |
---|---|---|
a71c0334 MM |
1 | /* Automatic switching between software and hardware IEEE 128-bit |
2 | floating-point emulation for PowerPC. | |
3 | ||
7adcbafe | 4 | Copyright (C) 2016-2022 Free Software Foundation, Inc. |
a71c0334 MM |
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 | ||
d4391a62 | 48 | #define SW_OR_HW(SW, HW) (__builtin_cpu_supports ("ieee128") ? HW : SW) |
47749c43 | 49 | #ifdef FLOAT128_HW_INSNS_ISA3_1 |
9090f480 | 50 | #define SW_OR_HW_ISA3_1(SW, HW) (__builtin_cpu_supports ("arch_3_1") ? HW : SW) |
47749c43 | 51 | #endif |
a71c0334 MM |
52 | |
53 | /* Resolvers. */ | |
75ad35b5 | 54 | static __typeof__ (__addkf3_sw) * |
a71c0334 MM |
55 | __addkf3_resolve (void) |
56 | { | |
75ad35b5 | 57 | return SW_OR_HW (__addkf3_sw, __addkf3_hw); |
a71c0334 MM |
58 | } |
59 | ||
75ad35b5 | 60 | static __typeof__ (__subkf3_sw) * |
a71c0334 MM |
61 | __subkf3_resolve (void) |
62 | { | |
75ad35b5 | 63 | return SW_OR_HW (__subkf3_sw, __subkf3_hw); |
a71c0334 MM |
64 | } |
65 | ||
75ad35b5 | 66 | static __typeof__ (__mulkf3_sw) * |
a71c0334 MM |
67 | __mulkf3_resolve (void) |
68 | { | |
75ad35b5 | 69 | return SW_OR_HW (__mulkf3_sw, __mulkf3_hw); |
a71c0334 MM |
70 | } |
71 | ||
75ad35b5 | 72 | static __typeof__ (__divkf3_sw) * |
a71c0334 MM |
73 | __divkf3_resolve (void) |
74 | { | |
75ad35b5 | 75 | return SW_OR_HW (__divkf3_sw, __divkf3_hw); |
a71c0334 MM |
76 | } |
77 | ||
75ad35b5 | 78 | static __typeof__ (__negkf2_sw) * |
a71c0334 MM |
79 | __negkf2_resolve (void) |
80 | { | |
75ad35b5 | 81 | return SW_OR_HW (__negkf2_sw, __negkf2_hw); |
a71c0334 MM |
82 | } |
83 | ||
661eb8f9 MM |
84 | static __typeof__ (__powikf2_sw) * |
85 | __powikf2_resolve (void) | |
86 | { | |
87 | return SW_OR_HW (__powikf2_sw, __powikf2_hw); | |
88 | } | |
89 | ||
75ad35b5 | 90 | static __typeof__ (__floatsikf_sw) * |
a71c0334 MM |
91 | __floatsikf_resolve (void) |
92 | { | |
75ad35b5 | 93 | return SW_OR_HW (__floatsikf_sw, __floatsikf_hw); |
a71c0334 MM |
94 | } |
95 | ||
75ad35b5 | 96 | static __typeof__ (__floatdikf_sw) * |
a71c0334 MM |
97 | __floatdikf_resolve (void) |
98 | { | |
75ad35b5 | 99 | return SW_OR_HW (__floatdikf_sw, __floatdikf_hw); |
a71c0334 MM |
100 | } |
101 | ||
47749c43 | 102 | #ifdef FLOAT128_HW_INSNS_ISA3_1 |
9090f480 CL |
103 | static __typeof__ (__floattikf_sw) * |
104 | __floattikf_resolve (void) | |
105 | { | |
106 | return SW_OR_HW_ISA3_1 (__floattikf_sw, __floattikf_hw); | |
107 | } | |
108 | ||
109 | static __typeof__ (__floatuntikf_sw) * | |
110 | __floatuntikf_resolve (void) | |
111 | { | |
112 | return SW_OR_HW_ISA3_1 (__floatuntikf_sw, __floatuntikf_hw); | |
113 | } | |
47749c43 | 114 | #endif |
9090f480 | 115 | |
75ad35b5 | 116 | static __typeof__ (__floatunsikf_sw) * |
a71c0334 MM |
117 | __floatunsikf_resolve (void) |
118 | { | |
75ad35b5 | 119 | return SW_OR_HW (__floatunsikf_sw, __floatunsikf_hw); |
a71c0334 MM |
120 | } |
121 | ||
75ad35b5 | 122 | static __typeof__ (__floatundikf_sw) * |
a71c0334 MM |
123 | __floatundikf_resolve (void) |
124 | { | |
75ad35b5 | 125 | return SW_OR_HW (__floatundikf_sw, __floatundikf_hw); |
a71c0334 MM |
126 | } |
127 | ||
47749c43 | 128 | #ifdef FLOAT128_HW_INSNS_ISA3_1 |
9090f480 CL |
129 | static __typeof__ (__fixkfti_sw) * |
130 | __fixkfti_resolve (void) | |
131 | { | |
132 | return SW_OR_HW_ISA3_1 (__fixkfti_sw, __fixkfti_hw); | |
133 | } | |
134 | ||
135 | static __typeof__ (__fixunskfti_sw) * | |
136 | __fixunskfti_resolve (void) | |
137 | { | |
138 | return SW_OR_HW_ISA3_1 (__fixunskfti_sw, __fixunskfti_hw); | |
139 | } | |
47749c43 | 140 | #endif |
9090f480 | 141 | |
75ad35b5 | 142 | static __typeof__ (__fixkfsi_sw) * |
a71c0334 MM |
143 | __fixkfsi_resolve (void) |
144 | { | |
75ad35b5 | 145 | return SW_OR_HW (__fixkfsi_sw, __fixkfsi_hw); |
a71c0334 MM |
146 | } |
147 | ||
75ad35b5 | 148 | static __typeof__ (__fixkfdi_sw) * |
a71c0334 MM |
149 | __fixkfdi_resolve (void) |
150 | { | |
75ad35b5 | 151 | return SW_OR_HW (__fixkfdi_sw, __fixkfdi_hw); |
a71c0334 MM |
152 | } |
153 | ||
75ad35b5 | 154 | static __typeof__ (__fixunskfsi_sw) * |
a71c0334 MM |
155 | __fixunskfsi_resolve (void) |
156 | { | |
75ad35b5 | 157 | return SW_OR_HW (__fixunskfsi_sw, __fixunskfsi_hw); |
a71c0334 MM |
158 | } |
159 | ||
75ad35b5 | 160 | static __typeof__ (__fixunskfdi_sw) * |
a71c0334 MM |
161 | __fixunskfdi_resolve (void) |
162 | { | |
75ad35b5 | 163 | return SW_OR_HW (__fixunskfdi_sw, __fixunskfdi_hw); |
a71c0334 MM |
164 | } |
165 | ||
75ad35b5 | 166 | static __typeof__ (__extendsfkf2_sw) * |
a71c0334 MM |
167 | __extendsfkf2_resolve (void) |
168 | { | |
75ad35b5 | 169 | return SW_OR_HW (__extendsfkf2_sw, __extendsfkf2_hw); |
a71c0334 MM |
170 | } |
171 | ||
75ad35b5 | 172 | static __typeof__ (__extenddfkf2_sw) * |
a71c0334 MM |
173 | __extenddfkf2_resolve (void) |
174 | { | |
75ad35b5 | 175 | return SW_OR_HW (__extenddfkf2_sw, __extenddfkf2_hw); |
a71c0334 MM |
176 | } |
177 | ||
75ad35b5 | 178 | static __typeof__ (__trunckfsf2_sw) * |
a71c0334 MM |
179 | __trunckfsf2_resolve (void) |
180 | { | |
75ad35b5 | 181 | return SW_OR_HW (__trunckfsf2_sw, __trunckfsf2_hw); |
a71c0334 MM |
182 | } |
183 | ||
75ad35b5 | 184 | static __typeof__ (__trunckfdf2_sw) * |
a71c0334 MM |
185 | __trunckfdf2_resolve (void) |
186 | { | |
187 | return (void *) SW_OR_HW (__trunckfdf2_sw, __trunckfdf2_hw); | |
188 | } | |
189 | ||
75ad35b5 | 190 | static __typeof__ (__extendkftf2_sw) * |
a71c0334 MM |
191 | __extendkftf2_resolve (void) |
192 | { | |
75ad35b5 | 193 | return SW_OR_HW (__extendkftf2_sw, __extendkftf2_hw); |
a71c0334 MM |
194 | } |
195 | ||
75ad35b5 | 196 | static __typeof__ (__trunctfkf2_sw) * |
a71c0334 MM |
197 | __trunctfkf2_resolve (void) |
198 | { | |
75ad35b5 | 199 | return SW_OR_HW (__trunctfkf2_sw, __trunctfkf2_hw); |
a71c0334 MM |
200 | } |
201 | ||
75ad35b5 MM |
202 | static __typeof__ (__mulkc3_sw) * |
203 | __mulkc3_resolve (void) | |
204 | { | |
205 | return SW_OR_HW (__mulkc3_sw, __mulkc3_hw); | |
206 | } | |
207 | ||
208 | static __typeof__ (__divkc3_sw) * | |
209 | __divkc3_resolve (void) | |
210 | { | |
211 | return SW_OR_HW (__divkc3_sw, __divkc3_hw); | |
212 | } | |
213 | ||
214 | static __typeof__ (__eqkf2_sw) * | |
a71c0334 MM |
215 | __eqkf2_resolve (void) |
216 | { | |
75ad35b5 | 217 | return SW_OR_HW (__eqkf2_sw, __eqkf2_hw); |
a71c0334 MM |
218 | } |
219 | ||
75ad35b5 | 220 | static __typeof__ (__gekf2_sw) * |
a71c0334 MM |
221 | __gekf2_resolve (void) |
222 | { | |
75ad35b5 | 223 | return SW_OR_HW (__gekf2_sw, __gekf2_hw); |
a71c0334 MM |
224 | } |
225 | ||
75ad35b5 | 226 | static __typeof__ (__lekf2_sw) * |
a71c0334 MM |
227 | __lekf2_resolve (void) |
228 | { | |
75ad35b5 | 229 | return SW_OR_HW (__lekf2_sw, __lekf2_hw); |
a71c0334 MM |
230 | } |
231 | ||
75ad35b5 | 232 | static __typeof__ (__unordkf2_sw) * |
a71c0334 MM |
233 | __unordkf2_resolve (void) |
234 | { | |
75ad35b5 | 235 | return SW_OR_HW (__unordkf2_sw, __unordkf2_hw); |
a71c0334 MM |
236 | } |
237 | ||
238 | /* Resolve __nekf2, __gtkf2, __ltkf2 like __eqkf2, __gekf2, and __lekf2, since | |
239 | the functions return the same values. */ | |
240 | ||
75ad35b5 | 241 | static __typeof__ (__eqkf2_sw) * |
a71c0334 MM |
242 | __nekf2_resolve (void) |
243 | { | |
75ad35b5 | 244 | return SW_OR_HW (__eqkf2_sw, __eqkf2_hw); |
a71c0334 MM |
245 | } |
246 | ||
75ad35b5 | 247 | static __typeof__ (__eqkf2_sw) * |
a71c0334 MM |
248 | __gtkf2_resolve (void) |
249 | { | |
75ad35b5 | 250 | return SW_OR_HW (__gekf2_sw, __gekf2_hw); |
a71c0334 MM |
251 | } |
252 | ||
75ad35b5 | 253 | static __typeof__ (__eqkf2_sw) * |
a71c0334 MM |
254 | __ltkf2_resolve (void) |
255 | { | |
75ad35b5 | 256 | return SW_OR_HW (__lekf2_sw, __lekf2_hw); |
a71c0334 MM |
257 | } |
258 | ||
259 | ||
260 | \f | |
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"))); | |
661eb8f9 MM |
276 | |
277 | TFtype __powikf2 (TFtype, SItype_ppc) | |
278 | __attribute__ ((__ifunc__ ("__powikf2_resolve"))); | |
a71c0334 MM |
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 | ||
47749c43 | 331 | #ifdef FLOAT128_HW_INSNS_ISA3_1 |
9090f480 CL |
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"))); | |
47749c43 | 343 | #endif |
9090f480 | 344 | |
a71c0334 MM |
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"))); | |
75ad35b5 MM |
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"))); |