Statistics
| Branch: | Revision:

root / fpu / softfloat-native.h @ 94ac5158

History | View | Annotate | Download (9 kB)

1
/* Native implementation of soft float functions */
2
#include <math.h>
3
#if defined(_BSD) && !defined(__APPLE__)
4
#include <ieeefp.h>
5
#else
6
#if !defined(_PRESOLARIS10)
7
#include <fenv.h>
8
#endif
9
#endif
10

    
11
typedef float float32;
12
typedef double float64;
13
#ifdef FLOATX80
14
typedef long double floatx80;
15
#endif
16

    
17
typedef union {
18
    float32 f;
19
    uint32_t i;
20
} float32u;
21
typedef union {
22
    float64 f;
23
    uint64_t i;
24
} float64u;
25
#ifdef FLOATX80
26
typedef union {
27
    floatx80 f;
28
    struct {
29
        uint64_t low;
30
        uint16_t high;
31
    } i;
32
} floatx80u;
33
#endif
34

    
35
/*----------------------------------------------------------------------------
36
| Software IEC/IEEE floating-point rounding mode.
37
*----------------------------------------------------------------------------*/
38
#if defined(_BSD) && !defined(__APPLE__)
39
enum {
40
    float_round_nearest_even = FP_RN,
41
    float_round_down         = FE_RM,
42
    float_round_up           = FE_RP,
43
    float_round_to_zero      = FE_RZ
44
};
45
#elif defined(__arm__)
46
enum {
47
    float_round_nearest_even = 0,
48
    float_round_down         = 1,
49
    float_round_up           = 2,
50
    float_round_to_zero      = 3
51
};
52
#else
53
enum {
54
    float_round_nearest_even = FE_TONEAREST,
55
    float_round_down         = FE_DOWNWARD,
56
    float_round_up           = FE_UPWARD,
57
    float_round_to_zero      = FE_TOWARDZERO
58
};
59
#endif
60

    
61
typedef struct float_status {
62
    signed char float_rounding_mode;
63
#ifdef FLOATX80
64
    signed char floatx80_rounding_precision;
65
#endif
66
} float_status;
67

    
68
void set_float_rounding_mode(int val STATUS_PARAM);
69
#ifdef FLOATX80
70
void set_floatx80_rounding_precision(int val STATUS_PARAM);
71
#endif
72

    
73
/*----------------------------------------------------------------------------
74
| Software IEC/IEEE integer-to-floating-point conversion routines.
75
*----------------------------------------------------------------------------*/
76
float32 int32_to_float32( int STATUS_PARAM);
77
float64 int32_to_float64( int STATUS_PARAM);
78
#ifdef FLOATX80
79
floatx80 int32_to_floatx80( int STATUS_PARAM);
80
#endif
81
#ifdef FLOAT128
82
float128 int32_to_float128( int STATUS_PARAM);
83
#endif
84
float32 int64_to_float32( int64_t STATUS_PARAM);
85
float64 int64_to_float64( int64_t STATUS_PARAM);
86
#ifdef FLOATX80
87
floatx80 int64_to_floatx80( int64_t STATUS_PARAM);
88
#endif
89
#ifdef FLOAT128
90
float128 int64_to_float128( int64_t STATUS_PARAM);
91
#endif
92

    
93
/*----------------------------------------------------------------------------
94
| Software IEC/IEEE single-precision conversion routines.
95
*----------------------------------------------------------------------------*/
96
int float32_to_int32( float32  STATUS_PARAM);
97
int float32_to_int32_round_to_zero( float32  STATUS_PARAM);
98
int64_t float32_to_int64( float32  STATUS_PARAM);
99
int64_t float32_to_int64_round_to_zero( float32  STATUS_PARAM);
100
float64 float32_to_float64( float32  STATUS_PARAM);
101
#ifdef FLOATX80
102
floatx80 float32_to_floatx80( float32  STATUS_PARAM);
103
#endif
104
#ifdef FLOAT128
105
float128 float32_to_float128( float32  STATUS_PARAM);
106
#endif
107

    
108
/*----------------------------------------------------------------------------
109
| Software IEC/IEEE single-precision operations.
110
*----------------------------------------------------------------------------*/
111
float32 float32_round_to_int( float32  STATUS_PARAM);
112
INLINE float32 float32_add( float32 a, float32 b STATUS_PARAM)
113
{
114
    return a + b;
115
}
116
INLINE float32 float32_sub( float32 a, float32 b STATUS_PARAM)
117
{
118
    return a - b;
119
}
120
INLINE float32 float32_mul( float32 a, float32 b STATUS_PARAM)
121
{
122
    return a * b;
123
}
124
INLINE float32 float32_div( float32 a, float32 b STATUS_PARAM)
125
{
126
    return a / b;
127
}
128
float32 float32_rem( float32, float32  STATUS_PARAM);
129
float32 float32_sqrt( float32  STATUS_PARAM);
130
INLINE char float32_eq( float32 a, float32 b STATUS_PARAM)
131
{
132
    return a == b;
133
}
134
INLINE char float32_le( float32 a, float32 b STATUS_PARAM)
135
{
136
    return a <= b;
137
}
138
INLINE char float32_lt( float32 a, float32 b STATUS_PARAM)
139
{
140
    return a < b;
141
}
142
INLINE char float32_eq_signaling( float32 a, float32 b STATUS_PARAM)
143
{
144
    return a <= b && a >= b;
145
}
146
INLINE char float32_le_quiet( float32 a, float32 b STATUS_PARAM)
147
{
148
    return islessequal(a, b);
149
}
150
INLINE char float32_lt_quiet( float32 a, float32 b STATUS_PARAM)
151
{
152
    return isless(a, b);
153
}
154
INLINE char float32_unordered( float32 a, float32 b STATUS_PARAM)
155
{
156
    return isunordered(a, b);
157

    
158
}
159
char float32_compare( float32, float32 STATUS_PARAM );
160
char float32_compare_quiet( float32, float32 STATUS_PARAM );
161
char float32_is_signaling_nan( float32 );
162

    
163
INLINE float32 float32_abs(float32 a)
164
{
165
    return fabsf(a);
166
}
167

    
168
INLINE float32 float32_chs(float32 a)
169
{
170
    return -a;
171
}
172

    
173
/*----------------------------------------------------------------------------
174
| Software IEC/IEEE double-precision conversion routines.
175
*----------------------------------------------------------------------------*/
176
int float64_to_int32( float64 STATUS_PARAM );
177
int float64_to_int32_round_to_zero( float64 STATUS_PARAM );
178
int64_t float64_to_int64( float64 STATUS_PARAM );
179
int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM );
180
float32 float64_to_float32( float64 STATUS_PARAM );
181
#ifdef FLOATX80
182
floatx80 float64_to_floatx80( float64 STATUS_PARAM );
183
#endif
184
#ifdef FLOAT128
185
float128 float64_to_float128( float64 STATUS_PARAM );
186
#endif
187

    
188
/*----------------------------------------------------------------------------
189
| Software IEC/IEEE double-precision operations.
190
*----------------------------------------------------------------------------*/
191
float64 float64_round_to_int( float64 STATUS_PARAM );
192
INLINE float64 float64_add( float64 a, float64 b STATUS_PARAM)
193
{
194
    return a + b;
195
}
196
INLINE float64 float64_sub( float64 a, float64 b STATUS_PARAM)
197
{
198
    return a - b;
199
}
200
INLINE float64 float64_mul( float64 a, float64 b STATUS_PARAM)
201
{
202
    return a * b;
203
}
204
INLINE float64 float64_div( float64 a, float64 b STATUS_PARAM)
205
{
206
    return a / b;
207
}
208
float64 float64_rem( float64, float64 STATUS_PARAM );
209
float64 float64_sqrt( float64 STATUS_PARAM );
210
INLINE char float64_eq( float64 a, float64 b STATUS_PARAM)
211
{
212
    return a == b;
213
}
214
INLINE char float64_le( float64 a, float64 b STATUS_PARAM)
215
{
216
    return a <= b;
217
}
218
INLINE char float64_lt( float64 a, float64 b STATUS_PARAM)
219
{
220
    return a < b;
221
}
222
INLINE char float64_eq_signaling( float64 a, float64 b STATUS_PARAM)
223
{
224
    return a <= b && a >= b;
225
}
226
INLINE char float64_le_quiet( float64 a, float64 b STATUS_PARAM)
227
{
228
    return islessequal(a, b);
229
}
230
INLINE char float64_lt_quiet( float64 a, float64 b STATUS_PARAM)
231
{
232
    return isless(a, b);
233

    
234
}
235
INLINE char float64_unordered( float64 a, float64 b STATUS_PARAM)
236
{
237
    return isunordered(a, b);
238

    
239
}
240
char float64_compare( float64, float64 STATUS_PARAM );
241
char float64_compare_quiet( float64, float64 STATUS_PARAM );
242
char float64_is_signaling_nan( float64 );
243

    
244
INLINE float64 float64_abs(float64 a)
245
{
246
    return fabs(a);
247
}
248

    
249
INLINE float64 float64_chs(float64 a)
250
{
251
    return -a;
252
}
253

    
254
#ifdef FLOATX80
255

    
256
/*----------------------------------------------------------------------------
257
| Software IEC/IEEE extended double-precision conversion routines.
258
*----------------------------------------------------------------------------*/
259
int floatx80_to_int32( floatx80 STATUS_PARAM );
260
int floatx80_to_int32_round_to_zero( floatx80 STATUS_PARAM );
261
int64_t floatx80_to_int64( floatx80 STATUS_PARAM);
262
int64_t floatx80_to_int64_round_to_zero( floatx80 STATUS_PARAM);
263
float32 floatx80_to_float32( floatx80 STATUS_PARAM );
264
float64 floatx80_to_float64( floatx80 STATUS_PARAM );
265
#ifdef FLOAT128
266
float128 floatx80_to_float128( floatx80 STATUS_PARAM );
267
#endif
268

    
269
/*----------------------------------------------------------------------------
270
| Software IEC/IEEE extended double-precision operations.
271
*----------------------------------------------------------------------------*/
272
floatx80 floatx80_round_to_int( floatx80 STATUS_PARAM );
273
INLINE floatx80 floatx80_add( floatx80 a, floatx80 b STATUS_PARAM)
274
{
275
    return a + b;
276
}
277
INLINE floatx80 floatx80_sub( floatx80 a, floatx80 b STATUS_PARAM)
278
{
279
    return a - b;
280
}
281
INLINE floatx80 floatx80_mul( floatx80 a, floatx80 b STATUS_PARAM)
282
{
283
    return a * b;
284
}
285
INLINE floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM)
286
{
287
    return a / b;
288
}
289
floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM );
290
floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
291
INLINE char floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM)
292
{
293
    return a == b;
294
}
295
INLINE char floatx80_le( floatx80 a, floatx80 b STATUS_PARAM)
296
{
297
    return a <= b;
298
}
299
INLINE char floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM)
300
{
301
    return a < b;
302
}
303
INLINE char floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM)
304
{
305
    return a <= b && a >= b;
306
}
307
INLINE char floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM)
308
{
309
    return islessequal(a, b);
310
}
311
INLINE char floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM)
312
{
313
    return isless(a, b);
314

    
315
}
316
INLINE char floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM)
317
{
318
    return isunordered(a, b);
319

    
320
}
321
char floatx80_compare( floatx80, floatx80 STATUS_PARAM );
322
char floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM );
323
char floatx80_is_signaling_nan( floatx80 );
324

    
325
INLINE floatx80 floatx80_abs(floatx80 a)
326
{
327
    return fabsl(a);
328
}
329

    
330
INLINE floatx80 floatx80_chs(floatx80 a)
331
{
332
    return -a;
333
}
334
#endif