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 #include <ieeefp.h>
20 
21 
22 /* Test fp getround and fp setround */
23 
24 void
test_getround(void)25 test_getround (void)
26 {
27 
28   newfunc("fpgetround/fpsetround");
29   line(1);
30   if (fpsetround(FP_RN) != -1)
31     test_iok(fpgetround(), FP_RN);
32   line(2);
33   if (fpsetround(FP_RM) != -1)
34     test_iok(fpgetround(), FP_RM);
35   line(3);
36   if (fpsetround(FP_RP) != -1)
37     test_iok(fpgetround(), FP_RP);
38   line(4);
39   if (fpsetround(FP_RZ) != -1)
40     test_iok(fpgetround(), FP_RZ);
41 }
42 
43 /* And fpset/fpgetmask */
44 void
test_getmask(void)45 test_getmask (void)
46 {
47   newfunc("fpsetmask/fpgetmask");
48   line(1);
49   if (fpsetmask(FP_X_INV) != -1)
50     test_iok(fpgetmask(),FP_X_INV);
51   line(2);
52   if (fpsetmask(FP_X_DX) != -1)
53     test_iok(fpgetmask(),FP_X_DX);
54   line(3);
55   if (fpsetmask(FP_X_OFL ) != -1)
56     test_iok(fpgetmask(),FP_X_OFL);
57   line(4);
58   if (fpsetmask(FP_X_UFL) != -1)
59     test_iok(fpgetmask(),FP_X_UFL);
60   line(5);
61   if (fpsetmask(FP_X_IMP) != -1)
62     test_iok(fpgetmask(),FP_X_IMP);
63 }
64 
65 void
test_getsticky(void)66 test_getsticky (void)
67 {
68   newfunc("fpsetsticky/fpgetsticky");
69   line(1);
70   if (fpsetsticky(FP_X_INV) != -1)
71     test_iok(fpgetsticky(),FP_X_INV);
72   line(2);
73   if (fpsetsticky(FP_X_DX) != -1)
74     test_iok(fpgetsticky(),FP_X_DX);
75   line(3);
76   if (fpsetsticky(FP_X_OFL ) != -1)
77     test_iok(fpgetsticky(),FP_X_OFL);
78   line(4);
79   if (fpsetsticky(FP_X_UFL) != -1)
80     test_iok(fpgetsticky(),FP_X_UFL);
81   line(5);
82   if (fpsetsticky(FP_X_IMP) != -1)
83     test_iok(fpgetsticky(),FP_X_IMP);
84 }
85 
86 void
test_getroundtoi(void)87 test_getroundtoi (void)
88 {
89   newfunc("fpsetroundtoi/fpgetroundtoi");
90   line(1);
91   if (fpsetroundtoi(FP_RDI_TOZ) != -1)
92     test_iok(fpgetroundtoi(),FP_RDI_TOZ);
93 
94   line(2);
95   if (fpsetroundtoi(FP_RDI_RD) != -1)
96     test_iok(fpgetroundtoi(),FP_RDI_RD);
97 
98 }
99 
100 double
dnumber(int msw,int lsw)101  dnumber (int msw,
102 	int lsw)
103 {
104 
105   __ieee_double_shape_type v;
106   v.parts.lsw = lsw;
107   v.parts.msw = msw;
108   return v.value;
109 }
110 
111   /* Lets see if changing the rounding alters the arithmetic.
112      Test by creating numbers which will have to be rounded when
113      added, and seeing what happens to them */
114  /* Keep them out here to stop  the compiler from folding the results */
115 double n;
116 double m;
117 double add_rounded_up;
118 double add_rounded_down;
119 double sub_rounded_down ;
120 double sub_rounded_up ;
121   double r1,r2,r3,r4;
122 void
test_round(void)123 test_round (void)
124 {
125   n =                dnumber(0x40000000, 0x00000008); /* near 2 */
126   m =                dnumber(0x40400000, 0x00000003); /* near 3.4 */
127 
128   add_rounded_up   = dnumber(0x40410000, 0x00000004); /* For RN, RP */
129   add_rounded_down = dnumber(0x40410000, 0x00000003); /* For RM, RZ */
130   sub_rounded_down = dnumber(0xc0410000, 0x00000004); /* for RN, RM */
131   sub_rounded_up   = dnumber(0xc0410000, 0x00000003); /* for RP, RZ */
132 
133   newfunc("fpsetround");
134 
135   line(1);
136 
137   if (fpsetround(FP_RN) != -1) {
138     r1 = n + m;
139     test_mok(r1, add_rounded_up, 64);
140   }
141 
142   line(2);
143   if (fpsetround(FP_RM) != -1) {
144     r2 = n + m;
145     test_mok(r2, add_rounded_down, 64);
146   }
147 
148   line(3);
149   if (fpsetround(FP_RP) != -1) {
150     r3 = n + m;
151     test_mok(r3,add_rounded_up, 64);
152   }
153 
154   line(4);
155   if (fpsetround(FP_RZ) != -1) {
156     r4 = n + m;
157     test_mok(r4,add_rounded_down,64);
158   }
159 
160 
161   line(5);
162   if (fpsetround(FP_RN) != -1) {
163     r1 = - n - m;
164     test_mok(r1,sub_rounded_down,64);
165   }
166 
167   line(6);
168   if (fpsetround(FP_RM) != -1) {
169     r2 = - n - m;
170     test_mok(r2,sub_rounded_down,64);
171   }
172 
173 
174   line(7);
175   if (fpsetround(FP_RP) != -1) {
176     r3 = - n - m;
177     test_mok(r3,sub_rounded_up,64);
178   }
179 
180   line(8);
181   if (fpsetround(FP_RZ) != -1) {
182     r4 = - n - m;
183     test_mok(r4,sub_rounded_up,64);
184   }
185 }
186 
187 
188 void
test_ieee(void)189 test_ieee (void)
190 {
191   fp_rnd old = fpgetround();
192   test_getround();
193   test_getmask();
194   test_getsticky();
195   test_getroundtoi();
196 
197   test_round();
198   fpsetround(old);
199 
200 
201 }
202 
203 
204