1 /* Software floating-point emulation.
2    Definitions for IEEE Quad Precision on the PowerPC.
3    Copyright (C) 2016-2021 Free Software Foundation, Inc.
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 
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__
37 #define TF KF
38 
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 
43 #else
44 typedef __complex float TCtype __attribute__ ((mode (TC)));
45 #endif
46 
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 <stddef.h>
53 #include <quad.h>
54 
55 #define IBM128_TYPE	__ibm128
56 
57 /* Add prototypes of the library functions created.  In case the appropriate
58    int/long types are not declared in scope by the time quad.h is included,
59    provide our own version.  */
60 typedef int	 SItype_ppc  __attribute__ ((__mode__ (__SI__)));
61 typedef int	 DItype_ppc  __attribute__ ((__mode__ (__DI__)));
62 typedef unsigned USItype_ppc __attribute__ ((__mode__ (__SI__)));
63 typedef unsigned UDItype_ppc __attribute__ ((__mode__ (__DI__)));
64 
65 #ifdef _ARCH_PPC64
66 typedef int	 TItype_ppc  __attribute__ ((__mode__ (__TI__)));
67 typedef unsigned UTItype_ppc __attribute__ ((__mode__ (__TI__)));
68 #endif
69 
70 /* Software emulation functions.  */
71 extern TFtype __addkf3_sw (TFtype, TFtype);
72 extern TFtype __subkf3_sw (TFtype, TFtype);
73 extern TFtype __mulkf3_sw (TFtype, TFtype);
74 extern TFtype __divkf3_sw (TFtype, TFtype);
75 extern TFtype __negkf2_sw (TFtype);
76 extern TFtype __powikf2_sw (TFtype, SItype_ppc);
77 extern CMPtype __eqkf2_sw (TFtype, TFtype);
78 extern CMPtype __gekf2_sw (TFtype, TFtype);
79 extern CMPtype __lekf2_sw (TFtype, TFtype);
80 extern CMPtype __unordkf2_sw (TFtype, TFtype);
81 extern TFtype __extendsfkf2_sw (float);
82 extern TFtype __extenddfkf2_sw (double);
83 extern float __trunckfsf2_sw (TFtype);
84 extern double __trunckfdf2_sw (TFtype);
85 extern SItype_ppc __fixkfsi_sw (TFtype);
86 extern DItype_ppc __fixkfdi_sw (TFtype);
87 extern USItype_ppc __fixunskfsi_sw (TFtype);
88 extern UDItype_ppc __fixunskfdi_sw (TFtype);
89 extern TFtype __floatsikf_sw (SItype_ppc);
90 extern TFtype __floatdikf_sw (DItype_ppc);
91 #ifdef _ARCH_PPC64
92 extern TFtype __floattikf_sw (TItype_ppc);
93 #endif
94 extern TFtype __floatunsikf_sw (USItype_ppc);
95 extern TFtype __floatundikf_sw (UDItype_ppc);
96 #ifdef _ARCH_PPC64
97 extern TFtype __floatuntikf_sw (UTItype_ppc);
98 extern TItype_ppc __fixkfti_sw (TFtype);
99 extern UTItype_ppc __fixunskfti_sw (TFtype);
100 #endif
101 extern IBM128_TYPE __extendkftf2_sw (TFtype);
102 extern TFtype __trunctfkf2_sw (IBM128_TYPE);
103 extern TCtype __mulkc3_sw (TFtype, TFtype, TFtype, TFtype);
104 extern TCtype __divkc3_sw (TFtype, TFtype, TFtype, TFtype);
105 
106 #ifdef _ARCH_PPC64
107 extern TItype_ppc __fixkfti (TFtype);
108 extern UTItype_ppc __fixunskfti (TFtype);
109 extern TFtype __floattikf (TItype_ppc);
110 extern TFtype __floatuntikf (UTItype_ppc);
111 #endif
112 
113 /* Functions using the ISA 3.0 hardware support.  If the code is compiled with
114    -mcpu=power9, it will not use these functions, but if it was compiled with
115    -mcpu=power7 or -mcpu=power8 and run on a ISA 3.0 system, it will use the
116    hardware instruction.  */
117 extern TFtype __addkf3_hw (TFtype, TFtype);
118 extern TFtype __subkf3_hw (TFtype, TFtype);
119 extern TFtype __mulkf3_hw (TFtype, TFtype);
120 extern TFtype __divkf3_hw (TFtype, TFtype);
121 extern TFtype __negkf2_hw (TFtype);
122 extern TFtype __powikf2_hw (TFtype, SItype_ppc);
123 extern CMPtype __eqkf2_hw (TFtype, TFtype);
124 extern CMPtype __gekf2_hw (TFtype, TFtype);
125 extern CMPtype __lekf2_hw (TFtype, TFtype);
126 extern CMPtype __unordkf2_hw (TFtype, TFtype);
127 extern TFtype __extendsfkf2_hw (float);
128 extern TFtype __extenddfkf2_hw (double);
129 extern float __trunckfsf2_hw (TFtype);
130 extern double __trunckfdf2_hw (TFtype);
131 extern SItype_ppc __fixkfsi_hw (TFtype);
132 extern DItype_ppc __fixkfdi_hw (TFtype);
133 extern USItype_ppc __fixunskfsi_hw (TFtype);
134 extern UDItype_ppc __fixunskfdi_hw (TFtype);
135 extern TFtype __floatsikf_hw (SItype_ppc);
136 extern TFtype __floatdikf_hw (DItype_ppc);
137 #ifdef _ARCH_PPC64
138 extern TFtype __floattikf_hw (TItype_ppc);
139 #endif
140 extern TFtype __floatunsikf_hw (USItype_ppc);
141 extern TFtype __floatundikf_hw (UDItype_ppc);
142 #ifdef _ARCH_PPC64
143 extern TFtype __floatuntikf_hw (UTItype_ppc);
144 extern TItype_ppc __fixkfti_hw (TFtype);
145 extern UTItype_ppc __fixunskfti_hw (TFtype);
146 #endif
147 extern IBM128_TYPE __extendkftf2_hw (TFtype);
148 extern TFtype __trunctfkf2_hw (IBM128_TYPE);
149 extern TCtype __mulkc3_hw (TFtype, TFtype, TFtype, TFtype);
150 extern TCtype __divkc3_hw (TFtype, TFtype, TFtype, TFtype);
151 
152 /* Ifunc function declarations, to automatically switch between software
153    emulation and hardware support.  */
154 extern TFtype __addkf3 (TFtype, TFtype);
155 extern TFtype __subkf3 (TFtype, TFtype);
156 extern TFtype __mulkf3 (TFtype, TFtype);
157 extern TFtype __divkf3 (TFtype, TFtype);
158 extern TFtype __negkf2 (TFtype);
159 extern TFtype __powikf2 (TFtype, SItype_ppc);
160 extern CMPtype __eqkf2 (TFtype, TFtype);
161 extern CMPtype __nekf2 (TFtype, TFtype);
162 extern CMPtype __gekf2 (TFtype, TFtype);
163 extern CMPtype __gtkf2 (TFtype, TFtype);
164 extern CMPtype __lekf2 (TFtype, TFtype);
165 extern CMPtype __ltkf2 (TFtype, TFtype);
166 extern CMPtype __unordkf2 (TFtype, TFtype);
167 extern TFtype __extendsfkf2 (float);
168 extern TFtype __extenddfkf2 (double);
169 extern float __trunckfsf2 (TFtype);
170 extern double __trunckfdf2 (TFtype);
171 extern SItype_ppc __fixkfsi (TFtype);
172 extern DItype_ppc __fixkfdi (TFtype);
173 extern USItype_ppc __fixunskfsi (TFtype);
174 extern UDItype_ppc __fixunskfdi (TFtype);
175 extern TFtype __floatsikf (SItype_ppc);
176 extern TFtype __floatdikf (DItype_ppc);
177 #ifdef _ARCH_PPC64
178 extern TFtype __floattikf (TItype_ppc);
179 #endif
180 extern TFtype __floatunsikf (USItype_ppc);
181 extern TFtype __floatundikf (UDItype_ppc);
182 #ifdef _ARCH_PPC64
183 extern TFtype __floatuntikf (UTItype_ppc);
184 extern TItype_ppc __fixkfti (TFtype);
185 extern UTItype_ppc __fixunskfti (TFtype);
186 #endif
187 extern IBM128_TYPE __extendkftf2 (TFtype);
188 extern TFtype __trunctfkf2 (IBM128_TYPE);
189 
190 /* Complex __float128 built on __float128 interfaces.  */
191 extern TCtype __mulkc3 (TFtype, TFtype, TFtype, TFtype);
192 extern TCtype __divkc3 (TFtype, TFtype, TFtype, TFtype);
193 
194 /* Convert IEEE 128-bit floating point to/from string.  We explicitly use
195    _Float128 instead of TFmode because _strtokf and _strfromkf must be compiled
196    with long double being IBM 128.  */
197 extern _Float128 __strtokf (const char *, char **);
198 extern int __strfromkf (char *restrict, size_t, const char *restrict,
199 			_Float128);
200 
201 /* Implementation of conversions between __ibm128 and __float128, to allow the
202    same code to be used on systems with IEEE 128-bit emulation and with IEEE
203    128-bit hardware support.  */
204 
205 union ibm128_union {
206   IBM128_TYPE ibm128;
207   double dbl[2];
208 };
209 
210 #define CVT_FLOAT128_TO_IBM128(RESULT, VALUE)				\
211 {									\
212   double __high, __low;							\
213   TFtype __value = (VALUE);						\
214   union ibm128_union u;							\
215 									\
216   __high = (double) __value;						\
217   if (__builtin_isnan (__high) || __builtin_isinf (__high))		\
218     __low = 0.0;							\
219 									\
220   else									\
221     {									\
222       double __high_temp;						\
223 									\
224       __low = (double) (__value - (TFtype) __high);			\
225       /* Renormalize low/high and move them into canonical IBM long	\
226 	 double form.  */						\
227       __high_temp = __high + __low;					\
228       __low = (__high - __high_temp) + __low;				\
229       __high = __high_temp;						\
230     }									\
231 									\
232   u.dbl[0] = __high;							\
233   u.dbl[1] = __low;							\
234   RESULT = u.ibm128;							\
235 }
236 
237 #define CVT_IBM128_TO_FLOAT128(RESULT, VALUE)				\
238 {									\
239   union ibm128_union u;							\
240   double __high, __low;							\
241 									\
242   u.ibm128 = (VALUE);							\
243   __high = u.dbl[0];							\
244   __low = u.dbl[1];							\
245 									\
246   /* Handle the special cases of NAN and infinity.  */			\
247   if (__builtin_isnan (__high) || __builtin_isinf (__high))		\
248     RESULT = (TFtype) __high;						\
249 									\
250   /* If low is 0.0, there no need to do the add.  In addition,		\
251      avoiding the add produces the correct sign if high is -0.0.  */	\
252   else if (__low == 0.0)						\
253     RESULT = (TFtype) __high;						\
254 									\
255   else									\
256     RESULT = ((TFtype) __high) + ((TFtype) __low);			\
257 }
258