Statistics
| Branch: | Revision:

root / fpu / softfloat-native.c @ ea785922

History | View | Annotate | Download (8.3 kB)

1
/* Native implementation of soft float functions. Only a single status
2
   context is supported */
3
#include "softfloat.h"
4
#include <math.h>
5

    
6
void 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)
10
    fpsetround(val);
11
#elif defined(__arm__)
12
    /* nothing to do */
13
#else
14
    fesetround(val);
15
#endif
16
}
17

    
18
#ifdef FLOATX80
19
void 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) */
38
double 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
*----------------------------------------------------------------------------*/
57
float32 int32_to_float32(int v STATUS_PARAM)
58
{
59
    return (float32)v;
60
}
61

    
62
float64 int32_to_float64(int v STATUS_PARAM)
63
{
64
    return (float64)v;
65
}
66

    
67
#ifdef FLOATX80
68
floatx80 int32_to_floatx80(int v STATUS_PARAM)
69
{
70
    return (floatx80)v;
71
}
72
#endif
73
float32 int64_to_float32( int64_t v STATUS_PARAM)
74
{
75
    return (float32)v;
76
}
77
float64 int64_to_float64( int64_t v STATUS_PARAM)
78
{
79
    return (float64)v;
80
}
81
#ifdef FLOATX80
82
floatx80 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
static inline int long_to_int32(long a)
91
{
92
    return a;
93
}
94
#else
95
static inline int long_to_int32(long a)
96
{
97
    if (a != (int32_t)a) 
98
        a = 0x80000000;
99
    return a;
100
}
101
#endif
102

    
103
/*----------------------------------------------------------------------------
104
| Software IEC/IEEE single-precision conversion routines.
105
*----------------------------------------------------------------------------*/
106
int float32_to_int32( float32 a STATUS_PARAM)
107
{
108
    return long_to_int32(lrintf(a));
109
}
110
int float32_to_int32_round_to_zero( float32 a STATUS_PARAM)
111
{
112
    return (int)a;
113
}
114
int64_t float32_to_int64( float32 a STATUS_PARAM)
115
{
116
    return llrintf(a);
117
}
118

    
119
int64_t float32_to_int64_round_to_zero( float32 a STATUS_PARAM)
120
{
121
    return (int64_t)a;
122
}
123

    
124
float64 float32_to_float64( float32 a STATUS_PARAM)
125
{
126
    return a;
127
}
128
#ifdef FLOATX80
129
floatx80 float32_to_floatx80( float32 a STATUS_PARAM)
130
{
131
    return a;
132
}
133
#endif
134

    
135
/*----------------------------------------------------------------------------
136
| Software IEC/IEEE single-precision operations.
137
*----------------------------------------------------------------------------*/
138
float32 float32_round_to_int( float32 a STATUS_PARAM)
139
{
140
    return rintf(a);
141
}
142

    
143
float32 float32_rem( float32 a, float32 b STATUS_PARAM)
144
{
145
    return remainderf(a, b);
146
}
147

    
148
float32 float32_sqrt( float32 a STATUS_PARAM)
149
{
150
    return sqrtf(a);
151
}
152
int float32_compare( float32 a, float32 b STATUS_PARAM )
153
{
154
    if (a < b) {
155
        return -1;
156
    } else if (a == b) {
157
        return 0;
158
    } else if (a > b) {
159
        return 1;
160
    } else {
161
        return 2;
162
    }
163
}
164
int float32_compare_quiet( float32 a, float32 b STATUS_PARAM )
165
{
166
    if (isless(a, b)) {
167
        return -1;
168
    } else if (a == b) {
169
        return 0;
170
    } else if (isgreater(a, b)) {
171
        return 1;
172
    } else {
173
        return 2;
174
    }
175
}
176
int float32_is_signaling_nan( float32 a1)
177
{
178
    float32u u;
179
    uint32_t a;
180
    u.f = a1;
181
    a = u.i;
182
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
183
}
184

    
185
/*----------------------------------------------------------------------------
186
| Software IEC/IEEE double-precision conversion routines.
187
*----------------------------------------------------------------------------*/
188
int float64_to_int32( float64 a STATUS_PARAM)
189
{
190
    return long_to_int32(lrint(a));
191
}
192
int float64_to_int32_round_to_zero( float64 a STATUS_PARAM)
193
{
194
    return (int)a;
195
}
196
int64_t float64_to_int64( float64 a STATUS_PARAM)
197
{
198
    return llrint(a);
199
}
200
int64_t float64_to_int64_round_to_zero( float64 a STATUS_PARAM)
201
{
202
    return (int64_t)a;
203
}
204
float32 float64_to_float32( float64 a STATUS_PARAM)
205
{
206
    return a;
207
}
208
#ifdef FLOATX80
209
floatx80 float64_to_floatx80( float64 a STATUS_PARAM)
210
{
211
    return a;
212
}
213
#endif
214
#ifdef FLOAT128
215
float128 float64_to_float128( float64 a STATUS_PARAM)
216
{
217
    return a;
218
}
219
#endif
220

    
221
/*----------------------------------------------------------------------------
222
| Software IEC/IEEE double-precision operations.
223
*----------------------------------------------------------------------------*/
224
float64 float64_trunc_to_int( float64 a STATUS_PARAM )
225
{
226
    return trunc(a);
227
}
228

    
229
float64 float64_round_to_int( float64 a STATUS_PARAM )
230
{
231
#if defined(__arm__)
232
    switch(STATUS(float_rounding_mode)) {
233
    default:
234
    case float_round_nearest_even:
235
        asm("rndd %0, %1" : "=f" (a) : "f"(a));
236
        break;
237
    case float_round_down:
238
        asm("rnddm %0, %1" : "=f" (a) : "f"(a));
239
        break;
240
    case float_round_up:
241
        asm("rnddp %0, %1" : "=f" (a) : "f"(a));
242
        break;
243
    case float_round_to_zero:
244
        asm("rnddz %0, %1" : "=f" (a) : "f"(a));
245
        break;
246
    }
247
#else
248
    return rint(a);
249
#endif
250
}
251

    
252
float64 float64_rem( float64 a, float64 b STATUS_PARAM)
253
{
254
    return remainder(a, b);
255
}
256

    
257
float64 float64_sqrt( float64 a STATUS_PARAM)
258
{
259
    return sqrt(a);
260
}
261
int float64_compare( float64 a, float64 b STATUS_PARAM )
262
{
263
    if (a < b) {
264
        return -1;
265
    } else if (a == b) {
266
        return 0;
267
    } else if (a > b) {
268
        return 1;
269
    } else {
270
        return 2;
271
    }
272
}
273
int float64_compare_quiet( float64 a, float64 b STATUS_PARAM )
274
{
275
    if (isless(a, b)) {
276
        return -1;
277
    } else if (a == b) {
278
        return 0;
279
    } else if (isgreater(a, b)) {
280
        return 1;
281
    } else {
282
        return 2;
283
    }
284
}
285
int float64_is_signaling_nan( float64 a1)
286
{
287
    float64u u;
288
    uint64_t a;
289
    u.f = a1;
290
    a = u.i;
291
    return
292
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
293
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
294

    
295
}
296

    
297
int float64_is_nan( float64 a1 )
298
{
299
    float64u u;
300
    uint64_t a;
301
    u.f = a1;
302
    a = u.i;
303

    
304
    return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
305

    
306
}
307

    
308
#ifdef FLOATX80
309

    
310
/*----------------------------------------------------------------------------
311
| Software IEC/IEEE extended double-precision conversion routines.
312
*----------------------------------------------------------------------------*/
313
int floatx80_to_int32( floatx80 a STATUS_PARAM)
314
{
315
    return long_to_int32(lrintl(a));
316
}
317
int floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM)
318
{
319
    return (int)a;
320
}
321
int64_t floatx80_to_int64( floatx80 a STATUS_PARAM)
322
{
323
    return llrintl(a);
324
}
325
int64_t floatx80_to_int64_round_to_zero( floatx80 a STATUS_PARAM)
326
{
327
    return (int64_t)a;
328
}
329
float32 floatx80_to_float32( floatx80 a STATUS_PARAM)
330
{
331
    return a;
332
}
333
float64 floatx80_to_float64( floatx80 a STATUS_PARAM)
334
{
335
    return a;
336
}
337

    
338
/*----------------------------------------------------------------------------
339
| Software IEC/IEEE extended double-precision operations.
340
*----------------------------------------------------------------------------*/
341
floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM)
342
{
343
    return rintl(a);
344
}
345
floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM)
346
{
347
    return remainderl(a, b);
348
}
349
floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM)
350
{
351
    return sqrtl(a);
352
}
353
int floatx80_compare( floatx80 a, floatx80 b STATUS_PARAM )
354
{
355
    if (a < b) {
356
        return -1;
357
    } else if (a == b) {
358
        return 0;
359
    } else if (a > b) {
360
        return 1;
361
    } else {
362
        return 2;
363
    }
364
}
365
int floatx80_compare_quiet( floatx80 a, floatx80 b STATUS_PARAM )
366
{
367
    if (isless(a, b)) {
368
        return -1;
369
    } else if (a == b) {
370
        return 0;
371
    } else if (isgreater(a, b)) {
372
        return 1;
373
    } else {
374
        return 2;
375
    }
376
}
377
int floatx80_is_signaling_nan( floatx80 a1)
378
{
379
    floatx80u u;
380
    u.f = a1;
381
    return ( ( u.i.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( u.i.low<<1 );
382
}
383

    
384
#endif