Statistics
| Branch: | Revision:

root / fpu / softfloat-native.c @ 42673936

History | View | Annotate | Download (11 kB)

1 158142c2 bellard
/* Native implementation of soft float functions. Only a single status
2 158142c2 bellard
   context is supported */
3 158142c2 bellard
#include "softfloat.h"
4 158142c2 bellard
#include <math.h>
5 dfe5fff3 Juan Quintela
#if defined(CONFIG_SOLARIS)
6 14d483ec blueswir1
#include <fenv.h>
7 14d483ec blueswir1
#endif
8 158142c2 bellard
9 158142c2 bellard
void set_float_rounding_mode(int val STATUS_PARAM)
10 158142c2 bellard
{
11 158142c2 bellard
    STATUS(float_rounding_mode) = val;
12 a167ba50 Aurelien Jarno
#if (defined(CONFIG_BSD) && !defined(__APPLE__) && !defined(__GLIBC__)) || \
13 dfe5fff3 Juan Quintela
    (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10)
14 158142c2 bellard
    fpsetround(val);
15 158142c2 bellard
#else
16 158142c2 bellard
    fesetround(val);
17 158142c2 bellard
#endif
18 158142c2 bellard
}
19 158142c2 bellard
20 158142c2 bellard
#ifdef FLOATX80
21 158142c2 bellard
void set_floatx80_rounding_precision(int val STATUS_PARAM)
22 158142c2 bellard
{
23 158142c2 bellard
    STATUS(floatx80_rounding_precision) = val;
24 158142c2 bellard
}
25 158142c2 bellard
#endif
26 158142c2 bellard
27 71e72a19 Juan Quintela
#if defined(CONFIG_BSD) || \
28 dfe5fff3 Juan Quintela
    (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10)
29 fdbb4691 bellard
#define lrint(d)                ((int32_t)rint(d))
30 fdbb4691 bellard
#define llrint(d)                ((int64_t)rint(d))
31 fdbb4691 bellard
#define lrintf(f)                ((int32_t)rint(f))
32 fdbb4691 bellard
#define llrintf(f)                ((int64_t)rint(f))
33 fdbb4691 bellard
#define sqrtf(f)                ((float)sqrt(f))
34 fdbb4691 bellard
#define remainderf(fa, fb)        ((float)remainder(fa, fb))
35 fdbb4691 bellard
#define rintf(f)                ((float)rint(f))
36 dfe5fff3 Juan Quintela
#if !defined(__sparc__) && \
37 dfe5fff3 Juan Quintela
    (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10)
