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