]>
Commit | Line | Data |
---|---|---|
a71c0334 MM |
1 | /* Software floating-point emulation. |
2 | Definitions for IEEE Quad Precision on the PowerPC. | |
7adcbafe | 3 | Copyright (C) 2016-2022 Free Software Foundation, Inc. |
a71c0334 MM |
4 | This file is part of the GNU C Library. |
5 | Contributed by Michael Meissner (meissner@linux.vnet.ibm.com). | |
6 | ||
7 | The GNU C Library is free software; you can redistribute it and/or | |
8 | modify it under the terms of the GNU Lesser General Public | |
9 | License as published by the Free Software Foundation; either | |
10 | version 2.1 of the License, or (at your option) any later version. | |
11 | ||
12 | In addition to the permissions in the GNU Lesser General Public | |
13 | License, the Free Software Foundation gives you unlimited | |
14 | permission to link the compiled version of this file into | |
15 | combinations with other programs, and to distribute those | |
16 | combinations without any restriction coming from the use of this | |
17 | file. (The Lesser General Public License restrictions do apply in | |
18 | other respects; for example, they cover modification of the file, | |
19 | and distribution when not linked into a combine executable.) | |
20 | ||
21 | The GNU C Library is distributed in the hope that it will be useful, | |
22 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
23 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
24 | Lesser General Public License for more details. | |
25 | ||
26 | You should have received a copy of the GNU Lesser General Public | |
27 | License along with the GNU C Library; if not, see | |
28 | <http://www.gnu.org/licenses/>. */ | |
29 | ||
d54e3d92 MM |
30 | /* Override the types for IEEE 128-bit scalar and complex. */ |
31 | #ifdef __LONG_DOUBLE_IEEE128__ | |
32 | #define TFtype long double | |
33 | #define TCtype _Complex long double | |
972623a3 MM |
34 | |
35 | #else | |
d54e3d92 MM |
36 | #define TFtype _Float128 |
37 | #define TCtype _Complex _Float128 | |
972623a3 | 38 | #endif |
75ad35b5 | 39 | |
a71c0334 MM |
40 | /* Force the use of the VSX instruction set. */ |
41 | #if defined(_ARCH_PPC) && (!defined(__VSX__) || !defined(__FLOAT128__)) | |
42 | #pragma GCC target ("vsx,float128") | |
43 | #endif | |
44 | ||
78118359 | 45 | #include <stddef.h> |
a71c0334 MM |
46 | #include <quad.h> |
47 | ||
d5eea0f7 | 48 | #define IBM128_TYPE __ibm128 |
a71c0334 MM |
49 | |
50 | /* Add prototypes of the library functions created. In case the appropriate | |
51 | int/long types are not declared in scope by the time quad.h is included, | |
52 | provide our own version. */ | |
53 | typedef int SItype_ppc __attribute__ ((__mode__ (__SI__))); | |
54 | typedef int DItype_ppc __attribute__ ((__mode__ (__DI__))); | |
55 | typedef unsigned USItype_ppc __attribute__ ((__mode__ (__SI__))); | |
56 | typedef unsigned UDItype_ppc __attribute__ ((__mode__ (__DI__))); | |
57 | ||
58 | #ifdef _ARCH_PPC64 | |
59 | typedef int TItype_ppc __attribute__ ((__mode__ (__TI__))); | |
60 | typedef unsigned UTItype_ppc __attribute__ ((__mode__ (__TI__))); | |
61 | #endif | |
62 | ||
63 | /* Software emulation functions. */ | |
64 | extern TFtype __addkf3_sw (TFtype, TFtype); | |
65 | extern TFtype __subkf3_sw (TFtype, TFtype); | |
66 | extern TFtype __mulkf3_sw (TFtype, TFtype); | |
67 | extern TFtype __divkf3_sw (TFtype, TFtype); | |
68 | extern TFtype __negkf2_sw (TFtype); | |
661eb8f9 | 69 | extern TFtype __powikf2_sw (TFtype, SItype_ppc); |
a71c0334 MM |
70 | extern CMPtype __eqkf2_sw (TFtype, TFtype); |
71 | extern CMPtype __gekf2_sw (TFtype, TFtype); | |
72 | extern CMPtype __lekf2_sw (TFtype, TFtype); | |
73 | extern CMPtype __unordkf2_sw (TFtype, TFtype); | |
74 | extern TFtype __extendsfkf2_sw (float); | |
75 | extern TFtype __extenddfkf2_sw (double); | |
76 | extern float __trunckfsf2_sw (TFtype); | |
77 | extern double __trunckfdf2_sw (TFtype); | |
78 | extern SItype_ppc __fixkfsi_sw (TFtype); | |
79 | extern DItype_ppc __fixkfdi_sw (TFtype); | |
80 | extern USItype_ppc __fixunskfsi_sw (TFtype); | |
81 | extern UDItype_ppc __fixunskfdi_sw (TFtype); | |
82 | extern TFtype __floatsikf_sw (SItype_ppc); | |
83 | extern TFtype __floatdikf_sw (DItype_ppc); | |
7a895955 | 84 | #ifdef _ARCH_PPC64 |
9090f480 | 85 | extern TFtype __floattikf_sw (TItype_ppc); |
7a895955 | 86 | #endif |
a71c0334 MM |
87 | extern TFtype __floatunsikf_sw (USItype_ppc); |
88 | extern TFtype __floatundikf_sw (UDItype_ppc); | |
7a895955 | 89 | #ifdef _ARCH_PPC64 |
9090f480 CL |
90 | extern TFtype __floatuntikf_sw (UTItype_ppc); |
91 | extern TItype_ppc __fixkfti_sw (TFtype); | |
92 | extern UTItype_ppc __fixunskfti_sw (TFtype); | |
7a895955 | 93 | #endif |
a71c0334 MM |
94 | extern IBM128_TYPE __extendkftf2_sw (TFtype); |
95 | extern TFtype __trunctfkf2_sw (IBM128_TYPE); | |
68ed94d0 MM |
96 | extern TCtype __mulkc3_sw (TFtype, TFtype, TFtype, TFtype); |
97 | extern TCtype __divkc3_sw (TFtype, TFtype, TFtype, TFtype); | |
a71c0334 MM |
98 | |
99 | #ifdef _ARCH_PPC64 | |
a71c0334 MM |
100 | extern TItype_ppc __fixkfti (TFtype); |
101 | extern UTItype_ppc __fixunskfti (TFtype); | |
102 | extern TFtype __floattikf (TItype_ppc); | |
103 | extern TFtype __floatuntikf (UTItype_ppc); | |
104 | #endif | |
105 | ||
106 | /* Functions using the ISA 3.0 hardware support. If the code is compiled with | |
107 | -mcpu=power9, it will not use these functions, but if it was compiled with | |
108 | -mcpu=power7 or -mcpu=power8 and run on a ISA 3.0 system, it will use the | |
109 | hardware instruction. */ | |
110 | extern TFtype __addkf3_hw (TFtype, TFtype); | |
111 | extern TFtype __subkf3_hw (TFtype, TFtype); | |
112 | extern TFtype __mulkf3_hw (TFtype, TFtype); | |
113 | extern TFtype __divkf3_hw (TFtype, TFtype); | |
114 | extern TFtype __negkf2_hw (TFtype); | |
661eb8f9 | 115 | extern TFtype __powikf2_hw (TFtype, SItype_ppc); |
a71c0334 MM |
116 | extern CMPtype __eqkf2_hw (TFtype, TFtype); |
117 | extern CMPtype __gekf2_hw (TFtype, TFtype); | |
118 | extern CMPtype __lekf2_hw (TFtype, TFtype); | |
119 | extern CMPtype __unordkf2_hw (TFtype, TFtype); | |
120 | extern TFtype __extendsfkf2_hw (float); | |
121 | extern TFtype __extenddfkf2_hw (double); | |
122 | extern float __trunckfsf2_hw (TFtype); | |
123 | extern double __trunckfdf2_hw (TFtype); | |
124 | extern SItype_ppc __fixkfsi_hw (TFtype); | |
125 | extern DItype_ppc __fixkfdi_hw (TFtype); | |
126 | extern USItype_ppc __fixunskfsi_hw (TFtype); | |
127 | extern UDItype_ppc __fixunskfdi_hw (TFtype); | |
128 | extern TFtype __floatsikf_hw (SItype_ppc); | |
129 | extern TFtype __floatdikf_hw (DItype_ppc); | |
7a895955 | 130 | #ifdef _ARCH_PPC64 |
9090f480 | 131 | extern TFtype __floattikf_hw (TItype_ppc); |
7a895955 | 132 | #endif |
a71c0334 MM |
133 | extern TFtype __floatunsikf_hw (USItype_ppc); |
134 | extern TFtype __floatundikf_hw (UDItype_ppc); | |
7a895955 | 135 | #ifdef _ARCH_PPC64 |
9090f480 CL |
136 | extern TFtype __floatuntikf_hw (UTItype_ppc); |
137 | extern TItype_ppc __fixkfti_hw (TFtype); | |
138 | extern UTItype_ppc __fixunskfti_hw (TFtype); | |
7a895955 | 139 | #endif |
a71c0334 MM |
140 | extern IBM128_TYPE __extendkftf2_hw (TFtype); |
141 | extern TFtype __trunctfkf2_hw (IBM128_TYPE); | |
68ed94d0 MM |
142 | extern TCtype __mulkc3_hw (TFtype, TFtype, TFtype, TFtype); |
143 | extern TCtype __divkc3_hw (TFtype, TFtype, TFtype, TFtype); | |
a71c0334 MM |
144 | |
145 | /* Ifunc function declarations, to automatically switch between software | |
146 | emulation and hardware support. */ | |
147 | extern TFtype __addkf3 (TFtype, TFtype); | |
148 | extern TFtype __subkf3 (TFtype, TFtype); | |
149 | extern TFtype __mulkf3 (TFtype, TFtype); | |
150 | extern TFtype __divkf3 (TFtype, TFtype); | |
151 | extern TFtype __negkf2 (TFtype); | |
661eb8f9 | 152 | extern TFtype __powikf2 (TFtype, SItype_ppc); |
a71c0334 MM |
153 | extern CMPtype __eqkf2 (TFtype, TFtype); |
154 | extern CMPtype __nekf2 (TFtype, TFtype); | |
155 | extern CMPtype __gekf2 (TFtype, TFtype); | |
156 | extern CMPtype __gtkf2 (TFtype, TFtype); | |
157 | extern CMPtype __lekf2 (TFtype, TFtype); | |
158 | extern CMPtype __ltkf2 (TFtype, TFtype); | |
159 | extern CMPtype __unordkf2 (TFtype, TFtype); | |
160 | extern TFtype __extendsfkf2 (float); | |
161 | extern TFtype __extenddfkf2 (double); | |
162 | extern float __trunckfsf2 (TFtype); | |
163 | extern double __trunckfdf2 (TFtype); | |
164 | extern SItype_ppc __fixkfsi (TFtype); | |
165 | extern DItype_ppc __fixkfdi (TFtype); | |
166 | extern USItype_ppc __fixunskfsi (TFtype); | |
167 | extern UDItype_ppc __fixunskfdi (TFtype); | |
168 | extern TFtype __floatsikf (SItype_ppc); | |
169 | extern TFtype __floatdikf (DItype_ppc); | |
7a895955 | 170 | #ifdef _ARCH_PPC64 |
9090f480 | 171 | extern TFtype __floattikf (TItype_ppc); |
7a895955 | 172 | #endif |
a71c0334 MM |
173 | extern TFtype __floatunsikf (USItype_ppc); |
174 | extern TFtype __floatundikf (UDItype_ppc); | |
7a895955 | 175 | #ifdef _ARCH_PPC64 |
9090f480 CL |
176 | extern TFtype __floatuntikf (UTItype_ppc); |
177 | extern TItype_ppc __fixkfti (TFtype); | |
178 | extern UTItype_ppc __fixunskfti (TFtype); | |
7a895955 | 179 | #endif |
a71c0334 MM |
180 | extern IBM128_TYPE __extendkftf2 (TFtype); |
181 | extern TFtype __trunctfkf2 (IBM128_TYPE); | |
182 | ||
972623a3 | 183 | /* Complex __float128 built on __float128 interfaces. */ |
68ed94d0 MM |
184 | extern TCtype __mulkc3 (TFtype, TFtype, TFtype, TFtype); |
185 | extern TCtype __divkc3 (TFtype, TFtype, TFtype, TFtype); | |
972623a3 | 186 | |
78118359 MM |
187 | /* Convert IEEE 128-bit floating point to/from string. We explicitly use |
188 | _Float128 instead of TFmode because _strtokf and _strfromkf must be compiled | |
189 | with long double being IBM 128. */ | |
190 | extern _Float128 __strtokf (const char *, char **); | |
191 | extern int __strfromkf (char *restrict, size_t, const char *restrict, | |
192 | _Float128); | |
193 | ||
a71c0334 MM |
194 | /* Implementation of conversions between __ibm128 and __float128, to allow the |
195 | same code to be used on systems with IEEE 128-bit emulation and with IEEE | |
196 | 128-bit hardware support. */ | |
197 | ||
198 | union ibm128_union { | |
199 | IBM128_TYPE ibm128; | |
200 | double dbl[2]; | |
201 | }; | |
202 | ||
203 | #define CVT_FLOAT128_TO_IBM128(RESULT, VALUE) \ | |
204 | { \ | |
205 | double __high, __low; \ | |
d5eea0f7 | 206 | TFtype __value = (VALUE); \ |
a71c0334 MM |
207 | union ibm128_union u; \ |
208 | \ | |
209 | __high = (double) __value; \ | |
210 | if (__builtin_isnan (__high) || __builtin_isinf (__high)) \ | |
211 | __low = 0.0; \ | |
212 | \ | |
213 | else \ | |
214 | { \ | |
215 | double __high_temp; \ | |
216 | \ | |
d5eea0f7 | 217 | __low = (double) (__value - (TFtype) __high); \ |
a71c0334 MM |
218 | /* Renormalize low/high and move them into canonical IBM long \ |
219 | double form. */ \ | |
220 | __high_temp = __high + __low; \ | |
221 | __low = (__high - __high_temp) + __low; \ | |
222 | __high = __high_temp; \ | |
223 | } \ | |
224 | \ | |
225 | u.dbl[0] = __high; \ | |
226 | u.dbl[1] = __low; \ | |
227 | RESULT = u.ibm128; \ | |
228 | } | |
229 | ||
230 | #define CVT_IBM128_TO_FLOAT128(RESULT, VALUE) \ | |
231 | { \ | |
232 | union ibm128_union u; \ | |
233 | double __high, __low; \ | |
234 | \ | |
235 | u.ibm128 = (VALUE); \ | |
236 | __high = u.dbl[0]; \ | |
237 | __low = u.dbl[1]; \ | |
238 | \ | |
239 | /* Handle the special cases of NAN and infinity. */ \ | |
240 | if (__builtin_isnan (__high) || __builtin_isinf (__high)) \ | |
d5eea0f7 | 241 | RESULT = (TFtype) __high; \ |
a71c0334 MM |
242 | \ |
243 | /* If low is 0.0, there no need to do the add. In addition, \ | |
244 | avoiding the add produces the correct sign if high is -0.0. */ \ | |
245 | else if (__low == 0.0) \ | |
d5eea0f7 | 246 | RESULT = (TFtype) __high; \ |
a71c0334 MM |
247 | \ |
248 | else \ | |
d5eea0f7 | 249 | RESULT = ((TFtype) __high) + ((TFtype) __low); \ |
a71c0334 | 250 | } |