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