cloudy trunk
|
00001 /* This file is part of Cloudy and is copyright (C)1978-2008 by Gary J. Ferland and 00002 * others. For conditions of distribution and use see copyright notice in license.txt */ 00003 00004 #ifndef _CPU_H_ 00005 #define _CPU_H_ 00006 00011 /* disable conditional expressions is constant */ 00012 #ifdef _MSC_VER 00013 #pragma warning( disable : 4127 ) 00014 #endif 00015 00017 #ifndef INT16_MAX 00018 #define INT16_MAX 32767 00019 #endif 00020 #ifndef INT16_MIN 00021 #define INT16_MIN (-INT16_MAX - 1) 00022 #endif 00023 00024 #if INT_MAX == INT16_MAX 00025 typedef int int16; 00026 #elif SHRT_MAX == INT16_MAX 00027 typedef short int int16; 00028 #else 00029 #error failed to define int16, please report this to gary@pa.uky.edu 00030 #endif 00031 00032 #ifndef UINT16_MAX 00033 #define UINT16_MAX 65535 00034 #endif 00035 00036 #if UINT_MAX == UINT16_MAX 00037 typedef unsigned int uint16; 00038 #elif USHRT_MAX == UINT16_MAX 00039 typedef unsigned short int uint16; 00040 #else 00041 #error failed to define uint16, please report this to gary@pa.uky.edu 00042 #endif 00043 00044 #ifndef INT32_MAX 00045 #define INT32_MAX 2147483647L 00046 #endif 00047 #ifndef INT32_MIN 00048 #define INT32_MIN (-INT32_MAX - 1) 00049 #endif 00050 00051 #if LONG_MAX == INT32_MAX 00052 typedef long int int32; 00053 #elif INT_MAX == INT32_MAX 00054 typedef int int32; 00055 #else 00056 #error failed to define int32, please report this to gary@pa.uky.edu 00057 #endif 00058 00059 #ifndef UINT32_MAX 00060 #define UINT32_MAX 4294967295UL 00061 #endif 00062 00063 #if ULONG_MAX == UINT32_MAX 00064 typedef unsigned long int uint32; 00065 #elif UINT_MAX == UINT32_MAX 00066 typedef unsigned int uint32; 00067 #else 00068 #error failed to define uint32, please report this to gary@pa.uky.edu 00069 #endif 00070 00071 #if LONG_MAX > INT32_MAX 00072 00073 /* this will only be defined on LP64 systems 00074 * ILP32 systems may have long long support, but that is not 00075 * part of the ISO/ANSI standard, so we don't use it here... */ 00076 00077 /* INT64_MAX, etc, may be defined as long long, so avoid system definitions! */ 00078 00079 #undef INT64_MAX 00080 #define INT64_MAX 9223372036854775807L 00081 00082 #undef INT64_MIN 00083 #define INT64_MIN (-INT64_MAX - 1L) 00084 00085 #if LONG_MAX == INT64_MAX 00086 #define HAVE_INT64 1 00087 typedef long int int64; 00088 #endif 00089 00090 #endif 00091 00092 #if ULONG_MAX > UINT32_MAX 00093 00094 #undef UINT64_MAX 00095 #define UINT64_MAX 18446744073709551615UL 00096 00097 #if ULONG_MAX == UINT64_MAX 00098 #define HAVE_UINT64 1 00099 typedef unsigned long int uint64; 00100 #endif 00101 00102 #endif 00103 00104 /* make sure __func__ is defined, this can be removed once C++0x is in effect */ 00105 #ifdef __GNUC__ 00106 #if __STDC_VERSION__ < 199901L 00107 #if __GNUC__ >= 2 00108 #define __func__ __FUNCTION__ 00109 #else 00110 #define __func__ "<unknown>" 00111 #endif 00112 #endif 00113 #else 00114 #undef __func__ 00115 #define __func__ DEBUG_ENTRY.name() 00116 #endif 00117 00118 /* safe, small, numbers for the float and double */ 00121 /*FLT_MAX is 3.40e38 on wintel, so BIGFLOAT is 3.40e36 */ 00122 const realnum BIGFLOAT = (realnum)(FLT_MAX/100.f); 00124 const realnum SMALLFLOAT = (realnum)(FLT_MIN*100.f); 00125 00127 const double BIGDOUBLE = DBL_MAX/100.; 00128 const double SMALLDOUBLE = DBL_MIN*100.; 00129 00130 const int STDLEN = 16; 00131 00139 typedef enum { AS_DATA_ONLY_TRY, AS_DATA_LOCAL_TRY, AS_LOCAL_DATA_TRY, AS_LOCAL_ONLY_TRY, 00140 AS_DATA_ONLY, AS_DATA_OPTIONAL, AS_DATA_LOCAL, AS_LOCAL_DATA, AS_LOCAL_ONLY } access_scheme; 00141 00142 FILE* open_data( const char* fname, const char* mode, access_scheme scheme=AS_DATA_ONLY ); 00143 00144 /* this class is deliberately kept global so that the constructor is executed before 00145 * any of the user code; this assures a correct FP environment right from the start */ 00146 EXTERN class t_cpu 00147 { 00150 union 00151 { 00152 char c[4]; 00153 int32 i; 00154 } endian; 00155 00156 int32 Float_SNaN_Value; 00157 # ifdef HAVE_INT64 00158 int64 Double_SNaN_Value; 00159 # else 00160 int32 Double_SNaN_Value[2]; 00161 # endif 00162 00163 # ifdef __unix 00164 struct sigaction p_action; 00165 struct sigaction p_default; 00166 # endif 00167 00169 bool p_lgAssertAbort; 00170 00172 long n_avail_CPU; 00174 char HostName[STDLEN]; 00176 vector<string> chSearchPath; 00177 int nFileDone; 00178 00179 void enable_traps() const; 00180 static void signal_handler(int sig); 00181 public: 00182 t_cpu(); 00183 00184 bool big_endian() const { return ( endian.i == 0x12345678 ); } 00185 bool little_endian() const { return ( endian.i == 0x78563412 ); } 00186 00187 # ifdef __unix 00188 const struct sigaction* action() const { return &p_action; } 00189 const struct sigaction* deflt() const { return &p_default; } 00190 # endif 00191 00192 void setAssertAbort(bool val) 00193 { 00194 p_lgAssertAbort = val; 00195 #ifdef CATCH_SIGNAL 00196 # ifdef __unix 00197 if( val ) 00198 sigaction( SIGABRT, deflt(), NULL ); 00199 else 00200 sigaction( SIGABRT, action(), NULL ); 00201 # endif 00202 # ifdef _MSC_VER 00203 if( val ) 00204 signal( SIGABRT, SIG_DFL ); 00205 else 00206 signal( SIGABRT, &signal_handler ); 00207 # endif 00208 #endif 00209 } 00210 bool lgAssertAbort() const { return p_lgAssertAbort; } 00211 00212 long nCPU() const { return n_avail_CPU; } 00213 const char *host_name() const { return HostName; } 00214 void printDataPath() const; 00215 00216 friend FILE* open_data( const char* fname, const char* mode, access_scheme scheme ); 00217 00218 friend void set_NaN(sys_float &x); 00219 friend void set_NaN(sys_float x[], long n); 00220 friend void set_NaN(double &x); 00221 friend void set_NaN(double x[], long n); 00222 } cpu; 00223 00225 void set_NaN(sys_float &x); 00226 void set_NaN(sys_float x[], /* x[n] */ 00227 long n); 00228 void set_NaN(double &x); 00229 void set_NaN(double x[], /* x[n] */ 00230 long n); 00231 00233 bool MyIsnan(sys_float &x); 00234 bool MyIsnan(double &x); 00235 00257 #ifdef cray 00258 #ifndef __cray 00259 #define __cray 1 00260 #endif 00261 #endif 00262 00264 #ifdef __x86_64 00265 #ifndef __amd64 00266 #define __amd64 1 00267 #endif 00268 #endif 00269 00270 #if defined(_ARCH_PPC) || defined(__POWERPC__) || defined(__powerpc__) || defined(PPC) 00271 #ifndef __ppc__ 00272 #define __ppc__ 1 00273 #endif 00274 #endif 00275 00281 #if defined(unix) || defined(__unix__) 00282 #ifndef __unix 00283 #define __unix 1 00284 #endif 00285 #endif 00286 00288 #ifdef __ECC 00289 #ifndef __ICC 00290 #define __ICC __ECC 00291 #endif 00292 #endif 00293 00295 #undef __GNUC_EXCL__ 00296 #if defined(__GNUC__) && ! ( defined(__ICC) || defined(__PATHSCALE__) ) 00297 #define __GNUC_EXCL__ 1 00298 #endif 00299 00300 /* Apply compiler directive saying that current routine does not 00301 return as modifier, as in "NORETURN void MyExit() { ... }" */ 00302 #ifdef _MSC_VER 00303 #define NORETURN __declspec(noreturn) /*@noreturn@*/ 00304 #elif defined(__GNUC__) || ( defined(__INTEL_COMPILER) && defined(__linux) ) 00305 #define NORETURN __attribute__ ((noreturn)) /*@noreturn@*/ 00306 #else 00307 #define NORETURN /*@noreturn@*/ 00308 #endif 00309 00310 /* Define __COMP and __COMP_VER macros for all systems */ 00311 /* the Intel compiler */ 00312 /* this needs to be before g++ since icc also sets __GNUC__ */ 00313 #if defined __INTEL_COMPILER 00314 # define __COMP "icc" 00315 # define __COMP_VER __INTEL_COMPILER 00316 00317 /* PathScale EKOPath compiler */ 00318 /* this needs to be before g++ since pathCC also sets __GNUC__ */ 00319 #elif defined __PATHSCALE__ 00320 # define __COMP "pathCC" 00321 # define __COMP_VER __PATHCC__ * 100 + __PATHCC_MINOR__ * 10 + __PATHCC_PATCHLEVEL__ 00322 00323 /* g++ */ 00324 #elif defined __GNUC__ 00325 # define __COMP "g++" 00326 # if defined(__GNUC_PATCHLEVEL__) 00327 # define __COMP_VER (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) 00328 # else 00329 # define __COMP_VER (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) 00330 # endif 00331 00332 #elif defined __PGI 00333 # define __COMP "Portland Group Compiler" 00334 /* this works under pgcc, but not pgCC; there doesn't seem to be an alternative... */ 00335 # if defined(__PGIC__) 00336 # define __COMP_VER (__PGIC__ * 100 + __PGIC_MINOR__ * 10 + __PGIC_PATCHLEVEL__) 00337 # else 00338 # define __COMP_VER 0 00339 # endif 00340 00341 /* SGI MIPSpro */ 00342 /* this needs to be after g++, since g++ under IRIX also sets _COMPILER_VERSION */ 00343 #elif defined(__sgi) && defined(_COMPILER_VERSION) 00344 # define __COMP "MIPSpro" 00345 # define __COMP_VER _COMPILER_VERSION 00346 00347 /* HP */ 00348 #elif defined __HP_aCC 00349 # define __COMP "HP aCC" 00350 # define __COMP_VER __HP_aCC 00351 00352 /* DEC - this one may be broken for C++, no way to test it... */ 00353 #elif defined __DECC 00354 # define __COMP "DEC CC" 00355 # define __COMP_VER __DECC_VER 00356 00357 /* MS VS */ 00358 #elif defined _MSC_VER 00359 # define __COMP "vs" 00360 # define __COMP_VER _MSC_VER 00361 00362 /* Sun */ 00363 #elif defined __SUNPRO_CC 00364 # define __COMP "Sun Workshop" 00365 # define __COMP_VER __SUNPRO_CC 00366 00367 /* unknown */ 00368 #else 00369 #define __COMP "unknown" 00370 #define __COMP_VER 0 00371 #endif 00372 00373 /* ---------------------------- OS ---------------------------- */ 00374 /* linux */ 00375 #if defined __linux 00376 # if defined __i386 00377 # define __OS "Linux (IA32)" 00378 # elif defined __amd64 00379 # define __OS "Linux (AMD64)" 00380 # elif defined __ia64 00381 # define __OS "Linux (IA64)" 00382 # elif defined __ppc__ 00383 # define __OS "Linux (PowerPC)" 00384 # else 00385 # define __OS "Linux (other)" 00386 # endif 00387 00388 /* macintosh */ 00389 #elif defined macintosh 00390 # define __OS "Mac OS 9" 00391 00392 /* macintosh */ 00393 #elif defined __MACOSX__ 00394 # define __OS "Mac OS X" 00395 00396 /* apple mac, ... */ 00397 #elif defined __APPLE__ 00398 # define __OS "Apple MacOS" 00399 00400 /* HP */ 00401 #elif defined hpux 00402 # define __OS "HP-UX" 00403 00404 /* Sun */ 00405 #elif defined __sun 00406 # define __OS "Solaris" 00407 00408 /* IBM AIX */ 00409 #elif defined _AIX 00410 # define __OS "AIX" 00411 00412 /* Compaq alpha */ 00413 #elif defined ultrix 00414 # define __OS "Ultrix" 00415 00416 /* the BSD variants */ 00417 #elif defined __FreeBSD__ 00418 # define __OS "FreeBSD" 00419 00420 #elif defined __NetBSD__ 00421 # define __OS "NetBSD" 00422 00423 #elif defined __OpenBSD__ 00424 # define __OS "OpenBSD" 00425 00426 /* Windows64 */ 00427 /* this needs to be before _WIN32 since Windows64 also sets _WIN32 */ 00428 #elif defined _WIN64 00429 # define __OS "Win64" 00430 00431 /* Windows */ 00432 #elif defined _WIN32 00433 # define __OS "Win32" 00434 00435 /* Cygwin */ 00436 #elif defined __CYGWIN__ 00437 # define __OS "Cygwin" 00438 00439 /* SGI */ 00440 #elif defined __sgi 00441 # define __OS "IRIX" 00442 00443 /* unknown */ 00444 #else 00445 # define __OS "unknown" 00446 #endif 00447 00448 #if !defined(HAVE_POWI) 00449 #if defined(__alpha) && !defined(__linux) 00450 #define HAVE_POWI 1 00451 #else 00452 #define HAVE_POWI 0 00453 #endif 00454 #endif 00455 00456 /* don't perform this check when we are generating dependencies */ 00457 #ifndef MM 00458 /* bomb out if the compiler is broken.... */ 00459 #if defined(__GNUC_EXCL__) && ((__GNUC__ == 2 && __GNUC_MINOR__ == 96) || (__GNUC__ == 3 && __GNUC_MINOR__ == 4)) 00460 #error "This g++ version cannot compile Cloudy and must not be used!" 00461 #error "Please update g++ to a functional version." 00462 #error "See http://cloud9.pa.uky.edu/trac/cloudy/wiki/CompilingCloudy for more details" 00463 #endif 00464 #endif 00465 00466 #ifdef _MSC_VER 00467 #pragma warning( default : 4127 )/* disable warning that conditional expression is constant*/ 00468 #endif 00469 00470 #endif /* _CPU_H_ */