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: #if defined(HOST_SOLARIS) && defined(NEEDS_LIBSUNMATH)
36: #include <sunmath.h>
37: #endif
38:
39: #include <inttypes.h>
40: #include "config.h"
41:
42:
43:
44:
45:
46:
47:
48:
49:
50: typedef uint8_t flag;
51: typedef uint8_t uint8;
52: typedef int8_t int8;
53: typedef int uint16;
54: typedef int int16;
55: typedef unsigned int uint32;
56: typedef signed int int32;
57: typedef uint64_t uint64;
58: typedef int64_t int64;
59:
60:
61:
62:
63:
64:
65:
66: typedef uint8_t bits8;
67: typedef int8_t sbits8;
68: typedef uint16_t bits16;
69: typedef int16_t sbits16;
70: typedef uint32_t bits32;
71: typedef int32_t sbits32;
72: typedef uint64_t bits64;
73: typedef int64_t sbits64;
74:
75: #define LIT64( a ) a##LL
76: #define INLINE static inline
77:
78:
79:
80:
81:
82:
83:
84:
85: #ifdef CONFIG_SOFTFLOAT
86:
87: #define FLOATX80
88: #define FLOAT128
89: #else
90:
91: #if (defined(__i386__) || defined(__x86_64__)) && !defined(_BSD)
92: #define FLOATX80
93: #endif
94: #endif
95:
96: #define STATUS_PARAM , float_status *status
97: #define STATUS(field) status->field
98: #define STATUS_VAR , status
99:
100:
101:
102:
103: enum {
104: float_relation_less = -1,
105: float_relation_equal = 0,
106: float_relation_greater = 1,
107: float_relation_unordered = 2
108: };
109:
110: #ifdef CONFIG_SOFTFLOAT
111:
112:
113:
114:
115:
116:
117:
118:
119: #ifdef USE_SOFTFLOAT_STRUCT_TYPES
120: typedef struct {
121: uint32_t v;
122: } float32;
123:
124: #define float32_val(x) (((float32)(x)).v)
125: #define make_float32(x) __extension__ ({ float32 f32_val = {x}; f32_val; })
126: typedef struct {
127: uint64_t v;
128: } float64;
129: #define float64_val(x) (((float64)(x)).v)
130: #define make_float64(x) __extension__ ({ float64 f64_val = {x}; f64_val; })
131: #else
132: typedef uint32_t float32;
133: typedef uint64_t float64;
134: #define float32_val(x) (x)
135: #define float64_val(x) (x)
136: #define make_float32(x) (x)
137: #define make_float64(x) (x)
138: #endif
139: #ifdef FLOATX80
140: typedef struct {
141: uint64_t low;
142: uint16_t high;
143: } floatx80;
144: #endif
145: #ifdef FLOAT128
146: typedef struct {
147: #ifdef WORDS_BIGENDIAN
148: uint64_t high, low;
149: #else
150: uint64_t low, high;
151: #endif
152: } float128;
153: #endif
154:
155:
156:
157:
158: enum {
159: float_tininess_after_rounding = 0,
160: float_tininess_before_rounding = 1
161: };
162:
163:
164:
165:
166: enum {
167: float_round_nearest_even = 0,
168: float_round_down = 1,
169: float_round_up = 2,
170: float_round_to_zero = 3
171: };
172:
173:
174:
175:
176: enum {
177: float_flag_invalid = 1,
178: float_flag_divbyzero = 4,
179: float_flag_overflow = 8,
180: float_flag_underflow = 16,
181: float_flag_inexact = 32
182: };
183:
184: typedef struct float_status {
185: signed char float_detect_tininess;
186: signed char float_rounding_mode;
187: signed char float_exception_flags;
188: #ifdef FLOATX80
189: signed char floatx80_rounding_precision;
190: #endif
191: } float_status;
192:
193: void set_float_rounding_mode(int val STATUS_PARAM);
194: void set_float_exception_flags(int val STATUS_PARAM);
195: INLINE int get_float_exception_flags(float_status *status)
196: {
197: return STATUS(float_exception_flags);
198: }
199: #ifdef FLOATX80
200: void set_floatx80_rounding_precision(int val STATUS_PARAM);
201: #endif
202:
203:
204:
205:
206:
207: void float_raise( int8 flags STATUS_PARAM);
208:
209:
210:
211:
212: float32 int32_to_float32( int STATUS_PARAM );
213: float64 int32_to_float64( int STATUS_PARAM );
214: float32 uint32_to_float32( unsigned int STATUS_PARAM );
215: float64 uint32_to_float64( unsigned int STATUS_PARAM );
216: #ifdef FLOATX80
217: floatx80 int32_to_floatx80( int STATUS_PARAM );
218: #endif
219: #ifdef FLOAT128
220: float128 int32_to_float128( int STATUS_PARAM );
221: #endif
222: float32 int64_to_float32( int64_t STATUS_PARAM );
223: float32 uint64_to_float32( uint64_t STATUS_PARAM );
224: float64 int64_to_float64( int64_t STATUS_PARAM );
225: float64 uint64_to_float64( uint64_t STATUS_PARAM );
226: #ifdef FLOATX80
227: floatx80 int64_to_floatx80( int64_t STATUS_PARAM );
228: #endif
229: #ifdef FLOAT128
230: float128 int64_to_float128( int64_t STATUS_PARAM );
231: #endif
232:
233:
234:
235:
236: int float32_to_int32( float32 STATUS_PARAM );
237: int float32_to_int32_round_to_zero( float32 STATUS_PARAM );
238: unsigned int float32_to_uint32( float32 STATUS_PARAM );
239: unsigned int float32_to_uint32_round_to_zero( float32 STATUS_PARAM );
240: int64_t float32_to_int64( float32 STATUS_PARAM );
241: int64_t float32_to_int64_round_to_zero( float32 STATUS_PARAM );
242: float64 float32_to_float64( float32 STATUS_PARAM );
243: #ifdef FLOATX80
244: floatx80 float32_to_floatx80( float32 STATUS_PARAM );
245: #endif
246: #ifdef FLOAT128
247: float128 float32_to_float128( float32 STATUS_PARAM );
248: #endif
249:
250:
251:
252:
253: float32 float32_round_to_int( float32 STATUS_PARAM );
254: float32 float32_add( float32, float32 STATUS_PARAM );
255: float32 float32_sub( float32, float32 STATUS_PARAM );
256: float32 float32_mul( float32, float32 STATUS_PARAM );
257: float32 float32_div( float32, float32 STATUS_PARAM );
258: float32 float32_rem( float32, float32 STATUS_PARAM );
259: float32 float32_sqrt( float32 STATUS_PARAM );
260: int float32_eq( float32, float32 STATUS_PARAM );
261: int float32_le( float32, float32 STATUS_PARAM );
262: int float32_lt( float32, float32 STATUS_PARAM );
263: int float32_eq_signaling( float32, float32 STATUS_PARAM );
264: int float32_le_quiet( float32, float32 STATUS_PARAM );
265: int float32_lt_quiet( float32, float32 STATUS_PARAM );
266: int float32_compare( float32, float32 STATUS_PARAM );
267: int float32_compare_quiet( float32, float32 STATUS_PARAM );
268: int float32_is_nan( float32 );
269: int float32_is_signaling_nan( float32 );
270: float32 float32_scalbn( float32, int STATUS_PARAM );
271:
272: INLINE float32 float32_abs(float32 a)
273: {
274: return make_float32(float32_val(a) & 0x7fffffff);
275: }
276:
277: INLINE float32 float32_chs(float32 a)
278: {
279: return make_float32(float32_val(a) ^ 0x80000000);
280: }
281:
282: #define float32_zero make_float32(0)
283:
284:
285:
286:
287: int float64_to_int32( float64 STATUS_PARAM );
288: int float64_to_int32_round_to_zero( float64 STATUS_PARAM );
289: unsigned int float64_to_uint32( float64 STATUS_PARAM );
290: unsigned int float64_to_uint32_round_to_zero( float64 STATUS_PARAM );
291: int64_t float64_to_int64( float64 STATUS_PARAM );
292: int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM );
293: uint64_t float64_to_uint64 (float64 a STATUS_PARAM);
294: uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM);
295: float32 float64_to_float32( float64 STATUS_PARAM );
296: #ifdef FLOATX80
297: floatx80 float64_to_floatx80( float64 STATUS_PARAM );
298: #endif
299: #ifdef FLOAT128
300: float128 float64_to_float128( float64 STATUS_PARAM );
301: #endif
302:
303:
304:
305:
306: float64 float64_round_to_int( float64 STATUS_PARAM );
307: float64 float64_trunc_to_int( float64 STATUS_PARAM );
308: float64 float64_add( float64, float64 STATUS_PARAM );
309: float64 float64_sub( float64, float64 STATUS_PARAM );
310: float64 float64_mul( float64, float64 STATUS_PARAM );
311: float64 float64_div( float64, float64 STATUS_PARAM );
312: float64 float64_rem( float64, float64 STATUS_PARAM );
313: float64 float64_sqrt( float64 STATUS_PARAM );
314: int float64_eq( float64, float64 STATUS_PARAM );
315: int float64_le( float64, float64 STATUS_PARAM );
316: int float64_lt( float64, float64 STATUS_PARAM );
317: int float64_eq_signaling( float64, float64 STATUS_PARAM );
318: int float64_le_quiet( float64, float64 STATUS_PARAM );
319: int float64_lt_quiet( float64, float64 STATUS_PARAM );
320: int float64_compare( float64, float64 STATUS_PARAM );
321: int float64_compare_quiet( float64, float64 STATUS_PARAM );
322: int float64_is_nan( float64 a );
323: int float64_is_signaling_nan( float64 );
324: float64 float64_scalbn( float64, int STATUS_PARAM );
325:
326: INLINE float64 float64_abs(float64 a)
327: {
328: return make_float64(float64_val(a) & 0x7fffffffffffffffLL);
329: }
330:
331: INLINE float64 float64_chs(float64 a)
332: {
333: return make_float64(float64_val(a) ^ 0x8000000000000000LL);
334: }
335:
336: #define float64_zero make_float64(0)
337:
338: #ifdef FLOATX80
339:
340:
341:
342:
343: int floatx80_to_int32( floatx80 STATUS_PARAM );
344: int floatx80_to_int32_round_to_zero( floatx80 STATUS_PARAM );
345: int64_t floatx80_to_int64( floatx80 STATUS_PARAM );
346: int64_t floatx80_to_int64_round_to_zero( floatx80 STATUS_PARAM );
347: float32 floatx80_to_float32( floatx80 STATUS_PARAM );
348: float64 floatx80_to_float64( floatx80 STATUS_PARAM );
349: #ifdef FLOAT128
350: float128 floatx80_to_float128( floatx80 STATUS_PARAM );
351: #endif
352:
353:
354:
355:
356: floatx80 floatx80_round_to_int( floatx80 STATUS_PARAM );
357: floatx80 floatx80_add( floatx80, floatx80 STATUS_PARAM );
358: floatx80 floatx80_sub( floatx80, floatx80 STATUS_PARAM );
359: floatx80 floatx80_mul( floatx80, floatx80 STATUS_PARAM );
360: floatx80 floatx80_div( floatx80, floatx80 STATUS_PARAM );
361: floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM );
362: floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
363: int floatx80_eq( floatx80, floatx80 STATUS_PARAM );
364: int floatx80_le( floatx80, floatx80 STATUS_PARAM );
365: int floatx80_lt( floatx80, floatx80 STATUS_PARAM );
366: int floatx80_eq_signaling( floatx80, floatx80 STATUS_PARAM );
367: int floatx80_le_quiet( floatx80, floatx80 STATUS_PARAM );
368: int floatx80_lt_quiet( floatx80, floatx80 STATUS_PARAM );
369: int floatx80_is_nan( floatx80 );
370: int floatx80_is_signaling_nan( floatx80 );
371: floatx80 floatx80_scalbn( floatx80, int STATUS_PARAM );
372:
373: INLINE floatx80 floatx80_abs(floatx80 a)
374: {
375: a.high &= 0x7fff;
376: return a;
377: }
378:
379: INLINE floatx80 floatx80_chs(floatx80 a)
380: {
381: a.high ^= 0x8000;
382: return a;
383: }
384:
385: #endif
386:
387: #ifdef FLOAT128
388:
389:
390:
391:
392: int float128_to_int32( float128 STATUS_PARAM );
393: int float128_to_int32_round_to_zero( float128 STATUS_PARAM );
394: int64_t float128_to_int64( float128 STATUS_PARAM );
395: int64_t float128_to_int64_round_to_zero( float128 STATUS_PARAM );
396: float32 float128_to_float32( float128 STATUS_PARAM );
397: float64 float128_to_float64( float128 STATUS_PARAM );
398: #ifdef FLOATX80
399: floatx80 float128_to_floatx80( float128 STATUS_PARAM );
400: #endif
401:
402:
403:
404:
405: float128 float128_round_to_int( float128 STATUS_PARAM );
406: float128 float128_add( float128, float128 STATUS_PARAM );
407: float128 float128_sub( float128, float128 STATUS_PARAM );
408: float128 float128_mul( float128, float128 STATUS_PARAM );
409: float128 float128_div( float128, float128 STATUS_PARAM );
410: float128 float128_rem( float128, float128 STATUS_PARAM );
411: float128 float128_sqrt( float128 STATUS_PARAM );
412: int float128_eq( float128, float128 STATUS_PARAM );
413: int float128_le( float128, float128 STATUS_PARAM );
414: int float128_lt( float128, float128 STATUS_PARAM );
415: int float128_eq_signaling( float128, float128 STATUS_PARAM );
416: int float128_le_quiet( float128, float128 STATUS_PARAM );
417: int float128_lt_quiet( float128, float128 STATUS_PARAM );
418: int float128_compare( float128, float128 STATUS_PARAM );
419: int float128_compare_quiet( float128, float128 STATUS_PARAM );
420: int float128_is_nan( float128 );
421: int float128_is_signaling_nan( float128 );
422: float128 float128_scalbn( float128, int STATUS_PARAM );
423:
424: INLINE float128 float128_abs(float128 a)
425: {
426: a.high &= 0x7fffffffffffffffLL;
427: return a;
428: }
429:
430: INLINE float128 float128_chs(float128 a)
431: {
432: a.high ^= 0x8000000000000000LL;
433: return a;
434: }
435:
436: #endif
437:
438: #else
439:
440: #include "softfloat-native.h"
441:
442: #endif
443:
444: #endif