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()60 Lcheck()
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()87 icheck()
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()116 ccheck()
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()137 fzcheck()
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()156 need_nancheck()
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
main()169 main()
170 {
171 FILE *f;
172 Akind *a = 0;
173 int Ldef = 0;
174
175 fpinit_ASL();
176 #ifdef WRITE_ARITH_H /* for Symantec's buggy "make" */
177 f = fopen("arith.h", "w");
178 if (!f) {
179 printf("Cannot open arith.h\n");
180 return 1;
181 }
182 #else
183 f = stdout;
184 #endif
185
186 if (sizeof(double) == 2*sizeof(long))
187 a = Lcheck();
188 else if (sizeof(double) == 2*sizeof(int)) {
189 Ldef = 1;
190 a = icheck();
191 }
192 else if (sizeof(double) == sizeof(long))
193 a = ccheck();
194 if (a) {
195 fprintf(f, "#define %s\n#define Arith_Kind_ASL %d\n",
196 a->name, a->kind);
197 if (Ldef)
198 fprintf(f, "#define Long int\n#define Intcast (int)(long)\n");
199 if (dalign)
200 fprintf(f, "#define Double_Align\n");
201 if (sizeof(char*) == 8)
202 fprintf(f, "#define X64_bit_pointers\n");
203 #ifndef NO_LONG_LONG
204 if (sizeof(long long) < 8)
205 #endif
206 fprintf(f, "#define NO_LONG_LONG\n");
207 if (a->kind <= 2) {
208 if (fzcheck())
209 fprintf(f, "#define Sudden_Underflow\n");
210 t_nan = -a->kind;
211 if (need_nancheck())
212 fprintf(f, "#define NANCHECK\n");
213 }
214 return 0;
215 }
216 fprintf(f, "/* Unknown arithmetic */\n");
217 return 1;
218 }
219
220 #ifdef __sun
221 #ifdef __i386
222 /* kludge for Intel Solaris */
fpsetprec(int x)223 void fpsetprec(int x) { }
224 #endif
225 #endif
226