Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
576 serge 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.8 1998/11/27 11:33:46 drepper Exp $
15
 */
16
 
17
#ifndef _MATH_PRIVATE_H_
18
#define _MATH_PRIVATE_H_
19
 
20
 
21
/* The original fdlibm code used statements like:
22
	n0 = ((*(int*)&one)>>29)^1;		* index of high word *
23
	ix0 = *(n0+(int*)&x);			* high word of x *
24
	ix1 = *((1-n0)+(int*)&x);		* low word of x *
25
   to dig two 32 bit words out of the 64 bit IEEE floating point
26
   value.  That is non-ANSI, and, moreover, the gcc instruction
27
   scheduler gets it wrong.  We instead use the following macros.
28
   Unlike the original code, we determine the endianness at compile
29
   time, not at run time; I don't see much benefit to selecting
30
   endianness at run time.  */
31
 
32
/* A union which permits us to convert between a double and two 32 bit
33
   ints.  */
34
 
35
typedef int int32_t;
36
typedef unsigned int u_int32_t;
37
 
38
typedef union
39
{
40
  double value;
41
  struct
42
  {
43
    u_int32_t lsw;
44
    u_int32_t msw;
45
  } parts;
46
} ieee_double_shape_type;
47
 
48
/* Get two 32 bit ints from a double.  */
49
 
50
#define EXTRACT_WORDS(ix0,ix1,d)				\
51
do {								\
52
  ieee_double_shape_type ew_u;					\
53
  ew_u.value = (d);						\
54
  (ix0) = ew_u.parts.msw;					\
55
  (ix1) = ew_u.parts.lsw;					\
56
} while (0)
57
 
58
/* Get the more significant 32 bit int from a double.  */
59
 
60
#define GET_HIGH_WORD(i,d)					\
61
do {								\
62
  ieee_double_shape_type gh_u;					\
63
  gh_u.value = (d);						\
64
  (i) = gh_u.parts.msw;						\
65
} while (0)
66
 
67
/* Get the less significant 32 bit int from a double.  */
68
 
69
#define GET_LOW_WORD(i,d)					\
70
do {								\
71
  ieee_double_shape_type gl_u;					\
72
  gl_u.value = (d);						\
73
  (i) = gl_u.parts.lsw;						\
74
} while (0)
75
 
76
/* Set a double from two 32 bit ints.  */
77
 
78
#define INSERT_WORDS(d,ix0,ix1)					\
79
do {								\
80
  ieee_double_shape_type iw_u;					\
81
  iw_u.parts.msw = (ix0);					\
82
  iw_u.parts.lsw = (ix1);					\
83
  (d) = iw_u.value;						\
84
} while (0)
85
 
86
/* Set the more significant 32 bits of a double from an int.  */
87
 
88
#define SET_HIGH_WORD(d,v)					\
89
do {								\
90
  ieee_double_shape_type sh_u;					\
91
  sh_u.value = (d);						\
92
  sh_u.parts.msw = (v);						\
93
  (d) = sh_u.value;						\
94
} while (0)
95
 
96
/* Set the less significant 32 bits of a double from an int.  */
97
 
98
#define SET_LOW_WORD(d,v)					\
99
do {								\
100
  ieee_double_shape_type sl_u;					\
101
  sl_u.value = (d);						\
102
  sl_u.parts.lsw = (v);						\
103
  (d) = sl_u.value;						\
104
} while (0)
105
 
106
/* A union which permits us to convert between a float and a 32 bit
107
   int.  */
108
 
109
typedef union
110
{
111
  float value;
112
  u_int32_t word;
113
} ieee_float_shape_type;
114
 
115
/* Get a 32 bit int from a float.  */
116
 
117
#define GET_FLOAT_WORD(i,d)					\
118
do {								\
119
  ieee_float_shape_type gf_u;					\
120
  gf_u.value = (d);						\
121
  (i) = gf_u.word;						\
122
} while (0)
123
 
124
/* Set a float from a 32 bit int.  */
125
 
126
#define SET_FLOAT_WORD(d,i)					\
127
do {								\
128
  ieee_float_shape_type sf_u;					\
129
  sf_u.word = (i);						\
130
  (d) = sf_u.value;						\
131
} while (0)
132
 
133
/* A union which permits us to convert between a long double and
134
   three 32 bit ints.  */
135
 
136
 
137
typedef union
138
{
139
  long double value;
140
  struct
141
  {
142
    u_int32_t lsw;
143
    u_int32_t msw;
144
    unsigned int sign_exponent:16;
145
    unsigned int empty:16;
146
  } parts;
147
} ieee_long_double_shape_type;
148
 
149
/* Get three 32 bit ints from a double.  */
150
 
151
#define GET_LDOUBLE_WORDS(exp,ix0,ix1,d)			\
152
do {								\
153
  ieee_long_double_shape_type ew_u;				\
154
  ew_u.value = (d);						\
155
  (exp) = ew_u.parts.sign_exponent;				\
156
  (ix0) = ew_u.parts.msw;					\
157
  (ix1) = ew_u.parts.lsw;					\
158
} while (0)
159
 
160
/* Set a double from two 32 bit ints.  */
161
 
162
#define SET_LDOUBLE_WORDS(d,exp,ix0,ix1)			\
163
do {								\
164
  ieee_long_double_shape_type iw_u;				\
165
  iw_u.parts.sign_exponent = (exp);				\
166
  iw_u.parts.msw = (ix0);					\
167
  iw_u.parts.lsw = (ix1);					\
168
  (d) = iw_u.value;						\
169
} while (0)
170
 
171
/* Get the more significant 32 bits of a long double mantissa.  */
172
 
173
#define GET_LDOUBLE_MSW(v,d)					\
174
do {								\
175
  ieee_long_double_shape_type sh_u;				\
176
  sh_u.value = (d);						\
177
  (v) = sh_u.parts.msw;						\
178
} while (0)
179
 
180
/* Set the more significant 32 bits of a long double mantissa from an int.  */
181
 
182
#define SET_LDOUBLE_MSW(d,v)					\
183
do {								\
184
  ieee_long_double_shape_type sh_u;				\
185
  sh_u.value = (d);						\
186
  sh_u.parts.msw = (v);						\
187
  (d) = sh_u.value;						\
188
} while (0)
189
 
190
/* Get int from the exponent of a long double.  */
191
 
192
#define GET_LDOUBLE_EXP(exp,d)					\
193
do {								\
194
  ieee_long_double_shape_type ge_u;				\
195
  ge_u.value = (d);						\
196
  (exp) = ge_u.parts.sign_exponent;				\
197
} while (0)
198
 
199
/* Set exponent of a long double from an int.  */
200
 
201
#define SET_LDOUBLE_EXP(d,exp)					\
202
do {								\
203
  ieee_long_double_shape_type se_u;				\
204
  se_u.value = (d);						\
205
  se_u.parts.sign_exponent = (exp);				\
206
  (d) = se_u.value;						\
207
} while (0)
208
 
209
#endif /* _MATH_PRIVATE_H_ */