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