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