xref: /netbsd-src/lib/libc/gdtoa/arithchk.c (revision 3d365e7447a96c9a8d60ba350e9a77732c5aede8)
1*3d365e74Schristos /* $NetBSD: arithchk.c,v 1.4 2012/06/24 15:26:03 christos Exp $ */
27684d5e0Skleink 
37684d5e0Skleink /****************************************************************
47684d5e0Skleink Copyright (C) 1997, 1998 Lucent Technologies
57684d5e0Skleink All Rights Reserved
67684d5e0Skleink 
77684d5e0Skleink Permission to use, copy, modify, and distribute this software and
87684d5e0Skleink its documentation for any purpose and without fee is hereby
97684d5e0Skleink granted, provided that the above copyright notice appear in all
107684d5e0Skleink copies and that both that the copyright notice and this
117684d5e0Skleink permission notice and warranty disclaimer appear in supporting
127684d5e0Skleink documentation, and that the name of Lucent or any of its entities
137684d5e0Skleink not be used in advertising or publicity pertaining to
147684d5e0Skleink distribution of the software without specific, written prior
157684d5e0Skleink permission.
167684d5e0Skleink 
177684d5e0Skleink LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
187684d5e0Skleink INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
197684d5e0Skleink IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
207684d5e0Skleink SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
217684d5e0Skleink WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
227684d5e0Skleink IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
237684d5e0Skleink ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
247684d5e0Skleink THIS SOFTWARE.
257684d5e0Skleink ****************************************************************/
267684d5e0Skleink 
277684d5e0Skleink /* Try to deduce arith.h from arithmetic properties. */
287684d5e0Skleink 
297684d5e0Skleink #include <stdio.h>
307684d5e0Skleink 
317684d5e0Skleink static int dalign;
327684d5e0Skleink typedef struct
337684d5e0Skleink Akind {
347684d5e0Skleink 	char *name;
357684d5e0Skleink 	int   kind;
367684d5e0Skleink 	} Akind;
377684d5e0Skleink 
387684d5e0Skleink static Akind
39ac898a26Skleink IEEE_LITTLE_ENDIAN	= { "IEEE_LITTLE_ENDIAN", 1 },
40ac898a26Skleink IEEE_BIG_ENDIAN		= { "IEEE_BIG_ENDIAN", 2 },
417684d5e0Skleink IBM			= { "IBM", 3 },
427684d5e0Skleink VAX			= { "VAX", 4 },
437684d5e0Skleink CRAY			= { "CRAY", 5};
447684d5e0Skleink 
457684d5e0Skleink static Akind *
Lcheck(void)46*3d365e74Schristos Lcheck(void)
477684d5e0Skleink {
487684d5e0Skleink 	union {
497684d5e0Skleink 		double d;
507684d5e0Skleink 		long L[2];
517684d5e0Skleink 		} u;
527684d5e0Skleink 	struct {
537684d5e0Skleink 		double d;
547684d5e0Skleink 		long L;
557684d5e0Skleink 		} x[2];
567684d5e0Skleink 
577684d5e0Skleink 	if (sizeof(x) > 2*(sizeof(double) + sizeof(long)))
587684d5e0Skleink 		dalign = 1;
597684d5e0Skleink 	u.L[0] = u.L[1] = 0;
607684d5e0Skleink 	u.d = 1e13;
617684d5e0Skleink 	if (u.L[0] == 1117925532 && u.L[1] == -448790528)
62ac898a26Skleink 		return &IEEE_BIG_ENDIAN;
637684d5e0Skleink 	if (u.L[1] == 1117925532 && u.L[0] == -448790528)
64ac898a26Skleink 		return &IEEE_LITTLE_ENDIAN;
657684d5e0Skleink 	if (u.L[0] == -2065213935 && u.L[1] == 10752)
667684d5e0Skleink 		return &VAX;
677684d5e0Skleink 	if (u.L[0] == 1267827943 && u.L[1] == 704643072)
687684d5e0Skleink 		return &IBM;
697684d5e0Skleink 	return 0;
707684d5e0Skleink 	}
717684d5e0Skleink 
727684d5e0Skleink static Akind *
icheck(void)73*3d365e74Schristos icheck(void)
747684d5e0Skleink {
757684d5e0Skleink 	union {
767684d5e0Skleink 		double d;
777684d5e0Skleink 		int L[2];
787684d5e0Skleink 		} u;
797684d5e0Skleink 	struct {
807684d5e0Skleink 		double d;
817684d5e0Skleink 		int L;
827684d5e0Skleink 		} x[2];
837684d5e0Skleink 
847684d5e0Skleink 	if (sizeof(x) > 2*(sizeof(double) + sizeof(int)))
857684d5e0Skleink 		dalign = 1;
867684d5e0Skleink 	u.L[0] = u.L[1] = 0;
877684d5e0Skleink 	u.d = 1e13;
887684d5e0Skleink 	if (u.L[0] == 1117925532 && u.L[1] == -448790528)
89ac898a26Skleink 		return &IEEE_BIG_ENDIAN;
907684d5e0Skleink 	if (u.L[1] == 1117925532 && u.L[0] == -448790528)
91ac898a26Skleink 		return &IEEE_LITTLE_ENDIAN;
927684d5e0Skleink 	if (u.L[0] == -2065213935 && u.L[1] == 10752)
937684d5e0Skleink 		return &VAX;
947684d5e0Skleink 	if (u.L[0] == 1267827943 && u.L[1] == 704643072)
957684d5e0Skleink 		return &IBM;
967684d5e0Skleink 	return 0;
977684d5e0Skleink 	}
987684d5e0Skleink 
997684d5e0Skleink char *emptyfmt = "";	/* avoid possible warning message with printf("") */
1007684d5e0Skleink 
1017684d5e0Skleink static Akind *
ccheck(void)102*3d365e74Schristos ccheck(void)
1037684d5e0Skleink {
1047684d5e0Skleink 	union {
1057684d5e0Skleink 		double d;
1067684d5e0Skleink 		long L;
1077684d5e0Skleink 		} u;
1087684d5e0Skleink 	long Cray1;
1097684d5e0Skleink 
1107684d5e0Skleink 	/* Cray1 = 4617762693716115456 -- without overflow on non-Crays */
1117684d5e0Skleink 	Cray1 = printf(emptyfmt) < 0 ? 0 : 4617762;
1127684d5e0Skleink 	if (printf(emptyfmt, Cray1) >= 0)
1137684d5e0Skleink 		Cray1 = 1000000*Cray1 + 693716;
1147684d5e0Skleink 	if (printf(emptyfmt, Cray1) >= 0)
1157684d5e0Skleink 		Cray1 = 1000000*Cray1 + 115456;
1167684d5e0Skleink 	u.d = 1e13;
1177684d5e0Skleink 	if (u.L == Cray1)
1187684d5e0Skleink 		return &CRAY;
1197684d5e0Skleink 	return 0;
1207684d5e0Skleink 	}
1217684d5e0Skleink 
1227684d5e0Skleink static int
fzcheck(void)123*3d365e74Schristos fzcheck(void)
1247684d5e0Skleink {
1257684d5e0Skleink 	double a, b;
1267684d5e0Skleink 	int i;
1277684d5e0Skleink 
1287684d5e0Skleink 	a = 1.;
1297684d5e0Skleink 	b = .1;
1307684d5e0Skleink 	for(i = 155;; b *= b, i >>= 1) {
1317684d5e0Skleink 		if (i & 1) {
1327684d5e0Skleink 			a *= b;
1337684d5e0Skleink 			if (i == 1)
1347684d5e0Skleink 				break;
1357684d5e0Skleink 			}
1367684d5e0Skleink 		}
1377684d5e0Skleink 	b = a * a;
1387684d5e0Skleink 	return b == 0.;
1397684d5e0Skleink 	}
1407684d5e0Skleink 
1417684d5e0Skleink int
main(void)142*3d365e74Schristos main(void)
1437684d5e0Skleink {
1447684d5e0Skleink 	Akind *a = 0;
1457684d5e0Skleink 	int Ldef = 0;
1467684d5e0Skleink 	FILE *f;
1477684d5e0Skleink 
1487684d5e0Skleink #ifdef WRITE_ARITH_H	/* for Symantec's buggy "make" */
1497684d5e0Skleink 	f = fopen("arith.h", "w");
1507684d5e0Skleink 	if (!f) {
1517684d5e0Skleink 		printf("Cannot open arith.h\n");
1527684d5e0Skleink 		return 1;
1537684d5e0Skleink 		}
1547684d5e0Skleink #else
1557684d5e0Skleink 	f = stdout;
1567684d5e0Skleink #endif
1577684d5e0Skleink 
1587684d5e0Skleink 	if (sizeof(double) == 2*sizeof(long))
1597684d5e0Skleink 		a = Lcheck();
1607684d5e0Skleink 	else if (sizeof(double) == 2*sizeof(int)) {
1617684d5e0Skleink 		Ldef = 1;
1627684d5e0Skleink 		a = icheck();
1637684d5e0Skleink 		}
1647684d5e0Skleink 	else if (sizeof(double) == sizeof(long))
1657684d5e0Skleink 		a = ccheck();
1667684d5e0Skleink 	if (a) {
1677684d5e0Skleink 		fprintf(f, "#define %s\n#define Arith_Kind_ASL %d\n",
1687684d5e0Skleink 			a->name, a->kind);
1697684d5e0Skleink 		if (Ldef)
1707684d5e0Skleink 			fprintf(f, "#define Long int\n#define Intcast (int)(long)\n");
1717684d5e0Skleink 		if (dalign)
1727684d5e0Skleink 			fprintf(f, "#define Double_Align\n");
1737684d5e0Skleink 		if (sizeof(char*) == 8)
1747684d5e0Skleink 			fprintf(f, "#define X64_bit_pointers\n");
1757684d5e0Skleink #ifndef NO_LONG_LONG
1767684d5e0Skleink 		if (sizeof(long long) < 8)
1777684d5e0Skleink #endif
1787684d5e0Skleink 			fprintf(f, "#define NO_LONG_LONG\n");
1797684d5e0Skleink 		if (a->kind <= 2 && fzcheck())
1807684d5e0Skleink 			fprintf(f, "#define Sudden_Underflow\n");
18115989318Swiz #ifdef WRITE_ARITH_H
18215989318Swiz 		fclose(f);
18315989318Swiz #endif
1847684d5e0Skleink 		return 0;
1857684d5e0Skleink 		}
1867684d5e0Skleink 	fprintf(f, "/* Unknown arithmetic */\n");
18715989318Swiz #ifdef WRITE_ARITH_H
18815989318Swiz 	fclose(f);
18915989318Swiz #endif
1907684d5e0Skleink 	return 1;
1917684d5e0Skleink 	}
192