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