VirtualBox

source: vbox/trunk/src/recompiler_new/fpu/softfloat-native.h@ 18595

Last change on this file since 18595 was 14447, checked in by vboxsync, 16 years ago

New REM compiles on Win/AMD64 (using wrapper yet), not tested if runs

File size: 10.8 KB
Line 
1/* Native implementation of soft float functions */
2#include <math.h>
3
4#if (defined(_BSD) && !defined(__APPLE__)) || defined(HOST_SOLARIS)
5# include <ieeefp.h>
6# define fabsf(f) ((float)fabs(f))
7#elif defined(_MSC_VER)
8# include <fpieee.h>
9# ifndef fabsf
10# define fabsf(f) ((float)fabs(f))
11# endif
12#else
13# include <fenv.h>
14#endif
15
16/*
17 * Define some C99-7.12.3 classification macros and
18 * some C99-.12.4 for Solaris systems OS less than 10,
19 * or Solaris 10 systems running GCC 3.x or less.
20 * Solaris 10 with GCC4 does not need these macros as they
21 * are defined in <iso/math_c99.h> with a compiler directive
22 */
23#if defined(HOST_SOLARIS) && (( HOST_SOLARIS <= 9 ) || ( ( HOST_SOLARIS >= 10 ) && ( __GNUC__ <= 4) ))
24/*
25 * C99 7.12.3 classification macros
26 * and
27 * C99 7.12.14 comparison macros
28 *
29 * ... do not work on Solaris 10 using GNU CC 3.4.x.
30 * Try to workaround the missing / broken C99 math macros.
31 */
32
33#define isnormal(x) (fpclass(x) >= FP_NZERO)
34#define isgreater(x, y) ((!unordered(x, y)) && ((x) > (y)))
35#define isgreaterequal(x, y) ((!unordered(x, y)) && ((x) >= (y)))
36#define isless(x, y) ((!unordered(x, y)) && ((x) < (y)))
37#define islessequal(x, y) ((!unordered(x, y)) && ((x) <= (y)))
38#define isunordered(x,y) unordered(x, y)
39#define isinf(x) ((fpclass(x) == FP_NINF) || (fpclass(x) == FP_PINF))
40
41#elif defined(_MSC_VER)
42#include <float.h>
43#define unordered(x1, x2) ((_fpclass(x1) <= 2) || (_fpclass(x2) <= 2))
44#define isless(x, y) ((!unordered(x, y)) && ((x) < (y)))
45#define islessequal(x, y) ((!unordered(x, y)) && ((x) <= (y)))
46#define isunordered(x,y) unordered(x, y)
47#endif
48
49typedef float float32;
50typedef double float64;
51#ifdef FLOATX80
52typedef long double floatx80;
53#endif
54
55typedef union {
56 float32 f;
57 uint32_t i;
58} float32u;
59typedef union {
60 float64 f;
61 uint64_t i;
62} float64u;
63#ifdef FLOATX80
64typedef union {
65 floatx80 f;
66 struct {
67 uint64_t low;
68 uint16_t high;
69 } i;
70} floatx80u;
71#endif
72
73/*----------------------------------------------------------------------------
74| Software IEC/IEEE floating-point rounding mode.
75*----------------------------------------------------------------------------*/
76#if (defined(_BSD) && !defined(__APPLE__)) || defined(HOST_SOLARIS)
77enum {
78 float_round_nearest_even = FP_RN,
79 float_round_down = FP_RM,
80 float_round_up = FP_RP,
81 float_round_to_zero = FP_RZ
82};
83#elif defined(__arm__)
84enum {
85 float_round_nearest_even = 0,
86 float_round_down = 1,
87 float_round_up = 2,
88 float_round_to_zero = 3
89};
90#elif defined(_MSC_VER)
91enum {
92 float_round_nearest_even = _FpRoundNearest,
93 float_round_down = _FpRoundMinusInfinity,
94 float_round_up = _FpRoundPlusInfinity,
95 float_round_to_zero = _FpRoundChopped
96};
97#else
98enum {
99 float_round_nearest_even = FE_TONEAREST,
100 float_round_down = FE_DOWNWARD,
101 float_round_up = FE_UPWARD,
102 float_round_to_zero = FE_TOWARDZERO
103};
104#endif
105
106typedef struct float_status {
107 signed char float_rounding_mode;
108#ifdef FLOATX80
109 signed char floatx80_rounding_precision;
110#endif
111} float_status;
112
113void set_float_rounding_mode(int val STATUS_PARAM);
114#ifdef FLOATX80
115void set_floatx80_rounding_precision(int val STATUS_PARAM);
116#endif
117
118/*----------------------------------------------------------------------------
119| Software IEC/IEEE integer-to-floating-point conversion routines.
120*----------------------------------------------------------------------------*/
121float32 int32_to_float32( int STATUS_PARAM);
122float64 int32_to_float64( int STATUS_PARAM);
123#ifdef FLOATX80
124floatx80 int32_to_floatx80( int STATUS_PARAM);
125#endif
126#ifdef FLOAT128
127float128 int32_to_float128( int STATUS_PARAM);
128#endif
129float32 int64_to_float32( int64_t STATUS_PARAM);
130float64 int64_to_float64( int64_t STATUS_PARAM);
131#ifdef FLOATX80
132floatx80 int64_to_floatx80( int64_t STATUS_PARAM);
133#endif
134#ifdef FLOAT128
135float128 int64_to_float128( int64_t STATUS_PARAM);
136#endif
137
138/*----------------------------------------------------------------------------
139| Software IEC/IEEE single-precision conversion routines.
140*----------------------------------------------------------------------------*/
141int float32_to_int32( float32 STATUS_PARAM);
142int float32_to_int32_round_to_zero( float32 STATUS_PARAM);
143int64_t float32_to_int64( float32 STATUS_PARAM);
144int64_t float32_to_int64_round_to_zero( float32 STATUS_PARAM);
145float64 float32_to_float64( float32 STATUS_PARAM);
146#ifdef FLOATX80
147floatx80 float32_to_floatx80( float32 STATUS_PARAM);
148#endif
149#ifdef FLOAT128
150float128 float32_to_float128( float32 STATUS_PARAM);
151#endif
152
153/*----------------------------------------------------------------------------
154| Software IEC/IEEE single-precision operations.
155*----------------------------------------------------------------------------*/
156float32 float32_round_to_int( float32 STATUS_PARAM);
157INLINE float32 float32_add( float32 a, float32 b STATUS_PARAM)
158{
159 return a + b;
160}
161INLINE float32 float32_sub( float32 a, float32 b STATUS_PARAM)
162{
163 return a - b;
164}
165INLINE float32 float32_mul( float32 a, float32 b STATUS_PARAM)
166{
167 return a * b;
168}
169INLINE float32 float32_div( float32 a, float32 b STATUS_PARAM)
170{
171 return a / b;
172}
173float32 float32_rem( float32, float32 STATUS_PARAM);
174float32 float32_sqrt( float32 STATUS_PARAM);
175INLINE int float32_eq( float32 a, float32 b STATUS_PARAM)
176{
177 return a == b;
178}
179INLINE int float32_le( float32 a, float32 b STATUS_PARAM)
180{
181 return a <= b;
182}
183INLINE int float32_lt( float32 a, float32 b STATUS_PARAM)
184{
185 return a < b;
186}
187INLINE int float32_eq_signaling( float32 a, float32 b STATUS_PARAM)
188{
189 return a <= b && a >= b;
190}
191INLINE int float32_le_quiet( float32 a, float32 b STATUS_PARAM)
192{
193 return islessequal(a, b);
194}
195INLINE int float32_lt_quiet( float32 a, float32 b STATUS_PARAM)
196{
197 return isless(a, b);
198}
199INLINE int float32_unordered( float32 a, float32 b STATUS_PARAM)
200{
201 return isunordered(a, b);
202
203}
204int float32_compare( float32, float32 STATUS_PARAM );
205int float32_compare_quiet( float32, float32 STATUS_PARAM );
206int float32_is_signaling_nan( float32 );
207
208INLINE float32 float32_abs(float32 a)
209{
210 return fabsf(a);
211}
212
213INLINE float32 float32_chs(float32 a)
214{
215 return -a;
216}
217
218/*----------------------------------------------------------------------------
219| Software IEC/IEEE double-precision conversion routines.
220*----------------------------------------------------------------------------*/
221int float64_to_int32( float64 STATUS_PARAM );
222int float64_to_int32_round_to_zero( float64 STATUS_PARAM );
223int64_t float64_to_int64( float64 STATUS_PARAM );
224int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM );
225float32 float64_to_float32( float64 STATUS_PARAM );
226#ifdef FLOATX80
227floatx80 float64_to_floatx80( float64 STATUS_PARAM );
228#endif
229#ifdef FLOAT128
230float128 float64_to_float128( float64 STATUS_PARAM );
231#endif
232
233/*----------------------------------------------------------------------------
234| Software IEC/IEEE double-precision operations.
235*----------------------------------------------------------------------------*/
236float64 float64_round_to_int( float64 STATUS_PARAM );
237float64 float64_trunc_to_int( float64 STATUS_PARAM );
238INLINE float64 float64_add( float64 a, float64 b STATUS_PARAM)
239{
240 return a + b;
241}
242INLINE float64 float64_sub( float64 a, float64 b STATUS_PARAM)
243{
244 return a - b;
245}
246INLINE float64 float64_mul( float64 a, float64 b STATUS_PARAM)
247{
248 return a * b;
249}
250INLINE float64 float64_div( float64 a, float64 b STATUS_PARAM)
251{
252 return a / b;
253}
254float64 float64_rem( float64, float64 STATUS_PARAM );
255float64 float64_sqrt( float64 STATUS_PARAM );
256INLINE int float64_eq( float64 a, float64 b STATUS_PARAM)
257{
258 return a == b;
259}
260INLINE int float64_le( float64 a, float64 b STATUS_PARAM)
261{
262 return a <= b;
263}
264INLINE int float64_lt( float64 a, float64 b STATUS_PARAM)
265{
266 return a < b;
267}
268INLINE int float64_eq_signaling( float64 a, float64 b STATUS_PARAM)
269{
270 return a <= b && a >= b;
271}
272INLINE int float64_le_quiet( float64 a, float64 b STATUS_PARAM)
273{
274 return islessequal(a, b);
275}
276INLINE int float64_lt_quiet( float64 a, float64 b STATUS_PARAM)
277{
278 return isless(a, b);
279
280}
281INLINE int float64_unordered( float64 a, float64 b STATUS_PARAM)
282{
283 return isunordered(a, b);
284
285}
286int float64_compare( float64, float64 STATUS_PARAM );
287int float64_compare_quiet( float64, float64 STATUS_PARAM );
288int float64_is_signaling_nan( float64 );
289int float64_is_nan( float64 );
290
291INLINE float64 float64_abs(float64 a)
292{
293 return fabs(a);
294}
295
296INLINE float64 float64_chs(float64 a)
297{
298 return -a;
299}
300
301#ifdef FLOATX80
302
303/*----------------------------------------------------------------------------
304| Software IEC/IEEE extended double-precision conversion routines.
305*----------------------------------------------------------------------------*/
306int floatx80_to_int32( floatx80 STATUS_PARAM );
307int floatx80_to_int32_round_to_zero( floatx80 STATUS_PARAM );
308int64_t floatx80_to_int64( floatx80 STATUS_PARAM);
309int64_t floatx80_to_int64_round_to_zero( floatx80 STATUS_PARAM);
310float32 floatx80_to_float32( floatx80 STATUS_PARAM );
311float64 floatx80_to_float64( floatx80 STATUS_PARAM );
312#ifdef FLOAT128
313float128 floatx80_to_float128( floatx80 STATUS_PARAM );
314#endif
315
316/*----------------------------------------------------------------------------
317| Software IEC/IEEE extended double-precision operations.
318*----------------------------------------------------------------------------*/
319floatx80 floatx80_round_to_int( floatx80 STATUS_PARAM );
320INLINE floatx80 floatx80_add( floatx80 a, floatx80 b STATUS_PARAM)
321{
322 return a + b;
323}
324INLINE floatx80 floatx80_sub( floatx80 a, floatx80 b STATUS_PARAM)
325{
326 return a - b;
327}
328INLINE floatx80 floatx80_mul( floatx80 a, floatx80 b STATUS_PARAM)
329{
330 return a * b;
331}
332INLINE floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM)
333{
334 return a / b;
335}
336floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM );
337floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
338INLINE int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM)
339{
340 return a == b;
341}
342INLINE int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM)
343{
344 return a <= b;
345}
346INLINE int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM)
347{
348 return a < b;
349}
350INLINE int floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM)
351{
352 return a <= b && a >= b;
353}
354INLINE int floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM)
355{
356 return islessequal(a, b);
357}
358INLINE int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM)
359{
360 return isless(a, b);
361
362}
363INLINE int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM)
364{
365 return isunordered(a, b);
366
367}
368int floatx80_compare( floatx80, floatx80 STATUS_PARAM );
369int floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM );
370int floatx80_is_signaling_nan( floatx80 );
371
372INLINE floatx80 floatx80_abs(floatx80 a)
373{
374 return fabsl(a);
375}
376
377INLINE floatx80 floatx80_chs(floatx80 a)
378{
379 return -a;
380}
381#endif
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette