VirtualBox

source: vbox/trunk/src/recompiler_new/fpu/softfloat-native.c@ 13556

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

more MSC stuff

File size: 8.5 KB
Line 
1/* Native implementation of soft float functions. Only a single status
2 context is supported */
3#include "softfloat.h"
4#include <math.h>
5
6void set_float_rounding_mode(int val STATUS_PARAM)
7{
8 STATUS(float_rounding_mode) = val;
9#if defined(_BSD) && !defined(__APPLE__) || (defined(HOST_SOLARIS) && (HOST_SOLARIS < 10 || HOST_SOLARIS == 11))
10 fpsetround(val);
11#elif defined(__arm__)
12 /* nothing to do */
13#else
14 fesetround(val);
15#endif
16}
17
18#ifdef FLOATX80
19void set_floatx80_rounding_precision(int val STATUS_PARAM)
20{
21 STATUS(floatx80_rounding_precision) = val;
22}
23#endif
24
25#if defined(_BSD) || (defined(HOST_SOLARIS) && HOST_SOLARIS < 10)
26#define lrint(d) ((int32_t)rint(d))
27#define llrint(d) ((int64_t)rint(d))
28#define lrintf(f) ((int32_t)rint(f))
29#define llrintf(f) ((int64_t)rint(f))
30#define sqrtf(f) ((float)sqrt(f))
31#define remainderf(fa, fb) ((float)remainder(fa, fb))
32#define rintf(f) ((float)rint(f))
33#endif
34
35#if defined(__powerpc__)
36
37/* correct (but slow) PowerPC rint() (glibc version is incorrect) */
38double qemu_rint(double x)
39{
40 double y = 4503599627370496.0;
41 if (fabs(x) >= y)
42 return x;
43 if (x < 0)
44 y = -y;
45 y = (x + y) - y;
46 if (y == 0.0)
47 y = copysign(y, x);
48 return y;
49}
50
51#define rint qemu_rint
52#endif
53
54/*----------------------------------------------------------------------------
55| Software IEC/IEEE integer-to-floating-point conversion routines.
56*----------------------------------------------------------------------------*/
57float32 int32_to_float32(int v STATUS_PARAM)
58{
59 return (float32)v;
60}
61
62float64 int32_to_float64(int v STATUS_PARAM)
63{
64 return (float64)v;
65}
66
67#ifdef FLOATX80
68floatx80 int32_to_floatx80(int v STATUS_PARAM)
69{
70 return (floatx80)v;
71}
72#endif
73float32 int64_to_float32( int64_t v STATUS_PARAM)
74{
75 return (float32)v;
76}
77float64 int64_to_float64( int64_t v STATUS_PARAM)
78{
79 return (float64)v;
80}
81#ifdef FLOATX80
82floatx80 int64_to_floatx80( int64_t v STATUS_PARAM)
83{
84 return (floatx80)v;
85}
86#endif
87
88/* XXX: this code implements the x86 behaviour, not the IEEE one. */
89#if HOST_LONG_BITS == 32
90#ifndef VBOX
91static inline int long_to_int32(long a)
92#else /* VBOX */
93DECLINLINE(int) long_to_int32(long a)
94#endif /* VBOX */
95{
96 return a;
97}
98#else
99#ifndef VBOX
100static inline int long_to_int32(long a)
101#else /* VBOX */
102DECLINLINE(int) long_to_int32(long a)
103#endif /* VBOX */
104{
105 if (a != (int32_t)a)
106 a = 0x80000000;
107 return a;
108}
109#endif
110
111/*----------------------------------------------------------------------------
112| Software IEC/IEEE single-precision conversion routines.
113*----------------------------------------------------------------------------*/
114int float32_to_int32( float32 a STATUS_PARAM)
115{
116 return long_to_int32(lrintf(a));
117}
118int float32_to_int32_round_to_zero( float32 a STATUS_PARAM)
119{
120 return (int)a;
121}
122int64_t float32_to_int64( float32 a STATUS_PARAM)
123{
124 return llrintf(a);
125}
126
127int64_t float32_to_int64_round_to_zero( float32 a STATUS_PARAM)
128{
129 return (int64_t)a;
130}
131
132float64 float32_to_float64( float32 a STATUS_PARAM)
133{
134 return a;
135}
136#ifdef FLOATX80
137floatx80 float32_to_floatx80( float32 a STATUS_PARAM)
138{
139 return a;
140}
141#endif
142
143/*----------------------------------------------------------------------------
144| Software IEC/IEEE single-precision operations.
145*----------------------------------------------------------------------------*/
146float32 float32_round_to_int( float32 a STATUS_PARAM)
147{
148 return rintf(a);
149}
150
151float32 float32_rem( float32 a, float32 b STATUS_PARAM)
152{
153 return remainderf(a, b);
154}
155
156float32 float32_sqrt( float32 a STATUS_PARAM)
157{
158 return sqrtf(a);
159}
160int float32_compare( float32 a, float32 b STATUS_PARAM )
161{
162 if (a < b) {
163 return -1;
164 } else if (a == b) {
165 return 0;
166 } else if (a > b) {
167 return 1;
168 } else {
169 return 2;
170 }
171}
172int float32_compare_quiet( float32 a, float32 b STATUS_PARAM )
173{
174 if (isless(a, b)) {
175 return -1;
176 } else if (a == b) {
177 return 0;
178 } else if (isgreater(a, b)) {
179 return 1;
180 } else {
181 return 2;
182 }
183}
184int float32_is_signaling_nan( float32 a1)
185{
186 float32u u;
187 uint32_t a;
188 u.f = a1;
189 a = u.i;
190 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
191}
192
193/*----------------------------------------------------------------------------
194| Software IEC/IEEE double-precision conversion routines.
195*----------------------------------------------------------------------------*/
196int float64_to_int32( float64 a STATUS_PARAM)
197{
198 return long_to_int32(lrint(a));
199}
200int float64_to_int32_round_to_zero( float64 a STATUS_PARAM)
201{
202 return (int)a;
203}
204int64_t float64_to_int64( float64 a STATUS_PARAM)
205{
206 return llrint(a);
207}
208int64_t float64_to_int64_round_to_zero( float64 a STATUS_PARAM)
209{
210 return (int64_t)a;
211}
212float32 float64_to_float32( float64 a STATUS_PARAM)
213{
214 return a;
215}
216#ifdef FLOATX80
217floatx80 float64_to_floatx80( float64 a STATUS_PARAM)
218{
219 return a;
220}
221#endif
222#ifdef FLOAT128
223float128 float64_to_float128( float64 a STATUS_PARAM)
224{
225 return a;
226}
227#endif
228
229/*----------------------------------------------------------------------------
230| Software IEC/IEEE double-precision operations.
231*----------------------------------------------------------------------------*/
232float64 float64_trunc_to_int( float64 a STATUS_PARAM )
233{
234 return trunc(a);
235}
236
237float64 float64_round_to_int( float64 a STATUS_PARAM )
238{
239#if defined(__arm__)
240 switch(STATUS(float_rounding_mode)) {
241 default:
242 case float_round_nearest_even:
243 asm("rndd %0, %1" : "=f" (a) : "f"(a));
244 break;
245 case float_round_down:
246 asm("rnddm %0, %1" : "=f" (a) : "f"(a));
247 break;
248 case float_round_up:
249 asm("rnddp %0, %1" : "=f" (a) : "f"(a));
250 break;
251 case float_round_to_zero:
252 asm("rnddz %0, %1" : "=f" (a) : "f"(a));
253 break;
254 }
255#else
256 return rint(a);
257#endif
258}
259
260float64 float64_rem( float64 a, float64 b STATUS_PARAM)
261{
262 return remainder(a, b);
263}
264
265float64 float64_sqrt( float64 a STATUS_PARAM)
266{
267 return sqrt(a);
268}
269int float64_compare( float64 a, float64 b STATUS_PARAM )
270{
271 if (a < b) {
272 return -1;
273 } else if (a == b) {
274 return 0;
275 } else if (a > b) {
276 return 1;
277 } else {
278 return 2;
279 }
280}
281int float64_compare_quiet( float64 a, float64 b STATUS_PARAM )
282{
283 if (isless(a, b)) {
284 return -1;
285 } else if (a == b) {
286 return 0;
287 } else if (isgreater(a, b)) {
288 return 1;
289 } else {
290 return 2;
291 }
292}
293int float64_is_signaling_nan( float64 a1)
294{
295 float64u u;
296 uint64_t a;
297 u.f = a1;
298 a = u.i;
299 return
300 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
301 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
302
303}
304
305int float64_is_nan( float64 a1 )
306{
307 float64u u;
308 uint64_t a;
309 u.f = a1;
310 a = u.i;
311
312 return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
313
314}
315
316#ifdef FLOATX80
317
318/*----------------------------------------------------------------------------
319| Software IEC/IEEE extended double-precision conversion routines.
320*----------------------------------------------------------------------------*/
321int floatx80_to_int32( floatx80 a STATUS_PARAM)
322{
323 return long_to_int32(lrintl(a));
324}
325int floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM)
326{
327 return (int)a;
328}
329int64_t floatx80_to_int64( floatx80 a STATUS_PARAM)
330{
331 return llrintl(a);
332}
333int64_t floatx80_to_int64_round_to_zero( floatx80 a STATUS_PARAM)
334{
335 return (int64_t)a;
336}
337float32 floatx80_to_float32( floatx80 a STATUS_PARAM)
338{
339 return a;
340}
341float64 floatx80_to_float64( floatx80 a STATUS_PARAM)
342{
343 return a;
344}
345
346/*----------------------------------------------------------------------------
347| Software IEC/IEEE extended double-precision operations.
348*----------------------------------------------------------------------------*/
349floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM)
350{
351 return rintl(a);
352}
353floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM)
354{
355 return remainderl(a, b);
356}
357floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM)
358{
359 return sqrtl(a);
360}
361int floatx80_compare( floatx80 a, floatx80 b STATUS_PARAM )
362{
363 if (a < b) {
364 return -1;
365 } else if (a == b) {
366 return 0;
367 } else if (a > b) {
368 return 1;
369 } else {
370 return 2;
371 }
372}
373int floatx80_compare_quiet( floatx80 a, floatx80 b STATUS_PARAM )
374{
375 if (isless(a, b)) {
376 return -1;
377 } else if (a == b) {
378 return 0;
379 } else if (isgreater(a, b)) {
380 return 1;
381 } else {
382 return 2;
383 }
384}
385int floatx80_is_signaling_nan( floatx80 a1)
386{
387 floatx80u u;
388 u.f = a1;
389 return ( ( u.i.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( u.i.low<<1 );
390}
391
392#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