Updated to fedora-glibc-20050106T1443
[glibc.git] / sysdeps / ia64 / fpu / libm_support.h
blob50dac331330cbc31fe45c5ce95a4f74bc2ef3e8f
1 /* file: libm_support.h */
4 // Copyright (c) 2000 - 2002, Intel Corporation
5 // All rights reserved.
6 //
7 // Contributed 2000 by the Intel Numerics Group, Intel Corporation
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are
11 // met:
13 // * Redistributions of source code must retain the above copyright
14 // notice, this list of conditions and the following disclaimer.
16 // * Redistributions in binary form must reproduce the above copyright
17 // notice, this list of conditions and the following disclaimer in the
18 // documentation and/or other materials provided with the distribution.
20 // * The name of Intel Corporation may not be used to endorse or promote
21 // products derived from this software without specific prior written
22 // permission.
24 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
28 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
32 // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR TORT (INCLUDING
33 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // Intel Corporation is the author of this code, and requests that all
37 // problem reports or change requests be submitted to it directly at
38 // http://www.intel.com/software/products/opensource/libraries/num.htm.
41 // History: 02/02/2000 Initial version
42 // 2/28/2000 added tags for logb and nextafter
43 // 3/22/2000 Changes to support _LIB_VERSIONIMF variable
44 // and filled some enum gaps. Added support for C99.
45 // 5/31/2000 added prototypes for __libm_frexp_4l/8l
46 // 8/10/2000 Changed declaration of _LIB_VERSIONIMF to work for library
47 // builds and other application builds (precompiler directives).
48 // 8/11/2000 Added pointers-to-matherr-functions declarations to allow
49 // for user-defined matherr functions in the dll build.
50 // 12/07/2000 Added scalbn error_types values.
51 // 5/01/2001 Added error_types values for C99 nearest integer
52 // functions.
53 // 6/07/2001 Added error_types values for fdim.
54 // 6/18/2001 Added include of complex_support.h.
55 // 8/03/2001 Added error_types values for nexttoward, scalbln.
56 // 8/23/2001 Corrected tag numbers from 186 and higher.
57 // 8/27/2001 Added check for long int and long long int definitions.
58 // 12/10/2001 Added error_types for erfc.
59 // 12/27/2001 Added error_types for degree argument functions.
60 // 01/02/2002 Added error_types for tand, cotd.
61 // 01/04/2002 Delete include of complex_support.h
62 // 01/23/2002 Deleted prototypes for __libm_frexp*. Added check for
63 // multiple int, long int, and long long int definitions.
64 // 05/20/2002 Added error_types for cot.
65 // 06/27/2002 Added error_types for sinhcosh.
66 // 12/05/2002 Added error_types for annuity and compound
67 // 04/10/2003 Added error_types for tgammal/tgamma/tgammaf
70 void __libm_sincos_pi4(double,double*,double*,int);
71 void __libm_y0y1(double , double *, double *);
72 void __libm_j0j1(double , double *, double *);
73 double __libm_j0(double);
74 double __libm_j1(double);
75 double __libm_jn(int,double);
76 double __libm_y0(double);
77 double __libm_y1(double);
78 double __libm_yn(int,double);
79 double __libm_copysign (double, double);
80 float __libm_copysignf (float, float);
81 long double __libm_copysignl (long double, long double);
83 extern double sqrt(double);
84 extern double fabs(double);
85 extern double log(double);
86 extern double log1p(double);
87 extern double sqrt(double);
88 extern double sin(double);
89 extern double exp(double);
90 extern double modf(double, double *);
91 extern double asinh(double);
92 extern double acosh(double);
93 extern double atanh(double);
94 extern double tanh(double);
95 extern double erf(double);
96 extern double erfc(double);
97 extern double j0(double);
98 extern double j1(double);
99 extern double jn(int, double);
100 extern double y0(double);
101 extern double y1(double);
102 extern double yn(int, double);
104 extern float fabsf(float);
105 extern float asinhf(float);
106 extern float acoshf(float);
107 extern float atanhf(float);
108 extern float tanhf(float);
109 extern float erff(float);
110 extern float erfcf(float);
111 extern float j0f(float);
112 extern float j1f(float);
113 extern float jnf(int, float);
114 extern float y0f(float);
115 extern float y1f(float);
116 extern float ynf(int, float);
118 extern long double log1pl(long double);
119 extern long double logl(long double);
120 extern long double sqrtl(long double);
121 extern long double expl(long double);
122 extern long double fabsl(long double);
124 #if !(defined(SIZE_INT_32) || defined(SIZE_INT_64))
125 #error integer size not established; define SIZE_INT_32 or SIZE_INT_64
126 #endif
128 #if (defined(SIZE_INT_32) && defined(SIZE_INT_64))
129 #error multiple integer size definitions; define SIZE_INT_32 or SIZE_INT_64
130 #endif
132 #if !(defined(SIZE_LONG_INT_32) || defined(SIZE_LONG_INT_64))
133 #error long int size not established; define SIZE_LONG_INT_32 or SIZE_LONG_INT_64
134 #endif
136 #if (defined(SIZE_LONG_INT_32) && defined(SIZE_LONG_INT_64))
137 #error multiple long int size definitions; define SIZE_LONG_INT_32 or SIZE_LONG_INT_64
138 #endif
140 #if !(defined(SIZE_LONG_LONG_INT_32) || defined(SIZE_LONG_LONG_INT_64))
141 #error long long int size not established; define SIZE_LONG_LONG_INT_32 or SIZE_LONG_LONG_INT_64
142 #endif
144 #if (defined(SIZE_LONG_LONG_INT_32) && defined(SIZE_LONG_LONG_INT_64))
145 #error multiple long long int size definitions; define SIZE_LONG_LONG_INT_32 or SIZE_LONG_LONG_INT_64
146 #endif
148 typedef enum
150 logl_zero=0, logl_negative, /* 0, 1 */
151 log_zero, log_negative, /* 2, 3 */
152 logf_zero, logf_negative, /* 4, 5 */
153 log10l_zero, log10l_negative, /* 6, 7 */
154 log10_zero, log10_negative, /* 8, 9 */
155 log10f_zero, log10f_negative, /* 10, 11 */
156 expl_overflow, expl_underflow, /* 12, 13 */
157 exp_overflow, exp_underflow, /* 14, 15 */
158 expf_overflow, expf_underflow, /* 16, 17 */
159 powl_overflow, powl_underflow, /* 18, 19 */
160 powl_zero_to_zero, /* 20 */
161 powl_zero_to_negative, /* 21 */
162 powl_neg_to_non_integer, /* 22 */
163 powl_nan_to_zero, /* 23 */
164 pow_overflow, pow_underflow, /* 24, 25 */
165 pow_zero_to_zero, /* 26 */
166 pow_zero_to_negative, /* 27 */
167 pow_neg_to_non_integer, /* 28 */
168 pow_nan_to_zero, /* 29 */
169 powf_overflow, powf_underflow, /* 30, 31 */
170 powf_zero_to_zero, /* 32 */
171 powf_zero_to_negative, /* 33 */
172 powf_neg_to_non_integer, /* 34 */
173 powf_nan_to_zero, /* 35 */
174 atan2l_zero, /* 36 */
175 atan2_zero, /* 37 */
176 atan2f_zero, /* 38 */
177 expm1l_overflow, /* 39 */
178 expm1l_underflow, /* 40 */
179 expm1_overflow, /* 41 */
180 expm1_underflow, /* 42 */
181 expm1f_overflow, /* 43 */
182 expm1f_underflow, /* 44 */
183 hypotl_overflow, /* 45 */
184 hypot_overflow, /* 46 */
185 hypotf_overflow, /* 47 */
186 sqrtl_negative, /* 48 */
187 sqrt_negative, /* 49 */
188 sqrtf_negative, /* 50 */
189 scalbl_overflow, scalbl_underflow, /* 51, 52 */
190 scalb_overflow, scalb_underflow, /* 53, 54 */
191 scalbf_overflow, scalbf_underflow, /* 55, 56 */
192 acosl_gt_one, acos_gt_one, acosf_gt_one, /* 57, 58, 59 */
193 asinl_gt_one, asin_gt_one, asinf_gt_one, /* 60, 61, 62 */
194 coshl_overflow, cosh_overflow, coshf_overflow, /* 63, 64, 65 */
195 y0l_zero, y0l_negative,y0l_gt_loss, /* 66, 67, 68 */
196 y0_zero, y0_negative,y0_gt_loss, /* 69, 70, 71 */
197 y0f_zero, y0f_negative,y0f_gt_loss, /* 72, 73, 74 */
198 y1l_zero, y1l_negative,y1l_gt_loss, /* 75, 76, 77 */
199 y1_zero, y1_negative,y1_gt_loss, /* 78, 79, 80 */
200 y1f_zero, y1f_negative,y1f_gt_loss, /* 81, 82, 83 */
201 ynl_zero, ynl_negative,ynl_gt_loss, /* 84, 85, 86 */
202 yn_zero, yn_negative,yn_gt_loss, /* 87, 88, 89 */
203 ynf_zero, ynf_negative,ynf_gt_loss, /* 90, 91, 92 */
204 j0l_gt_loss, /* 93 */
205 j0_gt_loss, /* 94 */
206 j0f_gt_loss, /* 95 */
207 j1l_gt_loss, /* 96 */
208 j1_gt_loss, /* 97 */
209 j1f_gt_loss, /* 98 */
210 jnl_gt_loss, /* 99 */
211 jn_gt_loss, /* 100 */
212 jnf_gt_loss, /* 101 */
213 lgammal_overflow, lgammal_negative,lgammal_reserve, /* 102, 103, 104 */
214 lgamma_overflow, lgamma_negative,lgamma_reserve, /* 105, 106, 107 */
215 lgammaf_overflow, lgammaf_negative, lgammaf_reserve,/* 108, 109, 110 */
216 gammal_overflow,gammal_negative, gammal_reserve, /* 111, 112, 113 */
217 gamma_overflow, gamma_negative, gamma_reserve, /* 114, 115, 116 */
218 gammaf_overflow,gammaf_negative,gammaf_reserve, /* 117, 118, 119 */
219 fmodl_by_zero, /* 120 */
220 fmod_by_zero, /* 121 */
221 fmodf_by_zero, /* 122 */
222 remainderl_by_zero, /* 123 */
223 remainder_by_zero, /* 124 */
224 remainderf_by_zero, /* 125 */
225 sinhl_overflow, sinh_overflow, sinhf_overflow, /* 126, 127, 128 */
226 atanhl_gt_one, atanhl_eq_one, /* 129, 130 */
227 atanh_gt_one, atanh_eq_one, /* 131, 132 */
228 atanhf_gt_one, atanhf_eq_one, /* 133, 134 */
229 acoshl_lt_one, /* 135 */
230 acosh_lt_one, /* 136 */
231 acoshf_lt_one, /* 137 */
232 log1pl_zero, log1pl_negative, /* 138, 139 */
233 log1p_zero, log1p_negative, /* 140, 141 */
234 log1pf_zero, log1pf_negative, /* 142, 143 */
235 ldexpl_overflow, ldexpl_underflow, /* 144, 145 */
236 ldexp_overflow, ldexp_underflow, /* 146, 147 */
237 ldexpf_overflow, ldexpf_underflow, /* 148, 149 */
238 logbl_zero, logb_zero, logbf_zero, /* 150, 151, 152 */
239 nextafterl_overflow, nextafter_overflow,
240 nextafterf_overflow, /* 153, 154, 155 */
241 ilogbl_zero, ilogb_zero, ilogbf_zero, /* 156, 157, 158 */
242 exp2l_overflow, exp2l_underflow, /* 159, 160 */
243 exp2_overflow, exp2_underflow, /* 161, 162 */
244 exp2f_overflow, exp2f_underflow, /* 163, 164 */
245 exp10l_overflow, exp10_overflow,
246 exp10f_overflow, /* 165, 166, 167 */
247 log2l_zero, log2l_negative, /* 168, 169 */
248 log2_zero, log2_negative, /* 170, 171 */
249 log2f_zero, log2f_negative, /* 172, 173 */
250 scalbnl_overflow, scalbnl_underflow, /* 174, 175 */
251 scalbn_overflow, scalbn_underflow, /* 176, 177 */
252 scalbnf_overflow, scalbnf_underflow, /* 178, 179 */
253 remquol_by_zero, /* 180 */
254 remquo_by_zero, /* 181 */
255 remquof_by_zero, /* 182 */
256 lrintl_large, lrint_large, lrintf_large, /* 183, 184, 185 */
257 llrintl_large, llrint_large, llrintf_large, /* 186, 187, 188 */
258 lroundl_large, lround_large, lroundf_large, /* 189, 190, 191 */
259 llroundl_large, llround_large, llroundf_large, /* 192, 193, 194 */
260 fdiml_overflow, fdim_overflow, fdimf_overflow, /* 195, 196, 197 */
261 nexttowardl_overflow, nexttoward_overflow,
262 nexttowardf_overflow, /* 198, 199, 200 */
263 scalblnl_overflow, scalblnl_underflow, /* 201, 202 */
264 scalbln_overflow, scalbln_underflow, /* 203, 204 */
265 scalblnf_overflow, scalblnf_underflow, /* 205, 206 */
266 erfcl_underflow, erfc_underflow, erfcf_underflow, /* 207, 208, 209 */
267 acosdl_gt_one, acosd_gt_one, acosdf_gt_one, /* 210, 211, 212 */
268 asindl_gt_one, asind_gt_one, asindf_gt_one, /* 213, 214, 215 */
269 atan2dl_zero, atan2d_zero, atan2df_zero, /* 216, 217, 218 */
270 tandl_overflow, tand_overflow, tandf_overflow, /* 219, 220, 221 */
271 cotdl_overflow, cotd_overflow, cotdf_overflow, /* 222, 223, 224 */
272 cotl_overflow, cot_overflow, cotf_overflow, /* 225, 226, 227 */
273 sinhcoshl_overflow, sinhcosh_overflow, sinhcoshf_overflow, /* 228, 229, 230 */
274 annuityl_by_zero, annuity_by_zero, annuityf_by_zero, /* 231, 232, 233 */
275 annuityl_less_m1, annuity_less_m1, annuityf_less_m1, /* 234, 235, 236 */
276 annuityl_overflow, annuity_overflow, annuityf_overflow, /* 237, 238, 239 */
277 annuityl_underflow, annuity_underflow, annuityf_underflow, /* 240, 241, 242 */
278 compoundl_by_zero, compound_by_zero, compoundf_by_zero, /* 243, 244, 245 */
279 compoundl_less_m1, compound_less_m1, compoundf_less_m1, /* 246, 247, 248 */
280 compoundl_overflow, compound_overflow, compoundf_overflow, /* 249, 250, 251 */
281 compoundl_underflow, compound_underflow, compoundf_underflow, /* 252, 253, 254 */
282 tgammal_overflow, tgammal_negative, tgammal_reserve, /* 255, 256, 257 */
283 tgamma_overflow, tgamma_negative, tgamma_reserve, /* 258, 259, 260 */
284 tgammaf_overflow, tgammaf_negative, tgammaf_reserve, /* 261, 262, 263 */
285 } error_types;
287 void __libm_error_support(void*,void*,void*,error_types);
288 #ifdef _LIBC
289 libc_hidden_proto(__libm_error_support)
290 #endif
292 #define HI_SIGNIFICAND_LESS(X, HI) ((X)->hi_significand < 0x ## HI)
293 #define f64abs(x) ((x) < 0.0 ? -(x) : (x))
295 #if !defined(__USE_EXTERNAL_FPMEMTYP_H__)
297 #define BIAS_32 0x007F
298 #define BIAS_64 0x03FF
299 #define BIAS_80 0x3FFF
301 #define MAXEXP_32 0x00FE
302 #define MAXEXP_64 0x07FE
303 #define MAXEXP_80 0x7FFE
305 #define EXPINF_32 0x00FF
306 #define EXPINF_64 0x07FF
307 #define EXPINF_80 0x7FFF
309 struct fp32 { /*// sign:1 exponent:8 significand:23 (implied leading 1)*/
310 #if defined(SIZE_INT_32)
311 unsigned significand:23;
312 unsigned exponent:8;
313 unsigned sign:1;
314 #elif defined(SIZE_INT_64)
315 unsigned significand:23;
316 unsigned exponent:8;
317 unsigned sign:1;
318 #endif
321 struct fp64 { /*/ sign:1 exponent:11 significand:52 (implied leading 1)*/
322 #if defined(SIZE_INT_32)
323 unsigned lo_significand:32;
324 unsigned hi_significand:20;
325 unsigned exponent:11;
326 unsigned sign:1;
327 #elif defined(SIZE_INT_64)
328 unsigned significand:52;
329 unsigned exponent:11;
330 unsigned sign:1;
331 #endif
334 struct fp80 { /*/ sign:1 exponent:15 significand:64 (NO implied bits) */
335 #if defined(SIZE_INT_32)
336 unsigned lo_significand;
337 unsigned hi_significand;
338 unsigned exponent:15;
339 unsigned sign:1;
340 #elif defined(SIZE_INT_64)
341 unsigned significand;
342 unsigned exponent:15;
343 unsigned sign:1;
344 #endif
347 #endif /*__USE_EXTERNAL_FPMEMTYP_H__*/
349 /* macros to form a double value in hex representation (unsigned int type) */
351 #define DOUBLE_HEX(hi,lo) 0x##lo,0x##hi /*LITTLE_ENDIAN*/
353 /* macros to form a long double value in hex representation (unsigned short type) */
355 #if defined(_WIN32) || defined(_WIN64)
356 #define LDOUBLE_ALIGN 16
357 #else
358 #define LDOUBLE_ALIGN 12
359 #endif
361 #if (LDOUBLE_ALIGN == 16)
362 #define _XPD_ ,0x0000,0x0000,0x0000
363 #else /*12*/
364 #define _XPD_ ,0x0000
365 #endif
367 #define LDOUBLE_HEX(w4,w3,w2,w1,w0) 0x##w0,0x##w1,0x##w2,0x##w3,0x##w4 _XPD_ /*LITTLE_ENDIAN*/
369 /* macros to sign-expand low 'num' bits of 'val' to native integer */
371 #if defined(SIZE_INT_32)
372 # define SIGN_EXPAND(val,num) ((int)(val) << (32-(num))) >> (32-(num)) /* sign expand of 'num' LSBs */
373 #elif defined(SIZE_INT_64)
374 # define SIGN_EXPAND(val,num) ((int)(val) << (64-(num))) >> (64-(num)) /* sign expand of 'num' LSBs */
375 #endif
377 /* macros to form pointers to FP number on-the-fly */
379 #define FP32(f) ((struct fp32 *)&f)
380 #define FP64(d) ((struct fp64 *)&d)
381 #define FP80(ld) ((struct fp80 *)&ld)
383 /* macros to extract signed low and high doubleword of long double */
385 #if defined(SIZE_INT_32)
386 # define HI_DWORD_80(ld) ((((FP80(ld)->sign << 15) | FP80(ld)->exponent) << 16) | \
387 ((FP80(ld)->hi_significand >> 16) & 0xFFFF))
388 # define LO_DWORD_80(ld) SIGN_EXPAND(FP80(ld)->lo_significand, 32)
389 #elif defined(SIZE_INT_64)
390 # define HI_DWORD_80(ld) ((((FP80(ld)->sign << 15) | FP80(ld)->exponent) << 16) | \
391 ((FP80(ld)->significand >> 48) & 0xFFFF))
392 # define LO_DWORD_80(ld) SIGN_EXPAND(FP80(ld)->significand, 32)
393 #endif
395 /* macros to extract hi bits of significand.
396 * note that explicit high bit do not count (returns as is)
399 #if defined(SIZE_INT_32)
400 # define HI_SIGNIFICAND_80(X,NBITS) ((X)->hi_significand >> (31 - (NBITS)))
401 #elif defined(SIZE_INT_64)
402 # define HI_SIGNIFICAND_80(X,NBITS) ((X)->significand >> (63 - (NBITS)))
403 #endif
405 /* macros to check, whether a significand bits are all zero, or some of them are non-zero.
406 * note that SIGNIFICAND_ZERO_80 tests high bit also, but SIGNIFICAND_NONZERO_80 does not
409 #define SIGNIFICAND_ZERO_32(X) ((X)->significand == 0)
410 #define SIGNIFICAND_NONZERO_32(X) ((X)->significand != 0)
412 #if defined(SIZE_INT_32)
413 # define SIGNIFICAND_ZERO_64(X) (((X)->hi_significand == 0) && ((X)->lo_significand == 0))
414 # define SIGNIFICAND_NONZERO_64(X) (((X)->hi_significand != 0) || ((X)->lo_significand != 0))
415 #elif defined(SIZE_INT_64)
416 # define SIGNIFICAND_ZERO_64(X) ((X)->significand == 0)
417 # define SIGNIFICAND_NONZERO_64(X) ((X)->significand != 0)
418 #endif
420 #if defined(SIZE_INT_32)
421 # define SIGNIFICAND_ZERO_80(X) (((X)->hi_significand == 0x00000000) && ((X)->lo_significand == 0))
422 # define SIGNIFICAND_NONZERO_80(X) (((X)->hi_significand != 0x80000000) || ((X)->lo_significand != 0))
423 #elif defined(SIZE_INT_64)
424 # define SIGNIFICAND_ZERO_80(X) ((X)->significand == 0x0000000000000000)
425 # define SIGNIFICAND_NONZERO_80(X) ((X)->significand != 0x8000000000000000)
426 #endif
428 /* macros to compare long double with constant value, represented as hex */
430 #define SIGNIFICAND_EQ_HEX_32(X,BITS) ((X)->significand == 0x ## BITS)
431 #define SIGNIFICAND_GT_HEX_32(X,BITS) ((X)->significand > 0x ## BITS)
432 #define SIGNIFICAND_GE_HEX_32(X,BITS) ((X)->significand >= 0x ## BITS)
433 #define SIGNIFICAND_LT_HEX_32(X,BITS) ((X)->significand < 0x ## BITS)
434 #define SIGNIFICAND_LE_HEX_32(X,BITS) ((X)->significand <= 0x ## BITS)
436 #if defined(SIZE_INT_32)
437 # define SIGNIFICAND_EQ_HEX_64(X,HI,LO) \
438 (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand == 0x ## LO))
439 # define SIGNIFICAND_GT_HEX_64(X,HI,LO) (((X)->hi_significand > 0x ## HI) || \
440 (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand > 0x ## LO)))
441 # define SIGNIFICAND_GE_HEX_64(X,HI,LO) (((X)->hi_significand > 0x ## HI) || \
442 (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand >= 0x ## LO)))
443 # define SIGNIFICAND_LT_HEX_64(X,HI,LO) (((X)->hi_significand < 0x ## HI) || \
444 (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand < 0x ## LO)))
445 # define SIGNIFICAND_LE_HEX_64(X,HI,LO) (((X)->hi_significand < 0x ## HI) || \
446 (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand <= 0x ## LO)))
447 #elif defined(SIZE_INT_64)
448 # define SIGNIFICAND_EQ_HEX_64(X,HI,LO) ((X)->significand == 0x ## HI ## LO)
449 # define SIGNIFICAND_GT_HEX_64(X,HI,LO) ((X)->significand > 0x ## HI ## LO)
450 # define SIGNIFICAND_GE_HEX_64(X,HI,LO) ((X)->significand >= 0x ## HI ## LO)
451 # define SIGNIFICAND_LT_HEX_64(X,HI,LO) ((X)->significand < 0x ## HI ## LO)
452 # define SIGNIFICAND_LE_HEX_64(X,HI,LO) ((X)->significand <= 0x ## HI ## LO)
453 #endif
455 #if defined(SIZE_INT_32)
456 # define SIGNIFICAND_EQ_HEX_80(X,HI,LO) \
457 (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand == 0x ## LO))
458 # define SIGNIFICAND_GT_HEX_80(X,HI,LO) (((X)->hi_significand > 0x ## HI) || \
459 (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand > 0x ## LO)))
460 # define SIGNIFICAND_GE_HEX_80(X,HI,LO) (((X)->hi_significand > 0x ## HI) || \
461 (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand >= 0x ## LO)))
462 # define SIGNIFICAND_LT_HEX_80(X,HI,LO) (((X)->hi_significand < 0x ## HI) || \
463 (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand < 0x ## LO)))
464 # define SIGNIFICAND_LE_HEX_80(X,HI,LO) (((X)->hi_significand < 0x ## HI) || \
465 (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand <= 0x ## LO)))
466 #elif defined(SIZE_INT_64)
467 # define SIGNIFICAND_EQ_HEX_80(X,HI,LO) ((X)->significand == 0x ## HI ## LO)
468 # define SIGNIFICAND_GT_HEX_80(X,HI,LO) ((X)->significand > 0x ## HI ## LO)
469 # define SIGNIFICAND_GE_HEX_80(X,HI,LO) ((X)->significand >= 0x ## HI ## LO)
470 # define SIGNIFICAND_LT_HEX_80(X,HI,LO) ((X)->significand < 0x ## HI ## LO)
471 # define SIGNIFICAND_LE_HEX_80(X,HI,LO) ((X)->significand <= 0x ## HI ## LO)
472 #endif
474 #define VALUE_EQ_HEX_32(X,EXP,BITS) \
475 (((X)->exponent == (EXP)) && (SIGNIFICAND_EQ_HEX_32(X, BITS)))
476 #define VALUE_GT_HEX_32(X,EXP,BITS) (((X)->exponent > (EXP)) || \
477 (((X)->exponent == (EXP)) && (SIGNIFICAND_GT_HEX_32(X, BITS))))
478 #define VALUE_GE_HEX_32(X,EXP,BITS) (((X)->exponent > (EXP)) || \
479 (((X)->exponent == (EXP)) && (SIGNIFICAND_GE_HEX_32(X, BITS))))
480 #define VALUE_LT_HEX_32(X,EXP,BITS) (((X)->exponent < (EXP)) || \
481 (((X)->exponent == (EXP)) && (SIGNIFICAND_LT_HEX_32(X, BITS))))
482 #define VALUE_LE_HEX_32(X,EXP,BITS) (((X)->exponent < (EXP)) || \
483 (((X)->exponent == (EXP)) && (SIGNIFICAND_LE_HEX_32(X, BITS))))
485 #define VALUE_EQ_HEX_64(X,EXP,HI,LO) \
486 (((X)->exponent == (EXP)) && (SIGNIFICAND_EQ_HEX_64(X, HI, LO)))
487 #define VALUE_GT_HEX_64(X,EXP,HI,LO) (((X)->exponent > (EXP)) || \
488 (((X)->exponent == (EXP)) && (SIGNIFICAND_GT_HEX_64(X, HI, LO))))
489 #define VALUE_GE_HEX_64(X,EXP,HI,LO) (((X)->exponent > (EXP)) || \
490 (((X)->exponent == (EXP)) && (SIGNIFICAND_GE_HEX_64(X, HI, LO))))
491 #define VALUE_LT_HEX_64(X,EXP,HI,LO) (((X)->exponent < (EXP)) || \
492 (((X)->exponent == (EXP)) && (SIGNIFICAND_LT_HEX_64(X, HI, LO))))
493 #define VALUE_LE_HEX_64(X,EXP,HI,LO) (((X)->exponent < (EXP)) || \
494 (((X)->exponent == (EXP)) && (SIGNIFICAND_LE_HEX_64(X, HI, LO))))
496 #define VALUE_EQ_HEX_80(X,EXP,HI,LO) \
497 (((X)->exponent == (EXP)) && (SIGNIFICAND_EQ_HEX_80(X, HI, LO)))
498 #define VALUE_GT_HEX_80(X,EXP,HI,LO) (((X)->exponent > (EXP)) || \
499 (((X)->exponent == (EXP)) && (SIGNIFICAND_GT_HEX_80(X, HI, LO))))
500 #define VALUE_GE_HEX_80(X,EXP,HI,LO) (((X)->exponent > (EXP)) || \
501 (((X)->exponent == (EXP)) && (SIGNIFICAND_GE_HEX_80(X, HI, LO))))
502 #define VALUE_LT_HEX_80(X,EXP,HI,LO) (((X)->exponent < (EXP)) || \
503 (((X)->exponent == (EXP)) && (SIGNIFICAND_LT_HEX_80(X, HI, LO))))
504 #define VALUE_LE_HEX_80(X,EXP,HI,LO) (((X)->exponent < (EXP)) || \
505 (((X)->exponent == (EXP)) && (SIGNIFICAND_LE_HEX_80(X, HI, LO))))
507 /* macros to compare two long doubles */
509 #define SIGNIFICAND_EQ_32(X,Y) ((X)->significand == (Y)->significand)
510 #define SIGNIFICAND_GT_32(X,Y) ((X)->significand > (Y)->significand)
511 #define SIGNIFICAND_GE_32(X,Y) ((X)->significand >= (Y)->significand)
512 #define SIGNIFICAND_LT_32(X,Y) ((X)->significand < (Y)->significand)
513 #define SIGNIFICAND_LE_32(X,Y) ((X)->significand <= (Y)->significand)
515 #if defined(SIZE_INT_32)
516 # define SIGNIFICAND_EQ_64(X,Y) \
517 (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand == (Y)->lo_significand))
518 # define SIGNIFICAND_GT_64(X,Y) (((X)->hi_significand > (Y)->hi_significand) || \
519 (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand > (Y)->lo_significand)))
520 # define SIGNIFICAND_GE_64(X,Y) (((X)->hi_significand > (Y)->hi_significand) || \
521 (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand >= (Y)->lo_significand)))
522 # define SIGNIFICAND_LT_64(X,Y) (((X)->hi_significand < (Y)->hi_significand) || \
523 (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand < (Y)->lo_significand)))
524 # define SIGNIFICAND_LE_64(X,Y) (((X)->hi_significand < (Y)->hi_significand) || \
525 (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand <= (Y)->lo_significand)))
526 #elif defined(SIZE_INT_64)
527 # define SIGNIFICAND_EQ_64(X,Y) ((X)->significand == (Y)->significand)
528 # define SIGNIFICAND_GT_64(X,Y) ((X)->significand > (Y)->significand)
529 # define SIGNIFICAND_GE_64(X,Y) ((X)->significand >= (Y)->significand)
530 # define SIGNIFICAND_LT_64(X,Y) ((X)->significand < (Y)->significand)
531 # define SIGNIFICAND_LE_64(X,Y) ((X)->significand <= (Y)->significand)
532 #endif
534 #if defined(SIZE_INT_32)
535 # define SIGNIFICAND_EQ_80(X,Y) \
536 (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand == (Y)->lo_significand))
537 # define SIGNIFICAND_GT_80(X,Y) (((X)->hi_significand > (Y)->hi_significand) || \
538 (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand > (Y)->lo_significand)))
539 # define SIGNIFICAND_GE_80(X,Y) (((X)->hi_significand > (Y)->hi_significand) || \
540 (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand >= (Y)->lo_significand)))
541 # define SIGNIFICAND_LT_80(X,Y) (((X)->hi_significand < (Y)->hi_significand) || \
542 (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand < (Y)->lo_significand)))
543 # define SIGNIFICAND_LE_80(X,Y) (((X)->hi_significand < (Y)->hi_significand) || \
544 (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand <= (Y)->lo_significand)))
545 #elif defined(SIZE_INT_64)
546 # define SIGNIFICAND_EQ_80(X,Y) ((X)->significand == (Y)->significand)
547 # define SIGNIFICAND_GT_80(X,Y) ((X)->significand > (Y)->significand)
548 # define SIGNIFICAND_GE_80(X,Y) ((X)->significand >= (Y)->significand)
549 # define SIGNIFICAND_LT_80(X,Y) ((X)->significand < (Y)->significand)
550 # define SIGNIFICAND_LE_80(X,Y) ((X)->significand <= (Y)->significand)
551 #endif
553 #define VALUE_EQ_32(X,Y) \
554 (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_EQ_32(X, Y)))
555 #define VALUE_GT_32(X,Y) (((X)->exponent > (Y)->exponent) || \
556 (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_GT_32(X, Y))))
557 #define VALUE_GE_32(X,Y) (((X)->exponent > (Y)->exponent) || \
558 (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_GE_32(X, Y))))
559 #define VALUE_LT_32(X,Y) (((X)->exponent < (Y)->exponent) || \
560 (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_LT_32(X, Y))))
561 #define VALUE_LE_32(X,Y) (((X)->exponent < (Y)->exponent) || \
562 (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_LE_32(X, Y))))
564 #define VALUE_EQ_64(X,Y) \
565 (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_EQ_64(X, Y)))
566 #define VALUE_GT_64(X,Y) (((X)->exponent > (Y)->exponent) || \
567 (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_GT_64(X, Y))))
568 #define VALUE_GE_64(X,Y) (((X)->exponent > (Y)->exponent) || \
569 (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_GE_64(X, Y))))
570 #define VALUE_LT_64(X,Y) (((X)->exponent < (Y)->exponent) || \
571 (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_LT_64(X, Y))))
572 #define VALUE_LE_64(X,Y) (((X)->exponent < (Y)->exponent) || \
573 (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_LE_64(X, Y))))
575 #define VALUE_EQ_80(X,Y) \
576 (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_EQ_80(X, Y)))
577 #define VALUE_GT_80(X,Y) (((X)->exponent > (Y)->exponent) || \
578 (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_GT_80(X, Y))))
579 #define VALUE_GE_80(X,Y) (((X)->exponent > (Y)->exponent) || \
580 (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_GE_80(X, Y))))
581 #define VALUE_LT_80(X,Y) (((X)->exponent < (Y)->exponent) || \
582 (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_LT_80(X, Y))))
583 #define VALUE_LE_80(X,Y) (((X)->exponent < (Y)->exponent) || \
584 (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_LE_80(X, Y))))
586 /* add/subtract 1 ulp macros */
588 #if defined(SIZE_INT_32)
589 # define ADD_ULP_80(X) \
590 if ((++(X)->lo_significand == 0) && \
591 (++(X)->hi_significand == (((X)->exponent == 0) ? 0x80000000 : 0))) \
593 (X)->hi_significand |= 0x80000000; \
594 ++(X)->exponent; \
596 # define SUB_ULP_80(X) \
597 if (--(X)->lo_significand == 0xFFFFFFFF) { \
598 --(X)->hi_significand; \
599 if (((X)->exponent != 0) && \
600 ((X)->hi_significand == 0x7FFFFFFF) && \
601 (--(X)->exponent != 0)) \
603 (X)->hi_significand |= 0x80000000; \
606 #elif defined(SIZE_INT_64)
607 # define ADD_ULP_80(X) \
608 if (++(X)->significand == (((X)->exponent == 0) ? 0x8000000000000000 : 0))) { \
609 (X)->significand |= 0x8000000000000000; \
610 ++(X)->exponent; \
612 # define SUB_ULP_80(X) \
614 --(X)->significand; \
615 if (((X)->exponent != 0) && \
616 ((X)->significand == 0x7FFFFFFFFFFFFFFF) && \
617 (--(X)->exponent != 0)) \
619 (X)->significand |= 0x8000000000000000; \
622 #endif
626 #if (defined(_WIN32) && !defined(_WIN64))
628 #define FP80_DECLARE()
629 #define _FPC_64 0x0300
630 static unsigned short __wControlWord, __wNewControlWord;
631 #define FP80_SET() { \
632 __asm { fnstcw word ptr [__wControlWord] } \
633 __wNewControlWord = __wControlWord | _FPC_64; \
634 __asm { fldcw word ptr [__wNewControlWord] } \
636 #define FP80_RESET() { \
637 __asm { fldcw word ptr [__wControlWord] } \
639 #else /* defined(_WIN32) && !defined(_WIN64) */
641 #define FP80_DECLARE()
642 #define FP80_SET()
643 #define FP80_RESET()
645 #endif /* defined(_WIN32) && !defined(_WIN64) */
648 #ifdef _LIBC
649 # include <math.h>
650 #else
652 static const unsigned INF[] = {
653 DOUBLE_HEX(7ff00000, 00000000),
654 DOUBLE_HEX(fff00000, 00000000)
657 static const double _zeroo = 0.0;
658 static const double _bigg = 1.0e300;
659 static const double _ponee = 1.0;
660 static const double _nonee = -1.0;
662 #define INVALID (_zeroo * *((double*)&INF[0]))
663 #define PINF *((double*)&INF[0])
664 #define NINF -PINF
665 #define PINF_DZ (_ponee/_zeroo)
666 #define X_TLOSS 1.41484755040568800000e+16
667 #endif
669 struct exceptionf
671 int type;
672 char *name;
673 float arg1, arg2, retval;
676 # ifdef __cplusplus
677 struct __exception
679 int type;
680 char *name;
681 double arg1, arg2, retval;
683 # else
685 # ifndef _LIBC
686 struct exception
688 int type;
689 char *name;
690 double arg1, arg2, retval;
692 # endif
693 # endif
697 struct exceptionl
699 int type;
700 char *name;
701 long double arg1, arg2, retval;
704 #ifdef _MS_
705 #define MATHERR_F _matherrf
706 #define MATHERR_D _matherr
707 #else
708 #define MATHERR_F matherrf
709 #define MATHERR_D matherr
710 #endif
712 # ifdef __cplusplus
713 #define EXC_DECL_D __exception
714 #else
715 // exception is a reserved name in C++
716 #define EXC_DECL_D exception
717 #endif
719 extern int MATHERR_F(struct exceptionf*);
720 extern int MATHERR_D(struct EXC_DECL_D*);
721 extern int matherrl(struct exceptionl*);
724 /* Set these appropriately to make thread Safe */
725 #define ERRNO_RANGE errno = ERANGE
726 #define ERRNO_DOMAIN errno = EDOM
729 // Add code to support _LIB_VERSIONIMF
730 #ifndef _LIBC
731 typedef enum
733 _IEEE_ = -1, // IEEE-like behavior
734 _SVID_, // SysV, Rel. 4 behavior
735 _XOPEN_, // Unix98
736 _POSIX_, // Posix
737 _ISOC_ // ISO C9X
738 } _LIB_VERSION_TYPE;
741 #if !defined( LIBM_BUILD )
742 #if defined( _DLL )
743 extern _LIB_VERSION_TYPE __declspec(dllimport) _LIB_VERSIONIMF;
744 #else
745 extern _LIB_VERSION_TYPE _LIB_VERSIONIMF;
746 #endif /* _DLL */
747 #else
748 extern int (*pmatherrf)(struct exceptionf*);
749 extern int (*pmatherr)(struct EXC_DECL_D*);
750 extern int (*pmatherrl)(struct exceptionl*);
751 #endif /* LIBM_BUILD */
753 // This is a run-time variable and may affect
754 // floating point behavior of the libm functions
755 #endif