sl@0: /* FDLIBM.H sl@0: * sl@0: * Portions Copyright (c) 1993-1999 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: */ sl@0: sl@0: sl@0: /* @(#)fdlibm.h 5.1 93/09/24 */ sl@0: /* sl@0: * ==================================================== sl@0: * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. sl@0: * sl@0: * Developed at SunPro, a Sun Microsystems, Inc. business. sl@0: * Permission to use, copy, modify, and distribute this sl@0: * software is freely granted, provided that this notice sl@0: * is preserved. sl@0: * ==================================================== sl@0: */ sl@0: sl@0: #ifdef __cplusplus sl@0: extern "C" { sl@0: #endif sl@0: sl@0: /** sl@0: SYMBIAN adaptations sl@0: @internalComponent sl@0: */ sl@0: #define huge fhuge sl@0: #define tiny ftiny sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: typedef unsigned long __uint32_t; sl@0: typedef long __int32_t; sl@0: sl@0: #ifdef __VC32__ sl@0: /* warning C4056: overflow in floating-point constant arithmetic sl@0: * Caused by negative floating point constants, it seems! sl@0: * For example, static double foo = -1.0; sl@0: */ sl@0: #pragma warning( disable: 4056 ) sl@0: #endif sl@0: #ifdef __ARMCC__ sl@0: /* Warning: #222-D: floating-point operation result is out of range sl@0: * The compiler detects constant math that overflows, we want overflow though! sl@0: */ sl@0: #pragma diag_suppress 222 sl@0: #endif sl@0: sl@0: #include sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: #define HUGE ((float)3.40282346638528860e+38) sl@0: sl@0: /** sl@0: set X_TLOSS = pi*2**52, which is possibly defined in sl@0: (one may replace the following line by "#include ") sl@0: @internalComponent sl@0: */ sl@0: #define X_TLOSS 1.41484755040568800000e+16 sl@0: sl@0: /** sl@0: ieee style elementary functions - ESTLIB is exporting sl@0: these functions directly, so we simply map the names across sl@0: @internalComponent sl@0: */ sl@0: #define __ieee754_cosh cosh sl@0: #define __ieee754_sinh sinh sl@0: #define __ieee754_tanh tanh sl@0: #define __ieee754_exp exp sl@0: sl@0: /* The original code used statements like sl@0: n0 = ((*(int*)&one)>>29)^1; * index of high word * sl@0: ix0 = *(n0+(int*)&x); * high word of x * sl@0: ix1 = *((1-n0)+(int*)&x); * low word of x * sl@0: to dig two 32 bit words out of the 64 bit IEEE floating point sl@0: value. That is non-ANSI, and, moreover, the gcc instruction sl@0: scheduler gets it wrong. We instead use the following macros. sl@0: Unlike the original code, we determine the endianness at compile sl@0: time, not at run time; I don't see much benefit to selecting sl@0: endianness at run time. */ sl@0: sl@0: #ifndef __IEEE_BIG_ENDIAN sl@0: #ifndef __IEEE_LITTLE_ENDIAN sl@0: #error Must define endianness sl@0: #endif sl@0: #endif sl@0: sl@0: /* A union which permits us to convert between a double and two 32 bit sl@0: ints. */ sl@0: sl@0: #ifdef __IEEE_BIG_ENDIAN sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: typedef union sl@0: { sl@0: double value; sl@0: struct sl@0: { sl@0: unsigned long msw; sl@0: unsigned long lsw; sl@0: } parts; sl@0: } ieee_double_shape_type; sl@0: sl@0: #else sl@0: sl@0: #ifdef __IEEE_LITTLE_ENDIAN sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: typedef union sl@0: { sl@0: double value; sl@0: struct sl@0: { sl@0: unsigned long lsw; sl@0: unsigned long msw; sl@0: } parts; sl@0: } ieee_double_shape_type; sl@0: sl@0: #endif sl@0: #endif sl@0: sl@0: /** sl@0: Get two 32 bit ints from a double. sl@0: @internalComponent sl@0: */ sl@0: #define EXTRACT_WORDS(ix0,ix1,d) \ sl@0: { \ sl@0: ieee_double_shape_type ew_u; \ sl@0: ew_u.value = (d); \ sl@0: (ix0) = ew_u.parts.msw; \ sl@0: (ix1) = ew_u.parts.lsw; \ sl@0: } sl@0: sl@0: /** sl@0: Get the more significant 32 bit int from a double. sl@0: @internalComponent sl@0: */ sl@0: #define GET_HIGH_WORD(i,d) \ sl@0: { \ sl@0: ieee_double_shape_type gh_u; \ sl@0: gh_u.value = (d); \ sl@0: (i) = gh_u.parts.msw; \ sl@0: } sl@0: sl@0: /** sl@0: Get the less significant 32 bit int from a double. sl@0: @internalComponent sl@0: */ sl@0: #define GET_LOW_WORD(i,d) \ sl@0: { \ sl@0: ieee_double_shape_type gl_u; \ sl@0: gl_u.value = (d); \ sl@0: (i) = gl_u.parts.lsw; \ sl@0: } sl@0: sl@0: /** sl@0: Set a double from two 32 bit ints. sl@0: @internalComponent sl@0: */ sl@0: #define INSERT_WORDS(d,ix0,ix1) \ sl@0: { \ sl@0: ieee_double_shape_type iw_u; \ sl@0: iw_u.parts.msw = (ix0); \ sl@0: iw_u.parts.lsw = (ix1); \ sl@0: (d) = iw_u.value; \ sl@0: } sl@0: sl@0: /** sl@0: Set the more significant 32 bits of a double from an int. sl@0: @internalComponent sl@0: */ sl@0: #define SET_HIGH_WORD(d,v) \ sl@0: { \ sl@0: ieee_double_shape_type sh_u; \ sl@0: sh_u.value = (d); \ sl@0: sh_u.parts.msw = (v); \ sl@0: (d) = sh_u.value; \ sl@0: } sl@0: sl@0: /** sl@0: Set the less significant 32 bits of a double from an int. sl@0: @internalComponent sl@0: */ sl@0: #define SET_LOW_WORD(d,v) \ sl@0: { \ sl@0: ieee_double_shape_type sl_u; \ sl@0: sl_u.value = (d); \ sl@0: sl_u.parts.lsw = (v); \ sl@0: (d) = sl_u.value; \ sl@0: } sl@0: sl@0: /** sl@0: A union which permits us to convert between a float and a 32 bit sl@0: int. sl@0: @internalComponent sl@0: */ sl@0: typedef union sl@0: { sl@0: float value; sl@0: unsigned long word; sl@0: } ieee_float_shape_type; sl@0: sl@0: /** sl@0: Get a 32 bit int from a float. sl@0: @internalComponent sl@0: */ sl@0: #define GET_FLOAT_WORD(i,d) \ sl@0: { \ sl@0: ieee_float_shape_type gf_u; \ sl@0: gf_u.value = (d); \ sl@0: (i) = gf_u.word; \ sl@0: } sl@0: sl@0: /** sl@0: Set a float from a 32 bit int. sl@0: @internalComponent sl@0: */ sl@0: #define SET_FLOAT_WORD(d,i) \ sl@0: { \ sl@0: ieee_float_shape_type sf_u; \ sl@0: sf_u.word = (i); \ sl@0: (d) = sf_u.value; \ sl@0: } sl@0: sl@0: /** sl@0: Test a 32-bit value for being 0. sl@0: (x==0)? 0: (some value with top bit set to 1) sl@0: @internalComponent sl@0: */ sl@0: sl@0: #define CHECK_ZERO(x) ((x)|-(__int32_t)(x)) sl@0: sl@0: #ifdef __cplusplus sl@0: } sl@0: #endif