38 0475a5ca ths
extern long double rintl(long double);
39 0475a5ca ths
extern long double scalbnl(long double, int);
40 0475a5ca ths
41 0475a5ca ths
long long
42 0475a5ca ths
llrintl(long double x) {
43 0475a5ca ths
        return ((long long) rintl(x));
44 0475a5ca ths
}
45 0475a5ca ths
46 0475a5ca ths
long
47 0475a5ca ths
lrintl(long double x) {
48 0475a5ca ths
        return ((long) rintl(x));
49 0475a5ca ths
}
50 0475a5ca ths
51 0475a5ca ths
long double
52 0475a5ca ths
ldexpl(long double x, int n) {
53 0475a5ca ths
        return (scalbnl(x, n));
54 0475a5ca ths
}
55 0475a5ca ths
#endif
56 158142c2 bellard
#endif
57 158142c2 bellard
58 e58ffeb3 malc
#if defined(_ARCH_PPC)
59 158142c2 bellard
60 158142c2 bellard
/* correct (but slow) PowerPC rint() (glibc version is incorrect) */
61 947f5fcb malc
static double qemu_rint(double x)
62 158142c2 bellard
{
63 158142c2 bellard
    double y = 4503599627370496.0;
64 158142c2 bellard
    if (fabs(x) >= y)
65 158142c2 bellard
        return x;
66 5fafdf24 ths
    if (x < 0)
67 158142c2 bellard
        y = -y;
68 158142c2 bellard
    y = (x + y) - y;
69 158142c2 bellard
    if (y == 0.0)
70 158142c2 bellard
        y = copysign(y, x);
71 158142c2 bellard
    return y;
72 158142c2 bellard
}
73 158142c2 bellard
74 158142c2 bellard
#define rint qemu_rint
75 158142c2 bellard
#endif
76 158142c2 bellard
77 158142c2 bellard
/*----------------------------------------------------------------------------
78 158142c2 bellard
| Software IEC/IEEE integer-to-floating-point conversion routines.
79 158142c2 bellard
*----------------------------------------------------------------------------*/
80 158142c2 bellard
float32 int32_to_float32(int v STATUS_PARAM)
81 158142c2 bellard
{
82 158142c2 bellard
    return (float32)v;
83 158142c2 bellard
}
84 158142c2 bellard
85 75d62a58 j_mayer
float32 uint32_to_float32(unsigned int v STATUS_PARAM)
86 75d62a58 j_mayer
{
87 75d62a58 j_mayer
    return (float32)v;
88 75d62a58 j_mayer
}
89 75d62a58 j_mayer
90 158142c2 bellard
float64 int32_to_float64(int v STATUS_PARAM)
91 158142c2 bellard
{
92 158142c2 bellard
    return (float64)v;
93 158142c2 bellard
}
94 158142c2 bellard
95 75d62a58 j_mayer
float64 uint32_to_float64(unsigned int v STATUS_PARAM)
96 75d62a58 j_mayer
{
97 75d62a58 j_mayer
    return (float64)v;
98 75d62a58 j_mayer
}
99 75d62a58 j_mayer
100 158142c2 bellard
#ifdef FLOATX80
101 158142c2 bellard
floatx80 int32_to_floatx80(int v STATUS_PARAM)
102 158142c2 bellard
{
103 158142c2 bellard
    return (floatx80)v;
104 158142c2 bellard
}
105 158142c2 bellard
#endif
106 158142c2 bellard
float32 int64_to_float32( int64_t v STATUS_PARAM)
107 158142c2 bellard
{
108 158142c2 bellard
    return (float32)v;
109 158142c2 bellard
}
110 75d62a58 j_mayer
float32 uint64_to_float32( uint64_t v STATUS_PARAM)
111 75d62a58 j_mayer
{
112 75d62a58 j_mayer
    return (float32)v;
113 75d62a58 j_mayer
}
114 158142c2 bellard
float64 int64_to_float64( int64_t v STATUS_PARAM)
115 158142c2 bellard
{
116 158142c2 bellard
    return (float64)v;
117 158142c2 bellard
}
118 75d62a58 j_mayer
float64 uint64_to_float64( uint64_t v STATUS_PARAM)
119 75d62a58 j_mayer
{
120 75d62a58 j_mayer
    return (float64)v;
121 75d62a58 j_mayer
}
122 158142c2 bellard
#ifdef FLOATX80
123 158142c2 bellard
floatx80 int64_to_floatx80( int64_t v STATUS_PARAM)
124 158142c2 bellard
{
125 158142c2 bellard
    return (floatx80)v;
126 158142c2 bellard
}
127 158142c2 bellard
#endif
128 158142c2 bellard
129 1b2b0af5 bellard
/* XXX: this code implements the x86 behaviour, not the IEEE one.  */
130 1b2b0af5 bellard
#if HOST_LONG_BITS == 32
131 1b2b0af5 bellard
static inline int long_to_int32(long a)
132 1b2b0af5 bellard
{
133 1b2b0af5 bellard
    return a;
134 1b2b0af5 bellard
}
135 1b2b0af5 bellard
#else
136 1b2b0af5 bellard
static inline int long_to_int32(long a)
137 1b2b0af5 bellard
{
138 5fafdf24 ths
    if (a != (int32_t)a)
139 1b2b0af5 bellard
        a = 0x80000000;
140 1b2b0af5 bellard
    return a;
141 1b2b0af5 bellard
}
142 1b2b0af5 bellard
#endif
143 1b2b0af5 bellard
144 158142c2 bellard
/*----------------------------------------------------------------------------
145 158142c2 bellard
| Software IEC/IEEE single-precision conversion routines.
146 158142c2 bellard
*----------------------------------------------------------------------------*/
147 158142c2 bellard
int float32_to_int32( float32 a STATUS_PARAM)
148 158142c2 bellard
{
149 1b2b0af5 bellard
    return long_to_int32(lrintf(a));
150 158142c2 bellard
}
151 158142c2 bellard
int float32_to_int32_round_to_zero( float32 a STATUS_PARAM)
152 158142c2 bellard
{
153 158142c2 bellard
    return (int)a;
154 158142c2 bellard
}
155 158142c2 bellard
int64_t float32_to_int64( float32 a STATUS_PARAM)
156 158142c2 bellard
{
157 158142c2 bellard
    return llrintf(a);
158 158142c2 bellard
}
159 158142c2 bellard
160 158142c2 bellard
int64_t float32_to_int64_round_to_zero( float32 a STATUS_PARAM)
161 158142c2 bellard
{
162 158142c2 bellard
    return (int64_t)a;
163 158142c2 bellard
}
164 158142c2 bellard
165 158142c2 bellard
float64 float32_to_float64( float32 a STATUS_PARAM)
166 158142c2 bellard
{
167 158142c2 bellard
    return a;
168 158142c2 bellard
}
169 158142c2 bellard
#ifdef FLOATX80
170 158142c2 bellard
floatx80 float32_to_floatx80( float32 a STATUS_PARAM)
171 158142c2 bellard
{
172 158142c2 bellard
    return a;
173 158142c2 bellard
}
174 158142c2 bellard
#endif
175 158142c2 bellard
176 75d62a58 j_mayer
unsigned int float32_to_uint32( float32 a STATUS_PARAM)
177 75d62a58 j_mayer
{
178 75d62a58 j_mayer
    int64_t v;
179 75d62a58 j_mayer
    unsigned int res;
180 75d62a58 j_mayer
181 75d62a58 j_mayer
    v = llrintf(a);
182 75d62a58 j_mayer
    if (v < 0) {
183 75d62a58 j_mayer
        res = 0;
184 75d62a58 j_mayer
    } else if (v > 0xffffffff) {
185 75d62a58 j_mayer
        res = 0xffffffff;
186 75d62a58 j_mayer
    } else {
187 75d62a58 j_mayer
        res = v;
188 75d62a58 j_mayer
    }
189 75d62a58 j_mayer
    return res;
190 75d62a58 j_mayer
}
191 75d62a58 j_mayer
unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM)
192 75d62a58 j_mayer
{
193 75d62a58 j_mayer
    int64_t v;
194 75d62a58 j_mayer
    unsigned int res;
195 75d62a58 j_mayer
196 75d62a58 j_mayer
    v = (int64_t)a;
197 75d62a58 j_mayer
    if (v < 0) {
198 75d62a58 j_mayer
        res = 0;
199 75d62a58 j_mayer
    } else if (v > 0xffffffff) {
200 75d62a58 j_mayer
        res = 0xffffffff;
201 75d62a58 j_mayer
    } else {
202 75d62a58 j_mayer
        res = v;
203 75d62a58 j_mayer
    }
204 75d62a58 j_mayer
    return res;
205 75d62a58 j_mayer
}
206 75d62a58 j_mayer
207 158142c2 bellard
/*----------------------------------------------------------------------------
208 158142c2 bellard
| Software IEC/IEEE single-precision operations.
209 158142c2 bellard
*----------------------------------------------------------------------------*/
210 158142c2 bellard
float32 float32_round_to_int( float32 a STATUS_PARAM)
211 158142c2 bellard
{
212 158142c2 bellard
    return rintf(a);
213 158142c2 bellard
}
214 158142c2 bellard
215 b109f9f8 bellard
float32 float32_rem( float32 a, float32 b STATUS_PARAM)
216 b109f9f8 bellard
{
217 b109f9f8 bellard
    return remainderf(a, b);
218 b109f9f8 bellard
}
219 b109f9f8 bellard
220 158142c2 bellard
float32 float32_sqrt( float32 a STATUS_PARAM)
221 158142c2 bellard
{
222 158142c2 bellard
    return sqrtf(a);
223 158142c2 bellard
}
224 750afe93 bellard
int float32_compare( float32 a, float32 b STATUS_PARAM )
225 b109f9f8 bellard
{
226 b109f9f8 bellard
    if (a < b) {
227 30e7a22e aurel32
        return float_relation_less;
228 b109f9f8 bellard
    } else if (a == b) {
229 30e7a22e aurel32
        return float_relation_equal;
230 b109f9f8 bellard
    } else if (a > b) {
231 30e7a22e aurel32
        return float_relation_greater;
232 b109f9f8 bellard
    } else {
233 30e7a22e aurel32
        return float_relation_unordered;
234 b109f9f8 bellard
    }
235 b109f9f8 bellard
}
236 750afe93 bellard
int float32_compare_quiet( float32 a, float32 b STATUS_PARAM )
237 b109f9f8 bellard
{
238 b109f9f8 bellard
    if (isless(a, b)) {
239 30e7a22e aurel32
        return float_relation_less;
240 b109f9f8 bellard
    } else if (a == b) {
241 30e7a22e aurel32
        return float_relation_equal;
242 b109f9f8 bellard
    } else if (isgreater(a, b)) {
243 30e7a22e aurel32
        return float_relation_greater;
244 b109f9f8 bellard
    } else {
245 30e7a22e aurel32
        return float_relation_unordered;
246 b109f9f8 bellard
    }
247 b109f9f8 bellard
}
248 750afe93 bellard
int float32_is_signaling_nan( float32 a1)
249 158142c2 bellard
{
250 158142c2 bellard
    float32u u;
251 158142c2 bellard
    uint32_t a;
252 158142c2 bellard
    u.f = a1;
253 158142c2 bellard
    a = u.i;
254 158142c2 bellard
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
255 158142c2 bellard
}
256 158142c2 bellard
257 629bd74a aurel32
int float32_is_nan( float32 a1 )
258 629bd74a aurel32
{
259 629bd74a aurel32
    float32u u;
260 629bd74a aurel32
    uint64_t a;
261 629bd74a aurel32
    u.f = a1;
262 629bd74a aurel32
    a = u.i;
263 629bd74a aurel32
    return ( 0xFF800000 < ( a<<1 ) );
264 629bd74a aurel32
}
265 629bd74a aurel32
266 158142c2 bellard
/*----------------------------------------------------------------------------
267 158142c2 bellard
| Software IEC/IEEE double-precision conversion routines.
268 158142c2 bellard
*----------------------------------------------------------------------------*/
269 158142c2 bellard
int float64_to_int32( float64 a STATUS_PARAM)
270 158142c2 bellard
{
271 1b2b0af5 bellard
    return long_to_int32(lrint(a));
272 158142c2 bellard
}
273 158142c2 bellard
int float64_to_int32_round_to_zero( float64 a STATUS_PARAM)
274 158142c2 bellard
{
275 158142c2 bellard
    return (int)a;
276 158142c2 bellard
}
277 158142c2 bellard
int64_t float64_to_int64( float64 a STATUS_PARAM)
278 158142c2 bellard
{
279 158142c2 bellard
    return llrint(a);
280 158142c2 bellard
}
281 158142c2 bellard
int64_t float64_to_int64_round_to_zero( float64 a STATUS_PARAM)
282 158142c2 bellard
{
283 158142c2 bellard
    return (int64_t)a;
284 158142c2 bellard
}
285 158142c2 bellard
float32 float64_to_float32( float64 a STATUS_PARAM)
286 158142c2 bellard
{
287 158142c2 bellard
    return a;
288 158142c2 bellard
}
289 158142c2 bellard
#ifdef FLOATX80
290 158142c2 bellard
floatx80 float64_to_floatx80( float64 a STATUS_PARAM)
291 158142c2 bellard
{
292 158142c2 bellard
    return a;
293 158142c2 bellard
}
294 158142c2 bellard
#endif
295 158142c2 bellard
#ifdef FLOAT128
296 158142c2 bellard
float128 float64_to_float128( float64 a STATUS_PARAM)
297 158142c2 bellard
{
298 158142c2 bellard
    return a;
299 158142c2 bellard
}
300 158142c2 bellard
#endif
301 158142c2 bellard
302 75d62a58 j_mayer
unsigned int float64_to_uint32( float64 a STATUS_PARAM)
303 75d62a58 j_mayer
{
304 75d62a58 j_mayer
    int64_t v;
305 75d62a58 j_mayer
    unsigned int res;
306 75d62a58 j_mayer
307 75d62a58 j_mayer
    v = llrint(a);
308 75d62a58 j_mayer
    if (v < 0) {
309 75d62a58 j_mayer
        res = 0;
310 75d62a58 j_mayer
    } else if (v > 0xffffffff) {
311 75d62a58 j_mayer
        res = 0xffffffff;
312 75d62a58 j_mayer
    } else {
313 75d62a58 j_mayer
        res = v;
314 75d62a58 j_mayer
    }
315 75d62a58 j_mayer
    return res;
316 75d62a58 j_mayer
}
317 75d62a58 j_mayer
unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM)
318 75d62a58 j_mayer
{
319 75d62a58 j_mayer
    int64_t v;
320 75d62a58 j_mayer
    unsigned int res;
321 75d62a58 j_mayer
322 75d62a58 j_mayer
    v = (int64_t)a;
323 75d62a58 j_mayer
    if (v < 0) {
324 75d62a58 j_mayer
        res = 0;
325 75d62a58 j_mayer
    } else if (v > 0xffffffff) {
326 75d62a58 j_mayer
        res = 0xffffffff;
327 75d62a58 j_mayer
    } else {
328 75d62a58 j_mayer
        res = v;
329 75d62a58 j_mayer
    }
330 75d62a58 j_mayer
    return res;
331 75d62a58 j_mayer
}
332 75d62a58 j_mayer
uint64_t float64_to_uint64 (float64 a STATUS_PARAM)
333 75d62a58 j_mayer
{
334 75d62a58 j_mayer
    int64_t v;
335 75d62a58 j_mayer
336 75d62a58 j_mayer
    v = llrint(a + (float64)INT64_MIN);
337 75d62a58 j_mayer
338 75d62a58 j_mayer
    return v - INT64_MIN;
339 75d62a58 j_mayer
}
340 75d62a58 j_mayer
uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM)
341 75d62a58 j_mayer
{
342 75d62a58 j_mayer
    int64_t v;
343 75d62a58 j_mayer
344 75d62a58 j_mayer
    v = (int64_t)(a + (float64)INT64_MIN);
345 75d62a58 j_mayer
346 75d62a58 j_mayer
    return v - INT64_MIN;
347 75d62a58 j_mayer
}
348 75d62a58 j_mayer
349 158142c2 bellard
/*----------------------------------------------------------------------------
350 158142c2 bellard
| Software IEC/IEEE double-precision operations.
351 158142c2 bellard
*----------------------------------------------------------------------------*/
352 dfe5fff3 Juan Quintela
#if defined(__sun__) && \
353 dfe5fff3 Juan Quintela
    (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10)
