src/libm/math_private.h
author Ryan C. Gordon <icculus@icculus.org>
Thu, 21 Apr 2016 03:16:44 -0400
changeset 11729 d1ce8396c356
parent 11713 0083f778ede4
child 11852 c3fc99758ad2
permissions -rw-r--r--
Initial shot at a renderer target for Apple's Metal API.

This isn't complete, but is enough to run testsprite2. It's currently
Mac-only; with a little work to figure out how to properly glue in a Metal
layer to a UIView, this will likely work on iOS, too.

This is only wired up to the configure script right now, and disabled by
default. CMake and Xcode still need their bits filled in as appropriate.
slouken@2756
     1
/*
slouken@2756
     2
 * ====================================================
slouken@2756
     3
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
slouken@2756
     4
 *
slouken@2756
     5
 * Developed at SunPro, a Sun Microsystems, Inc. business.
slouken@2756
     6
 * Permission to use, copy, modify, and distribute this
slouken@2756
     7
 * software is freely granted, provided that this notice
slouken@2756
     8
 * is preserved.
slouken@2756
     9
 * ====================================================
slouken@2756
    10
 */
slouken@2756
    11
slouken@2756
    12
/*
slouken@2756
    13
 * from: @(#)fdlibm.h 5.1 93/09/24
slouken@2756
    14
 * $Id: math_private.h,v 1.3 2004/02/09 07:10:38 andersen Exp $
slouken@2756
    15
 */
slouken@2756
    16
slouken@2756
    17
#ifndef _MATH_PRIVATE_H_
slouken@2756
    18
#define _MATH_PRIVATE_H_
slouken@2756
    19
gabomdq@7678
    20
/* #include <endian.h> */
Daniel@4909
    21
#include "SDL_endian.h"
gabomdq@7678
    22
/* #include <sys/types.h> */
slouken@2756
    23
slouken@11683
    24
#define _IEEE_LIBM
slouken@2756
    25
#define attribute_hidden
slouken@2756
    26
#define libm_hidden_proto(x)
slouken@2756
    27
#define libm_hidden_def(x)
slouken@11683
    28
#define strong_alias(x, y)
slouken@2756
    29
icculus@7404
    30
#ifndef __HAIKU__ /* already defined in a system header. */
slouken@2760
    31
typedef unsigned int u_int32_t;
icculus@7404
    32
#endif
slouken@2760
    33
slouken@7351
    34
#define atan            SDL_uclibc_atan
slouken@7351
    35
#define __ieee754_atan2 SDL_uclibc_atan2
slouken@7351
    36
#define copysign        SDL_uclibc_copysign
slouken@7351
    37
#define cos             SDL_uclibc_cos
slouken@7351
    38
#define fabs            SDL_uclibc_fabs
slouken@7351
    39
#define floor           SDL_uclibc_floor
slouken@11683
    40
#define __ieee754_fmod  SDL_uclibc_fmod
slouken@7351
    41
#define __ieee754_log   SDL_uclibc_log
slouken@7351
    42
#define __ieee754_pow   SDL_uclibc_pow
slouken@11713
    43
#define scalbln         SDL_uclibc_scalbln
slouken@7351
    44
#define scalbn          SDL_uclibc_scalbn
slouken@7351
    45
#define sin             SDL_uclibc_sin
slouken@7351
    46
#define __ieee754_sqrt  SDL_uclibc_sqrt
slouken@8840
    47
#define tan             SDL_uclibc_tan
slouken@7351
    48
slouken@2756
    49
/* The original fdlibm code used statements like:
slouken@2756
    50
	n0 = ((*(int*)&one)>>29)^1;		* index of high word *
slouken@2756
    51
	ix0 = *(n0+(int*)&x);			* high word of x *
slouken@2756
    52
	ix1 = *((1-n0)+(int*)&x);		* low word of x *
slouken@2756
    53
   to dig two 32 bit words out of the 64 bit IEEE floating point
slouken@2756
    54
   value.  That is non-ANSI, and, moreover, the gcc instruction
slouken@2756
    55
   scheduler gets it wrong.  We instead use the following macros.
slouken@2756
    56
   Unlike the original code, we determine the endianness at compile
slouken@2756
    57
   time, not at run time; I don't see much benefit to selecting
slouken@2756
    58
   endianness at run time.  */
slouken@2756
    59
slouken@2756
    60
/* A union which permits us to convert between a double and two 32 bit
slouken@2756
    61
   ints.  */
slouken@2756
    62
slouken@2756
    63
/*
slouken@2756
    64
 * Math on arm is special:
slouken@2756
    65
 * For FPA, float words are always big-endian.
slouken@2756
    66
 * For VFP, floats words follow the memory system mode.
slouken@2756
    67
 */
