Back to index

lightning-sunbird  0.9+nobinonly
jscpucfg.c
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  *
00003  * ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is Mozilla Communicator client code, released
00017  * March 31, 1998.
00018  *
00019  * The Initial Developer of the Original Code is
00020  * Netscape Communications Corporation.
00021  * Portions created by the Initial Developer are Copyright (C) 1998
00022  * the Initial Developer. All Rights Reserved.
00023  *
00024  * Contributor(s):
00025  *   Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
00026  *
00027  * Alternatively, the contents of this file may be used under the terms of
00028  * either of the GNU General Public License Version 2 or later (the "GPL"),
00029  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00030  * in which case the provisions of the GPL or the LGPL are applicable instead
00031  * of those above. If you wish to allow use of your version of this file only
00032  * under the terms of either the GPL or the LGPL, and not to allow others to
00033  * use your version of this file under the terms of the MPL, indicate your
00034  * decision by deleting the provisions above and replace them with the notice
00035  * and other provisions required by the GPL or the LGPL. If you do not delete
00036  * the provisions above, a recipient may use your version of this file under
00037  * the terms of any one of the MPL, the GPL or the LGPL.
00038  *
00039  * ***** END LICENSE BLOCK ***** */
00040 
00041 /*
00042  * Generate CPU-specific bit-size and similar #defines.
00043  */
00044 #include <stdio.h>
00045 #include <stdlib.h>
00046 
00047 #ifdef CROSS_COMPILE
00048 #include <prtypes.h>
00049 #define INT64 PRInt64
00050 #else
00051 
00052 /************************************************************************/
00053 
00054 /* Generate cpucfg.h */
00055 
00056 #if defined(XP_WIN) || defined(XP_OS2)
00057 #ifdef WIN32
00058 #if defined(__GNUC__)
00059 #define INT64   long long
00060 #else
00061 #define INT64   _int64
00062 #endif /* __GNUC__ */
00063 #else
00064 #define INT64   long
00065 #endif
00066 #else
00067 #if defined(HPUX) || defined(__QNX__) || defined(_SCO_DS) || defined(UNIXWARE)
00068 #define INT64   long
00069 #else
00070 #define INT64   long long
00071 #endif
00072 #endif
00073 
00074 #endif /* CROSS_COMPILE */
00075 
00076 #ifdef __GNUC__
00077 #define NS_NEVER_INLINE __attribute__((noinline))
00078 #else
00079 #define NS_NEVER_INLINE
00080 #endif
00081 
00082 #ifdef __SUNPRO_C
00083 static int StackGrowthDirection(int *dummy1addr);
00084 #pragma no_inline(StackGrowthDirection)
00085 #endif
00086 
00087 typedef void *prword;
00088 
00089 struct align_short {
00090     char c;
00091     short a;
00092 };
00093 struct align_int {
00094     char c;
00095     int a;
00096 };
00097 struct align_long {
00098     char c;
00099     long a;
00100 };
00101 struct align_int64 {
00102     char c;
00103     INT64 a;
00104 };
00105 struct align_fakelonglong {
00106     char c;
00107     struct {
00108         long hi, lo;
00109     } a;
00110 };
00111 struct align_float {
00112     char c;
00113     float a;
00114 };
00115 struct align_double {
00116     char c;
00117     double a;
00118 };
00119 struct align_pointer {
00120     char c;
00121     void *a;
00122 };
00123 struct align_prword {
00124     char c;
00125     prword a;
00126 };
00127 
00128 #define ALIGN_OF(type) \
00129     (((char*)&(((struct align_##type *)0)->a)) - ((char*)0))
00130 
00131 unsigned int bpb;
00132 
00133 static int Log2(unsigned int n)
00134 {
00135     int log2 = 0;
00136 
00137     if (n & (n-1))
00138         log2++;
00139     if (n >> 16)
00140         log2 += 16, n >>= 16;
00141     if (n >> 8)
00142         log2 += 8, n >>= 8;
00143     if (n >> 4)
00144         log2 += 4, n >>= 4;
00145     if (n >> 2)
00146         log2 += 2, n >>= 2;
00147     if (n >> 1)
00148         log2++;
00149     return log2;
00150 }
00151 
00152 /*
00153  * Conceivably this could actually be used, but there is lots of code out
00154  * there with ands and shifts in it that assumes a byte is exactly 8 bits,
00155  * so forget about porting THIS code to all those non 8 bit byte machines.
00156  */
00157 static void BitsPerByte(void)
00158 {
00159     bpb = 8;
00160 }
00161 
00162 static int NS_NEVER_INLINE StackGrowthDirection(int *dummy1addr)
00163 {
00164     int dummy2;
00165 
00166     return (&dummy2 < dummy1addr) ? -1 : 1;
00167 }
00168 
00169 int main(int argc, char **argv)
00170 {
00171     int sizeof_char, sizeof_short, sizeof_int, sizeof_int64, sizeof_long,
00172         sizeof_float, sizeof_double, sizeof_word, sizeof_dword;
00173     int bits_per_int64_log2, align_of_short, align_of_int, align_of_long,
00174         align_of_int64, align_of_float, align_of_double, align_of_pointer,
00175         align_of_word;
00176     int dummy1;
00177 
00178     BitsPerByte();
00179 
00180     printf("#ifndef js_cpucfg___\n");
00181     printf("#define js_cpucfg___\n\n");
00182 
00183     printf("/* AUTOMATICALLY GENERATED - DO NOT EDIT */\n\n");
00184 
00185 #ifdef CROSS_COMPILE
00186 #if defined(IS_LITTLE_ENDIAN)
00187     printf("#define IS_LITTLE_ENDIAN 1\n");
00188     printf("#undef  IS_BIG_ENDIAN\n\n");
00189 #elif defined(IS_BIG_ENDIAN)
00190     printf("#undef  IS_LITTLE_ENDIAN\n");
00191     printf("#define IS_BIG_ENDIAN 1\n\n");
00192 #else
00193 #error "Endianess not defined."
00194 #endif
00195 
00196     sizeof_char         = PR_BYTES_PER_BYTE;
00197     sizeof_short        = PR_BYTES_PER_SHORT;
00198     sizeof_int          = PR_BYTES_PER_INT;
00199     sizeof_int64        = PR_BYTES_PER_INT64;
00200     sizeof_long         = PR_BYTES_PER_LONG;
00201     sizeof_float        = PR_BYTES_PER_FLOAT;
00202     sizeof_double       = PR_BYTES_PER_DOUBLE;
00203     sizeof_word         = PR_BYTES_PER_WORD;
00204     sizeof_dword        = PR_BYTES_PER_DWORD;
00205 
00206     bits_per_int64_log2 = PR_BITS_PER_INT64_LOG2;
00207 
00208     align_of_short      = PR_ALIGN_OF_SHORT;
00209     align_of_int        = PR_ALIGN_OF_INT;
00210     align_of_long       = PR_ALIGN_OF_LONG;
00211     align_of_int64      = PR_ALIGN_OF_INT64;
00212     align_of_float      = PR_ALIGN_OF_FLOAT;
00213     align_of_double     = PR_ALIGN_OF_DOUBLE;
00214     align_of_pointer    = PR_ALIGN_OF_POINTER;
00215     align_of_word       = PR_ALIGN_OF_WORD;
00216 
00217 #else /* !CROSS_COMPILE */
00218 
00219     /*
00220      * We don't handle PDP-endian or similar orders: if a short is big-endian,
00221      * so must int and long be big-endian for us to generate the IS_BIG_ENDIAN
00222      * #define and the IS_LITTLE_ENDIAN #undef.
00223      */
00224     {
00225         int big_endian = 0, little_endian = 0, ntests = 0;
00226 
00227         if (sizeof(short) == 2) {
00228             /* force |volatile| here to get rid of any compiler optimisations
00229              * (var in register etc.) which may be appiled to |auto| vars -
00230              * even those in |union|s...
00231              * (|static| is used to get the same functionality for compilers
00232              * which do not honor |volatile|...).
00233              */
00234             volatile static union {
00235                 short i;
00236                 char c[2];
00237             } u;
00238 
00239             u.i = 0x0102;
00240             big_endian += (u.c[0] == 0x01 && u.c[1] == 0x02);
00241             little_endian += (u.c[0] == 0x02 && u.c[1] == 0x01);
00242             ntests++;
00243         }
00244 
00245         if (sizeof(int) == 4) {
00246             /* force |volatile| here ... */
00247             volatile static union {
00248                 int i;
00249                 char c[4];
00250             } u;
00251 
00252             u.i = 0x01020304;
00253             big_endian += (u.c[0] == 0x01 && u.c[1] == 0x02 &&
00254                            u.c[2] == 0x03 && u.c[3] == 0x04);
00255             little_endian += (u.c[0] == 0x04 && u.c[1] == 0x03 &&
00256                               u.c[2] == 0x02 && u.c[3] == 0x01);
00257             ntests++;
00258         }
00259 
00260         if (sizeof(long) == 8) {
00261             /* force |volatile| here ... */
00262             volatile static union {
00263                 long i;
00264                 char c[8];
00265             } u;
00266 
00267             /*
00268              * Write this as portably as possible: avoid 0x0102030405060708L
00269              * and <<= 32.
00270              */
00271             u.i = 0x01020304;
00272             u.i <<= 16, u.i <<= 16;
00273             u.i |= 0x05060708;
00274             big_endian += (u.c[0] == 0x01 && u.c[1] == 0x02 &&
00275                            u.c[2] == 0x03 && u.c[3] == 0x04 &&
00276                            u.c[4] == 0x05 && u.c[5] == 0x06 &&
00277                            u.c[6] == 0x07 && u.c[7] == 0x08);
00278             little_endian += (u.c[0] == 0x08 && u.c[1] == 0x07 &&
00279                               u.c[2] == 0x06 && u.c[3] == 0x05 &&
00280                               u.c[4] == 0x04 && u.c[5] == 0x03 &&
00281                               u.c[6] == 0x02 && u.c[7] == 0x01);
00282             ntests++;
00283         }
00284 
00285         if (big_endian && big_endian == ntests) {
00286             printf("#undef  IS_LITTLE_ENDIAN\n");
00287             printf("#define IS_BIG_ENDIAN 1\n\n");
00288         } else if (little_endian && little_endian == ntests) {
00289             printf("#define IS_LITTLE_ENDIAN 1\n");
00290             printf("#undef  IS_BIG_ENDIAN\n\n");
00291         } else {
00292             fprintf(stderr, "%s: unknown byte order"
00293                     "(big_endian=%d, little_endian=%d, ntests=%d)!\n",
00294                     argv[0], big_endian, little_endian, ntests);
00295             return EXIT_FAILURE;
00296         }
00297     }
00298 
00299     sizeof_char         = sizeof(char);
00300     sizeof_short        = sizeof(short);
00301     sizeof_int          = sizeof(int);
00302     sizeof_int64        = 8;
00303     sizeof_long         = sizeof(long);
00304     sizeof_float        = sizeof(float);
00305     sizeof_double       = sizeof(double);
00306     sizeof_word         = sizeof(prword);
00307     sizeof_dword        = 8;
00308 
00309     bits_per_int64_log2 = 6;
00310 
00311     align_of_short      = ALIGN_OF(short);
00312     align_of_int        = ALIGN_OF(int);
00313     align_of_long       = ALIGN_OF(long);
00314     if (sizeof(INT64) < 8) {
00315         /* this machine doesn't actually support int64's */
00316         align_of_int64  = ALIGN_OF(fakelonglong);
00317     } else {
00318         align_of_int64  = ALIGN_OF(int64);
00319     }
00320     align_of_float      = ALIGN_OF(float);
00321     align_of_double     = ALIGN_OF(double);
00322     align_of_pointer    = ALIGN_OF(pointer);
00323     align_of_word       = ALIGN_OF(prword);
00324 
00325 #endif /* CROSS_COMPILE */
00326 
00327     printf("#define JS_BYTES_PER_BYTE   %dL\n", sizeof_char);
00328     printf("#define JS_BYTES_PER_SHORT  %dL\n", sizeof_short);
00329     printf("#define JS_BYTES_PER_INT    %dL\n", sizeof_int);
00330     printf("#define JS_BYTES_PER_INT64  %dL\n", sizeof_int64);
00331     printf("#define JS_BYTES_PER_LONG   %dL\n", sizeof_long);
00332     printf("#define JS_BYTES_PER_FLOAT  %dL\n", sizeof_float);
00333     printf("#define JS_BYTES_PER_DOUBLE %dL\n", sizeof_double);
00334     printf("#define JS_BYTES_PER_WORD   %dL\n", sizeof_word);
00335     printf("#define JS_BYTES_PER_DWORD  %dL\n", sizeof_dword);
00336     printf("\n");
00337 
00338     printf("#define JS_BITS_PER_BYTE    %dL\n", bpb);
00339     printf("#define JS_BITS_PER_SHORT   %dL\n", bpb * sizeof_short);
00340     printf("#define JS_BITS_PER_INT     %dL\n", bpb * sizeof_int);
00341     printf("#define JS_BITS_PER_INT64   %dL\n", bpb * sizeof_int64);
00342     printf("#define JS_BITS_PER_LONG    %dL\n", bpb * sizeof_long);
00343     printf("#define JS_BITS_PER_FLOAT   %dL\n", bpb * sizeof_float);
00344     printf("#define JS_BITS_PER_DOUBLE  %dL\n", bpb * sizeof_double);
00345     printf("#define JS_BITS_PER_WORD    %dL\n", bpb * sizeof_word);
00346     printf("\n");
00347 
00348     printf("#define JS_BITS_PER_BYTE_LOG2   %dL\n", Log2(bpb));
00349     printf("#define JS_BITS_PER_SHORT_LOG2  %dL\n", Log2(bpb * sizeof_short));
00350     printf("#define JS_BITS_PER_INT_LOG2    %dL\n", Log2(bpb * sizeof_int));
00351     printf("#define JS_BITS_PER_INT64_LOG2  %dL\n", bits_per_int64_log2);
00352     printf("#define JS_BITS_PER_LONG_LOG2   %dL\n", Log2(bpb * sizeof_long));
00353     printf("#define JS_BITS_PER_FLOAT_LOG2  %dL\n", Log2(bpb * sizeof_float));
00354     printf("#define JS_BITS_PER_DOUBLE_LOG2 %dL\n", Log2(bpb * sizeof_double));
00355     printf("#define JS_BITS_PER_WORD_LOG2   %dL\n", Log2(bpb * sizeof_word));
00356     printf("\n");
00357 
00358     printf("#define JS_ALIGN_OF_SHORT   %dL\n", align_of_short);
00359     printf("#define JS_ALIGN_OF_INT     %dL\n", align_of_int);
00360     printf("#define JS_ALIGN_OF_LONG    %dL\n", align_of_long);
00361     printf("#define JS_ALIGN_OF_INT64   %dL\n", align_of_int64);
00362     printf("#define JS_ALIGN_OF_FLOAT   %dL\n", align_of_float);
00363     printf("#define JS_ALIGN_OF_DOUBLE  %dL\n", align_of_double);
00364     printf("#define JS_ALIGN_OF_POINTER %dL\n", align_of_pointer);
00365     printf("#define JS_ALIGN_OF_WORD    %dL\n", align_of_word);
00366     printf("\n");
00367 
00368     printf("#define JS_BYTES_PER_WORD_LOG2   %dL\n", Log2(sizeof_word));
00369     printf("#define JS_BYTES_PER_DWORD_LOG2  %dL\n", Log2(sizeof_dword));
00370     printf("#define JS_WORDS_PER_DWORD_LOG2  %dL\n", Log2(sizeof_dword/sizeof_word));
00371     printf("\n");
00372 
00373     printf("#define JS_STACK_GROWTH_DIRECTION (%d)\n", StackGrowthDirection(&dummy1));
00374     printf("\n");
00375 
00376     printf("#endif /* js_cpucfg___ */\n");
00377 
00378     return EXIT_SUCCESS;
00379 }
00380