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 14968 2005-11-16 18:33:51Z korli $
15 */
16
17#ifndef _MATH_PRIVATE_H_
18#define _MATH_PRIVATE_H_
19
20#include <endian.h>
21#include <sys/types.h>
22#include <stdint.h>
23
24#ifndef __FLOAT_WORD_ORDER
25#define __FLOAT_WORD_ORDER __BYTE_ORDER
26#endif
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#if __FLOAT_WORD_ORDER == BIG_ENDIAN
43
44typedef union
45{
46  double value;
47  struct
48  {
49    u_int32_t msw;
50    u_int32_t lsw;
51  } parts;
52} ieee_double_shape_type;
53
54#endif
55
56#if __FLOAT_WORD_ORDER == LITTLE_ENDIAN
57
58typedef union
59{
60  double value;
61  struct
62  {
63    u_int32_t lsw;
64    u_int32_t msw;
65  } parts;
66} ieee_double_shape_type;
67
68#endif
69
70/* Get two 32 bit ints from a double.  */
71
72#define EXTRACT_WORDS(ix0,ix1,d)				\
73do {								\
74  ieee_double_shape_type ew_u;					\
75  ew_u.value = (d);						\
76  (ix0) = ew_u.parts.msw;					\
77  (ix1) = ew_u.parts.lsw;					\
78} while (0)
79
80/* Get the more significant 32 bit int from a double.  */
81
82#define GET_HIGH_WORD(i,d)					\
83do {								\
84  ieee_double_shape_type gh_u;					\
85  gh_u.value = (d);						\
86  (i) = gh_u.parts.msw;						\
87} while (0)
88
89/* Get the less significant 32 bit int from a double.  */
90
91#define GET_LOW_WORD(i,d)					\
92do {								\
93  ieee_double_shape_type gl_u;					\
94  gl_u.value = (d);						\
95  (i) = gl_u.parts.lsw;						\
96} while (0)
97
98/* Set a double from two 32 bit ints.  */
99
100#define INSERT_WORDS(d,ix0,ix1)					\
101do {								\
102  ieee_double_shape_type iw_u;					\
103  iw_u.parts.msw = (ix0);					\
104  iw_u.parts.lsw = (ix1);					\
105  (d) = iw_u.value;						\
106} while (0)
107
108/* Set the more significant 32 bits of a double from an int.  */
109
110#define SET_HIGH_WORD(d,v)					\
111do {								\
112  ieee_double_shape_type sh_u;					\
113  sh_u.value = (d);						\
114  sh_u.parts.msw = (v);						\
115  (d) = sh_u.value;						\
116} while (0)
117
118/* Set the less significant 32 bits of a double from an int.  */
119
120#define SET_LOW_WORD(d,v)					\
121do {								\
122  ieee_double_shape_type sl_u;					\
123  sl_u.value = (d);						\
124  sl_u.parts.lsw = (v);						\
125  (d) = sl_u.value;						\
126} while (0)
127
128/* A union which permits us to convert between a float and a 32 bit
129   int.  */
130
131typedef union
132{
133  float value;
134  u_int32_t word;
135} ieee_float_shape_type;
136
137/* Get a 32 bit int from a float.  */
138
139#define GET_FLOAT_WORD(i,d)					\
140do {								\
141  ieee_float_shape_type gf_u;					\
142  gf_u.value = (d);						\
143  (i) = gf_u.word;						\
144} while (0)
145
146/* Set a float from a 32 bit int.  */
147
148#define SET_FLOAT_WORD(d,i)					\
149do {								\
150  ieee_float_shape_type sf_u;					\
151  sf_u.word = (i);						\
152  (d) = sf_u.value;						\
153} while (0)
154
155/* Get long double macros from a separate header.  */
156#include <math_ldbl.h>
157
158/* ieee style elementary functions */
159extern double __ieee754_sqrt (double);
160extern double __ieee754_acos (double);
161extern double __ieee754_acosh (double);
162extern double __ieee754_log (double);
163extern double __ieee754_atanh (double);
164extern double __ieee754_asin (double);
165extern double __ieee754_atan2 (double,double);
166extern double __ieee754_exp (double);
167extern double __ieee754_exp2 (double);
168extern double __ieee754_exp10 (double);
169extern double __ieee754_cosh (double);
170extern double __ieee754_fmod (double,double);
171extern double __ieee754_pow (double,double);
172extern double __ieee754_lgamma_r (double,int *);
173extern double __ieee754_gamma_r (double,int *);
174extern double __ieee754_lgamma (double);
175extern double __ieee754_gamma (double);
176extern double __ieee754_log10 (double);
177extern double __ieee754_log2 (double);
178extern double __ieee754_sinh (double);
179extern double __ieee754_hypot (double,double);
180extern double __ieee754_j0 (double);
181extern double __ieee754_j1 (double);
182extern double __ieee754_y0 (double);
183extern double __ieee754_y1 (double);
184extern double __ieee754_jn (int,double);
185extern double __ieee754_yn (int,double);
186extern double __ieee754_remainder (double,double);
187extern int32_t __ieee754_rem_pio2 (double,double*);
188extern double __ieee754_scalb (double,double);
189
190/* fdlibm kernel function */
191extern double __kernel_standard (double,double,int);
192extern double __kernel_sin (double,double,int);
193extern double __kernel_cos (double,double);
194extern double __kernel_tan (double,double,int);
195extern int    __kernel_rem_pio2 (double*,double*,int,int,int, const int32_t*);
196
197/* internal functions.  */
198extern double __copysign (double x, double __y);
199
200
201/* ieee style elementary float functions */
202extern float __ieee754_sqrtf (float);
203extern float __ieee754_acosf (float);
204extern float __ieee754_acoshf (float);
205extern float __ieee754_logf (float);
206extern float __ieee754_atanhf (float);
207extern float __ieee754_asinf (float);
208extern float __ieee754_atan2f (float,float);
209extern float __ieee754_expf (float);
210extern float __ieee754_exp2f (float);
211extern float __ieee754_exp10f (float);
212extern float __ieee754_coshf (float);
213extern float __ieee754_fmodf (float,float);
214extern float __ieee754_powf (float,float);
215extern float __ieee754_lgammaf_r (float,int *);
216extern float __ieee754_gammaf_r (float,int *);
217extern float __ieee754_lgammaf (float);
218extern float __ieee754_gammaf (float);
219extern float __ieee754_log10f (float);
220extern float __ieee754_log2f (float);
221extern float __ieee754_sinhf (float);
222extern float __ieee754_hypotf (float,float);
223extern float __ieee754_j0f (float);
224extern float __ieee754_j1f (float);
225extern float __ieee754_y0f (float);
226extern float __ieee754_y1f (float);
227extern float __ieee754_jnf (int,float);
228extern float __ieee754_ynf (int,float);
229extern float __ieee754_remainderf (float,float);
230extern int32_t __ieee754_rem_pio2f (float,float*);
231extern float __ieee754_scalbf (float,float);
232
233
234/* float versions of fdlibm kernel functions */
235extern float __kernel_sinf (float,float,int);
236extern float __kernel_cosf (float,float);
237extern float __kernel_tanf (float,float,int);
238extern int   __kernel_rem_pio2f (float*,float*,int,int,int, const int32_t*);
239
240/* internal functions.  */
241extern float __copysignf (float x, float __y);
242
243
244/* ieee style elementary long double functions */
245extern long double __ieee754_sqrtl (long double);
246extern long double __ieee754_acosl (long double);
247extern long double __ieee754_acoshl (long double);
248extern long double __ieee754_logl (long double);
249extern long double __ieee754_atanhl (long double);
250extern long double __ieee754_asinl (long double);
251extern long double __ieee754_atan2l (long double,long double);
252extern long double __ieee754_expl (long double);
253extern long double __ieee754_exp2l (long double);
254extern long double __ieee754_exp10l (long double);
255extern long double __ieee754_coshl (long double);
256extern long double __ieee754_fmodl (long double,long double);
257extern long double __ieee754_powl (long double,long double);
258extern long double __ieee754_lgammal_r (long double,int *);
259extern long double __ieee754_gammal_r (long double,int *);
260extern long double __ieee754_lgammal (long double);
261extern long double __ieee754_gammal (long double);
262extern long double __ieee754_log10l (long double);
263extern long double __ieee754_log2l (long double);
264extern long double __ieee754_sinhl (long double);
265extern long double __ieee754_hypotl (long double,long double);
266extern long double __ieee754_j0l (long double);
267extern long double __ieee754_j1l (long double);
268extern long double __ieee754_y0l (long double);
269extern long double __ieee754_y1l (long double);
270extern long double __ieee754_jnl (int,long double);
271extern long double __ieee754_ynl (int,long double);
272extern long double __ieee754_remainderl (long double,long double);
273extern int32_t   __ieee754_rem_pio2l (long double,long double*);
274extern long double __ieee754_scalbl (long double,long double);
275
276/* long double versions of fdlibm kernel functions */
277extern long double __kernel_sinl (long double,long double,int);
278extern long double __kernel_cosl (long double,long double);
279extern long double __kernel_tanl (long double,long double,int);
280extern void __kernel_sincosl (long double,long double,
281			      long double *,long double *, int);
282extern int   __kernel_rem_pio2l (long double*,long double*,int,int,
283				 int,const int*);
284
285#ifndef NO_LONG_DOUBLE
286/* prototypes required to compile the ldbl-96 support without warnings */
287extern int __finitel (long double);
288extern int __ilogbl (long double);
289extern int __isinfl (long double);
290extern int __isnanl (long double);
291extern long double __atanl (long double);
292extern long double __copysignl (long double, long double);
293extern long double __expm1l (long double);
294extern long double __floorl (long double);
295extern long double __frexpl (long double, int *);
296extern long double __ldexpl (long double, int);
297extern long double __log1pl (long double);
298extern long double __nanl (const char *);
299extern long double __rintl (long double);
300extern long double __scalbnl (long double, int);
301extern long double __sqrtl (long double x);
302extern long double fabsl (long double x);
303extern void __sincosl (long double, long double *, long double *);
304extern long double __logbl (long double x);
305extern long double __significandl (long double x);
306#endif
307
308/* Prototypes for functions of the IBM Accurate Mathematical Library.  */
309extern double __exp1 (double __x, double __xx, double __error);
310extern double __sin (double __x);
311extern double __cos (double __x);
312extern int __branred (double __x, double *__a, double *__aa);
313extern void __doasin (double __x, double __dx, double __v[]);
314extern void __dubsin (double __x, double __dx, double __v[]);
315extern void __dubcos (double __x, double __dx, double __v[]);
316extern double __halfulp (double __x, double __y);
317extern double __sin32 (double __x, double __res, double __res1);
318extern double __cos32 (double __x, double __res, double __res1);
319extern double __mpsin (double __x, double __dx);
320extern double __mpcos (double __x, double __dx);
321extern double __mpsin1 (double __x);
322extern double __mpcos1 (double __x);
323extern double __slowexp (double __x);
324extern double __slowpow (double __x, double __y, double __z);
325extern void __docos (double __x, double __dx, double __v[]);
326
327#endif /* _MATH_PRIVATE_H_ */
328