1 |
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
2 |
* |
3 |
* ***** BEGIN LICENSE BLOCK ***** |
4 |
* Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
5 |
* |
6 |
* The contents of this file are subject to the Mozilla Public License Version |
7 |
* 1.1 (the "License"); you may not use this file except in compliance with |
8 |
* the License. You may obtain a copy of the License at |
9 |
* http://www.mozilla.org/MPL/ |
10 |
* |
11 |
* Software distributed under the License is distributed on an "AS IS" basis, |
12 |
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
13 |
* for the specific language governing rights and limitations under the |
14 |
* License. |
15 |
* |
16 |
* The Original Code is Mozilla Communicator client code, released |
17 |
* March 31, 1998. |
18 |
* |
19 |
* The Initial Developer of the Original Code is |
20 |
* Netscape Communications Corporation. |
21 |
* Portions created by the Initial Developer are Copyright (C) 1998 |
22 |
* the Initial Developer. All Rights Reserved. |
23 |
* |
24 |
* Contributor(s): |
25 |
* Roland Mainz <roland.mainz@informatik.med.uni-giessen.de> |
26 |
* |
27 |
* Alternatively, the contents of this file may be used under the terms of |
28 |
* either of the GNU General Public License Version 2 or later (the "GPL"), |
29 |
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
30 |
* in which case the provisions of the GPL or the LGPL are applicable instead |
31 |
* of those above. If you wish to allow use of your version of this file only |
32 |
* under the terms of either the GPL or the LGPL, and not to allow others to |
33 |
* use your version of this file under the terms of the MPL, indicate your |
34 |
* decision by deleting the provisions above and replace them with the notice |
35 |
* and other provisions required by the GPL or the LGPL. If you do not delete |
36 |
* the provisions above, a recipient may use your version of this file under |
37 |
* the terms of any one of the MPL, the GPL or the LGPL. |
38 |
* |
39 |
* ***** END LICENSE BLOCK ***** */ |
40 |
|
41 |
/* |
42 |
* Generate CPU-specific bit-size and similar #defines. |
43 |
*/ |
44 |
#include <stdio.h> |
45 |
#include <stdlib.h> |
46 |
|
47 |
#ifdef CROSS_COMPILE |
48 |
#include <prtypes.h> |
49 |
#define INT64 PRInt64 |
50 |
#else |
51 |
|
52 |
/************************************************************************/ |
53 |
|
54 |
/* Generate cpucfg.h */ |
55 |
|
56 |
#if defined(XP_WIN) || defined(XP_OS2) |
57 |
#ifdef WIN32 |
58 |
#if defined(__GNUC__) |
59 |
#define INT64 long long |
60 |
#else |
61 |
#define INT64 _int64 |
62 |
#endif /* __GNUC__ */ |
63 |
#else |
64 |
#define INT64 long |
65 |
#endif |
66 |
#else |
67 |
#if defined(HPUX) || defined(__QNX__) |
68 |
#define INT64 long |
69 |
#else |
70 |
#define INT64 long long |
71 |
#endif |
72 |
#endif |
73 |
|
74 |
#endif /* CROSS_COMPILE */ |
75 |
|
76 |
#ifdef __GNUC__ |
77 |
#define NS_NEVER_INLINE __attribute__((noinline)) |
78 |
#else |
79 |
#define NS_NEVER_INLINE |
80 |
#endif |
81 |
|
82 |
#ifdef __SUNPRO_C |
83 |
static int StackGrowthDirection(int *dummy1addr); |
84 |
#pragma no_inline(StackGrowthDirection) |
85 |
#endif |
86 |
|
87 |
typedef void *prword; |
88 |
|
89 |
struct align_short { |
90 |
char c; |
91 |
short a; |
92 |
}; |
93 |
struct align_int { |
94 |
char c; |
95 |
int a; |
96 |
}; |
97 |
struct align_long { |
98 |
char c; |
99 |
long a; |
100 |
}; |
101 |
struct align_int64 { |
102 |
char c; |
103 |
INT64 a; |
104 |
}; |
105 |
struct align_fakelonglong { |
106 |
char c; |
107 |
struct { |
108 |
long hi, lo; |
109 |
} a; |
110 |
}; |
111 |
struct align_float { |
112 |
char c; |
113 |
float a; |
114 |
}; |
115 |
struct align_double { |
116 |
char c; |
117 |
double a; |
118 |
}; |
119 |
struct align_pointer { |
120 |
char c; |
121 |
void *a; |
122 |
}; |
123 |
struct align_prword { |
124 |
char c; |
125 |
prword a; |
126 |
}; |
127 |
|
128 |
#define ALIGN_OF(type) \ |
129 |
(((char*)&(((struct align_##type *)0)->a)) - ((char*)0)) |
130 |
|
131 |
unsigned int bpb; |
132 |
|
133 |
static int Log2(unsigned int n) |
134 |
{ |
135 |
int log2 = 0; |
136 |
|
137 |
if (n & (n-1)) |
138 |
log2++; |
139 |
if (n >> 16) |
140 |
log2 += 16, n >>= 16; |
141 |
if (n >> 8) |
142 |
log2 += 8, n >>= 8; |
143 |
if (n >> 4) |
144 |
log2 += 4, n >>= 4; |
145 |
if (n >> 2) |
146 |
log2 += 2, n >>= 2; |
147 |
if (n >> 1) |
148 |
log2++; |
149 |
return log2; |
150 |
} |
151 |
|
152 |
/* |
153 |
* Conceivably this could actually be used, but there is lots of code out |
154 |
* there with ands and shifts in it that assumes a byte is exactly 8 bits, |
155 |
* so forget about porting THIS code to all those non 8 bit byte machines. |
156 |
*/ |
157 |
static void BitsPerByte(void) |
158 |
{ |
159 |
bpb = 8; |
160 |
} |
161 |
|
162 |
static int NS_NEVER_INLINE StackGrowthDirection(int *dummy1addr) |
163 |
{ |
164 |
int dummy2; |
165 |
|
166 |
return (&dummy2 < dummy1addr) ? -1 : 1; |
167 |
} |
168 |
|
169 |
int main(int argc, char **argv) |
170 |
{ |
171 |
int sizeof_char, sizeof_short, sizeof_int, sizeof_int64, sizeof_long, |
172 |
sizeof_float, sizeof_double, sizeof_word, sizeof_dword; |
173 |
int bits_per_int64_log2, align_of_short, align_of_int, align_of_long, |
174 |
align_of_int64, align_of_float, align_of_double, align_of_pointer, |
175 |
align_of_word; |
176 |
int dummy1; |
177 |
|
178 |
BitsPerByte(); |
179 |
|
180 |
printf("#ifndef js_cpucfg___\n"); |
181 |
printf("#define js_cpucfg___\n\n"); |
182 |
|
183 |
printf("/* AUTOMATICALLY GENERATED - DO NOT EDIT */\n\n"); |
184 |
|
185 |
#ifdef CROSS_COMPILE |
186 |
#if defined(IS_LITTLE_ENDIAN) |
187 |
printf("#define IS_LITTLE_ENDIAN 1\n"); |
188 |
printf("#undef IS_BIG_ENDIAN\n\n"); |
189 |
#elif defined(IS_BIG_ENDIAN) |
190 |
printf("#undef IS_LITTLE_ENDIAN\n"); |
191 |
printf("#define IS_BIG_ENDIAN 1\n\n"); |
192 |
#else |
193 |
#error "Endianess not defined." |
194 |
#endif |
195 |
|
196 |
sizeof_char = PR_BYTES_PER_BYTE; |
197 |
sizeof_short = PR_BYTES_PER_SHORT; |
198 |
sizeof_int = PR_BYTES_PER_INT; |
199 |
sizeof_int64 = PR_BYTES_PER_INT64; |
200 |
sizeof_long = PR_BYTES_PER_LONG; |
201 |
sizeof_float = PR_BYTES_PER_FLOAT; |
202 |
sizeof_double = PR_BYTES_PER_DOUBLE; |
203 |
sizeof_word = PR_BYTES_PER_WORD; |
204 |
sizeof_dword = PR_BYTES_PER_DWORD; |
205 |
|
206 |
bits_per_int64_log2 = PR_BITS_PER_INT64_LOG2; |
207 |
|
208 |
align_of_short = PR_ALIGN_OF_SHORT; |
209 |
align_of_int = PR_ALIGN_OF_INT; |
210 |
align_of_long = PR_ALIGN_OF_LONG; |
211 |
align_of_int64 = PR_ALIGN_OF_INT64; |
212 |
align_of_float = PR_ALIGN_OF_FLOAT; |
213 |
align_of_double = PR_ALIGN_OF_DOUBLE; |
214 |
align_of_pointer = PR_ALIGN_OF_POINTER; |
215 |
align_of_word = PR_ALIGN_OF_WORD; |
216 |
|
217 |
#else /* !CROSS_COMPILE */ |
218 |
|
219 |
/* |
220 |
* We don't handle PDP-endian or similar orders: if a short is big-endian, |
221 |
* so must int and long be big-endian for us to generate the IS_BIG_ENDIAN |
222 |
* #define and the IS_LITTLE_ENDIAN #undef. |
223 |
*/ |
224 |
{ |
225 |
int big_endian = 0, little_endian = 0, ntests = 0; |
226 |
|
227 |
if (sizeof(short) == 2) { |
228 |
/* force |volatile| here to get rid of any compiler optimisations |
229 |
* (var in register etc.) which may be appiled to |auto| vars - |
230 |
* even those in |union|s... |
231 |
* (|static| is used to get the same functionality for compilers |
232 |
* which do not honor |volatile|...). |
233 |
*/ |
234 |
volatile static union { |
235 |
short i; |
236 |
char c[2]; |
237 |
} u; |
238 |
|
239 |
u.i = 0x0102; |
240 |
big_endian += (u.c[0] == 0x01 && u.c[1] == 0x02); |
241 |
little_endian += (u.c[0] == 0x02 && u.c[1] == 0x01); |
242 |
ntests++; |
243 |
} |
244 |
|
245 |
if (sizeof(int) == 4) { |
246 |
/* force |volatile| here ... */ |
247 |
volatile static union { |
248 |
int i; |
249 |
char c[4]; |
250 |
} u; |
251 |
|
252 |
u.i = 0x01020304; |
253 |
big_endian += (u.c[0] == 0x01 && u.c[1] == 0x02 && |
254 |
u.c[2] == 0x03 && u.c[3] == 0x04); |
255 |
little_endian += (u.c[0] == 0x04 && u.c[1] == 0x03 && |
256 |
u.c[2] == 0x02 && u.c[3] == 0x01); |
257 |
ntests++; |
258 |
} |
259 |
|
260 |
if (sizeof(long) == 8) { |
261 |
/* force |volatile| here ... */ |
262 |
volatile static union { |
263 |
long i; |
264 |
char c[8]; |
265 |
} u; |
266 |
|
267 |
/* |
268 |
* Write this as portably as possible: avoid 0x0102030405060708L |
269 |
* and <<= 32. |
270 |
*/ |
271 |
u.i = 0x01020304; |
272 |
u.i <<= 16, u.i <<= 16; |
273 |
u.i |= 0x05060708; |
274 |
big_endian += (u.c[0] == 0x01 && u.c[1] == 0x02 && |
275 |
u.c[2] == 0x03 && u.c[3] == 0x04 && |
276 |
u.c[4] == 0x05 && u.c[5] == 0x06 && |
277 |
u.c[6] == 0x07 && u.c[7] == 0x08); |
278 |
little_endian += (u.c[0] == 0x08 && u.c[1] == 0x07 && |
279 |
u.c[2] == 0x06 && u.c[3] == 0x05 && |
280 |
u.c[4] == 0x04 && u.c[5] == 0x03 && |
281 |
u.c[6] == 0x02 && u.c[7] == 0x01); |
282 |
ntests++; |
283 |
} |
284 |
|
285 |
if (big_endian && big_endian == ntests) { |
286 |
printf("#undef IS_LITTLE_ENDIAN\n"); |
287 |
printf("#define IS_BIG_ENDIAN 1\n\n"); |
288 |
} else if (little_endian && little_endian == ntests) { |
289 |
printf("#define IS_LITTLE_ENDIAN 1\n"); |
290 |
printf("#undef IS_BIG_ENDIAN\n\n"); |
291 |
} else { |
292 |
fprintf(stderr, "%s: unknown byte order" |
293 |
"(big_endian=%d, little_endian=%d, ntests=%d)!\n", |
294 |
argv[0], big_endian, little_endian, ntests); |
295 |
return EXIT_FAILURE; |
296 |
} |
297 |
} |
298 |
|
299 |
sizeof_char = sizeof(char); |
300 |
sizeof_short = sizeof(short); |
301 |
sizeof_int = sizeof(int); |
302 |
sizeof_int64 = 8; |
303 |
sizeof_long = sizeof(long); |
304 |
sizeof_float = sizeof(float); |
305 |
sizeof_double = sizeof(double); |
306 |
sizeof_word = sizeof(prword); |
307 |
sizeof_dword = 8; |
308 |
|
309 |
bits_per_int64_log2 = 6; |
310 |
|
311 |
align_of_short = ALIGN_OF(short); |
312 |
align_of_int = ALIGN_OF(int); |
313 |
align_of_long = ALIGN_OF(long); |
314 |
if (sizeof(INT64) < 8) { |
315 |
/* this machine doesn't actually support int64's */ |
316 |
align_of_int64 = ALIGN_OF(fakelonglong); |
317 |
} else { |
318 |
align_of_int64 = ALIGN_OF(int64); |
319 |
} |
320 |
align_of_float = ALIGN_OF(float); |
321 |
align_of_double = ALIGN_OF(double); |
322 |
align_of_pointer = ALIGN_OF(pointer); |
323 |
align_of_word = ALIGN_OF(prword); |
324 |
|
325 |
#endif /* CROSS_COMPILE */ |
326 |
|
327 |
printf("#define JS_BYTES_PER_BYTE %dL\n", sizeof_char); |
328 |
printf("#define JS_BYTES_PER_SHORT %dL\n", sizeof_short); |
329 |
printf("#define JS_BYTES_PER_INT %dL\n", sizeof_int); |
330 |
printf("#define JS_BYTES_PER_INT64 %dL\n", sizeof_int64); |
331 |
printf("#define JS_BYTES_PER_LONG %dL\n", sizeof_long); |
332 |
printf("#define JS_BYTES_PER_FLOAT %dL\n", sizeof_float); |
333 |
printf("#define JS_BYTES_PER_DOUBLE %dL\n", sizeof_double); |
334 |
printf("#define JS_BYTES_PER_WORD %dL\n", sizeof_word); |
335 |
printf("#define JS_BYTES_PER_DWORD %dL\n", sizeof_dword); |
336 |
printf("\n"); |
337 |
|
338 |
printf("#define JS_BITS_PER_BYTE %dL\n", bpb); |
339 |
printf("#define JS_BITS_PER_SHORT %dL\n", bpb * sizeof_short); |
340 |
printf("#define JS_BITS_PER_INT %dL\n", bpb * sizeof_int); |
341 |
printf("#define JS_BITS_PER_INT64 %dL\n", bpb * sizeof_int64); |
342 |
printf("#define JS_BITS_PER_LONG %dL\n", bpb * sizeof_long); |
343 |
printf("#define JS_BITS_PER_FLOAT %dL\n", bpb * sizeof_float); |
344 |
printf("#define JS_BITS_PER_DOUBLE %dL\n", bpb * sizeof_double); |
345 |
printf("#define JS_BITS_PER_WORD %dL\n", bpb * sizeof_word); |
346 |
printf("\n"); |
347 |
|
348 |
printf("#define JS_BITS_PER_BYTE_LOG2 %dL\n", Log2(bpb)); |
349 |
printf("#define JS_BITS_PER_SHORT_LOG2 %dL\n", Log2(bpb * sizeof_short)); |
350 |
printf("#define JS_BITS_PER_INT_LOG2 %dL\n", Log2(bpb * sizeof_int)); |
351 |
printf("#define JS_BITS_PER_INT64_LOG2 %dL\n", bits_per_int64_log2); |
352 |
printf("#define JS_BITS_PER_LONG_LOG2 %dL\n", Log2(bpb * sizeof_long)); |
353 |
printf("#define JS_BITS_PER_FLOAT_LOG2 %dL\n", Log2(bpb * sizeof_float)); |
354 |
printf("#define JS_BITS_PER_DOUBLE_LOG2 %dL\n", Log2(bpb * sizeof_double)); |
355 |
printf("#define JS_BITS_PER_WORD_LOG2 %dL\n", Log2(bpb * sizeof_word)); |
356 |
printf("\n"); |
357 |
|
358 |
printf("#define JS_ALIGN_OF_SHORT %dL\n", align_of_short); |
359 |
printf("#define JS_ALIGN_OF_INT %dL\n", align_of_int); |
360 |
printf("#define JS_ALIGN_OF_LONG %dL\n", align_of_long); |
361 |
printf("#define JS_ALIGN_OF_INT64 %dL\n", align_of_int64); |
362 |
printf("#define JS_ALIGN_OF_FLOAT %dL\n", align_of_float); |
363 |
printf("#define JS_ALIGN_OF_DOUBLE %dL\n", align_of_double); |
364 |
printf("#define JS_ALIGN_OF_POINTER %dL\n", align_of_pointer); |
365 |
printf("#define JS_ALIGN_OF_WORD %dL\n", align_of_word); |
366 |
printf("\n"); |
367 |
|
368 |
printf("#define JS_BYTES_PER_WORD_LOG2 %dL\n", Log2(sizeof_word)); |
369 |
printf("#define JS_BYTES_PER_DWORD_LOG2 %dL\n", Log2(sizeof_dword)); |
370 |
printf("#define JS_WORDS_PER_DWORD_LOG2 %dL\n", Log2(sizeof_dword/sizeof_word)); |
371 |
printf("\n"); |
372 |
|
373 |
printf("#define JS_STACK_GROWTH_DIRECTION (%d)\n", StackGrowthDirection(&dummy1)); |
374 |
printf("\n"); |
375 |
|
376 |
printf("#define JS_HAVE_LONG_LONG\n"); |
377 |
printf("\n"); |
378 |
|
379 |
#if defined __GNUC__ && defined __x86_64__ |
380 |
printf("#define HAVE_VA_LIST_AS_ARRAY 1\n"); |
381 |
printf("\n"); |
382 |
#endif |
383 |
|
384 |
printf("#endif /* js_cpucfg___ */\n"); |
385 |
|
386 |
return EXIT_SUCCESS; |
387 |
} |
388 |
|