slouken@2756
    68
Daniel@4909
    69
#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
slouken@2756
    70
slouken@2756
    71
typedef union
slouken@2756
    72
{
slouken@2756
    73
    double value;
slouken@2756
    74
    struct
slouken@2756
    75
    {
slouken@2756
    76
        u_int32_t msw;
slouken@2756
    77
        u_int32_t lsw;
slouken@2756
    78
    } parts;
slouken@2756
    79
} ieee_double_shape_type;
slouken@2756
    80
slouken@2756
    81
#else
slouken@2756
    82
slouken@2756
    83
typedef union
slouken@2756
    84
{
slouken@2756
    85
    double value;
slouken@2756
    86
    struct
slouken@2756
    87
    {
slouken@2756
    88
        u_int32_t lsw;
slouken@2756
    89
        u_int32_t msw;
slouken@2756
    90
    } parts;
slouken@2756
    91
} ieee_double_shape_type;
slouken@2756
    92
slouken@2756
    93
#endif
slouken@2756
    94
slouken@2756
    95
/* Get two 32 bit ints from a double.  */
slouken@2756
    96
slouken@2756
    97
#define EXTRACT_WORDS(ix0,ix1,d)				\
slouken@2756
    98
do {								\
slouken@2756
    99
  ieee_double_shape_type ew_u;					\
slouken@2756
   100
  ew_u.value = (d);						\
slouken@2756
   101
  (ix0) = ew_u.parts.msw;					\
slouken@2756
   102
  (ix1) = ew_u.parts.lsw;					\
slouken@2756
   103
} while (0)
slouken@2756
   104
slouken@2756
   105
/* Get the more significant 32 bit int from a double.  */
slouken@2756
   106
slouken@2756
   107
#define GET_HIGH_WORD(i,d)					\
slouken@2756
   108
do {								\
slouken@2756
   109
  ieee_double_shape_type gh_u;					\
slouken@2756
   110
  gh_u.value = (d);						\
slouken@2756
   111
  (i) = gh_u.parts.msw;						\
slouken@2756
   112
} while (0)
slouken@2756
   113
slouken@2756
   114
/* Get the less significant 32 bit int from a double.  */
slouken@2756
   115
slouken@2756
   116
#define GET_LOW_WORD(i,d)					\
slouken@2756
   117
do {								\
slouken@2756
   118
  ieee_double_shape_type gl_u;					\
slouken@2756
   119
  gl_u.value = (d);						\
slouken@2756
   120
  (i) = gl_u.parts.lsw;						\
slouken@2756
   121
} while (0)
slouken@2756
   122
slouken@2756
   123
/* Set a double from two 32 bit ints.  */
slouken@2756
   124
slouken@2756
   125
#define INSERT_WORDS(d,ix0,ix1)					\
slouken@2756
   126
do {								\
slouken@2756
   127
  ieee_double_shape_type iw_u;					\
slouken@2756
   128
  iw_u.parts.msw = (ix0);					\
slouken@2756
   129
  iw_u.parts.lsw = (ix1);					\
slouken@2756
   130
  (d) = iw_u.value;						\
slouken@2756
   131
} while (0)
slouken@2756
   132
slouken@2756
   133
/* Set the more significant 32 bits of a double from an int.  */
slouken@2756
   134
slouken@2756
   135
#define SET_HIGH_WORD(d,v)					\
slouken@2756
   136
do {								\
slouken@2756
   137
  ieee_double_shape_type sh_u;					\
slouken@2756
   138
  sh_u.value = (d);						\
slouken@2756
   139
  sh_u.parts.msw = (v);						\
slouken@2756
   140
  (d) = sh_u.value;						\
slouken@2756
   141
} while (0)
slouken@2756
   142
slouken@2756
   143
/* Set the less significant 32 bits of a double from an int.  */
slouken@2756
   144
slouken@2756
   145
#define SET_LOW_WORD(d,v)					\
slouken@2756
   146
do {								\
slouken@2756
   147
  ieee_double_shape_type sl_u;					\
slouken@2756
   148
  sl_u.value = (d);						\
slouken@2756
   149
  sl_u.parts.lsw = (v);						\
slouken@2756
   150
  (d) = sl_u.value;						\
slouken@2756
   151
} while (0)
slouken@2756
   152
slouken@2756
   153
/* A union which permits us to convert between a float and a 32 bit
slouken@2756
   154
   int.  */
slouken@2756
   155
slouken@2756
   156
typedef union
slouken@2756
   157
{
slouken@2756
   158
    float value;
slouken@2756
   159
    u_int32_t word;
slouken@2756
   160
} ieee_float_shape_type;
slouken@2756
   161
