[BACK]Return to math_private.h CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libm / src

Annotation of src/lib/libm/src/math_private.h, Revision 1.16.8.1

1.1       jtc         1: /*
                      2:  * ====================================================
                      3:  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
                      4:  *
                      5:  * Developed at SunPro, a Sun Microsystems, Inc. business.
                      6:  * Permission to use, copy, modify, and distribute this
1.8       simonb      7:  * software is freely granted, provided that this notice
1.1       jtc         8:  * is preserved.
                      9:  * ====================================================
                     10:  */
                     11:
                     12: /*
                     13:  * from: @(#)fdlibm.h 5.1 93/09/24
1.16.8.1! riz        14:  * $NetBSD$
1.1       jtc        15:  */
                     16:
                     17: #ifndef _MATH_PRIVATE_H_
                     18: #define _MATH_PRIVATE_H_
                     19:
1.2       jtc        20: #include <sys/types.h>
1.1       jtc        21:
                     22: /* The original fdlibm code used statements like:
                     23:        n0 = ((*(int*)&one)>>29)^1;             * index of high word *
                     24:        ix0 = *(n0+(int*)&x);                   * high word of x *
                     25:        ix1 = *((1-n0)+(int*)&x);               * low word of x *
                     26:    to dig two 32 bit words out of the 64 bit IEEE floating point
                     27:    value.  That is non-ANSI, and, moreover, the gcc instruction
                     28:    scheduler gets it wrong.  We instead use the following macros.
                     29:    Unlike the original code, we determine the endianness at compile
                     30:    time, not at run time; I don't see much benefit to selecting
                     31:    endianness at run time.  */
                     32:
                     33: /* A union which permits us to convert between a double and two 32 bit
                     34:    ints.  */
                     35:
1.4       mark       36: /*
1.11      bjh21      37:  * The ARM ports are little endian except for the FPA word order which is
1.4       mark       38:  * big endian.
                     39:  */
                     40:
1.11      bjh21      41: #if (BYTE_ORDER == BIG_ENDIAN) || (defined(__arm__) && !defined(__VFP_FP__))
1.1       jtc        42:
1.8       simonb     43: typedef union
1.1       jtc        44: {
                     45:   double value;
1.8       simonb     46:   struct
1.1       jtc        47:   {
1.2       jtc        48:     u_int32_t msw;
                     49:     u_int32_t lsw;
1.1       jtc        50:   } parts;
                     51: } ieee_double_shape_type;
                     52:
                     53: #endif
                     54:
1.11      bjh21      55: #if (BYTE_ORDER == LITTLE_ENDIAN) && \
                     56:     !(defined(__arm__) && !defined(__VFP_FP__))
