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