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