1 /* $NetBSD: systfloat.c,v 1.7 2004/04/15 19:01:57 matt Exp $ */
3 /* This is a derivative work. */
6 * Copyright (c) 2001 The NetBSD Foundation, Inc.
9 * This code is derived from software contributed to The NetBSD Foundation
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
35 ===============================================================================
37 This C source file is part of TestFloat, Release 2a, a package of programs
38 for testing the correctness of floating-point arithmetic complying to the
39 IEC/IEEE Standard for Floating-Point.
41 Written by John R. Hauser. More information is available through the Web
42 page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
44 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
45 has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
46 TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
47 PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
48 AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
50 Derivative works are acceptable, even for commercial purposes, so long as
51 (1) they include prominent notice that the work is derivative, and (2) they
52 include prominent notice akin to these four paragraphs for those parts of
53 this code that are retained.
55 ===============================================================================
58 #include <sys/cdefs.h>
60 __RCSID("$NetBSD: systfloat.c,v 1.7 2004/04/15 19:01:57 matt Exp $");
66 #include "softfloat.h"
67 #include "systfloat.h"
68 #include "systflags.h"
69 #include "systmodes.h"
79 #if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
85 #if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
93 syst_float_flags_clear(void)
96 & (FP_X_IMP
| FP_X_UFL
| FP_X_OFL
| FP_X_DZ
| FP_X_INV
);
100 syst_float_set_rounding_mode(fp_rnd direction
)
102 fpsetround(direction
);
106 float32
syst_int32_to_float32( int32 a
)
108 const union32 uz
= { .f
= a
};
114 float64
syst_int32_to_float64( int32 a
)
116 const union64 uz
= { .d
= a
};
122 #if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
124 floatx80
syst_int32_to_floatx80( int32 a
)
126 const unionx80 uz
= { .ld
= a
};
134 #if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
136 float128
syst_int32_to_float128( int32 a
)
138 const union128 uz
= { .ld
= a
};
148 float32
syst_int64_to_float32( int64 a
)
150 const union32 uz
= { .f
= a
};
155 float64
syst_int64_to_float64( int64 a
)
157 const union64 uz
= { .d
= a
};
162 #if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
164 floatx80
syst_int64_to_floatx80( int64 a
)
166 const unionx80 uz
= { .ld
= a
};
173 #if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
175 float128
syst_int64_to_float128( int64 a
)
177 const union128 uz
= { .ld
= a
};
186 int32
syst_float32_to_int32_round_to_zero( float32 a
)
188 const union32 uz
= { .f32
= a
};
196 int64
syst_float32_to_int64_round_to_zero( float32 a
)
198 const union32 uz
= { .f32
= a
};
205 float64
syst_float32_to_float64( float32 a
)
207 const union32 ua
= { .f32
= a
};
215 #if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
217 floatx80
syst_float32_to_floatx80( float32 a
)
219 const union32 ua
= { .f32
= a
};
228 #if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
230 float128
syst_float32_to_float128( float32 a
)
232 const union32 ua
= { .f32
= a
};
241 float32
syst_float32_add( float32 a
, float32 b
)
243 const union32 ua
= { .f32
= a
}, ub
= { .f32
= b
};
250 float32
syst_float32_sub( float32 a
, float32 b
)
252 const union32 ua
= { .f32
= a
}, ub
= { .f32
= b
};
259 float32
syst_float32_mul( float32 a
, float32 b
)
261 const union32 ua
= { .f32
= a
}, ub
= { .f32
= b
};
268 float32
syst_float32_div( float32 a
, float32 b
)
270 const union32 ua
= { .f32
= a
}, ub
= { .f32
= b
};
277 flag
syst_float32_eq( float32 a
, float32 b
)
279 const union32 ua
= { .f32
= a
}, ub
= { .f32
= b
};
284 flag
syst_float32_le( float32 a
, float32 b
)
286 const union32 ua
= { .f32
= a
}, ub
= { .f32
= b
};
291 flag
syst_float32_lt( float32 a
, float32 b
)
293 const union32 ua
= { .f32
= a
}, ub
= { .f32
= b
};
298 int32
syst_float64_to_int32_round_to_zero( float64 a
)
300 const union64 uz
= { .f64
= a
};
307 int64
syst_float64_to_int64_round_to_zero( float64 a
)
309 const union64 uz
= { .f64
= a
};
316 float32
syst_float64_to_float32( float64 a
)
318 const union64 ua
= { .f64
= a
};
325 #if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
327 floatx80
syst_float64_to_floatx80( float64 a
)
329 const union64 ua
= { .f64
= a
};
338 #if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
340 float128
syst_float64_to_float128( float64 a
)
342 const union64 ua
= { .f64
= a
};
351 float64
syst_float64_add( float64 a
, float64 b
)
353 const union64 ua
= { .f64
= a
}, ub
= { .f64
= b
};
360 float64
syst_float64_sub( float64 a
, float64 b
)
362 const union64 ua
= { .f64
= a
}, ub
= { .f64
= b
};
369 float64
syst_float64_mul( float64 a
, float64 b
)
371 const union64 ua
= { .f64
= a
}, ub
= { .f64
= b
};
378 float64
syst_float64_div( float64 a
, float64 b
)
380 const union64 ua
= { .f64
= a
}, ub
= { .f64
= b
};
387 float64
syst_float64_sqrt( float64 a
)
389 const union64 ua
= { .f64
= a
};
396 flag
syst_float64_eq( float64 a
, float64 b
)
398 const union64 ua
= { .f64
= a
}, ub
= { .f64
= b
};
403 flag
syst_float64_le( float64 a
, float64 b
)
405 const union64 ua
= { .f64
= a
}, ub
= { .f64
= b
};
410 flag
syst_float64_lt( float64 a
, float64 b
)
412 const union64 ua
= { .f64
= a
}, ub
= { .f64
= b
};
417 #if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
419 int32
syst_floatx80_to_int32_round_to_zero( floatx80 a
)
421 const unionx80 uz
= { .fx80
= a
};
428 int64
syst_floatx80_to_int64_round_to_zero( floatx80 a
)
430 const unionx80 uz
= { .fx80
= a
};
437 float32
syst_floatx80_to_float32( floatx80 a
)
439 const unionx80 ua
= { .fx80
= a
};
446 float64
syst_floatx80_to_float64( floatx80 a
)
448 const unionx80 ua
= { .fx80
= a
};
455 floatx80
syst_floatx80_add( floatx80 a
, floatx80 b
)
457 const unionx80 ua
= { .fx80
= a
}, ub
= { .fx80
= b
};
460 uz
.ld
= ua
.ld
+ ub
.ld
;
464 floatx80
syst_floatx80_sub( floatx80 a
, floatx80 b
)
466 const unionx80 ua
= { .fx80
= a
}, ub
= { .fx80
= b
};
469 uz
.ld
= ua
.ld
- ub
.ld
;
473 floatx80
syst_floatx80_mul( floatx80 a
, floatx80 b
)
475 const unionx80 ua
= { .fx80
= a
}, ub
= { .fx80
= b
};
478 uz
.ld
= ua
.ld
* ub
.ld
;
482 floatx80
syst_floatx80_div( floatx80 a
, floatx80 b
)
484 const unionx80 ua
= { .fx80
= a
}, ub
= { .fx80
= b
};
487 uz
.ld
= ua
.ld
/ ub
.ld
;
491 flag
syst_floatx80_eq( floatx80 a
, floatx80 b
)
493 const unionx80 ua
= { .fx80
= a
}, ub
= { .fx80
= b
};
495 return ua
.ld
== ub
.ld
;
498 flag
syst_floatx80_le( floatx80 a
, floatx80 b
)
500 const unionx80 ua
= { .fx80
= a
}, ub
= { .fx80
= b
};
502 return ua
.ld
<= ub
.ld
;
505 flag
syst_floatx80_lt( floatx80 a
, floatx80 b
)
507 const unionx80 ua
= { .fx80
= a
}, ub
= { .fx80
= b
};
509 return ua
.ld
< ub
.ld
;
514 #if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
516 int32
syst_float128_to_int32_round_to_zero( float128 a
)
518 const union128 ua
= { .f128
= a
};
525 int64
syst_float128_to_int64_round_to_zero( float128 a
)
527 const union128 ua
= { .f128
= a
};
534 float32
syst_float128_to_float32( float128 a
)
536 const union128 ua
= { .f128
= a
};
544 float64
syst_float128_to_float64( float128 a
)
546 const union128 ua
= { .f128
= a
};
553 float128
syst_float128_add( float128 a
, float128 b
)
555 const union128 ua
= { .f128
= a
}, ub
= { .f128
= b
};
558 uz
.ld
= ua
.ld
+ ub
.ld
;
563 float128
syst_float128_sub( float128 a
, float128 b
)
565 const union128 ua
= { .f128
= a
}, ub
= { .f128
= b
};
568 uz
.ld
= ua
.ld
- ub
.ld
;
572 float128
syst_float128_mul( float128 a
, float128 b
)
574 const union128 ua
= { .f128
= a
}, ub
= { .f128
= b
};
577 uz
.ld
= ua
.ld
* ub
.ld
;
581 float128
syst_float128_div( float128 a
, float128 b
)
583 const union128 ua
= { .f128
= a
}, ub
= { .f128
= b
};
586 uz
.ld
= ua
.ld
/ ub
.ld
;
590 flag
syst_float128_eq( float128 a
, float128 b
)
592 const union128 ua
= { .f128
= a
}, ub
= { .f128
= b
};
594 return ua
.ld
== ub
.ld
;
597 flag
syst_float128_le( float128 a
, float128 b
)
599 const union128 ua
= { .f128
= a
}, ub
= { .f128
= b
};
601 return ua
.ld
<= ub
.ld
;
604 flag
syst_float128_lt( float128 a
, float128 b
)
606 const union128 ua
= { .f128
= a
}, ub
= { .f128
= b
};
608 return ua
.ld
< ub
.ld
;