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