1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32#ifndef __SOFTFLOAT_H__
33#define __SOFTFLOAT_H__
34
35
36
37
38
39
40
41
42
43
44#ifdef CONFIG_FPE_NWFPE_XP
45#define FLOATX80
46#endif
47
48
49
50
51
52
53typedef u32 float32;
54typedef u64 float64;
55typedef struct {
56#ifdef __ARMEB__
57 u16 __padding;
58 u16 high;
59#else
60 u16 high;
61 u16 __padding;
62#endif
63 u64 low;
64} __attribute__ ((packed,aligned(4))) floatx80;
65
66
67
68
69
70
71extern signed char float_detect_tininess;
72enum {
73 float_tininess_after_rounding = 0,
74 float_tininess_before_rounding = 1
75};
76
77
78
79
80
81
82
83enum {
84 float_round_nearest_even = 0,
85 float_round_to_zero = 1,
86 float_round_down = 2,
87 float_round_up = 3
88};
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106enum {
107 float_flag_invalid = 1,
108 float_flag_divbyzero = 2,
109 float_flag_overflow = 4,
110 float_flag_underflow = 8,
111 float_flag_inexact = 16
112};
113
114
115
116
117
118
119
120void float_raise( signed char );
121
122
123
124
125
126
127float32 int32_to_float32( struct roundingData *, signed int );
128float64 int32_to_float64( signed int );
129#ifdef FLOATX80
130floatx80 int32_to_floatx80( signed int );
131#endif
132
133
134
135
136
137
138signed int float32_to_int32( struct roundingData *, float32 );
139signed int float32_to_int32_round_to_zero( float32 );
140float64 float32_to_float64( float32 );
141#ifdef FLOATX80
142floatx80 float32_to_floatx80( float32 );
143#endif
144
145
146
147
148
149
150float32 float32_round_to_int( struct roundingData*, float32 );
151float32 float32_add( struct roundingData *, float32, float32 );
152float32 float32_sub( struct roundingData *, float32, float32 );
153float32 float32_mul( struct roundingData *, float32, float32 );
154float32 float32_div( struct roundingData *, float32, float32 );
155float32 float32_rem( struct roundingData *, float32, float32 );
156float32 float32_sqrt( struct roundingData*, float32 );
157char float32_eq( float32, float32 );
158char float32_le( float32, float32 );
159char float32_lt( float32, float32 );
160char float32_eq_signaling( float32, float32 );
161char float32_le_quiet( float32, float32 );
162char float32_lt_quiet( float32, float32 );
163char float32_is_signaling_nan( float32 );
164
165
166
167
168
169
170signed int float64_to_int32( struct roundingData *, float64 );
171signed int float64_to_int32_round_to_zero( float64 );
172float32 float64_to_float32( struct roundingData *, float64 );
173#ifdef FLOATX80
174floatx80 float64_to_floatx80( float64 );
175#endif
176
177
178
179
180
181
182float64 float64_round_to_int( struct roundingData *, float64 );
183float64 float64_add( struct roundingData *, float64, float64 );
184float64 float64_sub( struct roundingData *, float64, float64 );
185float64 float64_mul( struct roundingData *, float64, float64 );
186float64 float64_div( struct roundingData *, float64, float64 );
187float64 float64_rem( struct roundingData *, float64, float64 );
188float64 float64_sqrt( struct roundingData *, float64 );
189char float64_eq( float64, float64 );
190char float64_le( float64, float64 );
191char float64_lt( float64, float64 );
192char float64_eq_signaling( float64, float64 );
193char float64_le_quiet( float64, float64 );
194char float64_lt_quiet( float64, float64 );
195char float64_is_signaling_nan( float64 );
196
197#ifdef FLOATX80
198
199
200
201
202
203
204signed int floatx80_to_int32( struct roundingData *, floatx80 );
205signed int floatx80_to_int32_round_to_zero( floatx80 );
206float32 floatx80_to_float32( struct roundingData *, floatx80 );
207float64 floatx80_to_float64( struct roundingData *, floatx80 );
208
209
210
211
212
213
214floatx80 floatx80_round_to_int( struct roundingData *, floatx80 );
215floatx80 floatx80_add( struct roundingData *, floatx80, floatx80 );
216floatx80 floatx80_sub( struct roundingData *, floatx80, floatx80 );
217floatx80 floatx80_mul( struct roundingData *, floatx80, floatx80 );
218floatx80 floatx80_div( struct roundingData *, floatx80, floatx80 );
219floatx80 floatx80_rem( struct roundingData *, floatx80, floatx80 );
220floatx80 floatx80_sqrt( struct roundingData *, floatx80 );
221char floatx80_eq( floatx80, floatx80 );
222char floatx80_le( floatx80, floatx80 );
223char floatx80_lt( floatx80, floatx80 );
224char floatx80_eq_signaling( floatx80, floatx80 );
225char floatx80_le_quiet( floatx80, floatx80 );
226char floatx80_lt_quiet( floatx80, floatx80 );
227char floatx80_is_signaling_nan( floatx80 );
228
229extern flag floatx80_is_nan(floatx80);
230
231#endif
232
233static inline flag extractFloat32Sign(float32 a)
234{
235 return a >> 31;
236}
237
238static inline flag float32_eq_nocheck(float32 a, float32 b)
239{
240 return (a == b) || ((bits32) ((a | b) << 1) == 0);
241}
242
243static inline flag float32_lt_nocheck(float32 a, float32 b)
244{
245 flag aSign, bSign;
246
247 aSign = extractFloat32Sign(a);
248 bSign = extractFloat32Sign(b);
249 if (aSign != bSign)
250 return aSign && ((bits32) ((a | b) << 1) != 0);
251 return (a != b) && (aSign ^ (a < b));
252}
253
254static inline flag extractFloat64Sign(float64 a)
255{
256 return a >> 63;
257}
258
259static inline flag float64_eq_nocheck(float64 a, float64 b)
260{
261 return (a == b) || ((bits64) ((a | b) << 1) == 0);
262}
263
264static inline flag float64_lt_nocheck(float64 a, float64 b)
265{
266 flag aSign, bSign;
267
268 aSign = extractFloat64Sign(a);
269 bSign = extractFloat64Sign(b);
270 if (aSign != bSign)
271 return aSign && ((bits64) ((a | b) << 1) != 0);
272 return (a != b) && (aSign ^ (a < b));
273}
274
275extern flag float32_is_nan( float32 a );
276extern flag float64_is_nan( float64 a );
277
278extern int32 float64_to_uint32( struct roundingData *roundData, float64 a );
279extern int32 float64_to_uint32_round_to_zero( float64 a );
280
281#endif
282