]> gcc.gnu.org Git - gcc.git/blame - libgcc/config/rs6000/quad-float128.h
PR target/107299: Fix build issue when long double is IEEE 128-bit
[gcc.git] / libgcc / config / rs6000 / quad-float128.h
CommitLineData
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. */
53typedef int SItype_ppc __attribute__ ((__mode__ (__SI__)));
54typedef int DItype_ppc __attribute__ ((__mode__ (__DI__)));
55typedef unsigned USItype_ppc __attribute__ ((__mode__ (__SI__)));
56typedef unsigned UDItype_ppc __attribute__ ((__mode__ (__DI__)));
57
58#ifdef _ARCH_PPC64
59typedef int TItype_ppc __attribute__ ((__mode__ (__TI__)));
60typedef unsigned UTItype_ppc __attribute__ ((__mode__ (__TI__)));
61#endif
62
63/* Software emulation functions. */
64extern TFtype __addkf3_sw (TFtype, TFtype);
65extern TFtype __subkf3_sw (TFtype, TFtype);
66extern TFtype __mulkf3_sw (TFtype, TFtype);
67extern TFtype __divkf3_sw (TFtype, TFtype);
68extern TFtype __negkf2_sw (TFtype);
661eb8f9 69extern TFtype __powikf2_sw (TFtype, SItype_ppc);
a71c0334
MM
70extern CMPtype __eqkf2_sw (TFtype, TFtype);
71extern CMPtype __gekf2_sw (TFtype, TFtype);
72extern CMPtype __lekf2_sw (TFtype, TFtype);
73extern CMPtype __unordkf2_sw (TFtype, TFtype);
74extern TFtype __extendsfkf2_sw (float);
75extern TFtype __extenddfkf2_sw (double);
76extern float __trunckfsf2_sw (TFtype);
77extern double __trunckfdf2_sw (TFtype);
78extern SItype_ppc __fixkfsi_sw (TFtype);
79extern DItype_ppc __fixkfdi_sw (TFtype);
80extern USItype_ppc __fixunskfsi_sw (TFtype);
81extern UDItype_ppc __fixunskfdi_sw (TFtype);
82extern TFtype __floatsikf_sw (SItype_ppc);
83extern TFtype __floatdikf_sw (DItype_ppc);
7a895955 84#ifdef _ARCH_PPC64
9090f480 85extern TFtype __floattikf_sw (TItype_ppc);
7a895955 86#endif
a71c0334
MM
87extern TFtype __floatunsikf_sw (USItype_ppc);
88extern TFtype __floatundikf_sw (UDItype_ppc);
7a895955 89#ifdef _ARCH_PPC64
9090f480
CL
90extern TFtype __floatuntikf_sw (UTItype_ppc);
91extern TItype_ppc __fixkfti_sw (TFtype);
92extern UTItype_ppc __fixunskfti_sw (TFtype);
7a895955 93#endif
a71c0334
MM
94extern IBM128_TYPE __extendkftf2_sw (TFtype);
95extern TFtype __trunctfkf2_sw (IBM128_TYPE);
68ed94d0
MM
96extern TCtype __mulkc3_sw (TFtype, TFtype, TFtype, TFtype);
97extern TCtype __divkc3_sw (TFtype, TFtype, TFtype, TFtype);
a71c0334
MM
98
99#ifdef _ARCH_PPC64
a71c0334
MM
100extern TItype_ppc __fixkfti (TFtype);
101extern UTItype_ppc __fixunskfti (TFtype);
102extern TFtype __floattikf (TItype_ppc);
103extern 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. */
110extern TFtype __addkf3_hw (TFtype, TFtype);
111extern TFtype __subkf3_hw (TFtype, TFtype);
112extern TFtype __mulkf3_hw (TFtype, TFtype);
113extern TFtype __divkf3_hw (TFtype, TFtype);
114extern TFtype __negkf2_hw (TFtype);
661eb8f9 115extern TFtype __powikf2_hw (TFtype, SItype_ppc);
a71c0334
MM
116extern CMPtype __eqkf2_hw (TFtype, TFtype);
117extern CMPtype __gekf2_hw (TFtype, TFtype);
118extern CMPtype __lekf2_hw (TFtype, TFtype);
119extern CMPtype __unordkf2_hw (TFtype, TFtype);
120extern TFtype __extendsfkf2_hw (float);
121extern TFtype __extenddfkf2_hw (double);
122extern float __trunckfsf2_hw (TFtype);
123extern double __trunckfdf2_hw (TFtype);
124extern SItype_ppc __fixkfsi_hw (TFtype);
125extern DItype_ppc __fixkfdi_hw (TFtype);
126extern USItype_ppc __fixunskfsi_hw (TFtype);
127extern UDItype_ppc __fixunskfdi_hw (TFtype);
128extern TFtype __floatsikf_hw (SItype_ppc);
129extern TFtype __floatdikf_hw (DItype_ppc);
7a895955 130#ifdef _ARCH_PPC64
9090f480 131extern TFtype __floattikf_hw (TItype_ppc);
7a895955 132#endif
a71c0334
MM
133extern TFtype __floatunsikf_hw (USItype_ppc);
134extern TFtype __floatundikf_hw (UDItype_ppc);
7a895955 135#ifdef _ARCH_PPC64
9090f480
CL
136extern TFtype __floatuntikf_hw (UTItype_ppc);
137extern TItype_ppc __fixkfti_hw (TFtype);
138extern UTItype_ppc __fixunskfti_hw (TFtype);
7a895955 139#endif
a71c0334
MM
140extern IBM128_TYPE __extendkftf2_hw (TFtype);
141extern TFtype __trunctfkf2_hw (IBM128_TYPE);
68ed94d0
MM
142extern TCtype __mulkc3_hw (TFtype, TFtype, TFtype, TFtype);
143extern TCtype __divkc3_hw (TFtype, TFtype, TFtype, TFtype);
a71c0334
MM
144
145/* Ifunc function declarations, to automatically switch between software
146 emulation and hardware support. */
147extern TFtype __addkf3 (TFtype, TFtype);
148extern TFtype __subkf3 (TFtype, TFtype);
149extern TFtype __mulkf3 (TFtype, TFtype);
150extern TFtype __divkf3 (TFtype, TFtype);
151extern TFtype __negkf2 (TFtype);
661eb8f9 152extern TFtype __powikf2 (TFtype, SItype_ppc);
a71c0334
MM
153extern CMPtype __eqkf2 (TFtype, TFtype);
154extern CMPtype __nekf2 (TFtype, TFtype);
155extern CMPtype __gekf2 (TFtype, TFtype);
156extern CMPtype __gtkf2 (TFtype, TFtype);
157extern CMPtype __lekf2 (TFtype, TFtype);
158extern CMPtype __ltkf2 (TFtype, TFtype);
159extern CMPtype __unordkf2 (TFtype, TFtype);
160extern TFtype __extendsfkf2 (float);
161extern TFtype __extenddfkf2 (double);
162extern float __trunckfsf2 (TFtype);
163extern double __trunckfdf2 (TFtype);
164extern SItype_ppc __fixkfsi (TFtype);
165extern DItype_ppc __fixkfdi (TFtype);
166extern USItype_ppc __fixunskfsi (TFtype);
167extern UDItype_ppc __fixunskfdi (TFtype);
168extern TFtype __floatsikf (SItype_ppc);
169extern TFtype __floatdikf (DItype_ppc);
7a895955 170#ifdef _ARCH_PPC64
9090f480 171extern TFtype __floattikf (TItype_ppc);
7a895955 172#endif
a71c0334
MM
173extern TFtype __floatunsikf (USItype_ppc);
174extern TFtype __floatundikf (UDItype_ppc);
7a895955 175#ifdef _ARCH_PPC64
9090f480
CL
176extern TFtype __floatuntikf (UTItype_ppc);
177extern TItype_ppc __fixkfti (TFtype);
178extern UTItype_ppc __fixunskfti (TFtype);
7a895955 179#endif
a71c0334
MM
180extern IBM128_TYPE __extendkftf2 (TFtype);
181extern TFtype __trunctfkf2 (IBM128_TYPE);
182
972623a3 183/* Complex __float128 built on __float128 interfaces. */
68ed94d0
MM
184extern TCtype __mulkc3 (TFtype, TFtype, TFtype, TFtype);
185extern 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. */
190extern _Float128 __strtokf (const char *, char **);
191extern 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
198union 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}
This page took 0.704792 seconds and 5 git commands to generate.