ibm-ldouble.c revision 1.1.1.1.8.2 1 1.1.1.1.8.2 tls /* 128-bit long double support routines for Darwin.
2 1.1.1.1.8.2 tls Copyright (C) 1993-2013 Free Software Foundation, Inc.
3 1.1.1.1.8.2 tls
4 1.1.1.1.8.2 tls This file is part of GCC.
5 1.1.1.1.8.2 tls
6 1.1.1.1.8.2 tls GCC is free software; you can redistribute it and/or modify it under
7 1.1.1.1.8.2 tls the terms of the GNU General Public License as published by the Free
8 1.1.1.1.8.2 tls Software Foundation; either version 3, or (at your option) any later
9 1.1.1.1.8.2 tls version.
10 1.1.1.1.8.2 tls
11 1.1.1.1.8.2 tls GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 1.1.1.1.8.2 tls WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 1.1.1.1.8.2 tls FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 1.1.1.1.8.2 tls for more details.
15 1.1.1.1.8.2 tls
16 1.1.1.1.8.2 tls Under Section 7 of GPL version 3, you are granted additional
17 1.1.1.1.8.2 tls permissions described in the GCC Runtime Library Exception, version
18 1.1.1.1.8.2 tls 3.1, as published by the Free Software Foundation.
19 1.1.1.1.8.2 tls
20 1.1.1.1.8.2 tls You should have received a copy of the GNU General Public License and
21 1.1.1.1.8.2 tls a copy of the GCC Runtime Library Exception along with this program;
22 1.1.1.1.8.2 tls see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 1.1.1.1.8.2 tls <http://www.gnu.org/licenses/>. */
24 1.1.1.1.8.2 tls
25 1.1.1.1.8.2 tls
26 1.1.1.1.8.2 tls /* Implementations of floating-point long double basic arithmetic
27 1.1.1.1.8.2 tls functions called by the IBM C compiler when generating code for
28 1.1.1.1.8.2 tls PowerPC platforms. In particular, the following functions are
29 1.1.1.1.8.2 tls implemented: __gcc_qadd, __gcc_qsub, __gcc_qmul, and __gcc_qdiv.
30 1.1.1.1.8.2 tls Double-double algorithms are based on the paper "Doubled-Precision
31 1.1.1.1.8.2 tls IEEE Standard 754 Floating-Point Arithmetic" by W. Kahan, February 26,
32 1.1.1.1.8.2 tls 1987. An alternative published reference is "Software for
33 1.1.1.1.8.2 tls Doubled-Precision Floating-Point Computations", by Seppo Linnainmaa,
34 1.1.1.1.8.2 tls ACM TOMS vol 7 no 3, September 1981, pages 272-283. */
35 1.1.1.1.8.2 tls
36 1.1.1.1.8.2 tls /* Each long double is made up of two IEEE doubles. The value of the
37 1.1.1.1.8.2 tls long double is the sum of the values of the two parts. The most
38 1.1.1.1.8.2 tls significant part is required to be the value of the long double
39 1.1.1.1.8.2 tls rounded to the nearest double, as specified by IEEE. For Inf
40 1.1.1.1.8.2 tls values, the least significant part is required to be one of +0.0 or
41 1.1.1.1.8.2 tls -0.0. No other requirements are made; so, for example, 1.0 may be
42 1.1.1.1.8.2 tls represented as (1.0, +0.0) or (1.0, -0.0), and the low part of a
43 1.1.1.1.8.2 tls NaN is don't-care.
44 1.1.1.1.8.2 tls
45 1.1.1.1.8.2 tls This code currently assumes the most significant double is in
46 1.1.1.1.8.2 tls the lower numbered register or lower addressed memory. */
47 1.1.1.1.8.2 tls
48 1.1.1.1.8.2 tls #if defined (__MACH__) || defined (__powerpc__) || defined (_AIX)
49 1.1.1.1.8.2 tls
50 1.1.1.1.8.2 tls #define fabs(x) __builtin_fabs(x)
51 1.1.1.1.8.2 tls #define isless(x, y) __builtin_isless (x, y)
52 1.1.1.1.8.2 tls #define inf() __builtin_inf()
53 1.1.1.1.8.2 tls
54 1.1.1.1.8.2 tls #define unlikely(x) __builtin_expect ((x), 0)
55 1.1.1.1.8.2 tls
56 1.1.1.1.8.2 tls #define nonfinite(a) unlikely (! isless (fabs (a), inf ()))
57 1.1.1.1.8.2 tls
58 1.1.1.1.8.2 tls /* Define ALIASNAME as a strong alias for NAME. */
59 1.1.1.1.8.2 tls # define strong_alias(name, aliasname) _strong_alias(name, aliasname)
60 1.1.1.1.8.2 tls # define _strong_alias(name, aliasname) \
61 1.1.1.1.8.2 tls extern __typeof (name) aliasname __attribute__ ((alias (#name)));
62 1.1.1.1.8.2 tls
63 1.1.1.1.8.2 tls /* All these routines actually take two long doubles as parameters,
64 1.1.1.1.8.2 tls but GCC currently generates poor code when a union is used to turn
65 1.1.1.1.8.2 tls a long double into a pair of doubles. */
66 1.1.1.1.8.2 tls
67 1.1.1.1.8.2 tls long double __gcc_qadd (double, double, double, double);
68 1.1.1.1.8.2 tls long double __gcc_qsub (double, double, double, double);
69 1.1.1.1.8.2 tls long double __gcc_qmul (double, double, double, double);
70 1.1.1.1.8.2 tls long double __gcc_qdiv (double, double, double, double);
71 1.1.1.1.8.2 tls
72 1.1.1.1.8.2 tls #if defined __ELF__ && defined SHARED \
73 1.1.1.1.8.2 tls && (defined __powerpc64__ || !(defined __linux__ || defined __gnu_hurd__))
74 1.1.1.1.8.2 tls /* Provide definitions of the old symbol names to satisfy apps and
75 1.1.1.1.8.2 tls shared libs built against an older libgcc. To access the _xlq
76 1.1.1.1.8.2 tls symbols an explicit version reference is needed, so these won't
77 1.1.1.1.8.2 tls satisfy an unadorned reference like _xlqadd. If dot symbols are
78 1.1.1.1.8.2 tls not needed, the assembler will remove the aliases from the symbol
79 1.1.1.1.8.2 tls table. */
80 1.1.1.1.8.2 tls __asm__ (".symver __gcc_qadd,_xlqadd (at) GCC_3.4\n\t"
81 1.1.1.1.8.2 tls ".symver __gcc_qsub,_xlqsub (at) GCC_3.4\n\t"
82 1.1.1.1.8.2 tls ".symver __gcc_qmul,_xlqmul (at) GCC_3.4\n\t"
83 1.1.1.1.8.2 tls ".symver __gcc_qdiv,_xlqdiv (at) GCC_3.4\n\t"
84 1.1.1.1.8.2 tls ".symver .__gcc_qadd,._xlqadd (at) GCC_3.4\n\t"
85 1.1.1.1.8.2 tls ".symver .__gcc_qsub,._xlqsub (at) GCC_3.4\n\t"
86 1.1.1.1.8.2 tls ".symver .__gcc_qmul,._xlqmul (at) GCC_3.4\n\t"
87 1.1.1.1.8.2 tls ".symver .__gcc_qdiv,._xlqdiv (at) GCC_3.4");
88 1.1.1.1.8.2 tls #endif
89 1.1.1.1.8.2 tls
90 1.1.1.1.8.2 tls typedef union
91 1.1.1.1.8.2 tls {
92 1.1.1.1.8.2 tls long double ldval;
93 1.1.1.1.8.2 tls double dval[2];
94 1.1.1.1.8.2 tls } longDblUnion;
95 1.1.1.1.8.2 tls
96 1.1.1.1.8.2 tls /* Add two 'long double' values and return the result. */
97 1.1.1.1.8.2 tls long double
98 1.1.1.1.8.2 tls __gcc_qadd (double a, double aa, double c, double cc)
99 1.1.1.1.8.2 tls {
100 1.1.1.1.8.2 tls longDblUnion x;
101 1.1.1.1.8.2 tls double z, q, zz, xh;
102 1.1.1.1.8.2 tls
103 1.1.1.1.8.2 tls z = a + c;
104 1.1.1.1.8.2 tls
105 1.1.1.1.8.2 tls if (nonfinite (z))
106 1.1.1.1.8.2 tls {
107 1.1.1.1.8.2 tls z = cc + aa + c + a;
108 1.1.1.1.8.2 tls if (nonfinite (z))
109 1.1.1.1.8.2 tls return z;
110 1.1.1.1.8.2 tls x.dval[0] = z; /* Will always be DBL_MAX. */
111 1.1.1.1.8.2 tls zz = aa + cc;
112 1.1.1.1.8.2 tls if (fabs(a) > fabs(c))
113 1.1.1.1.8.2 tls x.dval[1] = a - z + c + zz;
114 1.1.1.1.8.2 tls else
115 1.1.1.1.8.2 tls x.dval[1] = c - z + a + zz;
116 1.1.1.1.8.2 tls }
117 1.1.1.1.8.2 tls else
118 1.1.1.1.8.2 tls {
119 1.1.1.1.8.2 tls q = a - z;
120 1.1.1.1.8.2 tls zz = q + c + (a - (q + z)) + aa + cc;
121 1.1.1.1.8.2 tls
122 1.1.1.1.8.2 tls /* Keep -0 result. */
123 1.1.1.1.8.2 tls if (zz == 0.0)
124 1.1.1.1.8.2 tls return z;
125 1.1.1.1.8.2 tls
126 1.1.1.1.8.2 tls xh = z + zz;
127 1.1.1.1.8.2 tls if (nonfinite (xh))
128 1.1.1.1.8.2 tls return xh;
129 1.1.1.1.8.2 tls
130 1.1.1.1.8.2 tls x.dval[0] = xh;
131 1.1.1.1.8.2 tls x.dval[1] = z - xh + zz;
132 1.1.1.1.8.2 tls }
133 1.1.1.1.8.2 tls return x.ldval;
134 1.1.1.1.8.2 tls }
135 1.1.1.1.8.2 tls
136 1.1.1.1.8.2 tls long double
137 1.1.1.1.8.2 tls __gcc_qsub (double a, double b, double c, double d)
138 1.1.1.1.8.2 tls {
139 1.1.1.1.8.2 tls return __gcc_qadd (a, b, -c, -d);
140 1.1.1.1.8.2 tls }
141 1.1.1.1.8.2 tls
142 1.1.1.1.8.2 tls #ifdef __NO_FPRS__
143 1.1.1.1.8.2 tls static double fmsub (double, double, double);
144 1.1.1.1.8.2 tls #endif
145 1.1.1.1.8.2 tls
146 1.1.1.1.8.2 tls long double
147 1.1.1.1.8.2 tls __gcc_qmul (double a, double b, double c, double d)
148 1.1.1.1.8.2 tls {
149 1.1.1.1.8.2 tls longDblUnion z;
150 1.1.1.1.8.2 tls double t, tau, u, v, w;
151 1.1.1.1.8.2 tls
152 1.1.1.1.8.2 tls t = a * c; /* Highest order double term. */
153 1.1.1.1.8.2 tls
154 1.1.1.1.8.2 tls if (unlikely (t == 0) /* Preserve -0. */
155 1.1.1.1.8.2 tls || nonfinite (t))
156 1.1.1.1.8.2 tls return t;
157 1.1.1.1.8.2 tls
158 1.1.1.1.8.2 tls /* Sum terms of two highest orders. */
159 1.1.1.1.8.2 tls
160 1.1.1.1.8.2 tls /* Use fused multiply-add to get low part of a * c. */
161 1.1.1.1.8.2 tls #ifndef __NO_FPRS__
162 1.1.1.1.8.2 tls asm ("fmsub %0,%1,%2,%3" : "=f"(tau) : "f"(a), "f"(c), "f"(t));
163 1.1.1.1.8.2 tls #else
164 1.1.1.1.8.2 tls tau = fmsub (a, c, t);
165 1.1.1.1.8.2 tls #endif
166 1.1.1.1.8.2 tls v = a*d;
167 1.1.1.1.8.2 tls w = b*c;
168 1.1.1.1.8.2 tls tau += v + w; /* Add in other second-order terms. */
169 1.1.1.1.8.2 tls u = t + tau;
170 1.1.1.1.8.2 tls
171 1.1.1.1.8.2 tls /* Construct long double result. */
172 1.1.1.1.8.2 tls if (nonfinite (u))
173 1.1.1.1.8.2 tls return u;
174 1.1.1.1.8.2 tls z.dval[0] = u;
175 1.1.1.1.8.2 tls z.dval[1] = (t - u) + tau;
176 1.1.1.1.8.2 tls return z.ldval;
177 1.1.1.1.8.2 tls }
178 1.1.1.1.8.2 tls
179 1.1.1.1.8.2 tls long double
180 1.1.1.1.8.2 tls __gcc_qdiv (double a, double b, double c, double d)
181 1.1.1.1.8.2 tls {
182 1.1.1.1.8.2 tls longDblUnion z;
183 1.1.1.1.8.2 tls double s, sigma, t, tau, u, v, w;
184 1.1.1.1.8.2 tls
185 1.1.1.1.8.2 tls t = a / c; /* highest order double term */
186 1.1.1.1.8.2 tls
187 1.1.1.1.8.2 tls if (unlikely (t == 0) /* Preserve -0. */
188 1.1.1.1.8.2 tls || nonfinite (t))
189 1.1.1.1.8.2 tls return t;
190 1.1.1.1.8.2 tls
191 1.1.1.1.8.2 tls /* Finite nonzero result requires corrections to the highest order
192 1.1.1.1.8.2 tls term. These corrections require the low part of c * t to be
193 1.1.1.1.8.2 tls exactly represented in double. */
194 1.1.1.1.8.2 tls if (fabs (a) <= 0x1p-969)
195 1.1.1.1.8.2 tls {
196 1.1.1.1.8.2 tls a *= 0x1p106;
197 1.1.1.1.8.2 tls b *= 0x1p106;
198 1.1.1.1.8.2 tls c *= 0x1p106;
199 1.1.1.1.8.2 tls d *= 0x1p106;
200 1.1.1.1.8.2 tls }
201 1.1.1.1.8.2 tls
202 1.1.1.1.8.2 tls s = c * t; /* (s,sigma) = c*t exactly. */
203 1.1.1.1.8.2 tls w = -(-b + d * t); /* Written to get fnmsub for speed, but not
204 1.1.1.1.8.2 tls numerically necessary. */
205 1.1.1.1.8.2 tls
206 1.1.1.1.8.2 tls /* Use fused multiply-add to get low part of c * t. */
207 1.1.1.1.8.2 tls #ifndef __NO_FPRS__
208 1.1.1.1.8.2 tls asm ("fmsub %0,%1,%2,%3" : "=f"(sigma) : "f"(c), "f"(t), "f"(s));
209 1.1.1.1.8.2 tls #else
210 1.1.1.1.8.2 tls sigma = fmsub (c, t, s);
211 1.1.1.1.8.2 tls #endif
212 1.1.1.1.8.2 tls v = a - s;
213 1.1.1.1.8.2 tls
214 1.1.1.1.8.2 tls tau = ((v-sigma)+w)/c; /* Correction to t. */
215 1.1.1.1.8.2 tls u = t + tau;
216 1.1.1.1.8.2 tls
217 1.1.1.1.8.2 tls /* Construct long double result. */
218 1.1.1.1.8.2 tls if (nonfinite (u))
219 1.1.1.1.8.2 tls return u;
220 1.1.1.1.8.2 tls z.dval[0] = u;
221 1.1.1.1.8.2 tls z.dval[1] = (t - u) + tau;
222 1.1.1.1.8.2 tls return z.ldval;
223 1.1.1.1.8.2 tls }
224 1.1.1.1.8.2 tls
225 1.1.1.1.8.2 tls #if defined (_SOFT_DOUBLE) && defined (__LONG_DOUBLE_128__)
226 1.1.1.1.8.2 tls
227 1.1.1.1.8.2 tls long double __gcc_qneg (double, double);
228 1.1.1.1.8.2 tls int __gcc_qeq (double, double, double, double);
229 1.1.1.1.8.2 tls int __gcc_qne (double, double, double, double);
230 1.1.1.1.8.2 tls int __gcc_qge (double, double, double, double);
231 1.1.1.1.8.2 tls int __gcc_qle (double, double, double, double);
232 1.1.1.1.8.2 tls long double __gcc_stoq (float);
233 1.1.1.1.8.2 tls long double __gcc_dtoq (double);
234 1.1.1.1.8.2 tls float __gcc_qtos (double, double);
235 1.1.1.1.8.2 tls double __gcc_qtod (double, double);
236 1.1.1.1.8.2 tls int __gcc_qtoi (double, double);
237 1.1.1.1.8.2 tls unsigned int __gcc_qtou (double, double);
238 1.1.1.1.8.2 tls long double __gcc_itoq (int);
239 1.1.1.1.8.2 tls long double __gcc_utoq (unsigned int);
240 1.1.1.1.8.2 tls
241 1.1.1.1.8.2 tls extern int __eqdf2 (double, double);
242 1.1.1.1.8.2 tls extern int __ledf2 (double, double);
243 1.1.1.1.8.2 tls extern int __gedf2 (double, double);
244 1.1.1.1.8.2 tls
245 1.1.1.1.8.2 tls /* Negate 'long double' value and return the result. */
246 1.1.1.1.8.2 tls long double
247 1.1.1.1.8.2 tls __gcc_qneg (double a, double aa)
248 1.1.1.1.8.2 tls {
249 1.1.1.1.8.2 tls longDblUnion x;
250 1.1.1.1.8.2 tls
251 1.1.1.1.8.2 tls x.dval[0] = -a;
252 1.1.1.1.8.2 tls x.dval[1] = -aa;
253 1.1.1.1.8.2 tls return x.ldval;
254 1.1.1.1.8.2 tls }
255 1.1.1.1.8.2 tls
256 1.1.1.1.8.2 tls /* Compare two 'long double' values for equality. */
257 1.1.1.1.8.2 tls int
258 1.1.1.1.8.2 tls __gcc_qeq (double a, double aa, double c, double cc)
259 1.1.1.1.8.2 tls {
260 1.1.1.1.8.2 tls if (__eqdf2 (a, c) == 0)
261 1.1.1.1.8.2 tls return __eqdf2 (aa, cc);
262 1.1.1.1.8.2 tls return 1;
263 1.1.1.1.8.2 tls }
264 1.1.1.1.8.2 tls
265 1.1.1.1.8.2 tls strong_alias (__gcc_qeq, __gcc_qne);
266 1.1.1.1.8.2 tls
267 1.1.1.1.8.2 tls /* Compare two 'long double' values for less than or equal. */
268 1.1.1.1.8.2 tls int
269 1.1.1.1.8.2 tls __gcc_qle (double a, double aa, double c, double cc)
270 1.1.1.1.8.2 tls {
271 1.1.1.1.8.2 tls if (__eqdf2 (a, c) == 0)
272 1.1.1.1.8.2 tls return __ledf2 (aa, cc);
273 1.1.1.1.8.2 tls return __ledf2 (a, c);
274 1.1.1.1.8.2 tls }
275 1.1.1.1.8.2 tls
276 1.1.1.1.8.2 tls strong_alias (__gcc_qle, __gcc_qlt);
277 1.1.1.1.8.2 tls
278 1.1.1.1.8.2 tls /* Compare two 'long double' values for greater than or equal. */
279 1.1.1.1.8.2 tls int
280 1.1.1.1.8.2 tls __gcc_qge (double a, double aa, double c, double cc)
281 1.1.1.1.8.2 tls {
282 1.1.1.1.8.2 tls if (__eqdf2 (a, c) == 0)
283 1.1.1.1.8.2 tls return __gedf2 (aa, cc);
284 1.1.1.1.8.2 tls return __gedf2 (a, c);
285 1.1.1.1.8.2 tls }
286 1.1.1.1.8.2 tls
287 1.1.1.1.8.2 tls strong_alias (__gcc_qge, __gcc_qgt);
288 1.1.1.1.8.2 tls
289 1.1.1.1.8.2 tls /* Convert single to long double. */
290 1.1.1.1.8.2 tls long double
291 1.1.1.1.8.2 tls __gcc_stoq (float a)
292 1.1.1.1.8.2 tls {
293 1.1.1.1.8.2 tls longDblUnion x;
294 1.1.1.1.8.2 tls
295 1.1.1.1.8.2 tls x.dval[0] = (double) a;
296 1.1.1.1.8.2 tls x.dval[1] = 0.0;
297 1.1.1.1.8.2 tls
298 1.1.1.1.8.2 tls return x.ldval;
299 1.1.1.1.8.2 tls }
300 1.1.1.1.8.2 tls
301 1.1.1.1.8.2 tls /* Convert double to long double. */
302 1.1.1.1.8.2 tls long double
303 1.1.1.1.8.2 tls __gcc_dtoq (double a)
304 1.1.1.1.8.2 tls {
305 1.1.1.1.8.2 tls longDblUnion x;
306 1.1.1.1.8.2 tls
307 1.1.1.1.8.2 tls x.dval[0] = a;
308 1.1.1.1.8.2 tls x.dval[1] = 0.0;
309 1.1.1.1.8.2 tls
310 1.1.1.1.8.2 tls return x.ldval;
311 1.1.1.1.8.2 tls }
312 1.1.1.1.8.2 tls
313 1.1.1.1.8.2 tls /* Convert long double to single. */
314 1.1.1.1.8.2 tls float
315 1.1.1.1.8.2 tls __gcc_qtos (double a, double aa __attribute__ ((__unused__)))
316 1.1.1.1.8.2 tls {
317 1.1.1.1.8.2 tls return (float) a;
318 1.1.1.1.8.2 tls }
319 1.1.1.1.8.2 tls
320 1.1.1.1.8.2 tls /* Convert long double to double. */
321 1.1.1.1.8.2 tls double
322 1.1.1.1.8.2 tls __gcc_qtod (double a, double aa __attribute__ ((__unused__)))
323 1.1.1.1.8.2 tls {
324 1.1.1.1.8.2 tls return a;
325 1.1.1.1.8.2 tls }
326 1.1.1.1.8.2 tls
327 1.1.1.1.8.2 tls /* Convert long double to int. */
328 1.1.1.1.8.2 tls int
329 1.1.1.1.8.2 tls __gcc_qtoi (double a, double aa)
330 1.1.1.1.8.2 tls {
331 1.1.1.1.8.2 tls double z = a + aa;
332 1.1.1.1.8.2 tls return (int) z;
333 1.1.1.1.8.2 tls }
334 1.1.1.1.8.2 tls
335 1.1.1.1.8.2 tls /* Convert long double to unsigned int. */
336 1.1.1.1.8.2 tls unsigned int
337 1.1.1.1.8.2 tls __gcc_qtou (double a, double aa)
338 1.1.1.1.8.2 tls {
339 1.1.1.1.8.2 tls double z = a + aa;
340 1.1.1.1.8.2 tls return (unsigned int) z;
341 1.1.1.1.8.2 tls }
342 1.1.1.1.8.2 tls
343 1.1.1.1.8.2 tls /* Convert int to long double. */
344 1.1.1.1.8.2 tls long double
345 1.1.1.1.8.2 tls __gcc_itoq (int a)
346 1.1.1.1.8.2 tls {
347 1.1.1.1.8.2 tls return __gcc_dtoq ((double) a);
348 1.1.1.1.8.2 tls }
349 1.1.1.1.8.2 tls
350 1.1.1.1.8.2 tls /* Convert unsigned int to long double. */
351 1.1.1.1.8.2 tls long double
352 1.1.1.1.8.2 tls __gcc_utoq (unsigned int a)
353 1.1.1.1.8.2 tls {
354 1.1.1.1.8.2 tls return __gcc_dtoq ((double) a);
355 1.1.1.1.8.2 tls }
356 1.1.1.1.8.2 tls
357 1.1.1.1.8.2 tls #endif
358 1.1.1.1.8.2 tls
359 1.1.1.1.8.2 tls #ifdef __NO_FPRS__
360 1.1.1.1.8.2 tls
361 1.1.1.1.8.2 tls int __gcc_qunord (double, double, double, double);
362 1.1.1.1.8.2 tls
363 1.1.1.1.8.2 tls extern int __eqdf2 (double, double);
364 1.1.1.1.8.2 tls extern int __unorddf2 (double, double);
365 1.1.1.1.8.2 tls
366 1.1.1.1.8.2 tls /* Compare two 'long double' values for unordered. */
367 1.1.1.1.8.2 tls int
368 1.1.1.1.8.2 tls __gcc_qunord (double a, double aa, double c, double cc)
369 1.1.1.1.8.2 tls {
370 1.1.1.1.8.2 tls if (__eqdf2 (a, c) == 0)
371 1.1.1.1.8.2 tls return __unorddf2 (aa, cc);
372 1.1.1.1.8.2 tls return __unorddf2 (a, c);
373 1.1.1.1.8.2 tls }
374 1.1.1.1.8.2 tls
375 1.1.1.1.8.2 tls #include "soft-fp/soft-fp.h"
376 1.1.1.1.8.2 tls #include "soft-fp/double.h"
377 1.1.1.1.8.2 tls #include "soft-fp/quad.h"
378 1.1.1.1.8.2 tls
379 1.1.1.1.8.2 tls /* Compute floating point multiply-subtract with higher (quad) precision. */
380 1.1.1.1.8.2 tls static double
381 1.1.1.1.8.2 tls fmsub (double a, double b, double c)
382 1.1.1.1.8.2 tls {
383 1.1.1.1.8.2 tls FP_DECL_EX;
384 1.1.1.1.8.2 tls FP_DECL_D(A);
385 1.1.1.1.8.2 tls FP_DECL_D(B);
386 1.1.1.1.8.2 tls FP_DECL_D(C);
387 1.1.1.1.8.2 tls FP_DECL_Q(X);
388 1.1.1.1.8.2 tls FP_DECL_Q(Y);
389 1.1.1.1.8.2 tls FP_DECL_Q(Z);
390 1.1.1.1.8.2 tls FP_DECL_Q(U);
391 1.1.1.1.8.2 tls FP_DECL_Q(V);
392 1.1.1.1.8.2 tls FP_DECL_D(R);
393 1.1.1.1.8.2 tls double r;
394 1.1.1.1.8.2 tls long double u, x, y, z;
395 1.1.1.1.8.2 tls
396 1.1.1.1.8.2 tls FP_INIT_ROUNDMODE;
397 1.1.1.1.8.2 tls FP_UNPACK_RAW_D (A, a);
398 1.1.1.1.8.2 tls FP_UNPACK_RAW_D (B, b);
399 1.1.1.1.8.2 tls FP_UNPACK_RAW_D (C, c);
400 1.1.1.1.8.2 tls
401 1.1.1.1.8.2 tls /* Extend double to quad. */
402 1.1.1.1.8.2 tls #if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
403 1.1.1.1.8.2 tls FP_EXTEND(Q,D,4,2,X,A);
404 1.1.1.1.8.2 tls FP_EXTEND(Q,D,4,2,Y,B);
405 1.1.1.1.8.2 tls FP_EXTEND(Q,D,4,2,Z,C);
406 1.1.1.1.8.2 tls #else
407 1.1.1.1.8.2 tls FP_EXTEND(Q,D,2,1,X,A);
408 1.1.1.1.8.2 tls FP_EXTEND(Q,D,2,1,Y,B);
409 1.1.1.1.8.2 tls FP_EXTEND(Q,D,2,1,Z,C);
410 1.1.1.1.8.2 tls #endif
411 1.1.1.1.8.2 tls FP_PACK_RAW_Q(x,X);
412 1.1.1.1.8.2 tls FP_PACK_RAW_Q(y,Y);
413 1.1.1.1.8.2 tls FP_PACK_RAW_Q(z,Z);
414 1.1.1.1.8.2 tls FP_HANDLE_EXCEPTIONS;
415 1.1.1.1.8.2 tls
416 1.1.1.1.8.2 tls /* Multiply. */
417 1.1.1.1.8.2 tls FP_INIT_ROUNDMODE;
418 1.1.1.1.8.2 tls FP_UNPACK_Q(X,x);
419 1.1.1.1.8.2 tls FP_UNPACK_Q(Y,y);
420 1.1.1.1.8.2 tls FP_MUL_Q(U,X,Y);
421 1.1.1.1.8.2 tls FP_PACK_Q(u,U);
422 1.1.1.1.8.2 tls FP_HANDLE_EXCEPTIONS;
423 1.1.1.1.8.2 tls
424 1.1.1.1.8.2 tls /* Subtract. */
425 1.1.1.1.8.2 tls FP_INIT_ROUNDMODE;
426 1.1.1.1.8.2 tls FP_UNPACK_SEMIRAW_Q(U,u);
427 1.1.1.1.8.2 tls FP_UNPACK_SEMIRAW_Q(Z,z);
428 1.1.1.1.8.2 tls FP_SUB_Q(V,U,Z);
429 1.1.1.1.8.2 tls
430 1.1.1.1.8.2 tls /* Truncate quad to double. */
431 1.1.1.1.8.2 tls #if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
432 1.1.1.1.8.2 tls V_f[3] &= 0x0007ffff;
433 1.1.1.1.8.2 tls FP_TRUNC(D,Q,2,4,R,V);
434 1.1.1.1.8.2 tls #else
435 1.1.1.1.8.2 tls V_f1 &= 0x0007ffffffffffffL;
436 1.1.1.1.8.2 tls FP_TRUNC(D,Q,1,2,R,V);
437 1.1.1.1.8.2 tls #endif
438 1.1.1.1.8.2 tls FP_PACK_SEMIRAW_D(r,R);
439 1.1.1.1.8.2 tls FP_HANDLE_EXCEPTIONS;
440 1.1.1.1.8.2 tls
441 1.1.1.1.8.2 tls return r;
442 1.1.1.1.8.2 tls }
443 1.1.1.1.8.2 tls
444 1.1.1.1.8.2 tls #endif
445 1.1.1.1.8.2 tls
446 1.1.1.1.8.2 tls #endif
447