xref: /netbsd-src/regress/lib/libc/ieeefp/testfloat/systfloat.c (revision 23c8222edbfb0f0932d88a8351d3a0cf817dfb9e)
1 /*	$NetBSD: systfloat.c,v 1.7 2004/04/15 19:01:57 matt Exp $	*/
2 
3 /* This is a derivative work. */
4 
5 /*-
6  * Copyright (c) 2001 The NetBSD Foundation, Inc.
7  * All rights reserved.
8  *
9  * This code is derived from software contributed to The NetBSD Foundation
10  * by Ross Harvey.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
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.
20  * 3. All advertising materials mentioning features or use of this software
21  *    must display the following acknowledgement:
22  *        This product includes software developed by the NetBSD
23  *        Foundation, Inc. and its contributors.
24  * 4. Neither the name of The NetBSD Foundation nor the names of its
25  *    contributors may be used to endorse or promote products derived
26  *    from this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  */
40 
41 /*
42 ===============================================================================
43 
44 This C source file is part of TestFloat, Release 2a, a package of programs
45 for testing the correctness of floating-point arithmetic complying to the
46 IEC/IEEE Standard for Floating-Point.
47 
48 Written by John R. Hauser.  More information is available through the Web
49 page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
50 
51 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
52 has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
53 TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
54 PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
55 AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
56 
57 Derivative works are acceptable, even for commercial purposes, so long as
58 (1) they include prominent notice that the work is derivative, and (2) they
59 include prominent notice akin to these four paragraphs for those parts of
60 this code that are retained.
61 
62 ===============================================================================
63 */
64 
65 #include <sys/cdefs.h>
66 #ifndef __lint
67 __RCSID("$NetBSD: systfloat.c,v 1.7 2004/04/15 19:01:57 matt Exp $");
68 #endif
69 
70 #include <math.h>
71 #include <ieeefp.h>
72 #include "milieu.h"
73 #include "softfloat.h"
74 #include "systfloat.h"
75 #include "systflags.h"
76 #include "systmodes.h"
77 
78 typedef union {
79     float32 f32;
80     float f;
81 } union32;
82 typedef union {
83     float64 f64;
84     double d;
85 } union64;
86 #if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
87 typedef union {
88     floatx80 fx80;
89     long double ld;
90 } unionx80;
91 #endif
92 #if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
93 typedef union {
94     float128 f128;
95     long double ld;
96 } union128;
97 #endif
98 
99 fp_except
100 syst_float_flags_clear(void)
101 {
102     return fpsetsticky(0)
103 	& (FP_X_IMP | FP_X_UFL | FP_X_OFL | FP_X_DZ | FP_X_INV);
104 }
105 
106 void
107 syst_float_set_rounding_mode(fp_rnd direction)
108 {
109     fpsetround(direction);
110     fpsetmask(0);
111 }
112 
113 float32 syst_int32_to_float32( int32 a )
114 {
115     const union32 uz = { .f = a };
116 
117     return uz.f32;
118 
119 }
120 
121 float64 syst_int32_to_float64( int32 a )
122 {
123     const union64 uz = { .d = a };
124 
125     return uz.f64;
126 
127 }
128 
129 #if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
130 
131 floatx80 syst_int32_to_floatx80( int32 a )
132 {
133     const unionx80 uz = { .ld = a };
134 
135     return uz.fx80;
136 
137 }
138 
139 #endif
140 
141 #if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
142 
143 float128 syst_int32_to_float128( int32 a )
144 {
145     const union128 uz = { .ld = a };
146 
147     return uz.f128;
148 
149 }
150 
151 #endif
152 
153 #ifdef BITS64
154 
155 float32 syst_int64_to_float32( int64 a )
156 {
157     const union32 uz = { .f = a };
158 
159     return uz.f32;
160 }
161 
162 float64 syst_int64_to_float64( int64 a )
163 {
164     const union64 uz = { .d = a };
165 
166     return uz.f64;
167 }
168 
169 #if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
170 
171 floatx80 syst_int64_to_floatx80( int64 a )
172 {
173     const unionx80 uz = { .ld = a };
174 
175     return uz.fx80;
176 }
177 
178 #endif
179 
180 #if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
181 
182 float128 syst_int64_to_float128( int64 a )
183 {
184     const union128 uz = { .ld = a };
185 
186     return uz.f128;
187 }
188 
189 #endif
190 
191 #endif
192 
193 int32 syst_float32_to_int32_round_to_zero( float32 a )
194 {
195     const union32 uz = { .f32 = a };
196 
197     return uz.f;
198 
199 }
200 
201 #ifdef BITS64
202 
203 int64 syst_float32_to_int64_round_to_zero( float32 a )
204 {
205     const union32 uz = { .f32 = a };
206 
207     return uz.f;
208 }
209 
210 #endif
211 
212 float64 syst_float32_to_float64( float32 a )
213 {
214     const union32 ua = { .f32 = a };
215     union64 uz;
216 
217     uz.d = ua.f;
218     return uz.f64;
219 
220 }
221 
222 #if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
223 
224 floatx80 syst_float32_to_floatx80( float32 a )
225 {
226     const union32 ua = { .f32 = a };
227     unionx80 uz;
228 
229     uz.ld = ua.f;
230     return uz.fx80;
231 }
232 
233 #endif
234 
235 #if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
236 
237 float128 syst_float32_to_float128( float32 a )
238 {
239     const union32 ua = { .f32 = a };
240     union128 ub;
241 
242     ub.ld = ua.f;
243     return ub.f128;
244 }
245 
246 #endif
247 
248 float32 syst_float32_add( float32 a, float32 b )
249 {
250     const union32 ua = { .f32 = a }, ub = { .f32 = b };
251     union32 uz;
252 
253     uz.f = ua.f + ub.f;
254     return uz.f32;
255 }
256 
257 float32 syst_float32_sub( float32 a, float32 b )
258 {
259     const union32 ua = { .f32 = a }, ub = { .f32 = b };
260     union32 uz;
261 
262     uz.f = ua.f - ub.f;
263     return uz.f32;
264 }
265 
266 float32 syst_float32_mul( float32 a, float32 b )
267 {
268     const union32 ua = { .f32 = a }, ub = { .f32 = b };
269     union32 uz;
270 
271     uz.f = ua.f * ub.f;
272     return uz.f32;
273 }
274 
275 float32 syst_float32_div( float32 a, float32 b )
276 {
277     const union32 ua = { .f32 = a }, ub = { .f32 = b };
278     union32 uz;
279 
280     uz.f = ua.f / ub.f;
281     return uz.f32;
282 }
283 
284 flag syst_float32_eq( float32 a, float32 b )
285 {
286     const union32 ua = { .f32 = a }, ub = { .f32 = b };
287 
288     return ua.f == ub.f;
289 }
290 
291 flag syst_float32_le( float32 a, float32 b )
292 {
293     const union32 ua = { .f32 = a }, ub = { .f32 = b };
294 
295     return ua.f <= ub.f;
296 }
297 
298 flag syst_float32_lt( float32 a, float32 b )
299 {
300     const union32 ua = { .f32 = a }, ub = { .f32 = b };
301 
302     return ua.f < ub.f;
303 }
304 
305 int32 syst_float64_to_int32_round_to_zero( float64 a )
306 {
307     const union64 uz = { .f64 = a };
308 
309     return uz.d;
310 }
311 
312 #ifdef BITS64
313 
314 int64 syst_float64_to_int64_round_to_zero( float64 a )
315 {
316     const union64 uz = { .f64 = a };
317 
318     return uz.d;
319 }
320 
321 #endif
322 
323 float32 syst_float64_to_float32( float64 a )
324 {
325     const union64 ua = { .f64 = a };
326     union32 uz;
327 
328     uz.f = ua.d;
329     return uz.f32;
330 }
331 
332 #if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
333 
334 floatx80 syst_float64_to_floatx80( float64 a )
335 {
336     const union64 ua = { .f64 = a };
337     unionx80 u;
338 
339     u.ld = ua.d;
340     return u.fx80;
341 }
342 
343 #endif
344 
345 #if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
346 
347 float128 syst_float64_to_float128( float64 a )
348 {
349     const union64 ua = { .f64 = a };
350     union128 uz;
351 
352     uz.ld = ua.d;
353     return uz.f128;
354 }
355 
356 #endif
357 
358 float64 syst_float64_add( float64 a, float64 b )
359 {
360     const union64 ua = { .f64 = a }, ub = { .f64 = b };
361     union64 uz;
362 
363     uz.d = ua.d + ub.d;
364     return uz.f64;
365 }
366 
367 float64 syst_float64_sub( float64 a, float64 b )
368 {
369     const union64 ua = { .f64 = a }, ub = { .f64 = b };
370     union64 uz;
371 
372     uz.d = ua.d - ub.d;
373     return uz.f64;
374 }
375 
376 float64 syst_float64_mul( float64 a, float64 b )
377 {
378     const union64 ua = { .f64 = a }, ub = { .f64 = b };
379     union64 uz;
380 
381     uz.d = ua.d * ub.d;
382     return uz.f64;
383 }
384 
385 float64 syst_float64_div( float64 a, float64 b )
386 {
387     const union64 ua = { .f64 = a }, ub = { .f64 = b };
388     union64 uz;
389 
390     uz.d = ua.d / ub.d;
391     return uz.f64;
392 }
393 
394 float64 syst_float64_sqrt( float64 a )
395 {
396     const union64 ua = { .f64 = a };
397     union64 uz;
398 
399     uz.d = sqrt(ua.d);
400     return uz.f64;
401 }
402 
403 flag syst_float64_eq( float64 a, float64 b )
404 {
405     const union64 ua = { .f64 = a }, ub = { .f64 = b };
406 
407     return ua.d == ub.d;
408 }
409 
410 flag syst_float64_le( float64 a, float64 b )
411 {
412     const union64 ua = { .f64 = a }, ub = { .f64 = b };
413 
414     return ua.d <= ub.d;
415 }
416 
417 flag syst_float64_lt( float64 a, float64 b )
418 {
419     const union64 ua = { .f64 = a }, ub = { .f64 = b };
420 
421     return ua.d < ub.d;
422 }
423 
424 #if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
425 
426 int32 syst_floatx80_to_int32_round_to_zero( floatx80 a )
427 {
428     const unionx80 uz = { .fx80 = a };
429 
430     return uz.ld;
431 }
432 
433 #ifdef BITS64
434 
435 int64 syst_floatx80_to_int64_round_to_zero( floatx80 a )
436 {
437     const unionx80 uz = { .fx80 = a };
438 
439     return uz.ld;
440 }
441 
442 #endif
443 
444 float32 syst_floatx80_to_float32( floatx80 a )
445 {
446     const unionx80 ua = { .fx80 = a };
447     union32 uz;
448 
449     uz.f = ua.ld;
450     return uz.f32;
451 }
452 
453 float64 syst_floatx80_to_float64( floatx80 a )
454 {
455     const unionx80 ua = { .fx80 = a };
456     union64 uz;
457 
458     uz.d = ua.ld;
459     return uz.f64;
460 }
461 
462 floatx80 syst_floatx80_add( floatx80 a, floatx80 b )
463 {
464     const unionx80 ua = { .fx80 = a }, ub = { .fx80 = b };
465     unionx80 uz;
466 
467     uz.ld = ua.ld + ub.ld;
468     return uz.fx80;
469 }
470 
471 floatx80 syst_floatx80_sub( floatx80 a, floatx80 b )
472 {
473     const unionx80 ua = { .fx80 = a }, ub = { .fx80 = b };
474     unionx80 uz;
475 
476     uz.ld = ua.ld - ub.ld;
477     return uz.fx80;
478 }
479 
480 floatx80 syst_floatx80_mul( floatx80 a, floatx80 b )
481 {
482     const unionx80 ua = { .fx80 = a }, ub = { .fx80 = b };
483     unionx80 uz;
484 
485     uz.ld = ua.ld * ub.ld;
486     return uz.fx80;
487 }
488 
489 floatx80 syst_floatx80_div( floatx80 a, floatx80 b )
490 {
491     const unionx80 ua = { .fx80 = a }, ub = { .fx80 = b };
492     unionx80 uz;
493 
494     uz.ld = ua.ld / ub.ld;
495     return uz.fx80;
496 }
497 
498 flag syst_floatx80_eq( floatx80 a, floatx80 b )
499 {
500     const unionx80 ua = { .fx80 = a }, ub = { .fx80 = b };
501 
502     return ua.ld == ub.ld;
503 }
504 
505 flag syst_floatx80_le( floatx80 a, floatx80 b )
506 {
507     const unionx80 ua = { .fx80 = a }, ub = { .fx80 = b };
508 
509     return ua.ld <= ub.ld;
510 }
511 
512 flag syst_floatx80_lt( floatx80 a, floatx80 b )
513 {
514     const unionx80 ua = { .fx80 = a }, ub = { .fx80 = b };
515 
516     return ua.ld < ub.ld;
517 }
518 
519 #endif
520 
521 #if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
522 
523 int32 syst_float128_to_int32_round_to_zero( float128 a )
524 {
525     const union128 ua = { .f128 = a };
526 
527     return ua.ld;
528 }
529 
530 #ifdef BITS64
531 
532 int64 syst_float128_to_int64_round_to_zero( float128 a )
533 {
534     const union128 ua = { .f128 = a };
535 
536     return ua.ld;
537 }
538 
539 #endif
540 
541 float32 syst_float128_to_float32( float128 a )
542 {
543     const union128 ua = { .f128 = a };
544     union32 uz;
545 
546     uz.f = ua.ld;
547     return uz.f32;
548 
549 }
550 
551 float64 syst_float128_to_float64( float128 a )
552 {
553     const union128 ua = { .f128 = a };
554     union64 uz;
555 
556     uz.d = ua.ld;
557     return uz.f64;
558 }
559 
560 float128 syst_float128_add( float128 a, float128 b )
561 {
562     const union128 ua = { .f128 = a }, ub = { .f128 = b };
563     union128 uz;
564 
565     uz.ld = ua.ld + ub.ld;
566     return uz.f128;
567 
568 }
569 
570 float128 syst_float128_sub( float128 a, float128 b )
571 {
572     const union128 ua = { .f128 = a }, ub = { .f128 = b };
573     union128 uz;
574 
575     uz.ld = ua.ld - ub.ld;
576     return uz.f128;
577 }
578 
579 float128 syst_float128_mul( float128 a, float128 b )
580 {
581     const union128 ua = { .f128 = a }, ub = { .f128 = b };
582     union128 uz;
583 
584     uz.ld = ua.ld * ub.ld;
585     return uz.f128;
586 }
587 
588 float128 syst_float128_div( float128 a, float128 b )
589 {
590     const union128 ua = { .f128 = a }, ub = { .f128 = b };
591     union128 uz;
592 
593     uz.ld = ua.ld / ub.ld;
594     return uz.f128;
595 }
596 
597 flag syst_float128_eq( float128 a, float128 b )
598 {
599     const union128 ua = { .f128 = a }, ub = { .f128 = b };
600 
601     return ua.ld == ub.ld;
602 }
603 
604 flag syst_float128_le( float128 a, float128 b )
605 {
606     const union128 ua = { .f128 = a }, ub = { .f128 = b };
607 
608     return ua.ld <= ub.ld;
609 }
610 
611 flag syst_float128_lt( float128 a, float128 b )
612 {
613     const union128 ua = { .f128 = a }, ub = { .f128 = b };
614 
615     return ua.ld < ub.ld;
616 }
617 
618 #endif
619