PR bootstrap/82916
[official-gcc.git] / libgcc / config / rs6000 / quad-float128.h
blob7d69c87c2acb40a67651ef63c398ca7384652c22
1 /* Software floating-point emulation.
2 Definitions for IEEE Quad Precision on the PowerPC.
3 Copyright (C) 2016-2017 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
5 Contributed by Michael Meissner (meissner@linux.vnet.ibm.com).
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.
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.)
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.
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/>. */
30 /* quad.h defines the TFtype type by:
31 typedef float TFtype __attribute__ ((mode (TF)));
33 This define forces it to use KFmode (aka, ieee 128-bit floating point). */
34 #define TF KF
36 /* We also need TCtype to represent complex ieee 128-bit float for
37 __mulkc3 and __divkc3. */
38 typedef __complex float TCtype __attribute__ ((mode (KC)));
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
45 #include <quad.h>
47 #ifdef __LONG_DOUBLE_IEEE128__
48 #define IBM128_TYPE __ibm128
50 #else
51 #define IBM128_TYPE long double
52 #endif
54 /* Add prototypes of the library functions created. In case the appropriate
55 int/long types are not declared in scope by the time quad.h is included,
56 provide our own version. */
57 typedef int SItype_ppc __attribute__ ((__mode__ (__SI__)));
58 typedef int DItype_ppc __attribute__ ((__mode__ (__DI__)));
59 typedef unsigned USItype_ppc __attribute__ ((__mode__ (__SI__)));
60 typedef unsigned UDItype_ppc __attribute__ ((__mode__ (__DI__)));
62 #ifdef _ARCH_PPC64
63 typedef int TItype_ppc __attribute__ ((__mode__ (__TI__)));
64 typedef unsigned UTItype_ppc __attribute__ ((__mode__ (__TI__)));
65 #endif
67 /* Software emulation functions. */
68 extern TFtype __addkf3_sw (TFtype, TFtype);
69 extern TFtype __subkf3_sw (TFtype, TFtype);
70 extern TFtype __mulkf3_sw (TFtype, TFtype);
71 extern TFtype __divkf3_sw (TFtype, TFtype);
72 extern TFtype __negkf2_sw (TFtype);
73 extern CMPtype __eqkf2_sw (TFtype, TFtype);
74 extern CMPtype __gekf2_sw (TFtype, TFtype);
75 extern CMPtype __lekf2_sw (TFtype, TFtype);
76 extern CMPtype __unordkf2_sw (TFtype, TFtype);
77 extern TFtype __extendsfkf2_sw (float);
78 extern TFtype __extenddfkf2_sw (double);
79 extern float __trunckfsf2_sw (TFtype);
80 extern double __trunckfdf2_sw (TFtype);
81 extern SItype_ppc __fixkfsi_sw (TFtype);
82 extern DItype_ppc __fixkfdi_sw (TFtype);
83 extern USItype_ppc __fixunskfsi_sw (TFtype);
84 extern UDItype_ppc __fixunskfdi_sw (TFtype);
85 extern TFtype __floatsikf_sw (SItype_ppc);
86 extern TFtype __floatdikf_sw (DItype_ppc);
87 extern TFtype __floatunsikf_sw (USItype_ppc);
88 extern TFtype __floatundikf_sw (UDItype_ppc);
89 extern IBM128_TYPE __extendkftf2_sw (TFtype);
90 extern TFtype __trunctfkf2_sw (IBM128_TYPE);
92 #ifdef _ARCH_PPC64
93 /* We do not provide ifunc resolvers for __fixkfti, __fixunskfti, __floattikf,
94 and __floatuntikf. There is no ISA 3.0 instruction that converts between
95 128-bit integer types and 128-bit IEEE floating point, or vice versa. So
96 use the emulator functions for these conversions. */
98 extern TItype_ppc __fixkfti (TFtype);
99 extern UTItype_ppc __fixunskfti (TFtype);
100 extern TFtype __floattikf (TItype_ppc);
101 extern TFtype __floatuntikf (UTItype_ppc);
102 #endif
104 /* Functions using the ISA 3.0 hardware support. If the code is compiled with
105 -mcpu=power9, it will not use these functions, but if it was compiled with
106 -mcpu=power7 or -mcpu=power8 and run on a ISA 3.0 system, it will use the
107 hardware instruction. */
108 extern TFtype __addkf3_hw (TFtype, TFtype);
109 extern TFtype __subkf3_hw (TFtype, TFtype);
110 extern TFtype __mulkf3_hw (TFtype, TFtype);
111 extern TFtype __divkf3_hw (TFtype, TFtype);
112 extern TFtype __negkf2_hw (TFtype);
113 extern CMPtype __eqkf2_hw (TFtype, TFtype);
114 extern CMPtype __gekf2_hw (TFtype, TFtype);
115 extern CMPtype __lekf2_hw (TFtype, TFtype);
116 extern CMPtype __unordkf2_hw (TFtype, TFtype);
117 extern TFtype __extendsfkf2_hw (float);
118 extern TFtype __extenddfkf2_hw (double);
119 extern float __trunckfsf2_hw (TFtype);
120 extern double __trunckfdf2_hw (TFtype);
121 extern SItype_ppc __fixkfsi_hw (TFtype);
122 extern DItype_ppc __fixkfdi_hw (TFtype);
123 extern USItype_ppc __fixunskfsi_hw (TFtype);
124 extern UDItype_ppc __fixunskfdi_hw (TFtype);
125 extern TFtype __floatsikf_hw (SItype_ppc);
126 extern TFtype __floatdikf_hw (DItype_ppc);
127 extern TFtype __floatunsikf_hw (USItype_ppc);
128 extern TFtype __floatundikf_hw (UDItype_ppc);
129 extern IBM128_TYPE __extendkftf2_hw (TFtype);
130 extern TFtype __trunctfkf2_hw (IBM128_TYPE);
132 /* Ifunc function declarations, to automatically switch between software
133 emulation and hardware support. */
134 extern TFtype __addkf3 (TFtype, TFtype);
135 extern TFtype __subkf3 (TFtype, TFtype);
136 extern TFtype __mulkf3 (TFtype, TFtype);
137 extern TFtype __divkf3 (TFtype, TFtype);
138 extern TFtype __negkf2 (TFtype);
139 extern CMPtype __eqkf2 (TFtype, TFtype);
140 extern CMPtype __nekf2 (TFtype, TFtype);
141 extern CMPtype __gekf2 (TFtype, TFtype);
142 extern CMPtype __gtkf2 (TFtype, TFtype);
143 extern CMPtype __lekf2 (TFtype, TFtype);
144 extern CMPtype __ltkf2 (TFtype, TFtype);
145 extern CMPtype __unordkf2 (TFtype, TFtype);
146 extern TFtype __extendsfkf2 (float);
147 extern TFtype __extenddfkf2 (double);
148 extern float __trunckfsf2 (TFtype);
149 extern double __trunckfdf2 (TFtype);
150 extern SItype_ppc __fixkfsi (TFtype);
151 extern DItype_ppc __fixkfdi (TFtype);
152 extern USItype_ppc __fixunskfsi (TFtype);
153 extern UDItype_ppc __fixunskfdi (TFtype);
154 extern TFtype __floatsikf (SItype_ppc);
155 extern TFtype __floatdikf (DItype_ppc);
156 extern TFtype __floatunsikf (USItype_ppc);
157 extern TFtype __floatundikf (UDItype_ppc);
158 extern IBM128_TYPE __extendkftf2 (TFtype);
159 extern TFtype __trunctfkf2 (IBM128_TYPE);
161 /* Complex __float128 built on __float128 interfaces. */
162 extern TCtype __mulkc3 (TFtype, TFtype, TFtype, TFtype);
163 extern TCtype __divkc3 (TFtype, TFtype, TFtype, TFtype);
165 /* Implementation of conversions between __ibm128 and __float128, to allow the
166 same code to be used on systems with IEEE 128-bit emulation and with IEEE
167 128-bit hardware support. */
169 union ibm128_union {
170 IBM128_TYPE ibm128;
171 double dbl[2];
174 #define CVT_FLOAT128_TO_IBM128(RESULT, VALUE) \
176 double __high, __low; \
177 __float128 __value = (VALUE); \
178 union ibm128_union u; \
180 __high = (double) __value; \
181 if (__builtin_isnan (__high) || __builtin_isinf (__high)) \
182 __low = 0.0; \
184 else \
186 double __high_temp; \
188 __low = (double) (__value - (__float128) __high); \
189 /* Renormalize low/high and move them into canonical IBM long \
190 double form. */ \
191 __high_temp = __high + __low; \
192 __low = (__high - __high_temp) + __low; \
193 __high = __high_temp; \
196 u.dbl[0] = __high; \
197 u.dbl[1] = __low; \
198 RESULT = u.ibm128; \
201 #define CVT_IBM128_TO_FLOAT128(RESULT, VALUE) \
203 union ibm128_union u; \
204 double __high, __low; \
206 u.ibm128 = (VALUE); \
207 __high = u.dbl[0]; \
208 __low = u.dbl[1]; \
210 /* Handle the special cases of NAN and infinity. */ \
211 if (__builtin_isnan (__high) || __builtin_isinf (__high)) \
212 RESULT = (__float128) __high; \
214 /* If low is 0.0, there no need to do the add. In addition, \
215 avoiding the add produces the correct sign if high is -0.0. */ \
216 else if (__low == 0.0) \
217 RESULT = (__float128) __high; \
219 else \
220 RESULT = ((__float128) __high) + ((__float128) __low); \