[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.18

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.18    ! christos   14:  * $NetBSD: math_private.h,v 1.17 2012/05/05 17:54:14 christos Exp $
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;
1.18    ! christos   51:   struct {
        !            52:     u_int64_t w;
        !            53:   } xparts;
1.1       jtc        54: } ieee_double_shape_type;
                     55:
                     56: #endif
                     57:
1.11      bjh21      58: #if (BYTE_ORDER == LITTLE_ENDIAN) && \
                     59:     !(defined(__arm__) && !defined(__VFP_FP__))
1.1       jtc        60:
1.8       simonb     61: typedef union
1.1       jtc        62: {
                     63:   double value;
1.8       simonb     64:   struct
1.1       jtc        65:   {
1.2       jtc        66:     u_int32_t lsw;
                     67:     u_int32_t msw;
1.1       jtc        68:   } parts;
1.18    ! christos   69:   struct {
        !            70:     u_int64_t w;
        !            71:   } xparts;
1.1       jtc        72: } ieee_double_shape_type;
                     73:
                     74: #endif
                     75:
                     76: /* Get two 32 bit ints from a double.  */
                     77:
                     78: #define EXTRACT_WORDS(ix0,ix1,d)                               \
                     79: do {                                                           \
                     80:   ieee_double_shape_type ew_u;                                 \
                     81:   ew_u.value = (d);                                            \
                     82:   (ix0) = ew_u.parts.msw;                                      \
                     83:   (ix1) = ew_u.parts.lsw;                                      \
1.13      christos   84: } while (/*CONSTCOND*/0)
1.1       jtc        85:
1.18    ! christos   86: /* Get a 64-bit int from a double. */
        !            87: #define EXTRACT_WORD64(ix,d)                                   \
        !            88: do {                                                           \
        !            89:   ieee_double_shape_type ew_u;                                 \
        !            90:   ew_u.value = (d);                                            \
        !            91:   (ix) = ew_u.xparts.w;                                                \
        !            92: } while (/*CONSTCOND*/0)
        !            93:
        !            94:
1.1       jtc        95: /* Get the more significant 32 bit int from a double.  */
                     96:
                     97: #define GET_HIGH_WORD(i,d)                                     \
                     98: do {                                                           \
                     99:   ieee_double_shape_type gh_u;                                 \
                    100:   gh_u.value = (d);                                            \
                    101:   (i) = gh_u.parts.msw;                                                \
1.13      christos  102: } while (/*CONSTCOND*/0)
1.1       jtc       103:
                    104: /* Get the less significant 32 bit int from a double.  */
                    105:
                    106: #define GET_LOW_WORD(i,d)                                      \
                    107: do {                                                           \
                    108:   ieee_double_shape_type gl_u;                                 \
                    109:   gl_u.value = (d);                                            \
                    110:   (i) = gl_u.parts.lsw;                                                \
1.13      christos  111: } while (/*CONSTCOND*/0)
1.1       jtc       112:
                    113: /* Set a double from two 32 bit ints.  */
                    114:
                    115: #define INSERT_WORDS(d,ix0,ix1)                                        \
                    116: do {                                                           \
                    117:   ieee_double_shape_type iw_u;                                 \
                    118:   iw_u.parts.msw = (ix0);                                      \
                    119:   iw_u.parts.lsw = (ix1);                                      \
                    120:   (d) = iw_u.value;                                            \
1.13      christos  121: } while (/*CONSTCOND*/0)
1.1       jtc       122:
1.18    ! christos  123: /* Set a double from a 64-bit int. */
        !           124: #define INSERT_WORD64(d,ix)                                    \
        !           125: do {                                                           \
        !           126:   ieee_double_shape_type iw_u;                                 \
        !           127:   iw_u.xparts.w = (ix);                                                \
        !           128:   (d) = iw_u.value;                                            \
        !           129: } while (/*CONSTCOND*/0)
        !           130:
        !           131:
