gonzui


Format: Advanced Search

t2ex/bsd_source/lib/libc/src_bsd/math/math_private.hbare sourcepermlink (0.05 seconds)

Search this content:

    1: /*      $OpenBSD: math_private.h,v 1.15 2011/07/26 11:43:01 martynas Exp $   */
    2: /*
    3:  * ====================================================
    4:  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
    5:  *
    6:  * Developed at SunPro, a Sun Microsystems, Inc. business.
    7:  * Permission to use, copy, modify, and distribute this
    8:  * software is freely granted, provided that this notice 
    9:  * is preserved.
   10:  * ====================================================
   11:  */
   12: 
   13: /*
   14:  * from: @(#)fdlibm.h 5.1 93/09/24
   15:  */
   16: 
   17: #ifndef _MATH_PRIVATE_H_
   18: #define _MATH_PRIVATE_H_
   19: 
   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 long double and
   34:    four 32 bit ints.  */
   35: 
   36: #if BYTE_ORDER == BIG_ENDIAN
   37: 
   38: typedef union
   39: {
   40:   long double value;
   41:   struct {
   42:     u_int32_t mswhi;
   43:     u_int32_t mswlo;
   44:     u_int32_t lswhi;
   45:     u_int32_t lswlo;
   46:   } parts32;
   47:   struct {
   48:     u_int64_t msw;
   49:     u_int64_t lsw;
   50:   } parts64;
   51: } ieee_quad_shape_type;
   52: 
   53: #endif
   54: 
   55: #if BYTE_ORDER == LITTLE_ENDIAN
   56: 
   57: typedef union
   58: {
   59:   long double value;
   60:   struct {
   61:     u_int32_t lswlo;
   62:     u_int32_t lswhi;
   63:     u_int32_t mswlo;
   64:     u_int32_t mswhi;
   65:   } parts32;
   66:   struct {
   67:     u_int64_t lsw;
   68:     u_int64_t msw;
   69:   } parts64;
   70: } ieee_quad_shape_type;
   71: 
   72: #endif
   73: 
   74: /* Get two 64 bit ints from a long double.  */
   75: 
   76: #define GET_LDOUBLE_WORDS64(ix0,ix1,d)                          \
   77: do {                                                            \
   78:   ieee_quad_shape_type qw_u;                                    \
   79:   qw_u.value = (d);                                             \
   80:   (ix0) = qw_u.parts64.msw;                                     \
   81:   (ix1) = qw_u.parts64.lsw;                                     \
   82: } while (0)
   83: 
   84: /* Set a long double from two 64 bit ints.  */
   85: 
   86: #define SET_LDOUBLE_WORDS64(d,ix0,ix1)                          \
   87: do {                                                            \
   88:   ieee_quad_shape_type qw_u;                                    \
   89:   qw_u.parts64.msw = (ix0);                                     \
   90:   qw_u.parts64.lsw = (ix1);                                     \
   91:   (d) = qw_u.value;                                             \
   92: } while (0)
   93: 
   94: /* Get the more significant 64 bits of a long double mantissa.  */
   95: 
   96: #define GET_LDOUBLE_MSW64(v,d)                                  \
   97: do {                                                            \
   98:   ieee_quad_shape_type sh_u;                                    \
   99:   sh_u.value = (d);                                             \
  100:   (v) = sh_u.parts64.msw;                                       \
  101: } while (0)
  102: 
  103: /* Set the more significant 64 bits of a long double mantissa from an int.  */
  104: 
  105: #define SET_LDOUBLE_MSW64(d,v)                                  \
  106: do {                                                            \
  107:   ieee_quad_shape_type sh_u;                                    \
  108:   sh_u.value = (d);                                             \
  109:   sh_u.parts64.msw = (v);                                       \
  110:   (d) = sh_u.value;                                             \
  111: } while (0)
  112: 
  113: /* Get the least significant 64 bits of a long double mantissa.  */
  114: 
  115: #define GET_LDOUBLE_LSW64(v,d)                                  \
  116: do {                                                            \
  117:   ieee_quad_shape_type sh_u;                                    \
  118:   sh_u.value = (d);                                             \
  119:   (v) = sh_u.parts64.lsw;                                       \
  120: } while (0)
  121: 
  122: /* A union which permits us to convert between a long double and
  123:    three 32 bit ints.  */
  124: 
  125: #if BYTE_ORDER == BIG_ENDIAN
  126: 
  127: typedef union
  128: {
  129:   long double value;
  130:   struct {
  131: #ifdef __LP64__
  132:     int padh:32;
  133: #endif
  134:     int exp:16;
  135:     int padl:16;
  136:     u_int32_t msw;
  137:     u_int32_t lsw;
  138:   } parts;
  139: } ieee_extended_shape_type;
  140: 
  141: #endif
  142: 
  143: #if BYTE_ORDER == LITTLE_ENDIAN
  144: 
  145: typedef union
  146: {
  147:   long double value;
  148:   struct {
  149:     u_int32_t lsw;
  150:     u_int32_t msw;
  151:     int exp:16;
  152:     int padl:16;
  153: #ifdef __LP64__
  154:     int padh:32;
  155: #endif
  156:   } parts;
  157: } ieee_extended_shape_type;
  158: 
  159: #endif
  160: 
  161: /* Get three 32 bit ints from a double.  */
  162: 
  163: #define GET_LDOUBLE_WORDS(se,ix0,ix1,d)                         \
  164: do {                                                            \
  165:   ieee_extended_shape_type ew_u;                                \
  166:   ew_u.value = (d);                                             \
  167:   (se) = ew_u.parts.exp;                                        \
  168:   (ix0) = ew_u.parts.msw;                                       \
  169:   (ix1) = ew_u.parts.lsw;                                       \
  170: } while (0)
  171: 
  172: /* Set a double from two 32 bit ints.  */
  173: 
  174: #define SET_LDOUBLE_WORDS(d,se,ix0,ix1)                         \
  175: do {                                                            \
  176:   ieee_extended_shape_type iw_u;                                \
  177:   iw_u.parts.exp = (se);                                        \
  178:   iw_u.parts.msw = (ix0);                                       \
  179:   iw_u.parts.lsw = (ix1);                                       \
  180:   (d) = iw_u.value;                                             \
  181: } while (0)
  182: 
  183: /* Get the more significant 32 bits of a long double mantissa.  */
  184: 
  185: #define GET_LDOUBLE_MSW(v,d)                                    \
  186: do {                                                            \
  187:   ieee_extended_shape_type sh_u;                                \
  188:   sh_u.value = (d);                                             \
  189:   (v) = sh_u.parts.msw;                                         \
  190: } while (0)
  191: 
  192: /* Set the more significant 32 bits of a long double mantissa from an int.  */
  193: 
  194: #define SET_LDOUBLE_MSW(d,v)                                    \
  195: do {                                                            \
  196:   ieee_extended_shape_type sh_u;                                \
  197:   sh_u.value = (d);                                             \
  198:   sh_u.parts.msw = (v);                                         \
  199:   (d) = sh_u.value;                                             \
  200: } while (0)
  201: 
  202: /* Get int from the exponent of a long double.  */
  203: 
  204: #define GET_LDOUBLE_EXP(se,d)                                   \
  205: do {                                                            \
  206:   ieee_extended_shape_type ge_u;                                \
  207:   ge_u.value = (d);                                             \
  208:   (se) = ge_u.parts.exp;                                        \
  209: } while (0)
  210: 
  211: /* Set exponent of a long double from an int.  */
  212: 
  213: #define SET_LDOUBLE_EXP(d,se)                                   \
  214: do {                                                            \
  215:   ieee_extended_shape_type se_u;                                \
  216:   se_u.value = (d);                                             \
  217:   se_u.parts.exp = (se);                                        \
  218:   (d) = se_u.value;                                             \
  219: } while (0)
  220: 
  221: /* A union which permits us to convert between a double and two 32 bit
  222:    ints.  */
  223: 
  224: /*
  225:  * The arm port is little endian except for the FP word order which is
  226:  * big endian.
  227:  */
  228: 
  229: #if (BYTE_ORDER == BIG_ENDIAN) || (defined(__arm__) && !defined(__VFP_FP__))
  230: 
  231: typedef union
  232: {
  233:   double value;
  234:   struct
  235:   {
  236:     u_int32_t msw;
  237:     u_int32_t lsw;
  238:   } parts;
  239: } ieee_double_shape_type;
  240: 
  241: #endif
  242: 
  243: #if (BYTE_ORDER == LITTLE_ENDIAN) && !(defined(__arm__) && !defined(__VFP_FP__))
  244: 
  245: typedef union
  246: {
  247:   double value;
  248:   struct
  249:   {
  250:     u_int32_t lsw;
  251:     u_int32_t msw;
  252:   } parts;
  253: } ieee_double_shape_type;
  254: 
  255: #endif
  256: 
  257: /* Get two 32 bit ints from a double.  */
  258: 
  259: #define EXTRACT_WORDS(ix0,ix1,d)                                \
  260: do {                                                            \
  261:   ieee_double_shape_type ew_u;                                  \
  262:   ew_u.value = (d);                                             \
  263:   (ix0) = ew_u.parts.msw;                                       \
  264:   (ix1) = ew_u.parts.lsw;                                       \
  265: } while (0)
  266: 
  267: /* Get the more significant 32 bit int from a double.  */
  268: 
  269: #define GET_HIGH_WORD(i,d)                                      \
  270: do {                                                            \
  271:   ieee_double_shape_type gh_u;                                  \
  272:   gh_u.value = (d);                                             \
  273:   (i) = gh_u.parts.msw;                                         \
  274: } while (0)
  275: 
  276: /* Get the less significant 32 bit int from a double.  */
  277: 
  278: #define GET_LOW_WORD(i,d)                                       \
  279: do {                                                            \
  280:   ieee_double_shape_type gl_u;                                  \
  281:   gl_u.value = (d);                                             \
  282:   (i) = gl_u.parts.lsw;                                         \
  283: } while (0)
  284: 
  285: /* Set a double from two 32 bit ints.  */
  286: 
  287: #define INSERT_WORDS(d,ix0,ix1)                                 \
  288: do {                                                            \
  289:   ieee_double_shape_type iw_u;                                  \
  290:   iw_u.parts.msw = (ix0);                                       \
  291:   iw_u.parts.lsw = (ix1);                                       \
  292:   (d) = iw_u.value;                                             \
  293: } while (0)
  294: 
  295: /* Set the more significant 32 bits of a double from an int.  */
  296: 
  297: #define SET_HIGH_WORD(d,v)                                      \
  298: do {                                                            \
  299:   ieee_double_shape_type sh_u;                                  \
  300:   sh_u.value = (d);                                             \
  301:   sh_u.parts.msw = (v);                                         \
  302:   (d) = sh_u.value;                                             \
  303: } while (0)
  304: 
  305: /* Set the less significant 32 bits of a double from an int.  */
  306: 
  307: #define SET_LOW_WORD(d,v)                                       \
  308: do {                                                            \
  309:   ieee_double_shape_type sl_u;                                  \
  310:   sl_u.value = (d);                                             \
  311:   sl_u.parts.lsw = (v);                                         \
  312:   (d) = sl_u.value;                                             \
  313: } while (0)
  314: 
  315: /* A union which permits us to convert between a float and a 32 bit
  316:    int.  */
  317: 
  318: typedef union
  319: {
  320:   float value;
  321:   u_int32_t word;
  322: } ieee_float_shape_type;
  323: 
  324: /* Get a 32 bit int from a float.  */
  325: 
  326: #define GET_FLOAT_WORD(i,d)                                     \
  327: do {                                                            \
  328:   ieee_float_shape_type gf_u;                                   \
  329:   gf_u.value = (d);                                             \
  330:   (i) = gf_u.word;                                              \
  331: } while (0)
  332: 
  333: /* Set a float from a 32 bit int.  */
  334: 
  335: #define SET_FLOAT_WORD(d,i)                                     \
  336: do {                                                            \
  337:   ieee_float_shape_type sf_u;                                   \
  338:   sf_u.word = (i);                                              \
  339:   (d) = sf_u.value;                                             \
  340: } while (0)
  341: 
  342: #ifdef FLT_EVAL_METHOD
  343: /*
  344:  * Attempt to get strict C99 semantics for assignment with non-C99 compilers.
  345:  */
  346: #if FLT_EVAL_METHOD == 0 || __GNUC__ == 0
  347: #define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval))
  348: #else /* FLT_EVAL_METHOD == 0 || __GNUC__ == 0 */
  349: #define STRICT_ASSIGN(type, lval, rval) do {    \
  350:         volatile type __lval;                  \
  351:                                                 \
  352:         if (sizeof(type) >= sizeof(double))    \
  353:                 (lval) = (rval);              \
  354:         else {                                 \
  355:                 __lval = (rval);              \
  356:                 (lval) = __lval;              \
  357:         }                                      \
  358: } while (0)
  359: #endif /* FLT_EVAL_METHOD == 0 || __GNUC__ == 0 */
  360: #endif /* FLT_EVAL_METHOD */
  361: 
  362: /* fdlibm kernel function */
  363: extern int    __ieee754_rem_pio2(double,double*);
  364: extern double __kernel_sin(double,double,int);
  365: extern double __kernel_cos(double,double);
  366: extern double __kernel_tan(double,double,int);
  367: extern int    __kernel_rem_pio2(double*,double*,int,int,int);
  368: 
  369: /* float versions of fdlibm kernel functions */
  370: extern int   __ieee754_rem_pio2f(float,float*);
  371: extern float __kernel_sinf(float,float,int);
  372: extern float __kernel_cosf(float,float);
  373: extern float __kernel_tanf(float,float,int);
  374: extern int   __kernel_rem_pio2f(float*,float*,int,int,int,const int*);
  375: 
  376: /* long double precision kernel functions */
  377: long double __kernel_sinl(long double, long double, int);
  378: long double __kernel_cosl(long double, long double);
  379: long double __kernel_tanl(long double, long double, int);
  380: 
  381: /*
  382:  * Common routine to process the arguments to nan(), nanf(), and nanl().
  383:  */
  384: void _scan_nan(uint32_t *__words, int __num_words, const char *__s);
  385: 
  386: /*
  387:  * TRUNC() is a macro that sets the trailing 27 bits in the mantissa
  388:  * of an IEEE double variable to zero.  It must be expression-like
  389:  * for syntactic reasons, and we implement this expression using
  390:  * an inline function instead of a pure macro to avoid depending
  391:  * on the gcc feature of statement-expressions.
  392:  */
  393: #define TRUNC(d)        (_b_trunc(&(d)))
  394: 
  395: static __inline void
  396: _b_trunc(volatile double *_dp)
  397: {
  398:         uint32_t _lw;
  399: 
  400:         GET_LOW_WORD(_lw, *_dp);
  401:         SET_LOW_WORD(*_dp, _lw & 0xf8000000);
  402: }
  403: 
  404: struct Double {
  405:         double a;
  406:         double b;
  407: };
  408: 
  409: /*
  410:  * Functions internal to the math package, yet not static.
  411:  */
  412: double __exp__D(double, double);
  413: struct Double __log__D(double);
  414: 
  415: #endif /* _MATH_PRIVATE_H_ */