From 5afc4868adc33c7e846267a988008e8883da3e93 Mon Sep 17 00:00:00 2001 From: Rainer Schuetze Date: Tue, 22 Nov 2011 08:34:48 +0100 Subject: [PATCH] tweaked command line moved some inline asm to C-function to not interfere with optimizations build with VS2011 --- src/root/longdouble.c | 63 ++++++++++----------------- src/root/longdouble.h | 92 +++++++++++++++++++++------------------- src/vcbuild/builddmd.bat | 3 ++ src/vcbuild/dmc_cl.bat | 7 +-- src/vcbuild/warnings.h | 1 + 5 files changed, 79 insertions(+), 87 deletions(-) diff --git a/src/root/longdouble.c b/src/root/longdouble.c index cb821bd979df..47e7e5f30628 100644 --- a/src/root/longdouble.c +++ b/src/root/longdouble.c @@ -23,12 +23,6 @@ extern "C" { // implemented in ldfpu.asm for _WIN64 int ld_initfpu(int bits, int mask); - double ld_read(longdouble* ld); - long long ld_readll(longdouble* ld); - unsigned long long ld_readull(longdouble* ld); - void ld_set(longdouble* ld, double d); - void ld_setll(longdouble* ld, long long d); - void ld_setull(longdouble* ld, unsigned long long d); void ld_expl(longdouble* ld, int exp); longdouble ld_add(longdouble ld1, longdouble ld2); longdouble ld_sub(longdouble ld1, longdouble ld2); @@ -61,24 +55,25 @@ bool initFPU() } static bool doInitFPU = initFPU(); -double longdouble::readd() +#ifndef _WIN64 +extern "C" +{ + +double ld_read(const longdouble* pthis) { -#ifdef _WIN64 - return ld_read(this); -#else - longdouble* pthis = this; + double res; __asm { mov eax, pthis fld tbyte ptr [eax] + fstp res } - // return double in FP register -#endif + return res; } -long long longdouble::readll() +long long ld_readll(const longdouble* pthis) { #if 1 - return readull(); + return ld_readull(pthis); #elif defined _WIN64 return ld_readll(this); #else @@ -94,26 +89,24 @@ long long longdouble::readll() #endif } -unsigned long long longdouble::readull() +unsigned long long ld_readull(const longdouble* pthis) { #if 1 // somehow the FPU does not respect the CHOP mode of the rounding control // in 64-bit mode // so we roll our own conversion (it also allows the usual C wrap-around // instead of the "invalid value" created by the FPU) - int expo = exponent - 0x3fff; + int expo = pthis->exponent - 0x3fff; unsigned long long u; if(expo < 0 || expo > 127) return 0; if(expo < 64) - u = mantissa >> (63 - expo); + u = pthis->mantissa >> (63 - expo); else - u = mantissa << (expo - 63); - if(sign) + u = pthis->mantissa << (expo - 63); + if(pthis->sign) u = ~u + 1; return u; -#elif defined _WIN64 - return ld_readull(this); #else longdouble* pthis = this; long long res; // cannot use unsigned, VC will not generate "fistp qword" @@ -133,41 +126,27 @@ unsigned long long longdouble::readull() #endif } -void longdouble::setd(double d) +void ld_set(longdouble* pthis, double d) { -#ifdef _WIN64 - return ld_set(this, d); -#else - longdouble* pthis = this; __asm { mov eax, pthis fld d fstp tbyte ptr [eax] } -#endif } -void longdouble::setll(long long d) +void ld_setll(longdouble* pthis, long long d) { -#ifdef _WIN64 - return ld_setll(this, d); -#else - longdouble* pthis = this; __asm { fild qword ptr d mov eax, pthis fstp tbyte ptr [eax] } -#endif } -void longdouble::setull(unsigned long long d) +void ld_setull(longdouble* pthis, unsigned long long d) { -#ifdef _WIN64 - return ld_setull(this, d); -#else d ^= (1LL << 63); - longdouble* pthis = this; longdouble twoPow63 = { 1ULL << 63, 0x3fff + 63, 0 }; __asm { @@ -177,9 +156,11 @@ void longdouble::setull(unsigned long long d) mov eax, pthis fstp tbyte ptr [eax] } -#endif } +} // extern "C" +#endif // !_WIN64 + longdouble ldexpl(longdouble ld, int exp) { #ifdef _WIN64 @@ -539,7 +520,7 @@ int ld_sprint(char* str, int fmt, longdouble x) if(fmt != 'a' && fmt != 'A') { char format[] = { '%', fmt, 0 }; - return sprintf(str, format, x.readd()); + return sprintf(str, format, ld_read(&x)); } unsigned short exp = x.exponent; diff --git a/src/root/longdouble.h b/src/root/longdouble.h index 269525ac9256..139a0d62f8e0 100644 --- a/src/root/longdouble.h +++ b/src/root/longdouble.h @@ -46,6 +46,19 @@ inline int ld_sprint(char* str, int fmt, longdouble x) #include #include +struct longdouble; + +extern "C" +{ + // implemented in ldfpu.asm for _WIN64 + double ld_read(const longdouble* ld); + long long ld_readll(const longdouble* ld); + unsigned long long ld_readull(const longdouble* ld); + void ld_set(longdouble* ld, double d); + void ld_setll(longdouble* ld, long long d); + void ld_setull(longdouble* ld, unsigned long long d); +} + struct longdouble { unsigned long long mantissa; @@ -56,49 +69,42 @@ struct longdouble // no constructor to be able to use this class in a union // use ldouble() to explicitely create a longdouble value - double readd(); - long long readll(); - unsigned long long readull(); - void setd(double d); - void setll(long long d); - void setull(unsigned long long d); - template longdouble& operator=(T x) { set(x); return *this; } void set(longdouble ld) { mantissa = ld.mantissa; exponent = ld.exponent; sign = ld.sign; } // we need to list all basic types to avoid ambiguities - void set(float d) { setd(d); } - void set(double d) { setd(d); } - void set(long double d) { setd(d); } - - void set(signed char d) { setd(d); } - void set(short d) { setd(d); } - void set(int d) { setd(d); } - void set(long d) { setd(d); } - void set(long long d) { setll(d); } - - void set(unsigned char d) { setd(d); } - void set(unsigned short d) { setd(d); } - void set(unsigned int d) { setd(d); } - void set(unsigned long d) { setd(d); } - void set(unsigned long long d) { setull(d); } - void set(bool d) { setd(d); } + void set(float d) { ld_set(this, d); } + void set(double d) { ld_set(this, d); } + void set(long double d) { ld_set(this, d); } + + void set(signed char d) { ld_set(this, d); } + void set(short d) { ld_set(this, d); } + void set(int d) { ld_set(this, d); } + void set(long d) { ld_set(this, d); } + void set(long long d) { ld_setll(this, d); } + + void set(unsigned char d) { ld_set(this, d); } + void set(unsigned short d) { ld_set(this, d); } + void set(unsigned int d) { ld_set(this, d); } + void set(unsigned long d) { ld_set(this, d); } + void set(unsigned long long d) { ld_setull(this, d); } + void set(bool d) { ld_set(this, d); } - operator float () { return readd(); } - operator double () { return readd(); } - - operator signed char () { return readd(); } - operator short () { return readd(); } - operator int () { return readd(); } - operator long () { return readd(); } - operator long long () { return readll(); } - - operator unsigned char () { return readd(); } - operator unsigned short () { return readd(); } - operator unsigned int () { return readd(); } - operator unsigned long () { return readd(); } - operator unsigned long long() { return readull(); } + operator float () { return ld_read(this); } + operator double () { return ld_read(this); } + + operator signed char () { return ld_read(this); } + operator short () { return ld_read(this); } + operator int () { return ld_read(this); } + operator long () { return ld_read(this); } + operator long long () { return ld_readll(this); } + + operator unsigned char () { return ld_read(this); } + operator unsigned short () { return ld_read(this); } + operator unsigned int () { return ld_read(this); } + operator unsigned long () { return ld_read(this); } + operator unsigned long long() { return ld_readull(this); } operator bool () { return mantissa != 0 || exponent != 0; } // correct? }; @@ -234,12 +240,12 @@ template<> class _CRTIMP2_PURE std::numeric_limits _STCONS(int, min_exponent10, (int)LDBL_MIN_10_EXP); }; -_STCONSDEF(numeric_limits, int, digits) -_STCONSDEF(numeric_limits, int, digits10) -_STCONSDEF(numeric_limits, int, max_exponent) -_STCONSDEF(numeric_limits, int, max_exponent10) -_STCONSDEF(numeric_limits, int, min_exponent) -_STCONSDEF(numeric_limits, int, min_exponent10) +//_STCONSDEF(numeric_limits, int, digits) +//_STCONSDEF(numeric_limits, int, digits10) +//_STCONSDEF(numeric_limits, int, max_exponent) +//_STCONSDEF(numeric_limits, int, max_exponent10) +//_STCONSDEF(numeric_limits, int, min_exponent) +//_STCONSDEF(numeric_limits, int, min_exponent10) int ld_sprint(char* str, int fmt, longdouble x); diff --git a/src/vcbuild/builddmd.bat b/src/vcbuild/builddmd.bat index dcae23bc607e..b355610d2fe3 100644 --- a/src/vcbuild/builddmd.bat +++ b/src/vcbuild/builddmd.bat @@ -4,6 +4,9 @@ rem vcbuild\builddmd.bat rem rem Make sure that you do not have cl.exe from the dmc compiler rem in your path! +rem +rem "make" should be the Digital Mars make, this can be found +rem if dmd's bin folder is in the path set DEBUG=/Zi if "%1" == "release" set DEBUG=/O2 diff --git a/src/vcbuild/dmc_cl.bat b/src/vcbuild/dmc_cl.bat index bc614f27c09a..f6dab6a23df1 100644 --- a/src/vcbuild/dmc_cl.bat +++ b/src/vcbuild/dmc_cl.bat @@ -1,7 +1,8 @@ @echo off rem echo called with: %* set def=/DLITTLE_ENDIAN=1 /D__pascal= /D_M_I86=1 -set copt= +rem copt defaults to linker options +set copt=/nologo /link /LARGEADDRESSAWARE set cmd= :next if "%1" == "" goto done @@ -15,7 +16,7 @@ if "%opt:~-2%" == ".c" goto isC if "%opt:~-4%" == ".obj" goto add set opt=%opt%.c :isC -set copt=/TP /Ivcbuild /Iroot /nologo /EHsc %def% +set copt=/TP /Ivcbuild /Iroot /nologo /EHsc /Zp1 %def% goto add :opt @@ -40,4 +41,4 @@ goto next :done rem echo cl %copt% %cmd% -cl %copt% %cmd% +cl %cmd% %copt% diff --git a/src/vcbuild/warnings.h b/src/vcbuild/warnings.h index 78e3f0b6854f..3e60ae6f7ade 100644 --- a/src/vcbuild/warnings.h +++ b/src/vcbuild/warnings.h @@ -15,6 +15,7 @@ #pragma warning(disable:4800) // forcing value to bool 'true' or 'false' (performance warning) #pragma warning(disable:4390) // ';' : empty controlled statement found; is this the intent? #pragma warning(disable:4702) // unreachable code +#pragma warning(disable:4703) // potentially uninitialized local pointer variable 'm' used #ifdef _WIN64 #pragma warning(disable:4366) // The result of the unary '&' operator may be unaligned