src/video/math_private.h
author Sam Lantinga
Tue, 07 Feb 2006 17:49:40 +0000
changeset 1344 2eed9997bd24
parent 1339 62802d9d7c87
child 1361 19418e4422cb
permissions -rw-r--r--
G:\SDL-12-CVS\src\video\math_private.h(171) : error C4226:
nonstandard extension used : 'huge' is an obsolete keyword
     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$
    15  */
    16 
    17 #ifndef _MATH_PRIVATE_H_
    18 #define _MATH_PRIVATE_H_
    19 
    20 #include "SDL_endian.h"
    21 
    22 #define huge		really_big /* huge is a reserved keyword in VC++ 6.0 */
    23 #define int32_t 	math_int32_t
    24 #define u_int32_t	math_u_int32_t
    25 typedef Sint32 math_int32_t;
    26 typedef Uint32 math_u_int32_t;
    27 
    28 /* The original fdlibm code used statements like:
    29 	n0 = ((*(int*)&one)>>29)^1;		* index of high word *
    30 	ix0 = *(n0+(int*)&x);			* high word of x *
    31 	ix1 = *((1-n0)+(int*)&x);		* low word of x *
    32    to dig two 32 bit words out of the 64 bit IEEE floating point
    33    value.  That is non-ANSI, and, moreover, the gcc instruction
    34    scheduler gets it wrong.  We instead use the following macros.
    35    Unlike the original code, we determine the endianness at compile
    36    time, not at run time; I don't see much benefit to selecting
    37    endianness at run time.  */
    38 
    39 /* A union which permits us to convert between a double and two 32 bit
    40    ints.  */
    41 
    42 /*
    43  * Math on arm is special:
    44  * For FPA, float words are always big-endian.
    45  * For VFP, floats words follow the memory system mode.
    46  */
    47 
    48 #if (SDL_BYTEORDER == SDL_BIG_ENDIAN) || \
    49     (!defined(__VFP_FP__) && (defined(__arm__) || defined(__thumb__)))
    50 
    51 typedef union
    52 {
    53   double value;
    54   struct
    55   {
    56     u_int32_t msw;
    57     u_int32_t lsw;
    58   } parts;
    59 } ieee_double_shape_type;
    60 
    61 #else
    62 
    63 typedef union
    64 {
    65   double value;
    66   struct
    67   {
    68     u_int32_t lsw;
    69     u_int32_t msw;
    70   } parts;
    71 } ieee_double_shape_type;
    72 
    73 #endif
    74 
    75 /* Get two 32 bit ints from a double.  */
    76 
    77 #define EXTRACT_WORDS(ix0,ix1,d)				\
    78 do {								\
    79   ieee_double_shape_type ew_u;					\
    80   ew_u.value = (d);						\
    81   (ix0) = ew_u.parts.msw;					\
    82   (ix1) = ew_u.parts.lsw;					\
    83 } while (0)
    84 
    85 /* Get the more significant 32 bit int from a double.  */
    86 
    87 #define GET_HIGH_WORD(i,d)					\
    88 do {								\
    89   ieee_double_shape_type gh_u;					\
    90   gh_u.value = (d);						\
    91   (i) = gh_u.parts.msw;						\
    92 } while (0)
    93 
    94 /* Get the less significant 32 bit int from a double.  */
    95 
    96 #define GET_LOW_WORD(i,d)					\
    97 do {								\
    98   ieee_double_shape_type gl_u;					\
    99   gl_u.value = (d);						\
   100   (i) = gl_u.parts.lsw;						\
   101 } while (0)
   102 
   103 /* Set a double from two 32 bit ints.  */
   104 
   105 #define INSERT_WORDS(d,ix0,ix1)					\
   106 do {								\
   107   ieee_double_shape_type iw_u;					\
   108   iw_u.parts.msw = (ix0);					\
   109   iw_u.parts.lsw = (ix1);					\
   110   (d) = iw_u.value;						\
   111 } while (0)
   112 
   113 /* Set the more significant 32 bits of a double from an int.  */
   114 
   115 #define SET_HIGH_WORD(d,v)					\
   116 do {								\
   117   ieee_double_shape_type sh_u;					\
   118   sh_u.value = (d);						\
   119   sh_u.parts.msw = (v);						\
   120   (d) = sh_u.value;						\
   121 } while (0)
   122 
   123 /* Set the less significant 32 bits of a double from an int.  */
   124 
   125 #define SET_LOW_WORD(d,v)					\
   126 do {								\
   127   ieee_double_shape_type sl_u;					\
   128   sl_u.value = (d);						\
   129   sl_u.parts.lsw = (v);						\
   130   (d) = sl_u.value;						\
   131 } while (0)
   132 
   133 /* A union which permits us to convert between a float and a 32 bit
   134    int.  */
   135 
   136 typedef union
   137 {
   138   float value;
   139   u_int32_t word;
   140 } ieee_float_shape_type;
   141 
   142 /* Get a 32 bit int from a float.  */
   143 
   144 #define GET_FLOAT_WORD(i,d)					\
   145 do {								\
   146   ieee_float_shape_type gf_u;					\
   147   gf_u.value = (d);						\
   148   (i) = gf_u.word;						\
   149 } while (0)
   150 
   151 /* Set a float from a 32 bit int.  */
   152 
   153 #define SET_FLOAT_WORD(d,i)					\
   154 do {								\
   155   ieee_float_shape_type sf_u;					\
   156   sf_u.word = (i);						\
   157   (d) = sf_u.value;						\
   158 } while (0)
   159 
   160 
   161 #ifdef __STDC__
   162 static const double
   163 #else
   164 static double
   165 #endif
   166 zero    =  0.0,
   167 one	=  1.0,
   168 two	=  2.0,
   169 two53	=  9007199254740992.0,	/* 0x43400000, 0x00000000 */
   170 two54   =  1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
   171 twom54  =  5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
   172 huge   = 1.0e+300,
   173 tiny   = 1.0e-300;
   174 
   175 #endif /* _MATH_PRIVATE_H_ */