Mercurial > projects > ldc
view dmd/root/port.c @ 1650:40bd4a0d4870
Update to work with LLVM 2.7.
Removed use of dyn_cast, llvm no compiles
without exceptions and rtti by
default. We do need exceptions for the libconfig stuff, but rtti isn't
necessary (anymore).
Debug info needs to be rewritten, as in LLVM 2.7 the format has
completely changed. To have something to look at while rewriting, the
old code has been wrapped inside #ifndef DISABLE_DEBUG_INFO , this means
that you have to define this to compile at the moment.
Updated tango 0.99.9 patch to include updated EH runtime code, which is
needed for LLVM 2.7 as well.
author | Tomas Lindquist Olsen |
---|---|
date | Wed, 19 May 2010 12:42:32 +0200 |
parents | 04177061f98d |
children |
line wrap: on
line source
// Copyright (c) 1999-2009 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com #include "port.h" #if __DMC__ #include <math.h> #include <float.h> #include <fp.h> #include <time.h> #include <stdlib.h> #include <string.h> double Port::nan = NAN; double Port::infinity = INFINITY; double Port::dbl_max = DBL_MAX; double Port::dbl_min = DBL_MIN; long double Port::ldbl_max = LDBL_MAX; int Port::isNan(double r) { return ::isnan(r); } int Port::isNan(long double r) { return ::isnan(r); } int Port::isSignallingNan(double r) { /* A signalling NaN is a NaN with 0 as the most significant bit of * its significand, which is bit 51 of 0..63 for 64 bit doubles. */ return isNan(r) && !((((unsigned char*)&r)[6]) & 8); } int Port::isSignallingNan(long double r) { /* A signalling NaN is a NaN with 0 as the most significant bit of * its significand, which is bit 62 of 0..79 for 80 bit reals. */ return isNan(r) && !((((unsigned char*)&r)[7]) & 0x40); } int Port::isFinite(double r) { return ::isfinite(r); } int Port::isInfinity(double r) { return (::fpclassify(r) == FP_INFINITE); } int Port::Signbit(double r) { return ::signbit(r); } double Port::floor(double d) { return ::floor(d); } double Port::pow(double x, double y) { return ::pow(x, y); } unsigned long long Port::strtoull(const char *p, char **pend, int base) { return ::strtoull(p, pend, base); } char *Port::ull_to_string(char *buffer, ulonglong ull) { sprintf(buffer, "%llu", ull); return buffer; } wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull) { swprintf(buffer, sizeof(ulonglong) * 3 + 1, L"%llu", ull); return buffer; } double Port::ull_to_double(ulonglong ull) { return (double) ull; } const char *Port::list_separator() { // LOCALE_SLIST for Windows return ","; } const wchar_t *Port::wlist_separator() { // LOCALE_SLIST for Windows return L","; } char *Port::strupr(char *s) { return ::strupr(s); } #endif #if _MSC_VER // Disable useless warnings about unreferenced functions #pragma warning (disable : 4514) #include <math.h> #include <float.h> #include <time.h> #include <errno.h> #include <string.h> #include <ctype.h> #include <stdlib.h> #include <limits> // for std::numeric_limits static unsigned long nanarray[2]= { 0xFFFFFFFF, 0x7FFFFFFF }; //static unsigned long nanarray[2] = {0,0x7FF80000 }; double Port::nan = (*(double *)nanarray); //static unsigned long infinityarray[2] = {0,0x7FF00000 }; static double zero = 0; double Port::infinity = 1 / zero; double Port::dbl_max = DBL_MAX; double Port::dbl_min = DBL_MIN; long double Port::ldbl_max = LDBL_MAX; struct PortInitializer { PortInitializer(); }; static PortInitializer portinitializer; PortInitializer::PortInitializer() { Port::infinity = std::numeric_limits<long double>::infinity(); } int Port::isNan(double r) { return ::_isnan(r); } int Port::isNan(long double r) { return ::_isnan(r); } int Port::isSignallingNan(double r) { /* A signalling NaN is a NaN with 0 as the most significant bit of * its significand, which is bit 51 of 0..63 for 64 bit doubles. */ return isNan(r) && !((((unsigned char*)&r)[6]) & 8); } int Port::isSignallingNan(long double r) { /* MSVC doesn't have 80 bit long doubles */ return isSignallingNan((double) r); } int Port::isFinite(double r) { return ::_finite(r); } int Port::isInfinity(double r) { return (::_fpclass(r) & (_FPCLASS_NINF | _FPCLASS_PINF)); } int Port::Signbit(double r) { return (long)(((long *)&(r))[1] & 0x80000000); } double Port::floor(double d) { return ::floor(d); } double Port::pow(double x, double y) { if (y == 0) return 1; // even if x is NAN return ::pow(x, y); } unsigned _int64 Port::strtoull(const char *p, char **pend, int base) { unsigned _int64 number = 0; int c; int error; #define ULLONG_MAX ((unsigned _int64)~0I64) while (isspace(*p)) /* skip leading white space */ p++; if (*p == '+') p++; switch (base) { case 0: base = 10; /* assume decimal base */ if (*p == '0') { base = 8; /* could be octal */ p++; switch (*p) { case 'x': case 'X': base = 16; /* hex */ p++; break; #if BINARY case 'b': case 'B': base = 2; /* binary */ p++; break; #endif } } break; case 16: /* skip over '0x' and '0X' */ if (*p == '0' && (p[1] == 'x' || p[1] == 'X')) p += 2; break; #if BINARY case 2: /* skip over '0b' and '0B' */ if (*p == '0' && (p[1] == 'b' || p[1] == 'B')) p += 2; break; #endif } error = 0; for (;;) { c = *p; if (isdigit(c)) c -= '0'; else if (isalpha(c)) c = (c & ~0x20) - ('A' - 10); else /* unrecognized character */ break; if (c >= base) /* not in number base */ break; if ((ULLONG_MAX - c) / base < number) error = 1; number = number * base + c; p++; } if (pend) *pend = (char *)p; if (error) { number = ULLONG_MAX; errno = ERANGE; } return number; } char *Port::ull_to_string(char *buffer, ulonglong ull) { _ui64toa(ull, buffer, 10); return buffer; } wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull) { _ui64tow(ull, buffer, 10); return buffer; } double Port::ull_to_double(ulonglong ull) { double d; if ((__int64) ull < 0) { // MSVC doesn't implement the conversion d = (double) (__int64)(ull - 0x8000000000000000i64); d += (double)(signed __int64)(0x7FFFFFFFFFFFFFFFi64) + 1.0; } else d = (double)(__int64)ull; return d; } const char *Port::list_separator() { // LOCALE_SLIST for Windows return ","; } const wchar_t *Port::wlist_separator() { // LOCALE_SLIST for Windows return L","; } char *Port::strupr(char *s) { return ::strupr(s); } #endif #if linux || __APPLE__ || __FreeBSD__ || __MINGW32__ #include <math.h> #if linux #include <bits/nan.h> #include <bits/mathdef.h> #endif #include <time.h> #include <sys/time.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <float.h> static double zero = 0; double Port::nan = NAN; double Port::infinity = 1 / zero; double Port::dbl_max = 1.7976931348623157e308; double Port::dbl_min = 5e-324; long double Port::ldbl_max = LDBL_MAX; struct PortInitializer { PortInitializer(); }; static PortInitializer portinitializer; PortInitializer::PortInitializer() { // gcc nan's have the sign bit set by default, so turn it off // Need the volatile to prevent gcc from doing incorrect // constant folding. volatile long double foo; foo = NAN; if (signbit(foo)) // signbit sometimes, not always, set foo = -foo; // turn off sign bit Port::nan = foo; #if __FreeBSD__ // LDBL_MAX comes out as infinity. Fix. static unsigned char x[sizeof(long double)] = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x7F }; Port::ldbl_max = *(long double *)&x[0]; #endif } #ifndef __MINGW32__ #undef isnan #endif int Port::isNan(double r) { #if __APPLE__ return __inline_isnan(r); #elif defined __MINGW32__ return isnan(r); #else return ::isnan(r); #endif } int Port::isNan(long double r) { #if __APPLE__ return __inline_isnan(r); #elif defined __MINGW32__ return isnan(r); #else return ::isnan(r); #endif } int Port::isSignallingNan(double r) { /* A signalling NaN is a NaN with 0 as the most significant bit of * its significand, which is bit 51 of 0..63 for 64 bit doubles. */ return isNan(r) && !((((unsigned char*)&r)[6]) & 8); } int Port::isSignallingNan(long double r) { /* A signalling NaN is a NaN with 0 as the most significant bit of * its significand, which is bit 62 of 0..79 for 80 bit reals. */ return isNan(r) && !((((unsigned char*)&r)[7]) & 0x40); } #undef isfinite int Port::isFinite(double r) { return ::finite(r); } #ifndef __MINGW32__ #undef isinf #endif int Port::isInfinity(double r) { #if __APPLE__ return fpclassify(r) == FP_INFINITE; #elif defined __MINGW32__ return isinf(r); #else return ::isinf(r); #endif } #undef signbit int Port::Signbit(double r) { return (long)(((long *)&r)[1] & 0x80000000); } double Port::floor(double d) { return ::floor(d); } double Port::pow(double x, double y) { return ::pow(x, y); } unsigned long long Port::strtoull(const char *p, char **pend, int base) { return ::strtoull(p, pend, base); } char *Port::ull_to_string(char *buffer, ulonglong ull) { sprintf(buffer, "%llu", ull); return buffer; } wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull) { #ifndef __MINGW32__ swprintf(buffer, sizeof(ulonglong) * 3 + 1, L"%llu", ull); #else _snwprintf(buffer, sizeof(ulonglong) * 3 + 1, L"%llu", ull); #endif return buffer; } double Port::ull_to_double(ulonglong ull) { return (double) ull; } const char *Port::list_separator() { return ","; } const wchar_t *Port::wlist_separator() { return L","; } char *Port::strupr(char *s) { char *t = s; while (*s) { *s = toupper(*s); s++; } return t; } #endif #if __sun&&__SVR4 #define __C99FEATURES__ 1 // Needed on Solaris for NaN and more #include <math.h> #include <time.h> #include <sys/time.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <float.h> #include <ieeefp.h> static double zero = 0; double Port::nan = NAN; double Port::infinity = 1 / zero; double Port::dbl_max = 1.7976931348623157e308; double Port::dbl_min = 5e-324; long double Port::ldbl_max = LDBL_MAX; struct PortInitializer { PortInitializer(); }; static PortInitializer portinitializer; PortInitializer::PortInitializer() { // gcc nan's have the sign bit set by default, so turn it off // Need the volatile to prevent gcc from doing incorrect // constant folding. volatile long double foo; foo = NAN; if (signbit(foo)) // signbit sometimes, not always, set foo = -foo; // turn off sign bit Port::nan = foo; } int Port::isNan(double r) { return isnan(r); } int Port::isNan(long double r) { return isnan(r); } int Port::isSignallingNan(double r) { /* A signalling NaN is a NaN with 0 as the most significant bit of * its significand, which is bit 51 of 0..63 for 64 bit doubles. */ return isNan(r) && !((((unsigned char*)&r)[6]) & 8); } int Port::isSignallingNan(long double r) { /* A signalling NaN is a NaN with 0 as the most significant bit of * its significand, which is bit 62 of 0..79 for 80 bit reals. */ return isNan(r) && !((((unsigned char*)&r)[7]) & 0x40); } #undef isfinite int Port::isFinite(double r) { return finite(r); } int Port::isInfinity(double r) { return isinf(r); } #undef signbit int Port::Signbit(double r) { return (long)(((long *)&r)[1] & 0x80000000); } double Port::floor(double d) { return ::floor(d); } double Port::pow(double x, double y) { return ::pow(x, y); } unsigned long long Port::strtoull(const char *p, char **pend, int base) { return ::strtoull(p, pend, base); } char *Port::ull_to_string(char *buffer, ulonglong ull) { sprintf(buffer, "%llu", ull); return buffer; } wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull) { swprintf(buffer, sizeof(ulonglong) * 3 + 1, L"%llu", ull); return buffer; } double Port::ull_to_double(ulonglong ull) { return (double) ull; } const char *Port::list_separator() { return ","; } const wchar_t *Port::wlist_separator() { return L","; } char *Port::strupr(char *s) { char *t = s; while (*s) { *s = toupper(*s); s++; } return t; } #endif #if IN_GCC #include <math.h> #include <bits/nan.h> #include <bits/mathdef.h> #include <time.h> #include <sys/time.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> static double zero = 0; double Port::nan = NAN; double Port::infinity = 1 / zero; double Port::dbl_max = 1.7976931348623157e308; double Port::dbl_min = 5e-324; long double Port::ldbl_max = LDBL_MAX; #include "d-gcc-real.h" extern "C" bool real_isnan (const real_t *); struct PortInitializer { PortInitializer(); }; static PortInitializer portinitializer; PortInitializer::PortInitializer() { Port::infinity = real_t::getinfinity(); Port::nan = real_t::getnan(real_t::LongDouble); } #undef isnan int Port::isNan(double r) { #if __APPLE__ return __inline_isnan(r); #else return ::isnan(r); #endif } int Port::isNan(long double r) { return real_isnan(&r); } int Port::isSignallingNan(double r) { /* A signalling NaN is a NaN with 0 as the most significant bit of * its significand, which is bit 51 of 0..63 for 64 bit doubles. */ return isNan(r) && !((((unsigned char*)&r)[6]) & 8); } int Port::isSignallingNan(long double r) { /* A signalling NaN is a NaN with 0 as the most significant bit of * its significand, which is bit 62 of 0..79 for 80 bit reals. */ return isNan(r) && !((((unsigned char*)&r)[7]) & 0x40); } #undef isfinite int Port::isFinite(double r) { return ::finite(r); } #undef isinf int Port::isInfinity(double r) { return ::isinf(r); } #undef signbit int Port::Signbit(double r) { return (long)(((long *)&r)[1] & 0x80000000); } double Port::floor(double d) { return ::floor(d); } double Port::pow(double x, double y) { return ::pow(x, y); } unsigned long long Port::strtoull(const char *p, char **pend, int base) { return ::strtoull(p, pend, base); } char *Port::ull_to_string(char *buffer, ulonglong ull) { sprintf(buffer, "%llu", ull); return buffer; } wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull) { swprintf(buffer, L"%llu", ull); return buffer; } double Port::ull_to_double(ulonglong ull) { return (double) ull; } const char *Port::list_separator() { return ","; } const wchar_t *Port::wlist_separator() { return L","; } char *Port::strupr(char *s) { char *t = s; while (*s) { *s = toupper(*s); s++; } return t; } #endif