|
|
1.1 root 1: /* Native implementation of soft float functions */
2: #include <math.h>
1.1.1.2 root 3:
4: #if (defined(_BSD) && !defined(__APPLE__)) || defined(HOST_SOLARIS)
1.1 root 5: #include <ieeefp.h>
1.1.1.2 root 6: #define fabsf(f) ((float)fabs(f))
1.1 root 7: #else
8: #include <fenv.h>
9: #endif
10:
1.1.1.2 root 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:
1.1 root 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: *----------------------------------------------------------------------------*/
1.1.1.2 root 63: #if (defined(_BSD) && !defined(__APPLE__)) || defined(HOST_SOLARIS)
1.1 root 64: enum {
65: float_round_nearest_even = FP_RN,
1.1.1.2 root 66: float_round_down = FP_RM,
67: float_round_up = FP_RP,
68: float_round_to_zero = FP_RZ
1.1 root 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);
1.1.1.3 ! root 155: INLINE int float32_eq( float32 a, float32 b STATUS_PARAM)
1.1 root 156: {
157: return a == b;
158: }
1.1.1.3 ! root 159: INLINE int float32_le( float32 a, float32 b STATUS_PARAM)
1.1 root 160: {
161: return a <= b;
162: }
1.1.1.3 ! root 163: INLINE int float32_lt( float32 a, float32 b STATUS_PARAM)
1.1 root 164: {
165: return a < b;
166: }
1.1.1.3 ! root 167: INLINE int float32_eq_signaling( float32 a, float32 b STATUS_PARAM)
1.1 root 168: {
169: return a <= b && a >= b;
170: }
1.1.1.3 ! root 171: INLINE int float32_le_quiet( float32 a, float32 b STATUS_PARAM)
1.1 root 172: {
173: return islessequal(a, b);
174: }
1.1.1.3 ! root 175: INLINE int float32_lt_quiet( float32 a, float32 b STATUS_PARAM)
1.1 root 176: {
177: return isless(a, b);
178: }
1.1.1.3 ! root 179: INLINE int float32_unordered( float32 a, float32 b STATUS_PARAM)
1.1 root 180: {
181: return isunordered(a, b);
182:
183: }
1.1.1.3 ! root 184: int float32_compare( float32, float32 STATUS_PARAM );
! 185: int float32_compare_quiet( float32, float32 STATUS_PARAM );
! 186: int float32_is_signaling_nan( float32 );
1.1 root 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 );
1.1.1.3 ! root 217: float64 float64_trunc_to_int( float64 STATUS_PARAM );
1.1 root 218: INLINE float64 float64_add( float64 a, float64 b STATUS_PARAM)
219: {
220: return a + b;
221: }
222: INLINE float64 float64_sub( float64 a, float64 b STATUS_PARAM)
223: {
224: return a - b;
225: }
226: INLINE float64 float64_mul( float64 a, float64 b STATUS_PARAM)
227: {
228: return a * b;
229: }
230: INLINE float64 float64_div( float64 a, float64 b STATUS_PARAM)
231: {
232: return a / b;
233: }
234: float64 float64_rem( float64, float64 STATUS_PARAM );
235: float64 float64_sqrt( float64 STATUS_PARAM );
1.1.1.3 ! root 236: INLINE int float64_eq( float64 a, float64 b STATUS_PARAM)
1.1 root 237: {
238: return a == b;
239: }
1.1.1.3 ! root 240: INLINE int float64_le( float64 a, float64 b STATUS_PARAM)
1.1 root 241: {
242: return a <= b;
243: }
1.1.1.3 ! root 244: INLINE int float64_lt( float64 a, float64 b STATUS_PARAM)
1.1 root 245: {
246: return a < b;
247: }
1.1.1.3 ! root 248: INLINE int float64_eq_signaling( float64 a, float64 b STATUS_PARAM)
1.1 root 249: {
250: return a <= b && a >= b;
251: }
1.1.1.3 ! root 252: INLINE int float64_le_quiet( float64 a, float64 b STATUS_PARAM)
1.1 root 253: {
254: return islessequal(a, b);
255: }
1.1.1.3 ! root 256: INLINE int float64_lt_quiet( float64 a, float64 b STATUS_PARAM)
1.1 root 257: {
258: return isless(a, b);
259:
260: }
1.1.1.3 ! root 261: INLINE int float64_unordered( float64 a, float64 b STATUS_PARAM)
1.1 root 262: {
263: return isunordered(a, b);
264:
265: }
1.1.1.3 ! root 266: int float64_compare( float64, float64 STATUS_PARAM );
! 267: int float64_compare_quiet( float64, float64 STATUS_PARAM );
! 268: int float64_is_signaling_nan( float64 );
! 269: int float64_is_nan( float64 );
1.1 root 270:
271: INLINE float64 float64_abs(float64 a)
272: {
273: return fabs(a);
274: }
275:
276: INLINE float64 float64_chs(float64 a)
277: {
278: return -a;
279: }
280:
281: #ifdef FLOATX80
282:
283: /*----------------------------------------------------------------------------
284: | Software IEC/IEEE extended double-precision conversion routines.
285: *----------------------------------------------------------------------------*/
286: int floatx80_to_int32( floatx80 STATUS_PARAM );
287: int floatx80_to_int32_round_to_zero( floatx80 STATUS_PARAM );
288: int64_t floatx80_to_int64( floatx80 STATUS_PARAM);
289: int64_t floatx80_to_int64_round_to_zero( floatx80 STATUS_PARAM);
290: float32 floatx80_to_float32( floatx80 STATUS_PARAM );
291: float64 floatx80_to_float64( floatx80 STATUS_PARAM );
292: #ifdef FLOAT128
293: float128 floatx80_to_float128( floatx80 STATUS_PARAM );
294: #endif
295:
296: /*----------------------------------------------------------------------------
297: | Software IEC/IEEE extended double-precision operations.
298: *----------------------------------------------------------------------------*/
299: floatx80 floatx80_round_to_int( floatx80 STATUS_PARAM );
300: INLINE floatx80 floatx80_add( floatx80 a, floatx80 b STATUS_PARAM)
301: {
302: return a + b;
303: }
304: INLINE floatx80 floatx80_sub( floatx80 a, floatx80 b STATUS_PARAM)
305: {
306: return a - b;
307: }
308: INLINE floatx80 floatx80_mul( floatx80 a, floatx80 b STATUS_PARAM)
309: {
310: return a * b;
311: }
312: INLINE floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM)
313: {
314: return a / b;
315: }
316: floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM );
317: floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
1.1.1.3 ! root 318: INLINE int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM)
1.1 root 319: {
320: return a == b;
321: }
1.1.1.3 ! root 322: INLINE int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM)
1.1 root 323: {
324: return a <= b;
325: }
1.1.1.3 ! root 326: INLINE int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM)
1.1 root 327: {
328: return a < b;
329: }
1.1.1.3 ! root 330: INLINE int floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM)
1.1 root 331: {
332: return a <= b && a >= b;
333: }
1.1.1.3 ! root 334: INLINE int floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM)
1.1 root 335: {
336: return islessequal(a, b);
337: }
1.1.1.3 ! root 338: INLINE int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM)
1.1 root 339: {
340: return isless(a, b);
341:
342: }
1.1.1.3 ! root 343: INLINE int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM)
1.1 root 344: {
345: return isunordered(a, b);
346:
347: }
1.1.1.3 ! root 348: int floatx80_compare( floatx80, floatx80 STATUS_PARAM );
! 349: int floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM );
! 350: int floatx80_is_signaling_nan( floatx80 );
1.1 root 351:
352: INLINE floatx80 floatx80_abs(floatx80 a)
353: {
354: return fabsl(a);
355: }
356:
357: INLINE floatx80 floatx80_chs(floatx80 a)
358: {
359: return -a;
360: }
361: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.