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 #include <stdlib.h>
18 #include <signal.h>
19 #include  "test.h"
20 #include <math.h>
21 #include <string.h>
22 #include <stdint.h>
23 #include <malloc.h>
24 int verbose;
25 static int count;
26 int inacc;
27 
28 int redo = 0;
29 extern int calc;
30 
31 #ifdef MALLOC_DEBUG
32 extern char **environ;
33 extern int _malloc_test_fail;
34 #endif
35 
36 int
main(int ac,char ** av)37 main (int ac,
38       char **av)
39 {
40 #ifdef MALLOC_DEBUG
41   environ = en;
42 #endif
43   int i;
44   int math2 = 1;
45   int string= 1;
46   int is = 1;
47   int math= 1;
48   int cvt = 1;
49 #ifdef _HAVE_IEEEFP_FUNCS
50   int ieee= 1;
51 #endif
52   int vector=0;
53   for (i = 1; i < ac; i++)
54   {
55     if (strcmp(av[i],"-v")==0)
56      verbose ++;
57     if (strcmp(av[i],"-nomath2") == 0)
58      math2 = 0;
59     if (strcmp(av[i],"-nostrin") == 0)
60      string= 0;
61     if (strcmp(av[i],"-nois") == 0)
62      is = 0;
63     if (strcmp(av[i],"-nomath") == 0)
64      math= 0;
65     if (strcmp(av[i],"-nocvt") == 0)
66      cvt = 0;
67 #ifdef _HAVE_IEEEFP_FUNCS
68     if (strcmp(av[i],"-noiee") == 0)
69      ieee= 0;
70 #endif
71     if (strcmp(av[i],"-generate") == 0) {
72      vector = 1;
73      calc = 1;
74     }
75   }
76   if (cvt)
77    test_cvt();
78 
79   if (math2)
80    test_math2();
81   if (string)
82    test_string();
83   if (math)
84    test_math(vector);
85   if (is)
86    test_is();
87 #ifdef _HAVE_IEEEFP_FUNCS
88   if (ieee)
89    test_ieee();
90 #endif
91   printf("Tested %d functions, %d errors detected\n", count, inacc);
92   exit(inacc != 0);
93 }
94 
95 static const char *iname = "foo";
newfunc(const char * string)96 void newfunc (const char *string)
97 {
98   if (strcmp(iname, string))
99   {
100 #ifdef MALLOC_DEBUG
101     char *memcheck = getenv("CHECK_NAME");
102     if (memcheck && !strcmp(string, memcheck))
103       _malloc_test_fail = atoi(getenv("CHECK_COUNT"));
104     if (memcheck && !strcmp(iname, memcheck)) {
105       if (_malloc_test_fail) {
106 	printf("malloc test fail remain %d\n", _malloc_test_fail);
107 	_malloc_test_fail = 0;
108       }
109     }
110 #endif
111     printf("testing %s\n", string);
112     fflush(stdout);
113     iname = string;
114   }
115 
116 }
117 
118 
119 static int theline;
120 
line(int li)121 void line(int li)
122 {
123   if (verbose)
124   {
125     printf("  %d\n", li);
126   }
127   theline = li;
128 
129   count++;
130 }
131 
132 
133 
134 int reduce = 0;
135 
136 int strtod_vector = 0;
137 
138 int
bigger(__ieee_double_shape_type * a,__ieee_double_shape_type * b)139 bigger (__ieee_double_shape_type *a,
140 	   __ieee_double_shape_type *b)
141 {
142 
143   if (a->parts.msw > b->parts.msw)
144     {
145 
146       return 1;
147     }
148   else if (a->parts.msw == b->parts.msw)
149     {
150       if (a->parts.lsw > b->parts.lsw)
151 	{
152 	  return 1;
153 	}
154     }
155   return 0;
156 }
157 
158 int
fbigger(__ieee_float_shape_type * a,__ieee_float_shape_type * b)159 fbigger (__ieee_float_shape_type *a,
160 	   __ieee_float_shape_type *b)
161 {
162 
163   if (a->p1 > b->p1)
164     {
165       return 1;
166     }
167   return 0;
168 }
169 
170 
171 
172 /* Return the first bit different between two double numbers */
173 int
mag_of_error(double is,double shouldbe)174 mag_of_error (double is,
175        double shouldbe)
176 {
177   __ieee_double_shape_type a,b;
178   int i;
179   int a_big;
180   unsigned  int mask;
181   unsigned long int __x;
182   unsigned long int msw, lsw;
183   a.value = is;
184 
185   b.value = shouldbe;
186 
187   if (a.parts.msw == b.parts.msw
188       && a.parts.lsw== b.parts.lsw) return 64;
189 
190 
191   /* Subtract the larger from the smaller number */
192 
193   a_big = bigger(&a, &b);
194 
195   if (!a_big) {
196     int t;
197     t = a.parts.msw;
198     a.parts.msw = b.parts.msw;
199     b.parts.msw = t;
200 
201     t = a.parts.lsw;
202     a.parts.lsw = b.parts.lsw;
203     b.parts.lsw = t;
204   }
205 
206 
207 
208   __x = (a.parts.lsw) - (b.parts.lsw);
209   msw = (a.parts.msw) - (b.parts.msw) - (__x > (a.parts.lsw));
210   lsw = __x;
211 
212 
213 
214 
215   /* Find out which bit the difference is in */
216   mask = 0x80000000;
217   for (i = 0; i < 32; i++)
218   {
219     if (((msw) & mask)!=0) return i;
220     mask >>=1;
221   }
222 
223   mask = 0x80000000;
224   for (i = 0; i < 32; i++)
225   {
226 
227     if (((lsw) & mask)!=0) return i+32;
228     mask >>=1;
229   }
230 
231   return 64;
232 
233 }
234 
235 /* Return the first bit different between two double numbers */
236 int
fmag_of_error(float is,float shouldbe)237 fmag_of_error (float is,
238        float shouldbe)
239 {
240   __ieee_float_shape_type a,b;
241   int i;
242   int a_big;
243   unsigned  int mask;
244   uint32_t sw;
245   a.value = is;
246 
247   b.value = shouldbe;
248 
249   if (a.p1 == b.p1) return 32;
250 
251   /* Subtract the larger from the smaller number */
252 
253   a_big = fbigger(&a, &b);
254 
255   if (!a_big) {
256     uint32_t t;
257     t = a.p1;
258     a.p1 = b.p1;
259     b.p1 = t;
260   }
261 
262   sw = (a.p1) - (b.p1);
263 
264   mask = 0x80000000;
265   for (i = 0; i < 32; i++)
266   {
267 	  if (((sw) & mask)!=0) return i;
268 	  mask >>=1;
269   }
270   return 32;
271 }
272 
273  int ok_mag;
274 
275 
276 
277 void
test_sok(char * is,char * shouldbe)278 test_sok (char *is,
279        char *shouldbe)
280 {
281   if (strcmp(is,shouldbe))
282     {
283     printf("%s:%d, inacurate answer: (%s should be %s)\n",
284 	   iname,
285 	   theline,
286 	   is, shouldbe);
287     inacc++;
288   }
289 }
290 void
test_iok(int is,int shouldbe)291 test_iok (int is,
292        int shouldbe)
293 {
294   if (is != shouldbe){
295     printf("%s:%d, inacurate answer: (%08x should be %08x)\n",
296 	   iname,
297 	   theline,
298 	   is, shouldbe);
299     inacc++;
300   }
301 }
302 
303 
304 /* Compare counted strings upto a certain length - useful to test single
305    prec float conversions against double results
306 */
307 void
test_scok(char * is,char * shouldbe,int count)308 test_scok (char *is,
309        char *shouldbe,
310        int count)
311 {
312   if (strncmp(is,shouldbe, count))
313     {
314     printf("%s:%d, inacurate answer: (%s should be %s)\n",
315 	   iname,
316 	   theline,
317 	   is, shouldbe);
318     inacc++;
319   }
320 }
321 
322 /* Compare counted strings upto a certain length, allowing two forms - useful to test single
323    prec float conversions against double results
324 */
325 void
test_scok2(char * is,char * maybe1,char * maybe2,int count)326 test_scok2 (char *is,
327        char *maybe1,
328        char *maybe2,
329        int count)
330 {
331   if (strncmp(is,maybe1, count) && (maybe2 == NULL || strncmp(is,maybe2,count)))
332     {
333     printf("%s:%d, inacurate answer: (%s may be %s or %s)\n",
334 	   iname,
335 	   theline,
336 	   is, maybe1, maybe2 ? maybe2 : "(nothing)");
337     inacc++;
338   }
339 }
340 
341 void
test_eok(int is,int shouldbe)342 test_eok (int is,
343        int shouldbe)
344 {
345   if (is != shouldbe){
346     printf("%s:%d, bad errno answer: (%d should be %d)\n",
347 	   iname,
348 	   theline,
349 	   is, shouldbe);
350     inacc++;
351   }
352 }
353 
354 void
test_mok(double value,double shouldbe,int okmag)355 test_mok (double value,
356        double shouldbe,
357        int okmag)
358 {
359   __ieee_double_shape_type a,b;
360   int mag = mag_of_error(value, shouldbe);
361   if (mag == 0)
362   {
363     /* error in the first bit is ok if the numbers are both 0 */
364     if (value == 0.0 && shouldbe == 0.0)
365      return;
366 
367   }
368   a.value = shouldbe;
369   b.value = value;
370 
371   if (mag < okmag)
372   {
373     printf("%s:%d, wrong answer: bit %d ",
374 	   iname,
375 	   theline,
376 	   mag);
377      printf("%08lx%08lx %08lx%08lx) ",
378 	    (unsigned long) a.parts.msw,	     (unsigned long) a.parts.lsw,
379 	    (unsigned long) b.parts.msw,	     (unsigned long) b.parts.lsw);
380     printf("(%g %g)\n",   a.value, b.value);
381     inacc++;
382   }
383 }
384 
385 void
test_mfok(float value,float shouldbe,int okmag)386 test_mfok (float value,
387 	   float shouldbe,
388 	   int okmag)
389 {
390   __ieee_float_shape_type a,b;
391   int mag = fmag_of_error(value, shouldbe);
392   if (mag == 0)
393   {
394     /* error in the first bit is ok if the numbers are both 0 */
395     if (value == 0.0f && shouldbe == 0.0f)
396      return;
397 
398   }
399   a.value = shouldbe;
400   b.value = value;
401 
402   if (mag < okmag)
403   {
404     printf("%s:%d, wrong answer: bit %d ",
405 	   iname,
406 	   theline,
407 	   mag);
408      printf("%08lx %08lx) ",
409 	    (unsigned long) a.p1,
410 	    (unsigned long) b.p1);
411      printf("(%g %g)\n",   (double) a.value, (double) b.value);
412     inacc++;
413   }
414 }
415 
416 #ifdef __PCCNECV70__
kill()417 kill() {}
getpid()418 getpid() {}
419 #endif
420 
bt(void)421 void bt(void){
422 
423   double f1,f2;
424   f1 = 0.0;
425   f2 = 0.0/f1;
426   printf("(%g)\n", f2);
427 
428 }
429