Warning clean up
[akaros.git] / kern / arch / riscv / softfloat.h
1 #ifndef _SOFTFLOAT_H
2 #define _SOFTFLOAT_H
3
4 #ifdef __cplusplus
5   extern "C" {
6 #endif
7
8 /*============================================================================
9
10 This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
11 Package, Release 2b.
12
13 Written by John R. Hauser.  This work was made possible in part by the
14 International Computer Science Institute, located at Suite 600, 1947 Center
15 Street, Berkeley, California 94704.  Funding was partially provided by the
16 National Science Foundation under grant MIP-9311980.  The original version
17 of this code was written as part of a project to build a fixed-point vector
18 processor in collaboration with the University of California at Berkeley,
19 overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
20 is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
21 arithmetic/SoftFloat.html'.
22
23 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort has
24 been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
25 RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
26 AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
27 COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
28 EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
29 INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
30 OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
31
32 Derivative works are acceptable, even for commercial purposes, so long as
33 (1) the source code for the derivative work includes prominent notice that
34 the work is derivative, and (2) the source code includes prominent notice with
35 these four paragraphs for those parts of this code that are retained.
36
37 =============================================================================*/
38
39 /*----------------------------------------------------------------------------
40 | The macro `FLOATX80' must be defined to enable the extended double-precision
41 | floating-point format `floatx80'.  If this macro is not defined, the
42 | `floatx80' type will not be defined, and none of the functions that either
43 | input or output the `floatx80' type will be defined.  The same applies to
44 | the `FLOAT128' macro and the quadruple-precision format `float128'.
45 *----------------------------------------------------------------------------*/
46 #define FLOATX80
47 #define FLOAT128
48
49 #include <arch/types.h>
50
51 /* asw */
52 typedef uint8_t flag;
53 typedef uint8_t bits8;
54 typedef int8_t sbits8;
55 typedef uint16_t bits16;
56 typedef int16_t sbits16;
57 typedef uint32_t bits32;
58 typedef int32_t sbits32;
59 typedef uint64_t bits64;
60 typedef int64_t sbits64;
61
62 #define INLINE
63 #define LIT64( a ) a##LL
64
65 /*----------------------------------------------------------------------------
66 | Software IEC/IEEE floating-point types.
67 *----------------------------------------------------------------------------*/
68 typedef unsigned int float32;
69 typedef unsigned long long float64;
70 #ifdef FLOATX80
71 typedef struct {
72     unsigned short high;
73     unsigned long long low;
74 } floatx80;
75 #endif
76 #ifdef FLOAT128
77 typedef struct {
78     unsigned long long high, low;
79 } float128;
80 #endif
81
82 /*----------------------------------------------------------------------------
83 | Internal canonical NaN format.
84 *----------------------------------------------------------------------------*/
85 typedef struct {
86     flag sign;
87     bits64 high, low;
88 } commonNaNT;
89
90 INLINE bits32 extractFloat32Frac( float32 a );
91 INLINE int16_t extractFloat32Exp( float32 a );
92 INLINE flag extractFloat32Sign( float32 a );
93 INLINE float32 packFloat32( flag zSign, int16_t zExp, bits32 zSig );
94 INLINE bits64 extractFloat64Frac( float64 a );
95 INLINE int16_t extractFloat64Exp( float64 a );
96 INLINE flag extractFloat64Sign( float64 a );
97 INLINE float64 packFloat64( flag zSign, int16_t zExp, bits64 zSig );
98 INLINE bits64 extractFloatx80Frac( floatx80 a );
99 INLINE int32_t extractFloatx80Exp( floatx80 a );
100 INLINE flag extractFloatx80Sign( floatx80 a );
101 INLINE floatx80 packFloatx80( flag zSign, int32_t zExp, bits64 zSig );
102 INLINE bits64 extractFloat128Frac1( float128 a );
103 INLINE bits64 extractFloat128Frac0( float128 a );
104 INLINE int32_t extractFloat128Exp( float128 a );
105 INLINE flag extractFloat128Sign( float128 a );
106 INLINE float128 packFloat128( flag zSign, int32_t zExp, bits64 zSig0, bits64 zSig1 );
107
108 typedef struct
109 {
110   int8_t float_detect_tininess;
111   int8_t float_rounding_mode;
112   int8_t float_exception_flags;
113   #ifdef FLOATX80
114     int floatx80_rounding_precision;
115   #endif
116 } softfloat_t;
117
118 float32 subFloat32Sigs( softfloat_t* sf, float32 a, float32 b, flag zSign );
119 float64 subFloat64Sigs( softfloat_t* sf, float64 a, float64 b, flag zSign );
120 floatx80 subFloatx80Sigs( softfloat_t* sf, floatx80 a, floatx80 b, flag zSign );
121 float128 subFloat128Sigs( softfloat_t* sf, float128 a, float128 b, flag zSign );
122 float32 addFloat32Sigs( softfloat_t* sf, float32 a, float32 b, flag zSign );
123 float64 addFloat64Sigs( softfloat_t* sf, float64 a, float64 b, flag zSign );
124 floatx80 addFloatx80Sigs( softfloat_t* sf, floatx80 a, floatx80 b, flag zSign );
125 float128 addFloat128Sigs( softfloat_t* sf, float128 a, float128 b, flag zSign );
126 float32 normalizeRoundAndPackFloat32( softfloat_t* sf, flag zSign, int16_t zExp, bits32 zSig );
127 float64 normalizeRoundAndPackFloat64( softfloat_t* sf, flag zSign, int16_t zExp, bits64 zSig );
128 floatx80 normalizeRoundAndPackFloatx80( softfloat_t* sf,
129      int8_t roundingPrecision, flag zSign, int32_t zExp, bits64 zSig0, bits64 zSig1);
130 float128 normalizeRoundAndPackFloat128( softfloat_t* sf,
131      flag zSign, int32_t zExp, bits64 zSig0, bits64 zSig1 );
132 int32_t roundAndPackInt32( softfloat_t* sf, flag zSign, bits64 absZ );
133 int64_t roundAndPackInt64( softfloat_t* sf, flag zSign, bits64 absZ0, bits64 absZ1 );
134 float32 roundAndPackFloat32( softfloat_t* sf, flag zSign, int16_t zExp, bits32 zSig );
135 float64 roundAndPackFloat64( softfloat_t* sf, flag zSign, int16_t zExp, bits64 zSig );
136 floatx80 roundAndPackFloatx80( softfloat_t* sf,
137      int8_t roundingPrecision, flag zSign, int32_t zExp, bits64 zSig0, bits64 zSig1);
138 float128 roundAndPackFloat128( softfloat_t* sf,
139      flag zSign, int32_t zExp, bits64 zSig0, bits64 zSig1, bits64 zSig2 );
140 void normalizeFloat32Subnormal( bits32 aSig, int16_t *zExpPtr, bits32 *zSigPtr );
141 void normalizeFloat64Subnormal( bits64 aSig, int16_t *zExpPtr, bits64 *zSigPtr );
142 void normalizeFloatx80Subnormal( bits64 aSig, int32_t *zExpPtr, bits64 *zSigPtr );
143 void normalizeFloat128Subnormal(
144      bits64 aSig0,
145      bits64 aSig1,
146      int32_t *zExpPtr,
147      bits64 *zSig0Ptr,
148      bits64 *zSig1Ptr
149  );
150
151 INLINE flag float32_is_nan( softfloat_t* sf, float32 a );
152 commonNaNT float32ToCommonNaN( softfloat_t* sf, float32 a );
153 float32 commonNaNToFloat32( softfloat_t* sf, commonNaNT a );
154 float32 propagateFloat32NaN( softfloat_t* sf, float32 a, float32 b );
155 flag float64_is_nan( softfloat_t* sf, float64 a );
156 commonNaNT float64ToCommonNaN( softfloat_t* sf, float64 a );
157 float64 commonNaNToFloat64( softfloat_t* sf, commonNaNT a );
158 float64 propagateFloat64NaN( softfloat_t* sf, float64 a, float64 b );
159 flag floatx80_is_nan( softfloat_t* sf, floatx80 a );
160 commonNaNT floatx80ToCommonNaN( softfloat_t* sf, floatx80 a );
161 floatx80 commonNaNToFloatx80( softfloat_t* sf, commonNaNT a );
162 floatx80 propagateFloatx80NaN( softfloat_t* sf, floatx80 a, floatx80 b );
163 flag float128_is_nan( softfloat_t* sf, float128 a );
164 commonNaNT float128ToCommonNaN( softfloat_t* sf, float128 a );
165 float128 commonNaNToFloat128( softfloat_t* sf, commonNaNT a );
166 float128 propagateFloat128NaN( softfloat_t* sf, float128 a, float128 b );
167
168 /*----------------------------------------------------------------------------
169 | Routine to raise any or all of the software IEC/IEEE floating-point
170 | exception flags.
171 *----------------------------------------------------------------------------*/
172 INLINE void float_raise( softfloat_t* sf, int );
173
174 /*----------------------------------------------------------------------------
175 | Software IEC/IEEE integer-to-floating-point conversion routines.
176 *----------------------------------------------------------------------------*/
177 float32 int32_to_float32( softfloat_t* sf, int );
178 float64 int32_to_float64( softfloat_t* sf, int );
179 #ifdef FLOATX80
180 floatx80 int32_to_floatx80( softfloat_t* sf, int );
181 #endif
182 #ifdef FLOAT128
183 float128 int32_to_float128( softfloat_t* sf, int );
184 #endif
185 float32 int64_to_float32( softfloat_t* sf, long long );
186 float64 int64_to_float64( softfloat_t* sf, long long );
187 #ifdef FLOATX80
188 floatx80 int64_to_floatx80( softfloat_t* sf, long long );
189 #endif
190 #ifdef FLOAT128
191 float128 int64_to_float128( softfloat_t* sf, long long );
192 #endif
193
194 /*----------------------------------------------------------------------------
195 | Software IEC/IEEE single-precision conversion routines.
196 *----------------------------------------------------------------------------*/
197 int float32_to_int32( softfloat_t* sf, float32 );
198 int float32_to_int32_round_to_zero( softfloat_t* sf, float32 );
199 long long float32_to_int64( softfloat_t* sf, float32 );
200 long long float32_to_int64_round_to_zero( softfloat_t* sf, float32 );
201 float64 float32_to_float64( softfloat_t* sf, float32 );
202 #ifdef FLOATX80
203 floatx80 float32_to_floatx80( softfloat_t* sf, float32 );
204 #endif
205 #ifdef FLOAT128
206 float128 float32_to_float128( softfloat_t* sf, float32 );
207 #endif
208
209 /*----------------------------------------------------------------------------
210 | Software IEC/IEEE single-precision operations.
211 *----------------------------------------------------------------------------*/
212 float32 float32_round_to_int( softfloat_t* sf, float32 );
213 float32 float32_add( softfloat_t* sf, float32, float32 );
214 float32 float32_sub( softfloat_t* sf, float32, float32 );
215 float32 float32_mul( softfloat_t* sf, float32, float32 );
216 float32 float32_div( softfloat_t* sf, float32, float32 );
217 float32 float32_rem( softfloat_t* sf, float32, float32 );
218 float32 float32_sqrt( softfloat_t* sf, float32 );
219 flag float32_eq( softfloat_t* sf, float32, float32 );
220 flag float32_le( softfloat_t* sf, float32, float32 );
221 flag float32_lt( softfloat_t* sf, float32, float32 );
222 flag float32_eq_signaling( softfloat_t* sf, float32, float32 );
223 flag float32_le_quiet( softfloat_t* sf, float32, float32 );
224 flag float32_lt_quiet( softfloat_t* sf, float32, float32 );
225 flag float32_is_signaling_nan( softfloat_t* sf, float32 );
226
227 /*----------------------------------------------------------------------------
228 | Software IEC/IEEE double-precision conversion routines.
229 *----------------------------------------------------------------------------*/
230 int float64_to_int32( softfloat_t* sf, float64 );
231 int float64_to_int32_round_to_zero( softfloat_t* sf, float64 );
232 long long float64_to_int64( softfloat_t* sf, float64 );
233 long long float64_to_int64_round_to_zero( softfloat_t* sf, float64 );
234 float32 float64_to_float32( softfloat_t* sf, float64 );
235 #ifdef FLOATX80
236 floatx80 float64_to_floatx80( softfloat_t* sf, float64 );
237 #endif
238 #ifdef FLOAT128
239 float128 float64_to_float128( softfloat_t* sf, float64 );
240 #endif
241
242 /*----------------------------------------------------------------------------
243 | Software IEC/IEEE double-precision operations.
244 *----------------------------------------------------------------------------*/
245 float64 float64_round_to_int( softfloat_t* sf, float64 );
246 float64 float64_add( softfloat_t* sf, float64, float64 );
247 float64 float64_sub( softfloat_t* sf, float64, float64 );
248 float64 float64_mul( softfloat_t* sf, float64, float64 );
249 float64 float64_div( softfloat_t* sf, float64, float64 );
250 float64 float64_rem( softfloat_t* sf, float64, float64 );
251 float64 float64_sqrt( softfloat_t* sf, float64 );
252 flag float64_eq( softfloat_t* sf, float64, float64 );
253 flag float64_le( softfloat_t* sf, float64, float64 );
254 flag float64_lt( softfloat_t* sf, float64, float64 );
255 flag float64_eq_signaling( softfloat_t* sf, float64, float64 );
256 flag float64_le_quiet( softfloat_t* sf, float64, float64 );
257 flag float64_lt_quiet( softfloat_t* sf, float64, float64 );
258 flag float64_is_signaling_nan( softfloat_t* sf, float64 );
259
260 #ifdef FLOATX80
261
262 /*----------------------------------------------------------------------------
263 | Software IEC/IEEE extended double-precision conversion routines.
264 *----------------------------------------------------------------------------*/
265 int floatx80_to_int32( softfloat_t* sf, floatx80 );
266 int floatx80_to_int32_round_to_zero( softfloat_t* sf, floatx80 );
267 long long floatx80_to_int64( softfloat_t* sf, floatx80 );
268 long long floatx80_to_int64_round_to_zero( softfloat_t* sf, floatx80 );
269 float32 floatx80_to_float32( softfloat_t* sf, floatx80 );
270 float64 floatx80_to_float64( softfloat_t* sf, floatx80 );
271 #ifdef FLOAT128
272 float128 floatx80_to_float128( softfloat_t* sf, floatx80 );
273 #endif
274
275 #endif
276
277 #ifdef FLOATX80
278 /*----------------------------------------------------------------------------
279 | Software IEC/IEEE extended double-precision operations.
280 *----------------------------------------------------------------------------*/
281 floatx80 floatx80_round_to_int( softfloat_t* sf, floatx80 );
282 floatx80 floatx80_add( softfloat_t* sf, floatx80, floatx80 );
283 floatx80 floatx80_sub( softfloat_t* sf, floatx80, floatx80 );
284 floatx80 floatx80_mul( softfloat_t* sf, floatx80, floatx80 );
285 floatx80 floatx80_div( softfloat_t* sf, floatx80, floatx80 );
286 floatx80 floatx80_rem( softfloat_t* sf, floatx80, floatx80 );
287 floatx80 floatx80_sqrt( softfloat_t* sf, floatx80 );
288 flag floatx80_eq( softfloat_t* sf, floatx80, floatx80 );
289 flag floatx80_le( softfloat_t* sf, floatx80, floatx80 );
290 flag floatx80_lt( softfloat_t* sf, floatx80, floatx80 );
291 flag floatx80_eq_signaling( softfloat_t* sf, floatx80, floatx80 );
292 flag floatx80_le_quiet( softfloat_t* sf, floatx80, floatx80 );
293 flag floatx80_lt_quiet( softfloat_t* sf, floatx80, floatx80 );
294 flag floatx80_is_signaling_nan( softfloat_t* sf, floatx80 );
295 #endif
296
297 #ifdef FLOAT128
298
299 /*----------------------------------------------------------------------------
300 | Software IEC/IEEE quadruple-precision conversion routines.
301 *----------------------------------------------------------------------------*/
302 int float128_to_int32( softfloat_t* sf, float128 );
303 int float128_to_int32_round_to_zero( softfloat_t* sf, float128 );
304 long long float128_to_int64( softfloat_t* sf, float128 );
305 long long float128_to_int64_round_to_zero( softfloat_t* sf, float128 );
306 float32 float128_to_float32( softfloat_t* sf, float128 );
307 float64 float128_to_float64( softfloat_t* sf, float128 );
308 #ifdef FLOATX80
309 floatx80 float128_to_floatx80( softfloat_t* sf, float128 );
310 #endif
311
312 /*----------------------------------------------------------------------------
313 | Software IEC/IEEE quadruple-precision operations.
314 *----------------------------------------------------------------------------*/
315 float128 float128_round_to_int( softfloat_t* sf, float128 );
316 float128 float128_add( softfloat_t* sf, float128, float128 );
317 float128 float128_sub( softfloat_t* sf, float128, float128 );
318 float128 float128_mul( softfloat_t* sf, float128, float128 );
319 float128 float128_div( softfloat_t* sf, float128, float128 );
320 float128 float128_rem( softfloat_t* sf, float128, float128 );
321 float128 float128_sqrt( softfloat_t* sf, float128 );
322 flag float128_eq( softfloat_t* sf, float128, float128 );
323 flag float128_le( softfloat_t* sf, float128, float128 );
324 flag float128_lt( softfloat_t* sf, float128, float128 );
325 flag float128_eq_signaling( softfloat_t* sf, float128, float128 );
326 flag float128_le_quiet( softfloat_t* sf, float128, float128 );
327 flag float128_lt_quiet( softfloat_t* sf, float128, float128 );
328 flag float128_is_signaling_nan( softfloat_t* sf, float128 );
329
330 #endif
331
332 void softfloat_init(softfloat_t* sf);
333
334 enum {
335     float_tininess_after_rounding  = 0,
336     float_tininess_before_rounding = 1
337 };
338
339 enum {
340     float_round_nearest_even = 0,
341     float_round_to_zero      = 1,
342     float_round_down         = 2,
343     float_round_up           = 3
344 };
345
346 enum {
347     float_flag_inexact   =  1,
348     float_flag_underflow =  4,
349     float_flag_overflow  =  8,
350     float_flag_divbyzero =  2,
351     float_flag_invalid   = 16
352 };
353
354 #ifdef __cplusplus
355  }
356 #endif
357
358 #endif