slouken@2756
   162
/* Get a 32 bit int from a float.  */
slouken@2756
   163
slouken@2756
   164
#define GET_FLOAT_WORD(i,d)					\
slouken@2756
   165
do {								\
slouken@2756
   166
  ieee_float_shape_type gf_u;					\
slouken@2756
   167
  gf_u.value = (d);						\
slouken@2756
   168
  (i) = gf_u.word;						\
slouken@2756
   169
} while (0)
slouken@2756
   170
slouken@2756
   171
/* Set a float from a 32 bit int.  */
slouken@2756
   172
slouken@2756
   173
#define SET_FLOAT_WORD(d,i)					\
slouken@2756
   174
do {								\
slouken@2756
   175
  ieee_float_shape_type sf_u;					\
slouken@2756
   176
  sf_u.word = (i);						\
slouken@2756
   177
  (d) = sf_u.value;						\
slouken@2756
   178
} while (0)
slouken@2756
   179
slouken@2756
   180
/* ieee style elementary functions */
slouken@2756
   181
extern double
slouken@2756
   182
__ieee754_sqrt(double)
slouken@2756
   183
    attribute_hidden;
slouken@2756
   184
     extern double __ieee754_acos(double) attribute_hidden;
slouken@2756
   185
     extern double __ieee754_acosh(double) attribute_hidden;
slouken@2756
   186
     extern double __ieee754_log(double) attribute_hidden;
slouken@2756
   187
     extern double __ieee754_atanh(double) attribute_hidden;
slouken@2756
   188
     extern double __ieee754_asin(double) attribute_hidden;
slouken@2756
   189
     extern double __ieee754_atan2(double, double) attribute_hidden;
slouken@2756
   190
     extern double __ieee754_exp(double) attribute_hidden;
slouken@2756
   191
     extern double __ieee754_cosh(double) attribute_hidden;
slouken@2756
   192
     extern double __ieee754_fmod(double, double) attribute_hidden;
slouken@2756
   193
     extern double __ieee754_pow(double, double) attribute_hidden;
slouken@2756
   194
     extern double __ieee754_lgamma_r(double, int *) attribute_hidden;
slouken@2756
   195
     extern double __ieee754_gamma_r(double, int *) attribute_hidden;
slouken@2756
   196
     extern double __ieee754_lgamma(double) attribute_hidden;
slouken@2756
   197
     extern double __ieee754_gamma(double) attribute_hidden;
slouken@2756
   198
     extern double __ieee754_log10(double) attribute_hidden;
slouken@2756
   199
     extern double __ieee754_sinh(double) attribute_hidden;
slouken@2756
   200
     extern double __ieee754_hypot(double, double) attribute_hidden;
slouken@2756
   201
     extern double __ieee754_j0(double) attribute_hidden;
slouken@2756
   202
     extern double __ieee754_j1(double) attribute_hidden;
slouken@2756
   203
     extern double __ieee754_y0(double) attribute_hidden;
slouken@2756
   204
     extern double __ieee754_y1(double) attribute_hidden;
slouken@2756
   205
     extern double __ieee754_jn(int, double) attribute_hidden;
slouken@2756
   206
     extern double __ieee754_yn(int, double) attribute_hidden;
slouken@2756
   207
     extern double __ieee754_remainder(double, double) attribute_hidden;
slouken@2756
   208
     extern int __ieee754_rem_pio2(double, double *) attribute_hidden;
slouken@2756
   209
#if defined(_SCALB_INT)
slouken@2756
   210
     extern double __ieee754_scalb(double, int) attribute_hidden;
slouken@2756
   211
#else
slouken@2756
   212
     extern double __ieee754_scalb(double, double) attribute_hidden;
slouken@2756
   213
#endif
slouken@2756
   214
slouken@2756
   215
/* fdlibm kernel function */
slouken@2756
   216
#ifndef _IEEE_LIBM
slouken@2756
   217
     extern double __kernel_standard(double, double, int) attribute_hidden;
slouken@2756
   218
#endif
slouken@2756
   219
     extern double __kernel_sin(double, double, int) attribute_hidden;
slouken@2756
   220
     extern double __kernel_cos(double, double) attribute_hidden;
slouken@2756
   221
     extern double __kernel_tan(double, double, int) attribute_hidden;
slouken@2756
   222
     extern int __kernel_rem_pio2(double *, double *, int, int, int,
slouken@2756
   223
                                  const int *) attribute_hidden;
slouken@2756
   224
slouken@2756
   225
#endif /* _MATH_PRIVATE_H_ */