1.1       jtc       132: /* Set the more significant 32 bits of a double from an int.  */
                    133:
                    134: #define SET_HIGH_WORD(d,v)                                     \
                    135: do {                                                           \
                    136:   ieee_double_shape_type sh_u;                                 \
                    137:   sh_u.value = (d);                                            \
                    138:   sh_u.parts.msw = (v);                                                \
                    139:   (d) = sh_u.value;                                            \
1.13      christos  140: } while (/*CONSTCOND*/0)
1.1       jtc       141:
                    142: /* Set the less significant 32 bits of a double from an int.  */
                    143:
                    144: #define SET_LOW_WORD(d,v)                                      \
                    145: do {                                                           \
                    146:   ieee_double_shape_type sl_u;                                 \
                    147:   sl_u.value = (d);                                            \
                    148:   sl_u.parts.lsw = (v);                                                \
                    149:   (d) = sl_u.value;                                            \
1.13      christos  150: } while (/*CONSTCOND*/0)
1.1       jtc       151:
                    152: /* A union which permits us to convert between a float and a 32 bit
                    153:    int.  */
                    154:
                    155: typedef union
                    156: {
                    157:   float value;
1.3       jtc       158:   u_int32_t word;
1.1       jtc       159: } ieee_float_shape_type;
                    160:
                    161: /* Get a 32 bit int from a float.  */
                    162:
                    163: #define GET_FLOAT_WORD(i,d)                                    \
                    164: do {                                                           \
                    165:   ieee_float_shape_type gf_u;                                  \
                    166:   gf_u.value = (d);                                            \
                    167:   (i) = gf_u.word;                                             \
1.13      christos  168: } while (/*CONSTCOND*/0)
1.1       jtc       169:
                    170: /* Set a float from a 32 bit int.  */
                    171:
                    172: #define SET_FLOAT_WORD(d,i)                                    \
                    173: do {                                                           \
                    174:   ieee_float_shape_type sf_u;                                  \
                    175:   sf_u.word = (i);                                             \
                    176:   (d) = sf_u.value;                                            \
1.13      christos  177: } while (/*CONSTCOND*/0)
1.1       jtc       178:
1.14      christos  179: /*
                    180:  * Attempt to get strict C99 semantics for assignment with non-C99 compilers.
                    181:  */
                    182: #if FLT_EVAL_METHOD == 0 || __GNUC__ == 0
                    183: #define        STRICT_ASSIGN(type, lval, rval) ((lval) = (rval))
                    184: #else
                    185: #define        STRICT_ASSIGN(type, lval, rval) do {    \
                    186:        volatile type __lval;                   \
                    187:                                                \
                    188:        if (sizeof(type) >= sizeof(double))     \
                    189:                (lval) = (rval);                \
                    190:        else {                                  \
                    191:                __lval = (rval);                \
                    192:                (lval) = __lval;                \
                    193:        }                                       \
                    194: } while (/*CONSTCOND*/0)
                    195: #endif
                    196:
1.15      christos  197: #ifdef _COMPLEX_H
                    198:
                    199: /*
                    200:  * Quoting from ISO/IEC 9899:TC2:
                    201:  *
                    202:  * 6.2.5.13 Types
                    203:  * Each complex type has the same representation and alignment requirements as
                    204:  * an array type containing exactly two elements of the corresponding real type;
                    205:  * the first element is equal to the real part, and the second element to the
                    206:  * imaginary part, of the complex number.
                    207:  */
                    208: typedef union {
                    209:        float complex z;
                    210:        float parts[2];
                    211: } float_complex;
                    212:
                    213: typedef union {
                    214:        double complex z;
                    215:        double parts[2];
                    216: } double_complex;
                    217:
                    218: typedef union {
                    219:        long double complex z;
1.16      drochner  220:        long double parts[2];
1.15      christos  221: } long_double_complex;
                    222:
                    223: #define        REAL_PART(z)    ((z).parts[0])
                    224: #define        IMAG_PART(z)    ((z).parts[1])
                    225:
                    226: #endif /* _COMPLEX_H */
                    227:
1.1       jtc       228: /* ieee style elementary functions */
1.8       simonb    229: extern double __ieee754_sqrt __P((double));
                    230: extern double __ieee754_acos __P((double));
                    231: extern double __ieee754_acosh __P((double));
                    232: extern double __ieee754_log __P((double));
                    233: extern double __ieee754_atanh __P((double));
                    234: extern double __ieee754_asin __P((double));
                    235: extern double __ieee754_atan2 __P((double,double));
1.1       jtc       236: extern double __ieee754_exp __P((double));
                    237: extern double __ieee754_cosh __P((double));
                    238: extern double __ieee754_fmod __P((double,double));
                    239: extern double __ieee754_pow __P((double,double));
                    240: extern double __ieee754_lgamma_r __P((double,int *));
                    241: extern double __ieee754_gamma_r __P((double,int *));
                    242: extern double __ieee754_lgamma __P((double));
                    243: extern double __ieee754_gamma __P((double));
                    244: extern double __ieee754_log10 __P((double));