1.1       jtc        57:
1.8       simonb     58: typedef union
1.1       jtc        59: {
                     60:   double value;
1.8       simonb     61:   struct
1.1       jtc        62:   {
1.2       jtc        63:     u_int32_t lsw;
                     64:     u_int32_t msw;
1.1       jtc        65:   } parts;
                     66: } ieee_double_shape_type;
                     67:
                     68: #endif
                     69:
                     70: /* Get two 32 bit ints from a double.  */
                     71:
                     72: #define EXTRACT_WORDS(ix0,ix1,d)                               \
                     73: do {                                                           \
                     74:   ieee_double_shape_type ew_u;                                 \
                     75:   ew_u.value = (d);                                            \
                     76:   (ix0) = ew_u.parts.msw;                                      \
                     77:   (ix1) = ew_u.parts.lsw;                                      \
1.13      christos   78: } while (/*CONSTCOND*/0)
1.1       jtc        79:
                     80: /* Get the more significant 32 bit int from a double.  */
                     81:
                     82: #define GET_HIGH_WORD(i,d)                                     \
                     83: do {                                                           \
                     84:   ieee_double_shape_type gh_u;                                 \
                     85:   gh_u.value = (d);                                            \
                     86:   (i) = gh_u.parts.msw;                                                \
1.13      christos   87: } while (/*CONSTCOND*/0)
1.1       jtc        88:
                     89: /* Get the less significant 32 bit int from a double.  */
                     90:
                     91: #define GET_LOW_WORD(i,d)                                      \
                     92: do {                                                           \
                     93:   ieee_double_shape_type gl_u;                                 \
                     94:   gl_u.value = (d);                                            \
                     95:   (i) = gl_u.parts.lsw;                                                \
1.13      christos   96: } while (/*CONSTCOND*/0)
1.1       jtc        97:
                     98: /* Set a double from two 32 bit ints.  */
                     99:
                    100: #define INSERT_WORDS(d,ix0,ix1)                                        \
                    101: do {                                                           \
                    102:   ieee_double_shape_type iw_u;                                 \
                    103:   iw_u.parts.msw = (ix0);                                      \
                    104:   iw_u.parts.lsw = (ix1);                                      \
                    105:   (d) = iw_u.value;                                            \
1.13      christos  106: } while (/*CONSTCOND*/0)
1.1       jtc       107:
                    108: /* Set the more significant 32 bits of a double from an int.  */
                    109:
                    110: #define SET_HIGH_WORD(d,v)                                     \
                    111: do {                                                           \
                    112:   ieee_double_shape_type sh_u;                                 \
                    113:   sh_u.value = (d);                                            \
                    114:   sh_u.parts.msw = (v);                                                \
                    115:   (d) = sh_u.value;                                            \
1.13      christos  116: } while (/*CONSTCOND*/0)
1.1       jtc       117:
                    118: /* Set the less significant 32 bits of a double from an int.  */
                    119:
                    120: #define SET_LOW_WORD(d,v)                                      \
                    121: do {                                                           \
                    122:   ieee_double_shape_type sl_u;                                 \
                    123:   sl_u.value = (d);                                            \
                    124:   sl_u.parts.lsw = (v);                                                \
                    125:   (d) = sl_u.value;                                            \
1.13      christos  126: } while (/*CONSTCOND*/0)
1.1       jtc       127:
                    128: /* A union which permits us to convert between a float and a 32 bit
                    129:    int.  */
                    130:
                    131: typedef union
                    132: {
                    133:   float value;
1.3       jtc       134:   u_int32_t word;
1.1       jtc       135: } ieee_float_shape_type;
                    136:
                    137: /* Get a 32 bit int from a float.  */
                    138:
                    139: #define GET_FLOAT_WORD(i,d)                                    \
                    140: do {                                                           \
                    141:   ieee_float_shape_type gf_u;                                  \
                    142:   gf_u.value = (d);                                            \
                    143:   (i) = gf_u.word;                                             \
1.13      christos  144: } while (/*CONSTCOND*/0)
1.1       jtc       145:
                    146: /* Set a float from a 32 bit int.  */
                    147:
                    148: #define SET_FLOAT_WORD(d,i)                                    \
                    149: do {                                                           \
                    150:   ieee_float_shape_type sf_u;                                  \
                    151:   sf_u.word = (i);                                             \
                    152:   (d) = sf_u.value;                                            \
1.13      christos  153: } while (/*CONSTCOND*/0)
1.1       jtc       154:
1.14      christos  155: /*
                    156:  * Attempt to get strict C99 semantics for assignment with non-C99 compilers.
                    157:  */
                    158: #if FLT_EVAL_METHOD == 0 || __GNUC__ == 0
                    159: #define        STRICT_ASSIGN(type, lval, rval) ((lval) = (rval))
                    160: #else
                    161: #define        STRICT_ASSIGN(type, lval, rval) do {    \
                    162:        volatile type __lval;                   \
                    163:                                                \
                    164:        if (sizeof(type) >= sizeof(double))     \
                    165:                (lval) = (rval);                \
                    166:        else {                                  \
                    167:                __lval = (rval);                \
                    168:                (lval) = __lval;                \
                    169:        }                                       \
                    170: } while (/*CONSTCOND*/0)
                    171: #endif
                    172:
1.15      christos  173: #ifdef _COMPLEX_H
                    174:
                    175: /*
                    176:  * Quoting from ISO/IEC 9899:TC2:
                    177:  *
                    178:  * 6.2.5.13 Types
                    179:  * Each complex type has the same representation and alignment requirements as
                    180:  * an array type containing exactly two elements of the corresponding real type;
                    181:  * the first element is equal to the real part, and the second element to the
                    182:  * imaginary part, of the complex number.
                    183:  */
                    184: typedef union {
                    185:        float complex z;
                    186:        float parts[2];
                    187: } float_complex;
                    188:
                    189: typedef union {
                    190:        double complex z;
                    191:        double parts[2];
                    192: } double_complex;
                    193:
                    194: typedef union {
                    195:        long double complex z;
1.16      drochner  196:        long double parts[2];
1.15      christos  197: } long_double_complex;
                    198:
                    199: #define        REAL_PART(z)    ((z).parts[0])
                    200: #define        IMAG_PART(z)    ((z).parts[1])
                    201:
                    202: #endif /* _COMPLEX_H */
                    203:
1.1       jtc       204: /* ieee style elementary functions */
1.8       simonb    205: extern double __ieee754_sqrt __P((double));
                    206: extern double __ieee754_acos __P((double));
                    207: extern double __ieee754_acosh __P((double));
                    208: extern double __ieee754_log __P((double));
                    209: extern double __ieee754_atanh __P((double));
                    210: extern double __ieee754_asin __P((double));
                    211: extern double __ieee754_atan2 __P((double,double));
