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