1 /*
2  * Copyright (c) 1994 Cygnus Support.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * and/or other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * at Cygnus Support, Inc.  Cygnus Support, Inc. may not be used to
11  * endorse or promote products derived from this software without
12  * specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #include "test.h"
19 
20 #ifdef _HAVE_IEEEFP_FUNCS
21 #include <ieeefp.h>
22 
23 
24 /* Test fp getround and fp setround */
25 
26 static void
test_getround(void)27 test_getround (void)
28 {
29 
30   newfunc("fpgetround/fpsetround");
31   line(1);
32   if (fpsetround(FP_RN) != -1)
33     test_iok(fpgetround(), FP_RN);
34   line(2);
35   if (fpsetround(FP_RM) != -1)
36     test_iok(fpgetround(), FP_RM);
37   line(3);
38   if (fpsetround(FP_RP) != -1)
39     test_iok(fpgetround(), FP_RP);
40   line(4);
41   if (fpsetround(FP_RZ) != -1)
42     test_iok(fpgetround(), FP_RZ);
43 }
44 
45 /* And fpset/fpgetmask */
46 static void
test_getmask(void)47 test_getmask (void)
48 {
49   newfunc("fpsetmask/fpgetmask");
50   line(1);
51   if (fpsetmask(FP_X_INV) != -1)
52     test_iok(fpgetmask(),FP_X_INV);
53   line(2);
54   if (fpsetmask(FP_X_DX) != -1)
55     test_iok(fpgetmask(),FP_X_DX);
56   line(3);
57   if (fpsetmask(FP_X_OFL ) != -1)
58     test_iok(fpgetmask(),FP_X_OFL);
59   line(4);
60   if (fpsetmask(FP_X_UFL) != -1)
61     test_iok(fpgetmask(),FP_X_UFL);
62   line(5);
63   if (fpsetmask(FP_X_IMP) != -1)
64     test_iok(fpgetmask(),FP_X_IMP);
65 }
66 
67 static void
test_getsticky(void)68 test_getsticky (void)
69 {
70   newfunc("fpsetsticky/fpgetsticky");
71   line(1);
72   if (fpsetsticky(FP_X_INV) != -1)
73     test_iok(fpgetsticky(),FP_X_INV);
74   line(2);
75   if (fpsetsticky(FP_X_DX) != -1)
76     test_iok(fpgetsticky(),FP_X_DX);
77   line(3);
78   if (fpsetsticky(FP_X_OFL ) != -1)
79     test_iok(fpgetsticky(),FP_X_OFL);
80   line(4);
81   if (fpsetsticky(FP_X_UFL) != -1)
82     test_iok(fpgetsticky(),FP_X_UFL);
83   line(5);
84   if (fpsetsticky(FP_X_IMP) != -1)
85     test_iok(fpgetsticky(),FP_X_IMP);
86 }
87 
88 static void
test_getroundtoi(void)89 test_getroundtoi (void)
90 {
91   newfunc("fpsetroundtoi/fpgetroundtoi");
92   line(1);
93   if (fpsetroundtoi(FP_RDI_TOZ) != -1)
94     test_iok(fpgetroundtoi(),FP_RDI_TOZ);
95 
96   line(2);
97   if (fpsetroundtoi(FP_RDI_RD) != -1)
98     test_iok(fpgetroundtoi(),FP_RDI_RD);
99 
100 }
101 
102 static double
dnumber(int msw,int lsw)103 dnumber (int msw,
104          int lsw)
105 {
106 
107   __ieee_double_shape_type v;
108   v.parts.lsw = lsw;
109   v.parts.msw = msw;
110   return v.value;
111 }
112 
113   /* Lets see if changing the rounding alters the arithmetic.
114      Test by creating numbers which will have to be rounded when
115      added, and seeing what happens to them */
116  /* Keep them out here to stop  the compiler from folding the results */
117 double n;
118 double m;
119 double add_rounded_up;
120 double add_rounded_down;
121 double sub_rounded_down ;
122 double sub_rounded_up ;
123 double r1,r2,r3,r4;
124 
125 static void
test_round(void)126 test_round (void)
127 {
128   n =                dnumber(0x40000000, 0x00000008); /* near 2 */
129   m =                dnumber(0x40400000, 0x00000003); /* near 3.4 */
130 
131   add_rounded_up   = dnumber(0x40410000, 0x00000004); /* For RN, RP */
132   add_rounded_down = dnumber(0x40410000, 0x00000003); /* For RM, RZ */
133   sub_rounded_down = dnumber(0xc0410000, 0x00000004); /* for RN, RM */
134   sub_rounded_up   = dnumber(0xc0410000, 0x00000003); /* for RP, RZ */
135 
136   newfunc("fpsetround");
137 
138   line(1);
139 
140   if (fpsetround(FP_RN) != -1) {
141     r1 = n + m;
142     test_mok(r1, add_rounded_up, 64);
143   }
144 
145   line(2);
146   if (fpsetround(FP_RM) != -1) {
147     r2 = n + m;
148     test_mok(r2, add_rounded_down, 64);
149   }
150 
151   line(3);
152   if (fpsetround(FP_RP) != -1) {
153     r3 = n + m;
154     test_mok(r3,add_rounded_up, 64);
155   }
156 
157   line(4);
158   if (fpsetround(FP_RZ) != -1) {
159     r4 = n + m;
160     test_mok(r4,add_rounded_down,64);
161   }
162 
163 
164   line(5);
165   if (fpsetround(FP_RN) != -1) {
166     r1 = - n - m;
167     test_mok(r1,sub_rounded_down,64);
168   }
169 
170   line(6);
171   if (fpsetround(FP_RM) != -1) {
172     r2 = - n - m;
173     test_mok(r2,sub_rounded_down,64);
174   }
175 
176 
177   line(7);
178   if (fpsetround(FP_RP) != -1) {
179     r3 = - n - m;
180     test_mok(r3,sub_rounded_up,64);
181   }
182 
183   line(8);
184   if (fpsetround(FP_RZ) != -1) {
185     r4 = - n - m;
186     test_mok(r4,sub_rounded_up,64);
187   }
188 }
189 
190 #endif
191 
192 void
test_ieee(void)193 test_ieee (void)
194 {
195 #ifdef _HAVE_IEEEFP_FUNCS
196   fp_rnd old = fpgetround();
197   test_getround();
198   test_getmask();
199   test_getsticky();
200   test_getroundtoi();
201 
202   test_round();
203   fpsetround(old);
204 #endif
205 }
206 
207 
208