1.12      christos  245: extern double __ieee754_log2 __P((double));
1.1       jtc       246: extern double __ieee754_sinh __P((double));
                    247: extern double __ieee754_hypot __P((double,double));
                    248: extern double __ieee754_j0 __P((double));
                    249: extern double __ieee754_j1 __P((double));
                    250: extern double __ieee754_y0 __P((double));
                    251: extern double __ieee754_y1 __P((double));
                    252: extern double __ieee754_jn __P((int,double));
                    253: extern double __ieee754_yn __P((int,double));
                    254: extern double __ieee754_remainder __P((double,double));
                    255: extern int    __ieee754_rem_pio2 __P((double,double*));
                    256: extern double __ieee754_scalb __P((double,double));
                    257:
                    258: /* fdlibm kernel function */
1.8       simonb    259: extern double __kernel_standard __P((double,double,int));
1.1       jtc       260: extern double __kernel_sin __P((double,double,int));
                    261: extern double __kernel_cos __P((double,double));
                    262: extern double __kernel_tan __P((double,double,int));
                    263: extern int    __kernel_rem_pio2 __P((double*,double*,int,int,int,const int*));
                    264:
                    265:
                    266: /* ieee style elementary float functions */
1.8       simonb    267: extern float __ieee754_sqrtf __P((float));
                    268: extern float __ieee754_acosf __P((float));
                    269: extern float __ieee754_acoshf __P((float));
                    270: extern float __ieee754_logf __P((float));
                    271: extern float __ieee754_atanhf __P((float));
                    272: extern float __ieee754_asinf __P((float));
                    273: extern float __ieee754_atan2f __P((float,float));
1.1       jtc       274: extern float __ieee754_expf __P((float));
                    275: extern float __ieee754_coshf __P((float));
                    276: extern float __ieee754_fmodf __P((float,float));
                    277: extern float __ieee754_powf __P((float,float));
                    278: extern float __ieee754_lgammaf_r __P((float,int *));
                    279: extern float __ieee754_gammaf_r __P((float,int *));
                    280: extern float __ieee754_lgammaf __P((float));
                    281: extern float __ieee754_gammaf __P((float));
                    282: extern float __ieee754_log10f __P((float));
1.12      christos  283: extern float __ieee754_log2f __P((float));
1.1       jtc       284: extern float __ieee754_sinhf __P((float));
                    285: extern float __ieee754_hypotf __P((float,float));
                    286: extern float __ieee754_j0f __P((float));
                    287: extern float __ieee754_j1f __P((float));
                    288: extern float __ieee754_y0f __P((float));
                    289: extern float __ieee754_y1f __P((float));
                    290: extern float __ieee754_jnf __P((int,float));
                    291: extern float __ieee754_ynf __P((int,float));
                    292: extern float __ieee754_remainderf __P((float,float));
                    293: extern int   __ieee754_rem_pio2f __P((float,float*));
                    294: extern float __ieee754_scalbf __P((float,float));
                    295:
                    296: /* float versions of fdlibm kernel functions */
                    297: extern float __kernel_sinf __P((float,float,int));
                    298: extern float __kernel_cosf __P((float,float));
                    299: extern float __kernel_tanf __P((float,float,int));
                    300: extern int   __kernel_rem_pio2f __P((float*,float*,int,int,int,const int*));
                    301:
1.17      christos  302: /*
                    303:  * TRUNC() is a macro that sets the trailing 27 bits in the mantissa of an
                    304:  * IEEE double variable to zero.  It must be expression-like for syntactic
                    305:  * reasons, and we implement this expression using an inline function
                    306:  * instead of a pure macro to avoid depending on the gcc feature of
                    307:  * statement-expressions.
                    308:  */
                    309: #define        TRUNC(d)        (_b_trunc(&(d)))
                    310:
                    311: static __inline void
                    312: _b_trunc(volatile double *_dp)
                    313: {
                    314:        uint32_t _lw;
                    315:
                    316:        GET_LOW_WORD(_lw, *_dp);
                    317:        SET_LOW_WORD(*_dp, _lw & 0xf8000000);
                    318: }
                    319:
                    320: struct Double {
                    321:        double  a;
                    322:        double  b;
                    323: };
                    324:
                    325: /*
                    326:  * Functions internal to the math package, yet not static.
                    327:  */
                    328: double __exp__D(double, double);
                    329: struct Double __log__D(double);
                    330:
1.1       jtc       331: #endif /* _MATH_PRIVATE_H_ */

CVSweb <webmaster@jp.NetBSD.org>