1 /****************************************************************
2 Copyright (C) 1997, 1998, 2000 Lucent Technologies
3 All Rights Reserved
4 
5 Permission to use, copy, modify, and distribute this software and
6 its documentation for any purpose and without fee is hereby
7 granted, provided that the above copyright notice appear in all
8 copies and that both that the copyright notice and this
9 permission notice and warranty disclaimer appear in supporting
10 documentation, and that the name of Lucent or any of its entities
11 not be used in advertising or publicity pertaining to
12 distribution of the software without specific, written prior
13 permission.
14 
15 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
17 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
18 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
20 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
21 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
22 THIS SOFTWARE.
23 ****************************************************************/
24 
25 /* Try to deduce arith.h from arithmetic properties. */
26 
27 #include <stdio.h>
28 #include <math.h>
29 #include <errno.h>
30 
31 #ifdef NO_FPINIT
32 #define fpinit_ASL()
33 #else
34 #ifndef KR_headers
35 extern
36 #ifdef __cplusplus
37 	"C"
38 #endif
39 	void fpinit_ASL(void);
40 #endif /*KR_headers*/
41 #endif /*NO_FPINIT*/
42 
43  static int dalign;
44  typedef struct
45 Akind {
46 	char *name;
47 	int   kind;
48 	} Akind;
49 
50  static Akind
51 IEEE_8087	= { "IEEE_8087", 1 },
52 IEEE_MC68k	= { "IEEE_MC68k", 2 },
53 IBM		= { "IBM", 3 },
54 VAX		= { "VAX", 4 },
55 CRAY		= { "CRAY", 5};
56 
57  static double t_nan;
58 
59  static Akind *
Lcheck(void)60 Lcheck(void)
61 {
62 	union {
63 		double d;
64 		long L[2];
65 		} u;
66 	struct {
67 		double d;
68 		long L;
69 		} x[2];
70 
71 	if (sizeof(x) > 2*(sizeof(double) + sizeof(long)))
72 		dalign = 1;
73 	u.L[0] = u.L[1] = 0;
74 	u.d = 1e13;
75 	if (u.L[0] == 1117925532 && u.L[1] == -448790528)
76 		return &IEEE_MC68k;
77 	if (u.L[1] == 1117925532 && u.L[0] == -448790528)
78 		return &IEEE_8087;
79 	if (u.L[0] == -2065213935 && u.L[1] == 10752)
80 		return &VAX;
81 	if (u.L[0] == 1267827943 && u.L[1] == 704643072)
82 		return &IBM;
83 	return 0;
84 	}
85 
86  static Akind *
icheck(void)87 icheck(void)
88 {
89 	union {
90 		double d;
91 		int L[2];
92 		} u;
93 	struct {
94 		double d;
95 		int L;
96 		} x[2];
97 
98 	if (sizeof(x) > 2*(sizeof(double) + sizeof(int)))
99 		dalign = 1;
100 	u.L[0] = u.L[1] = 0;
101 	u.d = 1e13;
102 	if (u.L[0] == 1117925532 && u.L[1] == -448790528)
103 		return &IEEE_MC68k;
104 	if (u.L[1] == 1117925532 && u.L[0] == -448790528)
105 		return &IEEE_8087;
106 	if (u.L[0] == -2065213935 && u.L[1] == 10752)
107 		return &VAX;
108 	if (u.L[0] == 1267827943 && u.L[1] == 704643072)
109 		return &IBM;
110 	return 0;
111 	}
112 
113 char *emptyfmt = "";	/* avoid possible warning message with printf("") */
114 
115  static Akind *
ccheck(void)116 ccheck(void)
117 {
118 	union {
119 		double d;
120 		long L;
121 		} u;
122 	long Cray1;
123 
124 	/* Cray1 = 4617762693716115456 -- without overflow on non-Crays */
125 	Cray1 = printf(emptyfmt) < 0 ? 0 : 4617762;
126 	if (printf(emptyfmt, Cray1) >= 0)
127 		Cray1 = 1000000*Cray1 + 693716;
128 	if (printf(emptyfmt, Cray1) >= 0)
129 		Cray1 = 1000000*Cray1 + 115456;
130 	u.d = 1e13;
131 	if (u.L == Cray1)
132 		return &CRAY;
133 	return 0;
134 	}
135 
136  static int
fzcheck(void)137 fzcheck(void)
138 {
139 	double a, b;
140 	int i;
141 
142 	a = 1.;
143 	b = .1;
144 	for(i = 155;; b *= b, i >>= 1) {
145 		if (i & 1) {
146 			a *= b;
147 			if (i == 1)
148 				break;
149 			}
150 		}
151 	b = a * a;
152 	return b == 0.;
153 	}
154 
155  static int
need_nancheck(void)156 need_nancheck(void)
157 {
158 	double t;
159 
160 	errno = 0;
161 	t = log(t_nan);
162 	if (errno == 0)
163 		return 1;
164 	errno = 0;
165 	t = sqrt(t_nan);
166 	return errno == 0;
167 	}
168 
169  void
get_nanbits(unsigned int * b,int k)170 get_nanbits(unsigned int *b, int k)
171 {
172 	union { double d; unsigned int z[2]; } u, u1, u2;
173 
174 	k = 2 - k;
175 	u1.z[k] = u2.z[k] = 0x7ff00000;
176 	u1.z[1-k] = u2.z[1-k] = 0;
177 	u.d = u1.d - u2.d;	/* Infinity - Infinity */
178 	b[0] = u.z[0];
179 	b[1] = u.z[1];
180 	}
181 
182  int
main(void)183 main(void)
184 {
185 	FILE *f;
186 	Akind *a = 0;
187 	int Ldef = 0;
188 	unsigned int nanbits[2];
189 
190 	fpinit_ASL();
191 #ifdef WRITE_ARITH_H	/* for Symantec's buggy "make" */
192 	f = fopen("arith.h", "w");
193 	if (!f) {
194 		printf("Cannot open arith.h\n");
195 		return 1;
196 		}
197 #else
198 	f = stdout;
199 #endif
200 
201 	if (sizeof(double) == 2*sizeof(long))
202 		a = Lcheck();
203 	else if (sizeof(double) == 2*sizeof(int)) {
204 		Ldef = 1;
205 		a = icheck();
206 		}
207 	else if (sizeof(double) == sizeof(long))
208 		a = ccheck();
209 	if (a) {
210 		fprintf(f, "#define %s\n#define Arith_Kind_ASL %d\n",
211 			a->name, a->kind);
212 		if (Ldef)
213 			fprintf(f, "#define Long int\n#define Intcast (int)(long)\n");
214 		if (dalign)
215 			fprintf(f, "#define Double_Align\n");
216 		if (sizeof(char*) == 8)
217 			fprintf(f, "#define X64_bit_pointers\n");
218 #ifndef NO_LONG_LONG
219 		if (sizeof(long long) < 8)
220 #endif
221 			fprintf(f, "#define NO_LONG_LONG\n");
222 		if (a->kind <= 2) {
223 			if (fzcheck())
224 				fprintf(f, "#define Sudden_Underflow\n");
225 			t_nan = -a->kind;
226 			if (need_nancheck())
227 				fprintf(f, "#define NANCHECK\n");
228 			if (sizeof(double) == 2*sizeof(unsigned int)) {
229 				get_nanbits(nanbits, a->kind);
230 				fprintf(f, "#define QNaN0 0x%x\n", nanbits[0]);
231 				fprintf(f, "#define QNaN1 0x%x\n", nanbits[1]);
232 				}
233 			}
234 		return 0;
235 		}
236 	fprintf(f, "/* Unknown arithmetic */\n");
237 	return 1;
238 	}
239 
240 #ifdef __sun
241 #ifdef __i386
242 /* kludge for Intel Solaris */
fpsetprec(int x)243 void fpsetprec(int x) { }
244 #endif
245 #endif
246