354 63a654bb ths
static inline float64 trunc(float64 x)
355 63a654bb ths
{
356 63a654bb ths
    return x < 0 ? -floor(-x) : floor(x);
357 63a654bb ths
}
358 63a654bb ths
#endif
359 e6e5906b pbrook
float64 float64_trunc_to_int( float64 a STATUS_PARAM )
360 e6e5906b pbrook
{
361 e6e5906b pbrook
    return trunc(a);
362 e6e5906b pbrook
}
363 e6e5906b pbrook
364 158142c2 bellard
float64 float64_round_to_int( float64 a STATUS_PARAM )
365 158142c2 bellard
{
366 158142c2 bellard
    return rint(a);
367 158142c2 bellard
}
368 158142c2 bellard
369 b109f9f8 bellard
float64 float64_rem( float64 a, float64 b STATUS_PARAM)
370 b109f9f8 bellard
{
371 b109f9f8 bellard
    return remainder(a, b);
372 b109f9f8 bellard
}
373 b109f9f8 bellard
374 158142c2 bellard
float64 float64_sqrt( float64 a STATUS_PARAM)
375 158142c2 bellard
{
376 158142c2 bellard
    return sqrt(a);
377 158142c2 bellard
}
378 750afe93 bellard
int float64_compare( float64 a, float64 b STATUS_PARAM )
379 b109f9f8 bellard
{
380 b109f9f8 bellard
    if (a < b) {
381 30e7a22e aurel32
        return float_relation_less;
382 b109f9f8 bellard
    } else if (a == b) {
383 30e7a22e aurel32
        return float_relation_equal;
384 b109f9f8 bellard
    } else if (a > b) {
385 30e7a22e aurel32
        return float_relation_greater;
386 b109f9f8 bellard
    } else {
387 30e7a22e aurel32
        return float_relation_unordered;
388 b109f9f8 bellard
    }
389 b109f9f8 bellard
}
390 750afe93 bellard
int float64_compare_quiet( float64 a, float64 b STATUS_PARAM )
391 b109f9f8 bellard
{
392 b109f9f8 bellard
    if (isless(a, b)) {
393 30e7a22e aurel32
        return float_relation_less;
394 b109f9f8 bellard
    } else if (a == b) {
395 30e7a22e aurel32
        return float_relation_equal;
396 b109f9f8 bellard
    } else if (isgreater(a, b)) {
397 30e7a22e aurel32
        return float_relation_greater;
398 b109f9f8 bellard
    } else {
399 30e7a22e aurel32
        return float_relation_unordered;
400 b109f9f8 bellard
    }
401 b109f9f8 bellard
}
402 750afe93 bellard
int float64_is_signaling_nan( float64 a1)
403 158142c2 bellard
{
404 158142c2 bellard
    float64u u;
405 158142c2 bellard
    uint64_t a;
406 158142c2 bellard
    u.f = a1;
407 158142c2 bellard
    a = u.i;
408 158142c2 bellard
    return
409 158142c2 bellard
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
410 158142c2 bellard
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
411 158142c2 bellard
412 158142c2 bellard
}
413 158142c2 bellard
414 750afe93 bellard
int float64_is_nan( float64 a1 )
415 e6e5906b pbrook
{
416 e6e5906b pbrook
    float64u u;
417 e6e5906b pbrook
    uint64_t a;
418 e6e5906b pbrook
    u.f = a1;
419 e6e5906b pbrook
    a = u.i;
420 e6e5906b pbrook
421 1b2ad2ec aurel32
    return ( LIT64( 0xFFF0000000000000 ) < (bits64) ( a<<1 ) );
422 e6e5906b pbrook
423 e6e5906b pbrook
}
424 e6e5906b pbrook
425 158142c2 bellard
#ifdef FLOATX80
426 158142c2 bellard
427 158142c2 bellard
/*----------------------------------------------------------------------------
428 158142c2 bellard
| Software IEC/IEEE extended double-precision conversion routines.
429 158142c2 bellard
*----------------------------------------------------------------------------*/
430 158142c2 bellard
int floatx80_to_int32( floatx80 a STATUS_PARAM)
431 158142c2 bellard
{
432 1b2b0af5 bellard
    return long_to_int32(lrintl(a));
433 158142c2 bellard
}
434 158142c2 bellard
int floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM)
435 158142c2 bellard
{
436 158142c2 bellard
    return (int)a;
437 158142c2 bellard
}
438 158142c2 bellard
int64_t floatx80_to_int64( floatx80 a STATUS_PARAM)
439 158142c2 bellard
{
440 158142c2 bellard
    return llrintl(a);
441 158142c2 bellard
}
442 158142c2 bellard
int64_t floatx80_to_int64_round_to_zero( floatx80 a STATUS_PARAM)
443 158142c2 bellard
{
444 158142c2 bellard
    return (int64_t)a;
445 158142c2 bellard
}
446 158142c2 bellard
float32 floatx80_to_float32( floatx80 a STATUS_PARAM)
447 158142c2 bellard
{
448 158142c2 bellard
    return a;
449 158142c2 bellard
}
450 158142c2 bellard
float64 floatx80_to_float64( floatx80 a STATUS_PARAM)
451 158142c2 bellard
{
452 158142c2 bellard
    return a;
453 158142c2 bellard
}
454 158142c2 bellard
455 158142c2 bellard
/*----------------------------------------------------------------------------
456 158142c2 bellard
| Software IEC/IEEE extended double-precision operations.
457 158142c2 bellard
*----------------------------------------------------------------------------*/
458 158142c2 bellard
floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM)
459 158142c2 bellard
{
460 158142c2 bellard
    return rintl(a);
461 158142c2 bellard
}
462 b109f9f8 bellard
floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM)
463 b109f9f8 bellard
{
464 b109f9f8 bellard
    return remainderl(a, b);
465 b109f9f8 bellard
}
466 158142c2 bellard
floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM)
467 158142c2 bellard
{
468 158142c2 bellard
    return sqrtl(a);
469 158142c2 bellard
}
470 750afe93 bellard
int floatx80_compare( floatx80 a, floatx80 b STATUS_PARAM )
471 b109f9f8 bellard
{
472 b109f9f8 bellard
    if (a < b) {
473 30e7a22e aurel32
        return float_relation_less;
474 b109f9f8 bellard
    } else if (a == b) {
475 30e7a22e aurel32
        return float_relation_equal;
476 b109f9f8 bellard
    } else if (a > b) {
477 30e7a22e aurel32
        return float_relation_greater;
478 b109f9f8 bellard
    } else {
479 30e7a22e aurel32
        return float_relation_unordered;
480 b109f9f8 bellard
    }
481 b109f9f8 bellard
}
482 750afe93 bellard
int floatx80_compare_quiet( floatx80 a, floatx80 b STATUS_PARAM )
483 b109f9f8 bellard
{
484 b109f9f8 bellard
    if (isless(a, b)) {
485 30e7a22e aurel32
        return float_relation_less;
486 b109f9f8 bellard
    } else if (a == b) {
487 30e7a22e aurel32
        return float_relation_equal;
488 b109f9f8 bellard
    } else if (isgreater(a, b)) {
489 30e7a22e aurel32
        return float_relation_greater;
490 b109f9f8 bellard
    } else {
491 30e7a22e aurel32
        return float_relation_unordered;
492 b109f9f8 bellard
    }
493 b109f9f8 bellard
}
494 750afe93 bellard
int floatx80_is_signaling_nan( floatx80 a1)
495 158142c2 bellard
{
496 158142c2 bellard
    floatx80u u;
497 1b2ad2ec aurel32
    uint64_t aLow;
498 1b2ad2ec aurel32
    u.f = a1;
499 1b2ad2ec aurel32
500 1b2ad2ec aurel32
    aLow = u.i.low & ~ LIT64( 0x4000000000000000 );
501 1b2ad2ec aurel32
    return
502 1b2ad2ec aurel32
           ( ( u.i.high & 0x7FFF ) == 0x7FFF )
503 1b2ad2ec aurel32
        && (bits64) ( aLow<<1 )
504 1b2ad2ec aurel32
        && ( u.i.low == aLow );
505 1b2ad2ec aurel32
}
506 1b2ad2ec aurel32
507 1b2ad2ec aurel32
int floatx80_is_nan( floatx80 a1 )
508 1b2ad2ec aurel32
{
509 1b2ad2ec aurel32
    floatx80u u;
510 158142c2 bellard
    u.f = a1;
511 158142c2 bellard
    return ( ( u.i.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( u.i.low<<1 );
512 158142c2 bellard
}
513 158142c2 bellard
514 158142c2 bellard
#endif