1112158Sdas/****************************************************************
2112158SdasCopyright (C) 1997, 1998 Lucent Technologies
3112158SdasAll Rights Reserved
4112158Sdas
5112158SdasPermission to use, copy, modify, and distribute this software and
6112158Sdasits documentation for any purpose and without fee is hereby
7112158Sdasgranted, provided that the above copyright notice appear in all
8112158Sdascopies and that both that the copyright notice and this
9112158Sdaspermission notice and warranty disclaimer appear in supporting
10112158Sdasdocumentation, and that the name of Lucent or any of its entities
11112158Sdasnot be used in advertising or publicity pertaining to
12112158Sdasdistribution of the software without specific, written prior
13112158Sdaspermission.
14112158Sdas
15112158SdasLUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16112158SdasINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
17112158SdasIN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
18112158SdasSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19112158SdasWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
20112158SdasIN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
21112158SdasARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
22112158SdasTHIS SOFTWARE.
23112158Sdas****************************************************************/
24112158Sdas
25112158Sdas/* Try to deduce arith.h from arithmetic properties. */
26112158Sdas
27112158Sdas#include <stdio.h>
28112158Sdas
29112158Sdas static int dalign;
30112158Sdas typedef struct
31112158SdasAkind {
32112158Sdas	char *name;
33112158Sdas	int   kind;
34112158Sdas	} Akind;
35112158Sdas
36112158Sdas static Akind
37112158SdasIEEE_8087	= { "IEEE_8087", 1 },
38112158SdasIEEE_MC68k	= { "IEEE_MC68k", 2 },
39112158SdasIBM		= { "IBM", 3 },
40112158SdasVAX		= { "VAX", 4 },
41112158SdasCRAY		= { "CRAY", 5};
42112158Sdas
43112158Sdas static Akind *
44112158SdasLcheck()
45112158Sdas{
46112158Sdas	union {
47112158Sdas		double d;
48112158Sdas		long L[2];
49112158Sdas		} u;
50112158Sdas	struct {
51112158Sdas		double d;
52112158Sdas		long L;
53112158Sdas		} x[2];
54112158Sdas
55112158Sdas	if (sizeof(x) > 2*(sizeof(double) + sizeof(long)))
56112158Sdas		dalign = 1;
57112158Sdas	u.L[0] = u.L[1] = 0;
58112158Sdas	u.d = 1e13;
59112158Sdas	if (u.L[0] == 1117925532 && u.L[1] == -448790528)
60112158Sdas		return &IEEE_MC68k;
61112158Sdas	if (u.L[1] == 1117925532 && u.L[0] == -448790528)
62112158Sdas		return &IEEE_8087;
63112158Sdas	if (u.L[0] == -2065213935 && u.L[1] == 10752)
64112158Sdas		return &VAX;
65112158Sdas	if (u.L[0] == 1267827943 && u.L[1] == 704643072)
66112158Sdas		return &IBM;
67112158Sdas	return 0;
68112158Sdas	}
69112158Sdas
70112158Sdas static Akind *
71112158Sdasicheck()
72112158Sdas{
73112158Sdas	union {
74112158Sdas		double d;
75112158Sdas		int L[2];
76112158Sdas		} u;
77112158Sdas	struct {
78112158Sdas		double d;
79112158Sdas		int L;
80112158Sdas		} x[2];
81112158Sdas
82112158Sdas	if (sizeof(x) > 2*(sizeof(double) + sizeof(int)))
83112158Sdas		dalign = 1;
84112158Sdas	u.L[0] = u.L[1] = 0;
85112158Sdas	u.d = 1e13;
86112158Sdas	if (u.L[0] == 1117925532 && u.L[1] == -448790528)
87112158Sdas		return &IEEE_MC68k;
88112158Sdas	if (u.L[1] == 1117925532 && u.L[0] == -448790528)
89112158Sdas		return &IEEE_8087;
90112158Sdas	if (u.L[0] == -2065213935 && u.L[1] == 10752)
91112158Sdas		return &VAX;
92112158Sdas	if (u.L[0] == 1267827943 && u.L[1] == 704643072)
93112158Sdas		return &IBM;
94112158Sdas	return 0;
95112158Sdas	}
96112158Sdas
97112158Sdaschar *emptyfmt = "";	/* avoid possible warning message with printf("") */
98112158Sdas
99112158Sdas static Akind *
100112158Sdasccheck()
101112158Sdas{
102112158Sdas	union {
103112158Sdas		double d;
104112158Sdas		long L;
105112158Sdas		} u;
106112158Sdas	long Cray1;
107112158Sdas
108112158Sdas	/* Cray1 = 4617762693716115456 -- without overflow on non-Crays */
109112158Sdas	Cray1 = printf(emptyfmt) < 0 ? 0 : 4617762;
110112158Sdas	if (printf(emptyfmt, Cray1) >= 0)
111112158Sdas		Cray1 = 1000000*Cray1 + 693716;
112112158Sdas	if (printf(emptyfmt, Cray1) >= 0)
113112158Sdas		Cray1 = 1000000*Cray1 + 115456;
114112158Sdas	u.d = 1e13;
115112158Sdas	if (u.L == Cray1)
116112158Sdas		return &CRAY;
117112158Sdas	return 0;
118112158Sdas	}
119112158Sdas
120112158Sdas static int
121112158Sdasfzcheck()
122112158Sdas{
123112158Sdas	double a, b;
124112158Sdas	int i;
125112158Sdas
126112158Sdas	a = 1.;
127112158Sdas	b = .1;
128112158Sdas	for(i = 155;; b *= b, i >>= 1) {
129112158Sdas		if (i & 1) {
130112158Sdas			a *= b;
131112158Sdas			if (i == 1)
132112158Sdas				break;
133112158Sdas			}
134112158Sdas		}
135112158Sdas	b = a * a;
136112158Sdas	return b == 0.;
137112158Sdas	}
138112158Sdas
139165743Sdas int
140112158Sdasmain()
141112158Sdas{
142112158Sdas	Akind *a = 0;
143112158Sdas	int Ldef = 0;
144112158Sdas	FILE *f;
145112158Sdas
146112158Sdas#ifdef WRITE_ARITH_H	/* for Symantec's buggy "make" */
147112158Sdas	f = fopen("arith.h", "w");
148112158Sdas	if (!f) {
149112158Sdas		printf("Cannot open arith.h\n");
150112158Sdas		return 1;
151112158Sdas		}
152112158Sdas#else
153112158Sdas	f = stdout;
154112158Sdas#endif
155112158Sdas
156112158Sdas	if (sizeof(double) == 2*sizeof(long))
157112158Sdas		a = Lcheck();
158112158Sdas	else if (sizeof(double) == 2*sizeof(int)) {
159112158Sdas		Ldef = 1;
160112158Sdas		a = icheck();
161112158Sdas		}
162112158Sdas	else if (sizeof(double) == sizeof(long))
163112158Sdas		a = ccheck();
164112158Sdas	if (a) {
165112158Sdas		fprintf(f, "#define %s\n#define Arith_Kind_ASL %d\n",
166112158Sdas			a->name, a->kind);
167112158Sdas		if (Ldef)
168112158Sdas			fprintf(f, "#define Long int\n#define Intcast (int)(long)\n");
169112158Sdas		if (dalign)
170112158Sdas			fprintf(f, "#define Double_Align\n");
171112158Sdas		if (sizeof(char*) == 8)
172112158Sdas			fprintf(f, "#define X64_bit_pointers\n");
173112158Sdas#ifndef NO_LONG_LONG
174112158Sdas		if (sizeof(long long) < 8)
175112158Sdas#endif
176112158Sdas			fprintf(f, "#define NO_LONG_LONG\n");
177112158Sdas		if (a->kind <= 2 && fzcheck())
178112158Sdas			fprintf(f, "#define Sudden_Underflow\n");
179112158Sdas		return 0;
180112158Sdas		}
181112158Sdas	fprintf(f, "/* Unknown arithmetic */\n");
182112158Sdas	return 1;
183112158Sdas	}
184