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