]>
Commit | Line | Data |
---|---|---|
a71c0334 MM |
1 | /* Software floating-point emulation. |
2 | Definitions for IEEE Quad Precision on the PowerPC. | |
8d9254fc | 3 | Copyright (C) 2016-2020 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 | ||
30 | /* quad.h defines the TFtype type by: | |
31 | typedef float TFtype __attribute__ ((mode (TF))); | |
32 | ||
75ad35b5 MM |
33 | This define forces it to use KFmode (aka, ieee 128-bit floating point). |
34 | However, when the compiler's default is changed so that long double is IEEE | |
35 | 128-bit floating point, we need to go back to using TFmode and TCmode. */ | |
36 | #ifndef __LONG_DOUBLE_IEEE128__ | |
a71c0334 MM |
37 | #define TF KF |
38 | ||
f906f5ed BS |
39 | /* We also need TCtype to represent complex ieee 128-bit float for |
40 | __mulkc3 and __divkc3. */ | |
41 | typedef __complex float TCtype __attribute__ ((mode (KC))); | |
42 | ||
75ad35b5 MM |
43 | #else |
44 | typedef __complex float TCtype __attribute__ ((mode (TC))); | |
45 | #endif | |
46 | ||
a71c0334 MM |
47 | /* Force the use of the VSX instruction set. */ |
48 | #if defined(_ARCH_PPC) && (!defined(__VSX__) || !defined(__FLOAT128__)) | |
49 | #pragma GCC target ("vsx,float128") | |
50 | #endif | |
51 | ||
52 | #include <quad.h> | |
53 | ||
d5eea0f7 | 54 | #define IBM128_TYPE __ibm128 |
a71c0334 MM |
55 | |
56 | /* Add prototypes of the library functions created. In case the appropriate | |
57 | int/long types are not declared in scope by the time quad.h is included, | |
58 | provide our own version. */ | |
59 | typedef int SItype_ppc __attribute__ ((__mode__ (__SI__))); | |
60 | typedef int DItype_ppc __attribute__ ((__mode__ (__DI__))); | |
61 | typedef unsigned USItype_ppc __attribute__ ((__mode__ (__SI__))); | |
62 | typedef unsigned UDItype_ppc __attribute__ ((__mode__ (__DI__))); | |
63 | ||
64 | #ifdef _ARCH_PPC64 | |
65 | typedef int TItype_ppc __attribute__ ((__mode__ (__TI__))); | |
66 | typedef unsigned UTItype_ppc __attribute__ ((__mode__ (__TI__))); | |
67 | #endif | |
68 | ||
69 | /* Software emulation functions. */ | |
70 | extern TFtype __addkf3_sw (TFtype, TFtype); | |
71 | extern TFtype __subkf3_sw (TFtype, TFtype); | |
72 | extern TFtype __mulkf3_sw (TFtype, TFtype); | |
73 | extern TFtype __divkf3_sw (TFtype, TFtype); | |
74 | extern TFtype __negkf2_sw (TFtype); | |
661eb8f9 | 75 | extern TFtype __powikf2_sw (TFtype, SItype_ppc); |
a71c0334 MM |
76 | extern CMPtype __eqkf2_sw (TFtype, TFtype); |
77 | extern CMPtype __gekf2_sw (TFtype, TFtype); | |
78 | extern CMPtype __lekf2_sw (TFtype, TFtype); | |
79 | extern CMPtype __unordkf2_sw (TFtype, TFtype); | |
80 | extern TFtype __extendsfkf2_sw (float); | |
81 | extern TFtype __extenddfkf2_sw (double); | |
82 | extern float __trunckfsf2_sw (TFtype); | |
83 | extern double __trunckfdf2_sw (TFtype); | |
84 | extern SItype_ppc __fixkfsi_sw (TFtype); | |
85 | extern DItype_ppc __fixkfdi_sw (TFtype); | |
86 | extern USItype_ppc __fixunskfsi_sw (TFtype); | |
87 | extern UDItype_ppc __fixunskfdi_sw (TFtype); | |
88 | extern TFtype __floatsikf_sw (SItype_ppc); | |
89 | extern TFtype __floatdikf_sw (DItype_ppc); | |
90 | extern TFtype __floatunsikf_sw (USItype_ppc); | |
91 | extern TFtype __floatundikf_sw (UDItype_ppc); | |
92 | extern IBM128_TYPE __extendkftf2_sw (TFtype); | |
93 | extern TFtype __trunctfkf2_sw (IBM128_TYPE); | |
75ad35b5 MM |
94 | extern TCtype __mulkc3_sw (TFtype, TFtype, TFtype, TFtype); |
95 | extern TCtype __divkc3_sw (TFtype, TFtype, TFtype, TFtype); | |
a71c0334 MM |
96 | |
97 | #ifdef _ARCH_PPC64 | |
98 | /* We do not provide ifunc resolvers for __fixkfti, __fixunskfti, __floattikf, | |
99 | and __floatuntikf. There is no ISA 3.0 instruction that converts between | |
100 | 128-bit integer types and 128-bit IEEE floating point, or vice versa. So | |
101 | use the emulator functions for these conversions. */ | |
102 | ||
103 | extern TItype_ppc __fixkfti (TFtype); | |
104 | extern UTItype_ppc __fixunskfti (TFtype); | |
105 | extern TFtype __floattikf (TItype_ppc); | |
106 | extern TFtype __floatuntikf (UTItype_ppc); | |
107 | #endif | |
108 | ||
109 | /* Functions using the ISA 3.0 hardware support. If the code is compiled with | |
110 | -mcpu=power9, it will not use these functions, but if it was compiled with | |
111 | -mcpu=power7 or -mcpu=power8 and run on a ISA 3.0 system, it will use the | |
112 | hardware instruction. */ | |
113 | extern TFtype __addkf3_hw (TFtype, TFtype); | |
114 | extern TFtype __subkf3_hw (TFtype, TFtype); | |
115 | extern TFtype __mulkf3_hw (TFtype, TFtype); | |
116 | extern TFtype __divkf3_hw (TFtype, TFtype); | |
117 | extern TFtype __negkf2_hw (TFtype); | |
661eb8f9 | 118 | extern TFtype __powikf2_hw (TFtype, SItype_ppc); |
a71c0334 MM |
119 | extern CMPtype __eqkf2_hw (TFtype, TFtype); |
120 | extern CMPtype __gekf2_hw (TFtype, TFtype); | |
121 | extern CMPtype __lekf2_hw (TFtype, TFtype); | |
122 | extern CMPtype __unordkf2_hw (TFtype, TFtype); | |
123 | extern TFtype __extendsfkf2_hw (float); | |
124 | extern TFtype __extenddfkf2_hw (double); | |
125 | extern float __trunckfsf2_hw (TFtype); | |
126 | extern double __trunckfdf2_hw (TFtype); | |
127 | extern SItype_ppc __fixkfsi_hw (TFtype); | |
128 | extern DItype_ppc __fixkfdi_hw (TFtype); | |
129 | extern USItype_ppc __fixunskfsi_hw (TFtype); | |
130 | extern UDItype_ppc __fixunskfdi_hw (TFtype); | |
131 | extern TFtype __floatsikf_hw (SItype_ppc); | |
132 | extern TFtype __floatdikf_hw (DItype_ppc); | |
133 | extern TFtype __floatunsikf_hw (USItype_ppc); | |
134 | extern TFtype __floatundikf_hw (UDItype_ppc); | |
135 | extern IBM128_TYPE __extendkftf2_hw (TFtype); | |
136 | extern TFtype __trunctfkf2_hw (IBM128_TYPE); | |
75ad35b5 MM |
137 | extern TCtype __mulkc3_hw (TFtype, TFtype, TFtype, TFtype); |
138 | extern TCtype __divkc3_hw (TFtype, TFtype, TFtype, TFtype); | |
a71c0334 MM |
139 | |
140 | /* Ifunc function declarations, to automatically switch between software | |
141 | emulation and hardware support. */ | |
142 | extern TFtype __addkf3 (TFtype, TFtype); | |
143 | extern TFtype __subkf3 (TFtype, TFtype); | |
144 | extern TFtype __mulkf3 (TFtype, TFtype); | |
145 | extern TFtype __divkf3 (TFtype, TFtype); | |
146 | extern TFtype __negkf2 (TFtype); | |
661eb8f9 | 147 | extern TFtype __powikf2 (TFtype, SItype_ppc); |
a71c0334 MM |
148 | extern CMPtype __eqkf2 (TFtype, TFtype); |
149 | extern CMPtype __nekf2 (TFtype, TFtype); | |
150 | extern CMPtype __gekf2 (TFtype, TFtype); | |
151 | extern CMPtype __gtkf2 (TFtype, TFtype); | |
152 | extern CMPtype __lekf2 (TFtype, TFtype); | |
153 | extern CMPtype __ltkf2 (TFtype, TFtype); | |
154 | extern CMPtype __unordkf2 (TFtype, TFtype); | |
155 | extern TFtype __extendsfkf2 (float); | |
156 | extern TFtype __extenddfkf2 (double); | |
157 | extern float __trunckfsf2 (TFtype); | |
158 | extern double __trunckfdf2 (TFtype); | |
159 | extern SItype_ppc __fixkfsi (TFtype); | |
160 | extern DItype_ppc __fixkfdi (TFtype); | |
161 | extern USItype_ppc __fixunskfsi (TFtype); | |
162 | extern UDItype_ppc __fixunskfdi (TFtype); | |
163 | extern TFtype __floatsikf (SItype_ppc); | |
164 | extern TFtype __floatdikf (DItype_ppc); | |
165 | extern TFtype __floatunsikf (USItype_ppc); | |
166 | extern TFtype __floatundikf (UDItype_ppc); | |
167 | extern IBM128_TYPE __extendkftf2 (TFtype); | |
168 | extern TFtype __trunctfkf2 (IBM128_TYPE); | |
169 | ||
f906f5ed BS |
170 | /* Complex __float128 built on __float128 interfaces. */ |
171 | extern TCtype __mulkc3 (TFtype, TFtype, TFtype, TFtype); | |
172 | extern TCtype __divkc3 (TFtype, TFtype, TFtype, TFtype); | |
173 | ||
a71c0334 MM |
174 | /* Implementation of conversions between __ibm128 and __float128, to allow the |
175 | same code to be used on systems with IEEE 128-bit emulation and with IEEE | |
176 | 128-bit hardware support. */ | |
177 | ||
178 | union ibm128_union { | |
179 | IBM128_TYPE ibm128; | |
180 | double dbl[2]; | |
181 | }; | |
182 | ||
183 | #define CVT_FLOAT128_TO_IBM128(RESULT, VALUE) \ | |
184 | { \ | |
185 | double __high, __low; \ | |
d5eea0f7 | 186 | TFtype __value = (VALUE); \ |
a71c0334 MM |
187 | union ibm128_union u; \ |
188 | \ | |
189 | __high = (double) __value; \ | |
190 | if (__builtin_isnan (__high) || __builtin_isinf (__high)) \ | |
191 | __low = 0.0; \ | |
192 | \ | |
193 | else \ | |
194 | { \ | |
195 | double __high_temp; \ | |
196 | \ | |
d5eea0f7 | 197 | __low = (double) (__value - (TFtype) __high); \ |
a71c0334 MM |
198 | /* Renormalize low/high and move them into canonical IBM long \ |
199 | double form. */ \ | |
200 | __high_temp = __high + __low; \ | |
201 | __low = (__high - __high_temp) + __low; \ | |
202 | __high = __high_temp; \ | |
203 | } \ | |
204 | \ | |
205 | u.dbl[0] = __high; \ | |
206 | u.dbl[1] = __low; \ | |
207 | RESULT = u.ibm128; \ | |
208 | } | |
209 | ||
210 | #define CVT_IBM128_TO_FLOAT128(RESULT, VALUE) \ | |
211 | { \ | |
212 | union ibm128_union u; \ | |
213 | double __high, __low; \ | |
214 | \ | |
215 | u.ibm128 = (VALUE); \ | |
216 | __high = u.dbl[0]; \ | |
217 | __low = u.dbl[1]; \ | |
218 | \ | |
219 | /* Handle the special cases of NAN and infinity. */ \ | |
220 | if (__builtin_isnan (__high) || __builtin_isinf (__high)) \ | |
d5eea0f7 | 221 | RESULT = (TFtype) __high; \ |
a71c0334 MM |
222 | \ |
223 | /* If low is 0.0, there no need to do the add. In addition, \ | |
224 | avoiding the add produces the correct sign if high is -0.0. */ \ | |
225 | else if (__low == 0.0) \ | |
d5eea0f7 | 226 | RESULT = (TFtype) __high; \ |
a71c0334 MM |
227 | \ |
228 | else \ | |
d5eea0f7 | 229 | RESULT = ((TFtype) __high) + ((TFtype) __low); \ |
a71c0334 | 230 | } |