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 attribute_hidden
25 #define libm_hidden_proto(x)
26 #define libm_hidden_def(x)
27 
28 #ifndef __HAIKU__ /* already defined in a system header. */
29 typedef unsigned int u_int32_t;
30 #endif
31 
32 #define atan            SDL_uclibc_atan
33 #define __ieee754_atan2 SDL_uclibc_atan2
34 #define copysign        SDL_uclibc_copysign
35 #define cos             SDL_uclibc_cos
36 #define fabs            SDL_uclibc_fabs
37 #define floor           SDL_uclibc_floor
38 #define __ieee754_log   SDL_uclibc_log
39 #define __ieee754_pow   SDL_uclibc_pow
40 #define scalbn          SDL_uclibc_scalbn
41 #define sin             SDL_uclibc_sin
42 #define __ieee754_sqrt  SDL_uclibc_sqrt
43 #define tan             SDL_uclibc_tan
44 
45 /* The original fdlibm code used statements like:
46 	n0 = ((*(int*)&one)>>29)^1;		* index of high word *
47 	ix0 = *(n0+(int*)&x);			* high word of x *
48 	ix1 = *((1-n0)+(int*)&x);		* low word of x *
49    to dig two 32 bit words out of the 64 bit IEEE floating point
50    value.  That is non-ANSI, and, moreover, the gcc instruction
51    scheduler gets it wrong.  We instead use the following macros.
52    Unlike the original code, we determine the endianness at compile
53    time, not at run time; I don't see much benefit to selecting
54    endianness at run time.  */
55 
56 /* A union which permits us to convert between a double and two 32 bit
57    ints.  */
58 
59 /*
60  * Math on arm is special:
61  * For FPA, float words are always big-endian.
62  * For VFP, floats words follow the memory system mode.
63  */
64 
65 #if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
66 
67 typedef union
68 {
69     double value;
70     struct
71     {
72         u_int32_t msw;
73         u_int32_t lsw;
74     } parts;
75 } ieee_double_shape_type;
76 
77 #else
78 
79 typedef union
80 {
81     double value;
82     struct
83     {
84         u_int32_t lsw;
85         u_int32_t msw;
86     } parts;
87 } ieee_double_shape_type;
88 
89 #endif
90 
91 /* Get two 32 bit ints from a double.  */
92 
93 #define EXTRACT_WORDS(ix0,ix1,d)				\
94 do {								\
95   ieee_double_shape_type ew_u;					\
96   ew_u.value = (d);						\
97   (ix0) = ew_u.parts.msw;					\
98   (ix1) = ew_u.parts.lsw;					\
99 } while (0)
100 
101 /* Get the more significant 32 bit int from a double.  */
102 
103 #define GET_HIGH_WORD(i,d)					\
104 do {								\
105   ieee_double_shape_type gh_u;					\
106   gh_u.value = (d);						\
107   (i) = gh_u.parts.msw;						\
108 } while (0)
109 
110 /* Get the less significant 32 bit int from a double.  */
111 
112 #define GET_LOW_WORD(i,d)					\
113 do {								\
114   ieee_double_shape_type gl_u;					\
115   gl_u.value = (d);						\
116   (i) = gl_u.parts.lsw;						\
117 } while (0)
118 
119 /* Set a double from two 32 bit ints.  */
120 
121 #define INSERT_WORDS(d,ix0,ix1)					\
122 do {								\
123   ieee_double_shape_type iw_u;					\
124   iw_u.parts.msw = (ix0);					\
125   iw_u.parts.lsw = (ix1);					\
126   (d) = iw_u.value;						\
127 } while (0)
128 
129 /* Set the more significant 32 bits of a double from an int.  */
130 
131 #define SET_HIGH_WORD(d,v)					\
132 do {								\
133   ieee_double_shape_type sh_u;					\
134   sh_u.value = (d);						\
135   sh_u.parts.msw = (v);						\
136   (d) = sh_u.value;						\
137 } while (0)
138 
139 /* Set the less significant 32 bits of a double from an int.  */
140 
141 #define SET_LOW_WORD(d,v)					\
142 do {								\
143   ieee_double_shape_type sl_u;					\
144   sl_u.value = (d);						\
145   sl_u.parts.lsw = (v);						\
146   (d) = sl_u.value;						\
147 } while (0)
148 
149 /* A union which permits us to convert between a float and a 32 bit
150    int.  */
151 
152 typedef union
153 {
154     float value;
155     u_int32_t word;
156 } ieee_float_shape_type;
157 
158 /* Get a 32 bit int from a float.  */
159 
160 #define GET_FLOAT_WORD(i,d)					\
161 do {								\
162   ieee_float_shape_type gf_u;					\
163   gf_u.value = (d);						\
164   (i) = gf_u.word;						\
165 } while (0)
166 
167 /* Set a float from a 32 bit int.  */
168 
169 #define SET_FLOAT_WORD(d,i)					\
170 do {								\
171   ieee_float_shape_type sf_u;					\
172   sf_u.word = (i);						\
173   (d) = sf_u.value;						\
174 } while (0)
175 
176 /* ieee style elementary functions */
177 extern double
178 __ieee754_sqrt(double)
179     attribute_hidden;
180      extern double __ieee754_acos(double) attribute_hidden;
181      extern double __ieee754_acosh(double) attribute_hidden;
182      extern double __ieee754_log(double) attribute_hidden;
183      extern double __ieee754_atanh(double) attribute_hidden;
184      extern double __ieee754_asin(double) attribute_hidden;
185      extern double __ieee754_atan2(double, double) attribute_hidden;
186      extern double __ieee754_exp(double) attribute_hidden;
187      extern double __ieee754_cosh(double) attribute_hidden;
188      extern double __ieee754_fmod(double, double) attribute_hidden;
189      extern double __ieee754_pow(double, double) attribute_hidden;
190      extern double __ieee754_lgamma_r(double, int *) attribute_hidden;
191      extern double __ieee754_gamma_r(double, int *) attribute_hidden;
192      extern double __ieee754_lgamma(double) attribute_hidden;
193      extern double __ieee754_gamma(double) attribute_hidden;
194      extern double __ieee754_log10(double) attribute_hidden;
195      extern double __ieee754_sinh(double) attribute_hidden;
196      extern double __ieee754_hypot(double, double) attribute_hidden;
197      extern double __ieee754_j0(double) attribute_hidden;
198      extern double __ieee754_j1(double) attribute_hidden;
199      extern double __ieee754_y0(double) attribute_hidden;
200      extern double __ieee754_y1(double) attribute_hidden;
201      extern double __ieee754_jn(int, double) attribute_hidden;
202      extern double __ieee754_yn(int, double) attribute_hidden;
203      extern double __ieee754_remainder(double, double) attribute_hidden;
204      extern int __ieee754_rem_pio2(double, double *) attribute_hidden;
205 #if defined(_SCALB_INT)
206      extern double __ieee754_scalb(double, int) attribute_hidden;
207 #else
208      extern double __ieee754_scalb(double, double) attribute_hidden;
209 #endif
210 
211 /* fdlibm kernel function */
212 #ifndef _IEEE_LIBM
213      extern double __kernel_standard(double, double, int) attribute_hidden;
214 #endif
215      extern double __kernel_sin(double, double, int) attribute_hidden;
216      extern double __kernel_cos(double, double) attribute_hidden;
217      extern double __kernel_tan(double, double, int) attribute_hidden;
218      extern int __kernel_rem_pio2(double *, double *, int, int, int,
219                                   const int *) attribute_hidden;
220 
221 #endif /* _MATH_PRIVATE_H_ */
222