src/libm/math_private.h
author Sam Lantinga <slouken@libsdl.org>
Sat, 04 Nov 2017 15:53:19 -0700
changeset 11683 48bcba563d9c
parent 9080 2e4e71ec140f
child 11713 0083f778ede4
permissions -rw-r--r--
Updated math code from the uClibc 0.9.33 release
     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  * $Id: math_private.h,v 1.3 2004/02/09 07:10:38 andersen Exp $
    15  */
    16 
    17 #ifndef _MATH_PRIVATE_H_
    18 #define _MATH_PRIVATE_H_
    19 
    20 /* #include <endian.h> */
    21 #include "SDL_endian.h"
    22 /* #include <sys/types.h> */
    23 
    24 #define _IEEE_LIBM
    25 #define attribute_hidden
    26 #define libm_hidden_proto(x)
    27 #define libm_hidden_def(x)
    28 #define strong_alias(x, y)
    29 
    30 #ifndef __HAIKU__ /* already defined in a system header. */
    31 typedef unsigned int u_int32_t;
    32 #endif
    33 
    34 #define atan            SDL_uclibc_atan
    35 #define __ieee754_atan2 SDL_uclibc_atan2
    36 #define copysign        SDL_uclibc_copysign
    37 #define cos             SDL_uclibc_cos
    38 #define fabs            SDL_uclibc_fabs
    39 #define floor           SDL_uclibc_floor
    40 #define __ieee754_fmod  SDL_uclibc_fmod
    41 #define __ieee754_log   SDL_uclibc_log
    42 #define __ieee754_pow   SDL_uclibc_pow
    43 #define scalbn          SDL_uclibc_scalbn
    44 #define sin             SDL_uclibc_sin
    45 #define __ieee754_sqrt  SDL_uclibc_sqrt
    46 #define tan             SDL_uclibc_tan
    47 
    48 /* The original fdlibm code used statements like:
    49 	n0 = ((*(int*)&one)>>29)^1;		* index of high word *
    50 	ix0 = *(n0+(int*)&x);			* high word of x *
    51 	ix1 = *((1-n0)+(int*)&x);		* low word of x *
    52    to dig two 32 bit words out of the 64 bit IEEE floating point
    53    value.  That is non-ANSI, and, moreover, the gcc instruction
    54    scheduler gets it wrong.  We instead use the following macros.
    55    Unlike the original code, we determine the endianness at compile
    56    time, not at run time; I don't see much benefit to selecting
    57    endianness at run time.  */
    58 
    59 /* A union which permits us to convert between a double and two 32 bit
    60    ints.  */
    61 
    62 /*
    63  * Math on arm is special:
    64  * For FPA, float words are always big-endian.
    65  * For VFP, floats words follow the memory system mode.
    66  */
    67 
    68 #if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
    69 
    70 typedef union
    71 {
    72     double value;
    73     struct
    74     {
    75         u_int32_t msw;
    76         u_int32_t lsw;
    77     } parts;
    78 } ieee_double_shape_type;
    79 
    80 #else
    81 
    82 typedef union
    83 {
    84     double value;
    85     struct
    86     {
    87         u_int32_t lsw;
    88         u_int32_t msw;
    89     } parts;
    90 } ieee_double_shape_type;
    91 
    92 #endif
    93 
    94 /* Get two 32 bit ints from a double.  */
    95 
    96 #define EXTRACT_WORDS(ix0,ix1,d)				\
    97 do {								\
    98   ieee_double_shape_type ew_u;					\
    99   ew_u.value = (d);						\
   100   (ix0) = ew_u.parts.msw;					\
   101   (ix1) = ew_u.parts.lsw;					\
   102 } while (0)
   103 
   104 /* Get the more significant 32 bit int from a double.  */
   105 
   106 #define GET_HIGH_WORD(i,d)					\
   107 do {								\
   108   ieee_double_shape_type gh_u;					\
   109   gh_u.value = (d);						\
   110   (i) = gh_u.parts.msw;						\
   111 } while (0)
   112 
   113 /* Get the less significant 32 bit int from a double.  */
   114 
   115 #define GET_LOW_WORD(i,d)					\
   116 do {								\
   117   ieee_double_shape_type gl_u;					\
   118   gl_u.value = (d);						\
   119   (i) = gl_u.parts.lsw;						\
   120 } while (0)
   121 
   122 /* Set a double from two 32 bit ints.  */
   123 
   124 #define INSERT_WORDS(d,ix0,ix1)					\
   125 do {								\
   126   ieee_double_shape_type iw_u;					\
   127   iw_u.parts.msw = (ix0);					\
   128   iw_u.parts.lsw = (ix1);					\
   129   (d) = iw_u.value;						\
   130 } while (0)
   131 
   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;						\
   140 } while (0)
   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;						\
   150 } while (0)
   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;
   158     u_int32_t word;
   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;						\
   168 } while (0)
   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;						\
   177 } while (0)
   178 
   179 /* ieee style elementary functions */
   180 extern double
   181 __ieee754_sqrt(double)
   182     attribute_hidden;
   183      extern double __ieee754_acos(double) attribute_hidden;
   184      extern double __ieee754_acosh(double) attribute_hidden;
   185      extern double __ieee754_log(double) attribute_hidden;
   186      extern double __ieee754_atanh(double) attribute_hidden;
   187      extern double __ieee754_asin(double) attribute_hidden;
   188      extern double __ieee754_atan2(double, double) attribute_hidden;
   189      extern double __ieee754_exp(double) attribute_hidden;
   190      extern double __ieee754_cosh(double) attribute_hidden;
   191      extern double __ieee754_fmod(double, double) attribute_hidden;
   192      extern double __ieee754_pow(double, double) attribute_hidden;
   193      extern double __ieee754_lgamma_r(double, int *) attribute_hidden;
   194      extern double __ieee754_gamma_r(double, int *) attribute_hidden;
   195      extern double __ieee754_lgamma(double) attribute_hidden;
   196      extern double __ieee754_gamma(double) attribute_hidden;
   197      extern double __ieee754_log10(double) attribute_hidden;
   198      extern double __ieee754_sinh(double) attribute_hidden;
   199      extern double __ieee754_hypot(double, double) attribute_hidden;
   200      extern double __ieee754_j0(double) attribute_hidden;
   201      extern double __ieee754_j1(double) attribute_hidden;
   202      extern double __ieee754_y0(double) attribute_hidden;
   203      extern double __ieee754_y1(double) attribute_hidden;
   204      extern double __ieee754_jn(int, double) attribute_hidden;
   205      extern double __ieee754_yn(int, double) attribute_hidden;
   206      extern double __ieee754_remainder(double, double) attribute_hidden;
   207      extern int __ieee754_rem_pio2(double, double *) attribute_hidden;
   208 #if defined(_SCALB_INT)
   209      extern double __ieee754_scalb(double, int) attribute_hidden;
   210 #else
   211      extern double __ieee754_scalb(double, double) attribute_hidden;
   212 #endif
   213 
   214 /* fdlibm kernel function */
   215 #ifndef _IEEE_LIBM
   216      extern double __kernel_standard(double, double, int) attribute_hidden;
   217 #endif
   218      extern double __kernel_sin(double, double, int) attribute_hidden;
   219      extern double __kernel_cos(double, double) attribute_hidden;
   220      extern double __kernel_tan(double, double, int) attribute_hidden;
   221      extern int __kernel_rem_pio2(double *, double *, int, int, int,
   222                                   const int *) attribute_hidden;
   223 
   224 #endif /* _MATH_PRIVATE_H_ */