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