gencfg.c (6083B)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #include <stdio.h> 7 8 #if defined(__sun) 9 # ifndef SOLARIS 10 error - 11 SOLARIS is not defined 12 # endif 13 #endif 14 15 #if defined(__hpux) 16 error - 17 HPUX is not supported 18 #endif 19 20 #if defined(__alpha) 21 # if !(defined(_WIN32)) && !(defined(__linux)) && !(defined(__FreeBSD__)) 22 error - 23 None of _WIN32, 24 __linux, or __FreeBSD__ is defined 25 # endif 26 #endif 27 28 #if defined(_IBMR2) 29 # ifndef AIX 30 error - 31 AIX is not defined 32 # endif 33 #endif 34 35 #if defined(linux) 36 # ifndef LINUX 37 error - 38 LINUX is not defined 39 # endif 40 #endif 41 42 #if defined(__APPLE__) 43 # ifndef DARWIN 44 error - 45 DARWIN is not defined 46 # endif 47 #endif 48 49 /************************************************************************/ 50 51 /* Generate cpucfg.h */ 52 53 #ifdef XP_PC 54 # ifdef WIN32 55 # define INT64 _PRInt64 56 # else 57 # define INT64 long 58 # endif 59 #else 60 # define INT64 long long 61 #endif 62 63 struct align_short { 64 char c; 65 short a; 66 }; 67 struct align_int { 68 char c; 69 int a; 70 }; 71 struct align_long { 72 char c; 73 long a; 74 }; 75 struct align_PRInt64 { 76 char c; 77 INT64 a; 78 }; 79 struct align_fakelonglong { 80 char c; 81 struct { 82 long hi, lo; 83 } a; 84 }; 85 struct align_float { 86 char c; 87 float a; 88 }; 89 struct align_double { 90 char c; 91 double a; 92 }; 93 struct align_pointer { 94 char c; 95 void* a; 96 }; 97 98 #define ALIGN_OF(type) (((char*)&(((struct align_##type*)0)->a)) - ((char*)0)) 99 100 int bpb; 101 102 /* Used if shell doesn't support redirection. By default, assume it does. */ 103 FILE* stream; 104 105 static int Log2(int n) { 106 int log2 = 0; 107 108 if (n & (n - 1)) { 109 log2++; 110 } 111 if (n >> 16) { 112 log2 += 16, n >>= 16; 113 } 114 if (n >> 8) { 115 log2 += 8, n >>= 8; 116 } 117 if (n >> 4) { 118 log2 += 4, n >>= 4; 119 } 120 if (n >> 2) { 121 log2 += 2, n >>= 2; 122 } 123 if (n >> 1) { 124 log2++; 125 } 126 return log2; 127 } 128 129 /* We assume that int's are 32 bits */ 130 static void do64(void) { 131 union { 132 int i; 133 char c[4]; 134 } u; 135 136 u.i = 0x01020304; 137 if (u.c[0] == 0x01) { 138 fprintf(stream, "#undef IS_LITTLE_ENDIAN\n"); 139 fprintf(stream, "#define IS_BIG_ENDIAN 1\n\n"); 140 } else { 141 fprintf(stream, "#define IS_LITTLE_ENDIAN 1\n"); 142 fprintf(stream, "#undef IS_BIG_ENDIAN\n\n"); 143 } 144 } 145 146 static void do32(void) { 147 union { 148 long i; 149 char c[4]; 150 } u; 151 152 u.i = 0x01020304; 153 if (u.c[0] == 0x01) { 154 fprintf(stream, "#undef IS_LITTLE_ENDIAN\n"); 155 fprintf(stream, "#define IS_BIG_ENDIAN 1\n\n"); 156 } else { 157 fprintf(stream, "#define IS_LITTLE_ENDIAN 1\n"); 158 fprintf(stream, "#undef IS_BIG_ENDIAN\n\n"); 159 } 160 } 161 162 /* 163 ** Concievably this could actually be used; but there is lots of code out 164 ** there with and's and shift's in it that assumes a byte is 8 bits, so 165 ** forget about porting THIS code to those non 8 bit byte machines. 166 */ 167 static void BitsPerByte(void) { bpb = 8; } 168 169 int main(int argc, char** argv) { 170 BitsPerByte(); 171 172 /* If we got a command line argument, try to use it as the stream. */ 173 ++argv; 174 if (*argv) { 175 if (!(stream = fopen(*argv, "wt"))) { 176 fprintf(stderr, "Could not write to output file %s.\n", *argv); 177 return 1; 178 } 179 } else { 180 stream = stdout; 181 } 182 183 fprintf(stream, "#ifndef nspr_cpucfg___\n"); 184 fprintf(stream, "#define nspr_cpucfg___\n\n"); 185 186 fprintf(stream, "/* AUTOMATICALLY GENERATED - DO NOT EDIT */\n\n"); 187 188 if (sizeof(long) == 8) { 189 do64(); 190 } else { 191 do32(); 192 } 193 fprintf(stream, "#define PR_BYTES_PER_BYTE %d\n", sizeof(char)); 194 fprintf(stream, "#define PR_BYTES_PER_SHORT %d\n", sizeof(short)); 195 fprintf(stream, "#define PR_BYTES_PER_INT %d\n", sizeof(int)); 196 fprintf(stream, "#define PR_BYTES_PER_INT64 %d\n", 8); 197 fprintf(stream, "#define PR_BYTES_PER_LONG %d\n", sizeof(long)); 198 fprintf(stream, "#define PR_BYTES_PER_FLOAT %d\n", sizeof(float)); 199 fprintf(stream, "#define PR_BYTES_PER_DOUBLE %d\n\n", sizeof(double)); 200 201 fprintf(stream, "#define PR_BITS_PER_BYTE %d\n", bpb); 202 fprintf(stream, "#define PR_BITS_PER_SHORT %d\n", bpb * sizeof(short)); 203 fprintf(stream, "#define PR_BITS_PER_INT %d\n", bpb * sizeof(int)); 204 fprintf(stream, "#define PR_BITS_PER_INT64 %d\n", bpb * 8); 205 fprintf(stream, "#define PR_BITS_PER_LONG %d\n", bpb * sizeof(long)); 206 fprintf(stream, "#define PR_BITS_PER_FLOAT %d\n", bpb * sizeof(float)); 207 fprintf(stream, "#define PR_BITS_PER_DOUBLE %d\n\n", bpb * sizeof(double)); 208 209 fprintf(stream, "#define PR_BITS_PER_BYTE_LOG2 %d\n", Log2(bpb)); 210 fprintf(stream, "#define PR_BITS_PER_SHORT_LOG2 %d\n", 211 Log2(bpb * sizeof(short))); 212 fprintf(stream, "#define PR_BITS_PER_INT_LOG2 %d\n", 213 Log2(bpb * sizeof(int))); 214 fprintf(stream, "#define PR_BITS_PER_INT64_LOG2 %d\n", 6); 215 fprintf(stream, "#define PR_BITS_PER_LONG_LOG2 %d\n", 216 Log2(bpb * sizeof(long))); 217 fprintf(stream, "#define PR_BITS_PER_FLOAT_LOG2 %d\n", 218 Log2(bpb * sizeof(float))); 219 fprintf(stream, "#define PR_BITS_PER_DOUBLE_LOG2 %d\n\n", 220 Log2(bpb * sizeof(double))); 221 222 fprintf(stream, "#define PR_ALIGN_OF_SHORT %d\n", ALIGN_OF(short)); 223 fprintf(stream, "#define PR_ALIGN_OF_INT %d\n", ALIGN_OF(int)); 224 fprintf(stream, "#define PR_ALIGN_OF_LONG %d\n", ALIGN_OF(long)); 225 if (sizeof(INT64) < 8) { 226 /* this machine doesn't actually support PRInt64's */ 227 fprintf(stream, "#define PR_ALIGN_OF_INT64 %d\n", ALIGN_OF(fakelonglong)); 228 } else { 229 fprintf(stream, "#define PR_ALIGN_OF_INT64 %d\n", ALIGN_OF(PRInt64)); 230 } 231 fprintf(stream, "#define PR_ALIGN_OF_FLOAT %d\n", ALIGN_OF(float)); 232 fprintf(stream, "#define PR_ALIGN_OF_DOUBLE %d\n", ALIGN_OF(double)); 233 fprintf(stream, "#define PR_ALIGN_OF_POINTER %d\n\n", ALIGN_OF(pointer)); 234 235 fprintf(stream, "#endif /* nspr_cpucfg___ */\n"); 236 fclose(stream); 237 238 return 0; 239 }