VirtualBox

source: vbox/trunk/src/recompiler/fpu/softfloat-native.h@ 24345

Last change on this file since 24345 was 21292, checked in by vboxsync, 15 years ago

svn:eol-style native

  • Property svn:eol-style set to native
File size: 13.9 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#elif defined(_MSC_VER)
7# include <fpieee.h>
8# ifndef fabsf
9# define fabsf(f) ((float)fabs(f))
10# endif
11#else
12#include <fenv.h>
13#endif
14
15#if defined(__OpenBSD__) || defined(__NetBSD__)
16#include <sys/param.h>
17#endif
18
19/*
20 * Define some C99-7.12.3 classification macros and
21 * some C99-.12.4 for Solaris systems OS less than 10,
22 * or Solaris 10 systems running GCC 3.x or less.
23 * Solaris 10 with GCC4 does not need these macros as they
24 * are defined in <iso/math_c99.h> with a compiler directive
25 */
26#if defined(HOST_SOLARIS) && (( HOST_SOLARIS <= 9 ) || ((HOST_SOLARIS >= 10) \
27 && (__GNUC__ <= 4))) \
28 || (defined(__OpenBSD__) && (OpenBSD < 200811))
29/*
30 * C99 7.12.3 classification macros
31 * and
32 * C99 7.12.14 comparison macros
33 *
34 * ... do not work on Solaris 10 using GNU CC 3.4.x.
35 * Try to workaround the missing / broken C99 math macros.
36 */
37#if defined(__OpenBSD__)
38#define unordered(x, y) (isnan(x) || isnan(y))
39#endif
40
41#ifdef __NetBSD__
42#ifndef isgreater
43#define isgreater(x, y) __builtin_isgreater(x, y)
44#endif
45#ifndef isgreaterequal
46#define isgreaterequal(x, y) __builtin_isgreaterequal(x, y)
47#endif
48#ifndef isless
49#define isless(x, y) __builtin_isless(x, y)
50#endif
51#ifndef islessequal
52#define islessequal(x, y) __builtin_islessequal(x, y)
53#endif
54#ifndef isunordered
55#define isunordered(x, y) __builtin_isunordered(x, y)
56#endif
57#endif
58
59
60#define isnormal(x) (fpclass(x) >= FP_NZERO)
61#define isgreater(x, y) ((!unordered(x, y)) && ((x) > (y)))
62#define isgreaterequal(x, y) ((!unordered(x, y)) && ((x) >= (y)))
63#define isless(x, y) ((!unordered(x, y)) && ((x) < (y)))
64#define islessequal(x, y) ((!unordered(x, y)) && ((x) <= (y)))
65#define isunordered(x,y) unordered(x, y)
66#elif defined(_MSC_VER)
67#include <float.h>
68#define unordered(x1, x2) ((_fpclass(x1) <= 2) || (_fpclass(x2) <= 2))
69#define isless(x, y) ((!unordered(x, y)) && ((x) < (y)))
70#define islessequal(x, y) ((!unordered(x, y)) && ((x) <= (y)))
71#define isunordered(x,y) unordered(x, y)
72#endif
73
74#if defined(__sun__) && !defined(NEED_LIBSUNMATH)
75
76#ifndef isnan
77# define isnan(x) \
78 (sizeof (x) == sizeof (long double) ? isnan_ld (x) \
79 : sizeof (x) == sizeof (double) ? isnan_d (x) \
80 : isnan_f (x))
81static inline int isnan_f (float x) { return x != x; }
82static inline int isnan_d (double x) { return x != x; }
83static inline int isnan_ld (long double x) { return x != x; }
84#endif
85
86#ifndef isinf
87# define isinf(x) \
88 (sizeof (x) == sizeof (long double) ? isinf_ld (x) \
89 : sizeof (x) == sizeof (double) ? isinf_d (x) \
90 : isinf_f (x))
91static inline int isinf_f (float x) { return isnan (x - x); }
92static inline int isinf_d (double x) { return isnan (x - x); }
93static inline int isinf_ld (long double x) { return isnan (x - x); }
94#endif
95#endif
96
97typedef float float32;
98typedef double float64;
99#ifdef FLOATX80
100typedef long double floatx80;
101#endif
102
103typedef union {
104 float32 f;
105 uint32_t i;
106} float32u;
107typedef union {
108 float64 f;
109 uint64_t i;
110} float64u;
111#ifdef FLOATX80
112typedef union {
113 floatx80 f;
114 struct {
115 uint64_t low;
116 uint16_t high;
117 } i;
118} floatx80u;
119#endif
120
121/*----------------------------------------------------------------------------
122| Software IEC/IEEE floating-point rounding mode.
123*----------------------------------------------------------------------------*/
124#if (defined(_BSD) && !defined(__APPLE__)) || defined(HOST_SOLARIS)
125#if defined(__OpenBSD__)
126#define FE_RM FP_RM
127#define FE_RP FP_RP
128#define FE_RZ FP_RZ
129#endif
130enum {
131 float_round_nearest_even = FP_RN,
132 float_round_down = FP_RM,
133 float_round_up = FP_RP,
134 float_round_to_zero = FP_RZ
135};
136#elif defined(__arm__)
137enum {
138 float_round_nearest_even = 0,
139 float_round_down = 1,
140 float_round_up = 2,
141 float_round_to_zero = 3
142};
143#elif defined(_MSC_VER)
144enum {
145 float_round_nearest_even = _FpRoundNearest,
146 float_round_down = _FpRoundMinusInfinity,
147 float_round_up = _FpRoundPlusInfinity,
148 float_round_to_zero = _FpRoundChopped
149};
150#else
151enum {
152 float_round_nearest_even = FE_TONEAREST,
153 float_round_down = FE_DOWNWARD,
154 float_round_up = FE_UPWARD,
155 float_round_to_zero = FE_TOWARDZERO
156};
157#endif
158
159typedef struct float_status {
160 int float_rounding_mode;
161#ifdef FLOATX80
162 int floatx80_rounding_precision;
163#endif
164} float_status;
165
166void set_float_rounding_mode(int val STATUS_PARAM);
167#ifdef FLOATX80
168void set_floatx80_rounding_precision(int val STATUS_PARAM);
169#endif
170
171/*----------------------------------------------------------------------------
172| Software IEC/IEEE integer-to-floating-point conversion routines.
173*----------------------------------------------------------------------------*/
174float32 int32_to_float32( int STATUS_PARAM);
175float32 uint32_to_float32( unsigned int STATUS_PARAM);
176float64 int32_to_float64( int STATUS_PARAM);
177float64 uint32_to_float64( unsigned int STATUS_PARAM);
178#ifdef FLOATX80
179floatx80 int32_to_floatx80( int STATUS_PARAM);
180#endif
181#ifdef FLOAT128
182float128 int32_to_float128( int STATUS_PARAM);
183#endif
184float32 int64_to_float32( int64_t STATUS_PARAM);
185float32 uint64_to_float32( uint64_t STATUS_PARAM);
186float64 int64_to_float64( int64_t STATUS_PARAM);
187float64 uint64_to_float64( uint64_t v STATUS_PARAM);
188#ifdef FLOATX80
189floatx80 int64_to_floatx80( int64_t STATUS_PARAM);
190#endif
191#ifdef FLOAT128
192float128 int64_to_float128( int64_t STATUS_PARAM);
193#endif
194
195/*----------------------------------------------------------------------------
196| Software IEC/IEEE single-precision conversion routines.
197*----------------------------------------------------------------------------*/
198int float32_to_int32( float32 STATUS_PARAM);
199int float32_to_int32_round_to_zero( float32 STATUS_PARAM);
200unsigned int float32_to_uint32( float32 a STATUS_PARAM);
201unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM);
202int64_t float32_to_int64( float32 STATUS_PARAM);
203int64_t float32_to_int64_round_to_zero( float32 STATUS_PARAM);
204float64 float32_to_float64( float32 STATUS_PARAM);
205#ifdef FLOATX80
206floatx80 float32_to_floatx80( float32 STATUS_PARAM);
207#endif
208#ifdef FLOAT128
209float128 float32_to_float128( float32 STATUS_PARAM);
210#endif
211
212/*----------------------------------------------------------------------------
213| Software IEC/IEEE single-precision operations.
214*----------------------------------------------------------------------------*/
215float32 float32_round_to_int( float32 STATUS_PARAM);
216INLINE float32 float32_add( float32 a, float32 b STATUS_PARAM)
217{
218 return a + b;
219}
220INLINE float32 float32_sub( float32 a, float32 b STATUS_PARAM)
221{
222 return a - b;
223}
224INLINE float32 float32_mul( float32 a, float32 b STATUS_PARAM)
225{
226 return a * b;
227}
228INLINE float32 float32_div( float32 a, float32 b STATUS_PARAM)
229{
230 return a / b;
231}
232float32 float32_rem( float32, float32 STATUS_PARAM);
233float32 float32_sqrt( float32 STATUS_PARAM);
234INLINE int float32_eq( float32 a, float32 b STATUS_PARAM)
235{
236 return a == b;
237}
238INLINE int float32_le( float32 a, float32 b STATUS_PARAM)
239{
240 return a <= b;
241}
242INLINE int float32_lt( float32 a, float32 b STATUS_PARAM)
243{
244 return a < b;
245}
246INLINE int float32_eq_signaling( float32 a, float32 b STATUS_PARAM)
247{
248 return a <= b && a >= b;
249}
250INLINE int float32_le_quiet( float32 a, float32 b STATUS_PARAM)
251{
252 return islessequal(a, b);
253}
254INLINE int float32_lt_quiet( float32 a, float32 b STATUS_PARAM)
255{
256 return isless(a, b);
257}
258INLINE int float32_unordered( float32 a, float32 b STATUS_PARAM)
259{
260 return isunordered(a, b);
261
262}
263int float32_compare( float32, float32 STATUS_PARAM );
264int float32_compare_quiet( float32, float32 STATUS_PARAM );
265int float32_is_signaling_nan( float32 );
266int float32_is_nan( float32 );
267
268INLINE float32 float32_abs(float32 a)
269{
270 return fabsf(a);
271}
272
273INLINE float32 float32_chs(float32 a)
274{
275 return -a;
276}
277
278INLINE float32 float32_is_infinity(float32 a)
279{
280 return fpclassify(a) == FP_INFINITE;
281}
282
283INLINE float32 float32_is_neg(float32 a)
284{
285 float32u u;
286 u.f = a;
287 return u.i >> 31;
288}
289
290INLINE float32 float32_is_zero(float32 a)
291{
292 return fpclassify(a) == FP_ZERO;
293}
294
295INLINE float32 float32_scalbn(float32 a, int n)
296{
297 return scalbnf(a, n);
298}
299
300/*----------------------------------------------------------------------------
301| Software IEC/IEEE double-precision conversion routines.
302*----------------------------------------------------------------------------*/
303int float64_to_int32( float64 STATUS_PARAM );
304int float64_to_int32_round_to_zero( float64 STATUS_PARAM );
305unsigned int float64_to_uint32( float64 STATUS_PARAM );
306unsigned int float64_to_uint32_round_to_zero( float64 STATUS_PARAM );
307int64_t float64_to_int64( float64 STATUS_PARAM );
308int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM );
309uint64_t float64_to_uint64( float64 STATUS_PARAM );
310uint64_t float64_to_uint64_round_to_zero( float64 STATUS_PARAM );
311float32 float64_to_float32( float64 STATUS_PARAM );
312#ifdef FLOATX80
313floatx80 float64_to_floatx80( float64 STATUS_PARAM );
314#endif
315#ifdef FLOAT128
316float128 float64_to_float128( float64 STATUS_PARAM );
317#endif
318
319/*----------------------------------------------------------------------------
320| Software IEC/IEEE double-precision operations.
321*----------------------------------------------------------------------------*/
322float64 float64_round_to_int( float64 STATUS_PARAM );
323float64 float64_trunc_to_int( float64 STATUS_PARAM );
324INLINE float64 float64_add( float64 a, float64 b STATUS_PARAM)
325{
326 return a + b;
327}
328INLINE float64 float64_sub( float64 a, float64 b STATUS_PARAM)
329{
330 return a - b;
331}
332INLINE float64 float64_mul( float64 a, float64 b STATUS_PARAM)
333{
334 return a * b;
335}
336INLINE float64 float64_div( float64 a, float64 b STATUS_PARAM)
337{
338 return a / b;
339}
340float64 float64_rem( float64, float64 STATUS_PARAM );
341float64 float64_sqrt( float64 STATUS_PARAM );
342INLINE int float64_eq( float64 a, float64 b STATUS_PARAM)
343{
344 return a == b;
345}
346INLINE int float64_le( float64 a, float64 b STATUS_PARAM)
347{
348 return a <= b;
349}
350INLINE int float64_lt( float64 a, float64 b STATUS_PARAM)
351{
352 return a < b;
353}
354INLINE int float64_eq_signaling( float64 a, float64 b STATUS_PARAM)
355{
356 return a <= b && a >= b;
357}
358INLINE int float64_le_quiet( float64 a, float64 b STATUS_PARAM)
359{
360 return islessequal(a, b);
361}
362INLINE int float64_lt_quiet( float64 a, float64 b STATUS_PARAM)
363{
364 return isless(a, b);
365
366}
367INLINE int float64_unordered( float64 a, float64 b STATUS_PARAM)
368{
369 return isunordered(a, b);
370
371}
372int float64_compare( float64, float64 STATUS_PARAM );
373int float64_compare_quiet( float64, float64 STATUS_PARAM );
374int float64_is_signaling_nan( float64 );
375int float64_is_nan( float64 );
376
377INLINE float64 float64_abs(float64 a)
378{
379 return fabs(a);
380}
381
382INLINE float64 float64_chs(float64 a)
383{
384 return -a;
385}
386
387INLINE float64 float64_is_infinity(float64 a)
388{
389 return fpclassify(a) == FP_INFINITE;
390}
391
392INLINE float64 float64_is_neg(float64 a)
393{
394 float64u u;
395 u.f = a;
396 return u.i >> 63;
397}
398
399INLINE float64 float64_is_zero(float64 a)
400{
401 return fpclassify(a) == FP_ZERO;
402}
403
404INLINE float64 float64_scalbn(float64 a, int n)
405{
406 return scalbn(a, n);
407}
408
409#ifdef FLOATX80
410
411/*----------------------------------------------------------------------------
412| Software IEC/IEEE extended double-precision conversion routines.
413*----------------------------------------------------------------------------*/
414int floatx80_to_int32( floatx80 STATUS_PARAM );
415int floatx80_to_int32_round_to_zero( floatx80 STATUS_PARAM );
416int64_t floatx80_to_int64( floatx80 STATUS_PARAM);
417int64_t floatx80_to_int64_round_to_zero( floatx80 STATUS_PARAM);
418float32 floatx80_to_float32( floatx80 STATUS_PARAM );
419float64 floatx80_to_float64( floatx80 STATUS_PARAM );
420#ifdef FLOAT128
421float128 floatx80_to_float128( floatx80 STATUS_PARAM );
422#endif
423
424/*----------------------------------------------------------------------------
425| Software IEC/IEEE extended double-precision operations.
426*----------------------------------------------------------------------------*/
427floatx80 floatx80_round_to_int( floatx80 STATUS_PARAM );
428INLINE floatx80 floatx80_add( floatx80 a, floatx80 b STATUS_PARAM)
429{
430 return a + b;
431}
432INLINE floatx80 floatx80_sub( floatx80 a, floatx80 b STATUS_PARAM)
433{
434 return a - b;
435}
436INLINE floatx80 floatx80_mul( floatx80 a, floatx80 b STATUS_PARAM)
437{
438 return a * b;
439}
440INLINE floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM)
441{
442 return a / b;
443}
444floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM );
445floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
446INLINE int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM)
447{
448 return a == b;
449}
450INLINE int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM)
451{
452 return a <= b;
453}
454INLINE int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM)
455{
456 return a < b;
457}
458INLINE int floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM)
459{
460 return a <= b && a >= b;
461}
462INLINE int floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM)
463{
464 return islessequal(a, b);
465}
466INLINE int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM)
467{
468 return isless(a, b);
469
470}
471INLINE int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM)
472{
473 return isunordered(a, b);
474
475}
476int floatx80_compare( floatx80, floatx80 STATUS_PARAM );
477int floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM );
478int floatx80_is_signaling_nan( floatx80 );
479int floatx80_is_nan( floatx80 );
480
481INLINE floatx80 floatx80_abs(floatx80 a)
482{
483 return fabsl(a);
484}
485
486INLINE floatx80 floatx80_chs(floatx80 a)
487{
488 return -a;
489}
490
491INLINE floatx80 floatx80_is_infinity(floatx80 a)
492{
493 return fpclassify(a) == FP_INFINITE;
494}
495
496INLINE floatx80 floatx80_is_neg(floatx80 a)
497{
498 floatx80u u;
499 u.f = a;
500 return u.i.high >> 15;
501}
502
503INLINE floatx80 floatx80_is_zero(floatx80 a)
504{
505 return fpclassify(a) == FP_ZERO;
506}
507
508INLINE floatx80 floatx80_scalbn(floatx80 a, int n)
509{
510 return scalbnl(a, n);
511}
512
513#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