(linenum→info "unix/slp.c:2238")

glibc/2.7/math/math_private.h

    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
    7:  * software is freely granted, provided that this notice
    8:  * is preserved.
    9:  * ====================================================
   10:  */
   11: 
   12: /*
   13:  * from: @(#)fdlibm.h 5.1 93/09/24
   14:  */
   15: 
   16: #ifndef _MATH_PRIVATE_H_
   17: #define _MATH_PRIVATE_H_
   18: 
   19: #include <endian.h>
   20: #include <sys/types.h>
   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: 
   36: #if __FLOAT_WORD_ORDER == BIG_ENDIAN
   37: 
   38: typedef union
   39: {
   40:   double value;
   41:   struct
   42:   {
   43:     u_int32_t msw;
   44:     u_int32_t lsw;
   45:   } parts;
   46: } ieee_double_shape_type;
   47: 
   48: #endif
   49: 
   50: #if __FLOAT_WORD_ORDER == LITTLE_ENDIAN
   51: 
   52: typedef union
   53: {
   54:   double value;
   55:   struct
   56:   {
   57:     u_int32_t lsw;
   58:     u_int32_t msw;
   59:   } parts;
   60: } ieee_double_shape_type;
   61: 
   62: #endif
   63: 
   64: /* Get two 32 bit ints from a double.  */
   65: 
   66: #define EXTRACT_WORDS(ix0,ix1,d)                                \
   67: do {                                                            \
   68:   ieee_double_shape_type ew_u;                                  \
   69:   ew_u.value = (d);                                             \
   70:   (ix0) = ew_u.parts.msw;                                       \
   71:   (ix1) = ew_u.parts.lsw;                                       \
   72: } while (0)
   73: 
   74: /* Get the more significant 32 bit int from a double.  */
   75: 
   76: #define GET_HIGH_WORD(i,d)                                      \
   77: do {                                                            \
   78:   ieee_double_shape_type gh_u;                                  \
   79:   gh_u.value = (d);                                             \
   80:   (i) = gh_u.parts.msw;                                         \
   81: } while (0)
   82: 
   83: /* Get the less significant 32 bit int from a double.  */
   84: 
   85: #define GET_LOW_WORD(i,d)                                       \
   86: do {                                                            \
   87:   ieee_double_shape_type gl_u;                                  \
   88:   gl_u.value = (d);                                             \
   89:   (i) = gl_u.parts.lsw;                                         \
   90: } while (0)
   91: 
   92: /* Set a double from two 32 bit ints.  */
   93: 
   94: #define INSERT_WORDS(d,ix0,ix1)                                 \
   95: do {                                                            \
   96:   ieee_double_shape_type iw_u;                                  \
   97:   iw_u.parts.msw = (ix0);                                       \
   98:   iw_u.parts.lsw = (ix1);                                       \
   99:   (d) = iw_u.value;                                             \
  100: } while (0)
  101: 
  102: /* Set the more significant 32 bits of a double from an int.  */
  103: 
  104: #define SET_HIGH_WORD(d,v)                                      \
  105: do {                                                            \
  106:   ieee_double_shape_type sh_u;                                  \
  107:   sh_u.value = (d);                                             \
  108:   sh_u.parts.msw = (v);                                         \
  109:   (d) = sh_u.value;                                             \
  110: } while (0)
  111: 
  112: /* Set the less significant 32 bits of a double from an int.  */
  113: 
  114: #define SET_LOW_WORD(d,v)                                       \
  115: do {                                                            \
  116:   ieee_double_shape_type sl_u;                                  \
  117:   sl_u.value = (d);                                             \
  118:   sl_u.parts.lsw = (v);                                         \
  119:   (d) = sl_u.value;                                             \
  120: } while (0)
  121: 
  122: /* A union which permits us to convert between a float and a 32 bit
  123:    int.  */
  124: 
  125: typedef union
  126: {
  127:   float value;
  128:   u_int32_t word;
  129: } ieee_float_shape_type;
  130: 
  131: /* Get a 32 bit int from a float.  */
  132: 
  133: #define GET_FLOAT_WORD(i,d)                                     \
  134: do {                                                            \
  135:   ieee_float_shape_type gf_u;                                   \
  136:   gf_u.value = (d);                                             \
  137:   (i) = gf_u.word;                                              \
  138: } while (0)
  139: 
  140: /* Set a float from a 32 bit int.  */
  141: 
  142: #define SET_FLOAT_WORD(d,i)                                     \
  143: do {                                                            \
  144:   ieee_float_shape_type sf_u;                                   \
  145:   sf_u.word = (i);                                              \
  146:   (d) = sf_u.value;                                             \
  147: } while (0)
  148: 
  149: /* Get long double macros from a separate header.  */
  150: #include <math_ldbl.h>
  151: 
  152: /* ieee style elementary functions */
  153: extern double __ieee754_sqrt (double);
  154: extern double __ieee754_acos (double);
  155: extern double __ieee754_acosh (double);
  156: extern double __ieee754_log (double);
  157: extern double __ieee754_atanh (double);
  158: extern double __ieee754_asin (double);
  159: extern double __ieee754_atan2 (double,double);
  160: extern double __ieee754_exp (double);
  161: extern double __ieee754_exp2 (double);
  162: extern double __ieee754_exp10 (double);
  163: extern double __ieee754_cosh (double);
  164: extern double __ieee754_fmod (double,double);
  165: extern double __ieee754_pow (double,double);
  166: extern double __ieee754_lgamma_r (double,int *);
  167: extern double __ieee754_gamma_r (double,int *);
  168: extern double __ieee754_lgamma (double);
  169: extern double __ieee754_gamma (double);
  170: extern double __ieee754_log10 (double);
  171: extern double __ieee754_log2 (double);
  172: extern double __ieee754_sinh (double);
  173: extern double __ieee754_hypot (double,double);
  174: extern double __ieee754_j0 (double);
  175: extern double __ieee754_j1 (double);
  176: extern double __ieee754_y0 (double);
  177: extern double __ieee754_y1 (double);
  178: extern double __ieee754_jn (int,double);
  179: extern double __ieee754_yn (int,double);
  180: extern double __ieee754_remainder (double,double);
  181: extern int32_t __ieee754_rem_pio2 (double,double*);
  182: extern double __ieee754_scalb (double,double);
  183: 
  184: /* fdlibm kernel function */
  185: extern double __kernel_standard (double,double,int);
  186: extern double __kernel_sin (double,double,int);
  187: extern double __kernel_cos (double,double);
  188: extern double __kernel_tan (double,double,int);
  189: extern int    __kernel_rem_pio2 (double*,double*,int,int,int, const int32_t*);
  190: 
  191: /* internal functions.  */
  192: extern double __copysign (double x, double __y);
  193: 
  194: #if __GNUC_PREREQ (4, 0)
  195: extern inline double __copysign (double x, double y)
  196: { return __builtin_copysign (x, y); }
  197: #endif
  198: 
  199: /* ieee style elementary float functions */
  200: extern float __ieee754_sqrtf (float);
  201: extern float __ieee754_acosf (float);
  202: extern float __ieee754_acoshf (float);
  203: extern float __ieee754_logf (float);
  204: extern float __ieee754_atanhf (float);
  205: extern float __ieee754_asinf (float);
  206: extern float __ieee754_atan2f (float,float);
  207: extern float __ieee754_expf (float);
  208: extern float __ieee754_exp2f (float);
  209: extern float __ieee754_exp10f (float);
  210: extern float __ieee754_coshf (float);
  211: extern float __ieee754_fmodf (float,float);
  212: extern float __ieee754_powf (float,float);
  213: extern float __ieee754_lgammaf_r (float,int *);
  214: extern float __ieee754_gammaf_r (float,int *);
  215: extern float __ieee754_lgammaf (float);
  216: extern float __ieee754_gammaf (float);
  217: extern float __ieee754_log10f (float);
  218: extern float __ieee754_log2f (float);
  219: extern float __ieee754_sinhf (float);
  220: extern float __ieee754_hypotf (float,float);
  221: extern float __ieee754_j0f (float);
  222: extern float __ieee754_j1f (float);
  223: extern float __ieee754_y0f (float);
  224: extern float __ieee754_y1f (float);
  225: extern float __ieee754_jnf (int,float);
  226: extern float __ieee754_ynf (int,float);
  227: extern float __ieee754_remainderf (float,float);
  228: extern int32_t __ieee754_rem_pio2f (float,float*);
  229: extern float __ieee754_scalbf (float,float);
  230: 
  231: 
  232: /* float versions of fdlibm kernel functions */
  233: extern float __kernel_sinf (float,float,int);
  234: extern float __kernel_cosf (float,float);
  235: extern float __kernel_tanf (float,float,int);
  236: extern int   __kernel_rem_pio2f (float*,float*,int,int,int, const int32_t*);
  237: 
  238: /* internal functions.  */
  239: extern float __copysignf (float x, float __y);
  240: 
  241: #if __GNUC_PREREQ (4, 0)
  242: extern inline float __copysignf (float x, float y)
  243: { return __builtin_copysignf (x, y); }
  244: #endif
  245: 
  246: /* ieee style elementary long double functions */
  247: extern long double __ieee754_sqrtl (long double);
  248: extern long double __ieee754_acosl (long double);
  249: extern long double __ieee754_acoshl (long double);
  250: extern long double __ieee754_logl (long double);
  251: extern long double __ieee754_atanhl (long double);
  252: extern long double __ieee754_asinl (long double);
  253: extern long double __ieee754_atan2l (long double,long double);
  254: extern long double __ieee754_expl (long double);
  255: extern long double __ieee754_exp2l (long double);
  256: extern long double __ieee754_exp10l (long double);
  257: extern long double __ieee754_coshl (long double);
  258: extern long double __ieee754_fmodl (long double,long double);
  259: extern long double __ieee754_powl (long double,long double);
  260: extern long double __ieee754_lgammal_r (long double,int *);
  261: extern long double __ieee754_gammal_r (long double,int *);
  262: extern long double __ieee754_lgammal (long double);
  263: extern long double __ieee754_gammal (long double);
  264: extern long double __ieee754_log10l (long double);
  265: extern long double __ieee754_log2l (long double);
  266: extern long double __ieee754_sinhl (long double);
  267: extern long double __ieee754_hypotl (long double,long double);
  268: extern long double __ieee754_j0l (long double);
  269: extern long double __ieee754_j1l (long double);
  270: extern long double __ieee754_y0l (long double);
  271: extern long double __ieee754_y1l (long double);
  272: extern long double __ieee754_jnl (int,long double);
  273: extern long double __ieee754_ynl (int,long double);
  274: extern long double __ieee754_remainderl (long double,long double);
  275: extern int   __ieee754_rem_pio2l (long double,long double*);
  276: extern long double __ieee754_scalbl (long double,long double);
  277: 
  278: /* long double versions of fdlibm kernel functions */
  279: extern long double __kernel_sinl (long double,long double,int);
  280: extern long double __kernel_cosl (long double,long double);
  281: extern long double __kernel_tanl (long double,long double,int);
  282: extern void __kernel_sincosl (long double,long double,
  283:                               long double *,long double *, int);
  284: extern int   __kernel_rem_pio2l (long double*,long double*,int,int,
  285:                                  int,const int*);
  286: 
  287: #ifndef NO_LONG_DOUBLE
  288: /* prototypes required to compile the ldbl-96 support without warnings */
  289: extern int __finitel (long double);
  290: extern int __ilogbl (long double);
  291: extern int __isinfl (long double);
  292: extern int __isnanl (long double);
  293: extern long double __atanl (long double);
  294: extern long double __copysignl (long double, long double);
  295: extern long double __expm1l (long double);
  296: extern long double __floorl (long double);
  297: extern long double __frexpl (long double, int *);
  298: extern long double __ldexpl (long double, int);
  299: extern long double __log1pl (long double);
  300: extern long double __nanl (const char *);
  301: extern long double __rintl (long double);
  302: extern long double __scalbnl (long double, int);
  303: extern long double __sqrtl (long double x);
  304: extern long double fabsl (long double x);
  305: extern void __sincosl (long double, long double *, long double *);
  306: extern long double __logbl (long double x);
  307: extern long double __significandl (long double x);
  308: 
  309: #if __GNUC_PREREQ (4, 0)
  310: extern inline long double __copysignl (long double x, long double y)
  311: { return __builtin_copysignl (x, y); }
  312: #endif
  313: 
  314: #endif
  315: 
  316: /* Prototypes for functions of the IBM Accurate Mathematical Library.  */
  317: extern double __exp1 (double __x, double __xx, double __error);
  318: extern double __sin (double __x);
  319: extern double __cos (double __x);
  320: extern int __branred (double __x, double *__a, double *__aa);
  321: extern void __doasin (double __x, double __dx, double __v[]);
  322: extern void __dubsin (double __x, double __dx, double __v[]);
  323: extern void __dubcos (double __x, double __dx, double __v[]);
  324: extern double __halfulp (double __x, double __y);
  325: extern double __sin32 (double __x, double __res, double __res1);
  326: extern double __cos32 (double __x, double __res, double __res1);
  327: extern double __mpsin (double __x, double __dx);
  328: extern double __mpcos (double __x, double __dx);
  329: extern double __mpsin1 (double __x);
  330: extern double __mpcos1 (double __x);
  331: extern double __slowexp (double __x);
  332: extern double __slowpow (double __x, double __y, double __z);
  333: extern void __docos (double __x, double __dx, double __v[]);
  334: 
  335: #ifndef math_opt_barrier
  336: #define math_opt_barrier(x) \
  337: ({ __typeof (x) __x = x; __asm ("" : "+m" (__x)); __x; })
  338: #define math_force_eval(x) __asm __volatile ("" : : "m" (x))
  339: #endif
  340: 
  341: #endif /* _MATH_PRIVATE_H_ */
Syntax (Markdown)