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