VirtualBox

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

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

MSVC related changes

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