1.1       jtc       212: extern double __ieee754_exp __P((double));
                    213: extern double __ieee754_cosh __P((double));
                    214: extern double __ieee754_fmod __P((double,double));
                    215: extern double __ieee754_pow __P((double,double));
                    216: extern double __ieee754_lgamma_r __P((double,int *));
                    217: extern double __ieee754_gamma_r __P((double,int *));
                    218: extern double __ieee754_lgamma __P((double));
                    219: extern double __ieee754_gamma __P((double));
                    220: extern double __ieee754_log10 __P((double));
1.12      christos  221: extern double __ieee754_log2 __P((double));
1.1       jtc       222: extern double __ieee754_sinh __P((double));
                    223: extern double __ieee754_hypot __P((double,double));
                    224: extern double __ieee754_j0 __P((double));
                    225: extern double __ieee754_j1 __P((double));
                    226: extern double __ieee754_y0 __P((double));
                    227: extern double __ieee754_y1 __P((double));
                    228: extern double __ieee754_jn __P((int,double));
                    229: extern double __ieee754_yn __P((int,double));
                    230: extern double __ieee754_remainder __P((double,double));
                    231: extern int    __ieee754_rem_pio2 __P((double,double*));
                    232: extern double __ieee754_scalb __P((double,double));
                    233:
                    234: /* fdlibm kernel function */
1.8       simonb    235: extern double __kernel_standard __P((double,double,int));
1.1       jtc       236: extern double __kernel_sin __P((double,double,int));
                    237: extern double __kernel_cos __P((double,double));
                    238: extern double __kernel_tan __P((double,double,int));
                    239: extern int    __kernel_rem_pio2 __P((double*,double*,int,int,int,const int*));
                    240:
                    241:
                    242: /* ieee style elementary float functions */
1.8       simonb    243: extern float __ieee754_sqrtf __P((float));
                    244: extern float __ieee754_acosf __P((float));
                    245: extern float __ieee754_acoshf __P((float));
                    246: extern float __ieee754_logf __P((float));
                    247: extern float __ieee754_atanhf __P((float));
                    248: extern float __ieee754_asinf __P((float));
                    249: extern float __ieee754_atan2f __P((float,float));
1.1       jtc       250: extern float __ieee754_expf __P((float));
                    251: extern float __ieee754_coshf __P((float));
                    252: extern float __ieee754_fmodf __P((float,float));
                    253: extern float __ieee754_powf __P((float,float));
                    254: extern float __ieee754_lgammaf_r __P((float,int *));
                    255: extern float __ieee754_gammaf_r __P((float,int *));
                    256: extern float __ieee754_lgammaf __P((float));
                    257: extern float __ieee754_gammaf __P((float));
                    258: extern float __ieee754_log10f __P((float));
1.12      christos  259: extern float __ieee754_log2f __P((float));
1.1       jtc       260: extern float __ieee754_sinhf __P((float));
                    261: extern float __ieee754_hypotf __P((float,float));
                    262: extern float __ieee754_j0f __P((float));
                    263: extern float __ieee754_j1f __P((float));
                    264: extern float __ieee754_y0f __P((float));
                    265: extern float __ieee754_y1f __P((float));
                    266: extern float __ieee754_jnf __P((int,float));
                    267: extern float __ieee754_ynf __P((int,float));
                    268: extern float __ieee754_remainderf __P((float,float));
                    269: extern int   __ieee754_rem_pio2f __P((float,float*));
                    270: extern float __ieee754_scalbf __P((float,float));
                    271:
                    272: /* float versions of fdlibm kernel functions */
                    273: extern float __kernel_sinf __P((float,float,int));
                    274: extern float __kernel_cosf __P((float,float));
                    275: extern float __kernel_tanf __P((float,float,int));
                    276: extern int   __kernel_rem_pio2f __P((float*,float*,int,int,int,const int*));
                    277:
1.16.8.1! riz       278: /*
        !           279:  * TRUNC() is a macro that sets the trailing 27 bits in the mantissa of an
        !           280:  * IEEE double variable to zero.  It must be expression-like for syntactic
        !           281:  * reasons, and we implement this expression using an inline function
        !           282:  * instead of a pure macro to avoid depending on the gcc feature of
        !           283:  * statement-expressions.
        !           284:  */
        !           285: #define        TRUNC(d)        (_b_trunc(&(d)))
        !           286:
        !           287: static __inline void
        !           288: _b_trunc(volatile double *_dp)
        !           289: {
        !           290:        uint32_t _lw;
        !           291:
        !           292:        GET_LOW_WORD(_lw, *_dp);
        !           293:        SET_LOW_WORD(*_dp, _lw & 0xf8000000);
        !           294: }
        !           295:
        !           296: struct Double {
        !           297:        double  a;
        !           298:        double  b;
        !           299: };
        !           300:
        !           301: /*
        !           302:  * Functions internal to the math package, yet not static.
        !           303:  */
        !           304: double __exp__D(double, double);
        !           305: struct Double __log__D(double);
        !           306:
1.1       jtc       307: #endif /* _MATH_PRIVATE_H_ */

CVSweb <webmaster@jp.NetBSD.org>