Statistics
| Branch: | Revision:

root / fpu / softfloat-native.h @ 8d7b0fbb

History | View | Annotate | Download (10 kB)

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
#else
8
#include <fenv.h>
9
#endif
10

    
11
/*
12
 * Define some C99-7.12.3 classification macros and
13
 *        some C99-.12.4 for Solaris systems OS less than 10,
14
 *        or Solaris 10 systems running GCC 3.x or less.
15
 *   Solaris 10 with GCC4 does not need these macros as they
16
 *   are defined in <iso/math_c99.h> with a compiler directive
17
 */
18
#if defined(HOST_SOLARIS) && (( HOST_SOLARIS <= 9 ) || ( ( HOST_SOLARIS >= 10 ) && ( __GNUC__ <= 4) ))
19
/*
20
 * C99 7.12.3 classification macros
21
 * and
22
 * C99 7.12.14 comparison macros
23
 *
24
 * ... do not work on Solaris 10 using GNU CC 3.4.x.
25
 * Try to workaround the missing / broken C99 math macros.
26
 */
27

    
28
#define isnormal(x)             (fpclass(x) >= FP_NZERO)
29
#define isgreater(x, y)         ((!unordered(x, y)) && ((x) > (y)))
30
#define isgreaterequal(x, y)    ((!unordered(x, y)) && ((x) >= (y)))
31
#define isless(x, y)            ((!unordered(x, y)) && ((x) < (y)))
32
#define islessequal(x, y)       ((!unordered(x, y)) && ((x) <= (y)))
33
#define isunordered(x,y)        unordered(x, y)
34
#endif
35

    
36
typedef float float32;
37
typedef double float64;
38
#ifdef FLOATX80
39
typedef long double floatx80;
40
#endif
41

    
42
typedef union {
43
    float32 f;
44
    uint32_t i;
45
} float32u;
46
typedef union {
47
    float64 f;
48
    uint64_t i;
49
} float64u;
50
#ifdef FLOATX80
51
typedef union {
52
    floatx80 f;
53
    struct {
54
        uint64_t low;
55
        uint16_t high;
56
    } i;
57
} floatx80u;
58
#endif
59

    
60
/*----------------------------------------------------------------------------
61
| Software IEC/IEEE floating-point rounding mode.
62
*----------------------------------------------------------------------------*/
63
#if (defined(_BSD) && !defined(__APPLE__)) || defined(HOST_SOLARIS)
64
enum {
65
    float_round_nearest_even = FP_RN,
66
    float_round_down         = FP_RM,
67
    float_round_up           = FP_RP,
68
    float_round_to_zero      = FP_RZ
69
};
70
#elif defined(__arm__)
71
enum {
72
    float_round_nearest_even = 0,
73
    float_round_down         = 1,
74
    float_round_up           = 2,
75
    float_round_to_zero      = 3
76
};
77
#else
78
enum {
79
    float_round_nearest_even = FE_TONEAREST,
80
    float_round_down         = FE_DOWNWARD,
81
    float_round_up           = FE_UPWARD,
82
    float_round_to_zero      = FE_TOWARDZERO
83
};
84
#endif
85

    
86
typedef struct float_status {
87
    signed char float_rounding_mode;
88
#ifdef FLOATX80
89
    signed char floatx80_rounding_precision;
90
#endif
91
} float_status;
92

    
93
void set_float_rounding_mode(int val STATUS_PARAM);
94
#ifdef FLOATX80
95
void set_floatx80_rounding_precision(int val STATUS_PARAM);
96
#endif
97

    
98
/*----------------------------------------------------------------------------
99
| Software IEC/IEEE integer-to-floating-point conversion routines.
100
*----------------------------------------------------------------------------*/
101
float32 int32_to_float32( int STATUS_PARAM);
102
float64 int32_to_float64( int STATUS_PARAM);
103
#ifdef FLOATX80
104
floatx80 int32_to_floatx80( int STATUS_PARAM);
105
#endif
106
#ifdef FLOAT128
107
float128 int32_to_float128( int STATUS_PARAM);
108
#endif
109
float32 int64_to_float32( int64_t STATUS_PARAM);
110
float64 int64_to_float64( int64_t STATUS_PARAM);
111
#ifdef FLOATX80
112
floatx80 int64_to_floatx80( int64_t STATUS_PARAM);
113
#endif
114
#ifdef FLOAT128
115
float128 int64_to_float128( int64_t STATUS_PARAM);
116
#endif
117

    
118
/*----------------------------------------------------------------------------
119
| Software IEC/IEEE single-precision conversion routines.
120
*----------------------------------------------------------------------------*/
121
int float32_to_int32( float32  STATUS_PARAM);
122
int float32_to_int32_round_to_zero( float32  STATUS_PARAM);
123
int64_t float32_to_int64( float32  STATUS_PARAM);
124
int64_t float32_to_int64_round_to_zero( float32  STATUS_PARAM);
125
float64 float32_to_float64( float32  STATUS_PARAM);
126
#ifdef FLOATX80
127
floatx80 float32_to_floatx80( float32  STATUS_PARAM);
128
#endif
129
#ifdef FLOAT128
130
float128 float32_to_float128( float32  STATUS_PARAM);
131
#endif
132

    
133
/*----------------------------------------------------------------------------
134
| Software IEC/IEEE single-precision operations.
135
*----------------------------------------------------------------------------*/
136
float32 float32_round_to_int( float32  STATUS_PARAM);
137
INLINE float32 float32_add( float32 a, float32 b STATUS_PARAM)
138
{
139
    return a + b;
140
}
141
INLINE float32 float32_sub( float32 a, float32 b STATUS_PARAM)
142
{
143
    return a - b;
144
}
145
INLINE float32 float32_mul( float32 a, float32 b STATUS_PARAM)
146
{
147
    return a * b;
148
}
149
INLINE float32 float32_div( float32 a, float32 b STATUS_PARAM)
150
{
151
    return a / b;
152
}
153
float32 float32_rem( float32, float32  STATUS_PARAM);
154
float32 float32_sqrt( float32  STATUS_PARAM);
155
INLINE char float32_eq( float32 a, float32 b STATUS_PARAM)
156
{
157
    return a == b;
158
}
159
INLINE char float32_le( float32 a, float32 b STATUS_PARAM)
160
{
161
    return a <= b;
162
}
163
INLINE char float32_lt( float32 a, float32 b STATUS_PARAM)
164
{
165
    return a < b;
166
}
167
INLINE char float32_eq_signaling( float32 a, float32 b STATUS_PARAM)
168
{
169
    return a <= b && a >= b;
170
}
171
INLINE char float32_le_quiet( float32 a, float32 b STATUS_PARAM)
172
{
173
    return islessequal(a, b);
174
}
175
INLINE char float32_lt_quiet( float32 a, float32 b STATUS_PARAM)
176
{
177
    return isless(a, b);
178
}
179
INLINE char float32_unordered( float32 a, float32 b STATUS_PARAM)
180
{
181
    return isunordered(a, b);
182

    
183
}
184
char float32_compare( float32, float32 STATUS_PARAM );
185
char float32_compare_quiet( float32, float32 STATUS_PARAM );
186
char float32_is_signaling_nan( float32 );
187

    
188
INLINE float32 float32_abs(float32 a)
189
{
190
    return fabsf(a);
191
}
192

    
193
INLINE float32 float32_chs(float32 a)
194
{
195
    return -a;
196
}
197

    
198
/*----------------------------------------------------------------------------
199
| Software IEC/IEEE double-precision conversion routines.
200
*----------------------------------------------------------------------------*/
201
int float64_to_int32( float64 STATUS_PARAM );
202
int float64_to_int32_round_to_zero( float64 STATUS_PARAM );
203
int64_t float64_to_int64( float64 STATUS_PARAM );
204
int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM );
205
float32 float64_to_float32( float64 STATUS_PARAM );
206
#ifdef FLOATX80
207
floatx80 float64_to_floatx80( float64 STATUS_PARAM );
208
#endif
209
#ifdef FLOAT128
210
float128 float64_to_float128( float64 STATUS_PARAM );
211
#endif
212

    
213
/*----------------------------------------------------------------------------
214
| Software IEC/IEEE double-precision operations.
215
*----------------------------------------------------------------------------*/
216
float64 float64_round_to_int( float64 STATUS_PARAM );
217
INLINE float64 float64_add( float64 a, float64 b STATUS_PARAM)
218
{
219
    return a + b;
220
}
221
INLINE float64 float64_sub( float64 a, float64 b STATUS_PARAM)
222
{
223
    return a - b;
224
}
225
INLINE float64 float64_mul( float64 a, float64 b STATUS_PARAM)
226
{
227
    return a * b;
228
}
229
INLINE float64 float64_div( float64 a, float64 b STATUS_PARAM)
230
{
231
    return a / b;
232
}
233
float64 float64_rem( float64, float64 STATUS_PARAM );
234
float64 float64_sqrt( float64 STATUS_PARAM );
235
INLINE char float64_eq( float64 a, float64 b STATUS_PARAM)
236
{
237
    return a == b;
238
}
239
INLINE char float64_le( float64 a, float64 b STATUS_PARAM)
240
{
241
    return a <= b;
242
}
243
INLINE char float64_lt( float64 a, float64 b STATUS_PARAM)
244
{
245
    return a < b;
246
}
247
INLINE char float64_eq_signaling( float64 a, float64 b STATUS_PARAM)
248
{
249
    return a <= b && a >= b;
250
}
251
INLINE char float64_le_quiet( float64 a, float64 b STATUS_PARAM)
252
{
253
    return islessequal(a, b);
254
}
255
INLINE char float64_lt_quiet( float64 a, float64 b STATUS_PARAM)
256
{
257
    return isless(a, b);
258

    
259
}
260
INLINE char float64_unordered( float64 a, float64 b STATUS_PARAM)
261
{
262
    return isunordered(a, b);
263

    
264
}
265
char float64_compare( float64, float64 STATUS_PARAM );
266
char float64_compare_quiet( float64, float64 STATUS_PARAM );
267
char float64_is_signaling_nan( float64 );
268

    
269
INLINE float64 float64_abs(float64 a)
270
{
271
    return fabs(a);
272
}
273

    
274
INLINE float64 float64_chs(float64 a)
275
{
276
    return -a;
277
}
278

    
279
#ifdef FLOATX80
280

    
281
/*----------------------------------------------------------------------------
282
| Software IEC/IEEE extended double-precision conversion routines.
283
*----------------------------------------------------------------------------*/
284
int floatx80_to_int32( floatx80 STATUS_PARAM );
285
int floatx80_to_int32_round_to_zero( floatx80 STATUS_PARAM );
286
int64_t floatx80_to_int64( floatx80 STATUS_PARAM);
287
int64_t floatx80_to_int64_round_to_zero( floatx80 STATUS_PARAM);
288
float32 floatx80_to_float32( floatx80 STATUS_PARAM );
289
float64 floatx80_to_float64( floatx80 STATUS_PARAM );
290
#ifdef FLOAT128
291
float128 floatx80_to_float128( floatx80 STATUS_PARAM );
292
#endif
293

    
294
/*----------------------------------------------------------------------------
295
| Software IEC/IEEE extended double-precision operations.
296
*----------------------------------------------------------------------------*/
297
floatx80 floatx80_round_to_int( floatx80 STATUS_PARAM );
298
INLINE floatx80 floatx80_add( floatx80 a, floatx80 b STATUS_PARAM)
299
{
300
    return a + b;
301
}
302
INLINE floatx80 floatx80_sub( floatx80 a, floatx80 b STATUS_PARAM)
303
{
304
    return a - b;
305
}
306
INLINE floatx80 floatx80_mul( floatx80 a, floatx80 b STATUS_PARAM)
307
{
308
    return a * b;
309
}
310
INLINE floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM)
311
{
312
    return a / b;
313
}
314
floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM );
315
floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
316
INLINE char floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM)
317
{
318
    return a == b;
319
}
320
INLINE char floatx80_le( floatx80 a, floatx80 b STATUS_PARAM)
321
{
322
    return a <= b;
323
}
324
INLINE char floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM)
325
{
326
    return a < b;
327
}
328
INLINE char floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM)
329
{
330
    return a <= b && a >= b;
331
}
332
INLINE char floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM)
333
{
334
    return islessequal(a, b);
335
}
336
INLINE char floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM)
337
{
338
    return isless(a, b);
339

    
340
}
341
INLINE char floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM)
342
{
343
    return isunordered(a, b);
344

    
345
}
346
char floatx80_compare( floatx80, floatx80 STATUS_PARAM );
347
char floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM );
348
char floatx80_is_signaling_nan( floatx80 );
349

    
350
INLINE floatx80 floatx80_abs(floatx80 a)
351
{
352
    return fabsl(a);
353
}
354

    
355
INLINE floatx80 floatx80_chs(floatx80 a)
356
{
357
    return -a;
358
}
359
#endif