19682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/*
29682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * ====================================================
39682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
49682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *
59682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Developed at SunPro, a Sun Microsystems, Inc. business.
69682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Permission to use, copy, modify, and distribute this
79682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * software is freely granted, provided that this notice
89682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * is preserved.
99682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * ====================================================
109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */
119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/*
139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * from: @(#)fdlibm.h 5.1 93/09/24
149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * $Id$
159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */
169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef _MATH_PRIVATE_H_
189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define _MATH_PRIVATE_H_
199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL_name.h"
219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL_endian.h"
229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define huge		really_big /* huge is a reserved keyword in VC++ 6.0 */
249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define u_int32_t	uint32_t
259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* The original fdlibm code used statements like:
279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	n0 = ((*(int*)&one)>>29)^1;		* index of high word *
289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	ix0 = *(n0+(int*)&x);			* high word of x *
299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	ix1 = *((1-n0)+(int*)&x);		* low word of x *
309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall   to dig two 32 bit words out of the 64 bit IEEE floating point
319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall   value.  That is non-ANSI, and, moreover, the gcc instruction
329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall   scheduler gets it wrong.  We instead use the following macros.
339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall   Unlike the original code, we determine the endianness at compile
349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall   time, not at run time; I don't see much benefit to selecting
359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall   endianness at run time.  */
369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* A union which permits us to convert between a double and two 32 bit
389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall   ints.  */
399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/*
419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Math on arm is special:
429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * For FPA, float words are always big-endian.
439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * For VFP, floats words follow the memory system mode.
449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */
459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if (SDL_BYTEORDER == SDL_BIG_ENDIAN) || \
479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    (!defined(__VFP_FP__) && (defined(__arm__) || defined(__thumb__)))
489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halltypedef union
509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  double value;
529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  struct
539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  {
549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    u_int32_t msw;
559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    u_int32_t lsw;
569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  } parts;
579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} ieee_double_shape_type;
589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else
609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halltypedef union
629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  double value;
649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  struct
659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  {
669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    u_int32_t lsw;
679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    u_int32_t msw;
689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  } parts;
699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} ieee_double_shape_type;
709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif
729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Get two 32 bit ints from a double.  */
749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define EXTRACT_WORDS(ix0,ix1,d)				\
769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halldo {								\
779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  ieee_double_shape_type ew_u;					\
789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  ew_u.value = (d);						\
799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  (ix0) = ew_u.parts.msw;					\
809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  (ix1) = ew_u.parts.lsw;					\
819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} while (0)
829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Get the more significant 32 bit int from a double.  */
849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define GET_HIGH_WORD(i,d)					\
869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halldo {								\
879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  ieee_double_shape_type gh_u;					\
889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  gh_u.value = (d);						\
899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  (i) = gh_u.parts.msw;						\
909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} while (0)
919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Get the less significant 32 bit int from a double.  */
939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define GET_LOW_WORD(i,d)					\
959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halldo {								\
969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  ieee_double_shape_type gl_u;					\
979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  gl_u.value = (d);						\
989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  (i) = gl_u.parts.lsw;						\
999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} while (0)
1009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Set a double from two 32 bit ints.  */
1029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define INSERT_WORDS(d,ix0,ix1)					\
1049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halldo {								\
1059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  ieee_double_shape_type iw_u;					\
1069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  iw_u.parts.msw = (ix0);					\
1079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  iw_u.parts.lsw = (ix1);					\
1089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  (d) = iw_u.value;						\
1099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} while (0)
1109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Set the more significant 32 bits of a double from an int.  */
1129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define SET_HIGH_WORD(d,v)					\
1149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halldo {								\
1159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  ieee_double_shape_type sh_u;					\
1169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  sh_u.value = (d);						\
1179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  sh_u.parts.msw = (v);						\
1189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  (d) = sh_u.value;						\
1199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} while (0)
1209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Set the less significant 32 bits of a double from an int.  */
1229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define SET_LOW_WORD(d,v)					\
1249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halldo {								\
1259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  ieee_double_shape_type sl_u;					\
1269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  sl_u.value = (d);						\
1279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  sl_u.parts.lsw = (v);						\
1289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  (d) = sl_u.value;						\
1299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} while (0)
1309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* A union which permits us to convert between a float and a 32 bit
1329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall   int.  */
1339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halltypedef union
1359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
1369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  float value;
1379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  u_int32_t word;
1389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} ieee_float_shape_type;
1399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Get a 32 bit int from a float.  */
1419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define GET_FLOAT_WORD(i,d)					\
1439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halldo {								\
1449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  ieee_float_shape_type gf_u;					\
1459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  gf_u.value = (d);						\
1469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  (i) = gf_u.word;						\
1479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} while (0)
1489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Set a float from a 32 bit int.  */
1509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define SET_FLOAT_WORD(d,i)					\
1529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halldo {								\
1539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  ieee_float_shape_type sf_u;					\
1549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  sf_u.word = (i);						\
1559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall  (d) = sf_u.value;						\
1569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} while (0)
1579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef __STDC__
1609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic const double
1619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else
1629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic double
1639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif
1649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallzero    =  0.0,
1659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallone	=  1.0,
1669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halltwo	=  2.0,
1679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halltwo53	=  9007199254740992.0,	/* 0x43400000, 0x00000000 */
1689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halltwo54   =  1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
1699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halltwom54  =  5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
1709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallhuge   = 1.0e+300,
1719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Halltiny   = 1.0e-300;
1729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif /* _MATH_PRIVATE_H_ */
174