diff --git a/CMakeLists.txt b/CMakeLists.txt index b933e8982c9..f8ba0ad9757 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -248,26 +248,6 @@ list(REMOVE_ITEM FE_SRC ${PROJECT_SOURCE_DIR}/${DMDFE_PATH}/id.c ${PROJECT_SOURCE_DIR}/${DMDFE_PATH}/impcnvtab.c ) -# Add/remove files for MSVC -if(MSVC) - list(APPEND FE_SRC - ${PROJECT_SOURCE_DIR}/vcbuild/strtold.c -# See below why this don't work -# if(CMAKE_CL_64) -# ${PROJECT_SOURCE_DIR}/vcbuild/ldfpu.asm -# endif() - ) - if(CMAKE_CL_64) - # MASM support does not work yet! - add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/ldfpu.obj - COMMAND ${CMAKE_ASM_MASM_COMPILER} /c /Fo${CMAKE_CURRENT_BINARY_DIR}/ldfpu.obj ${PROJECT_SOURCE_DIR}/vcbuild/ldfpu.asm - DEPENDS ${PROJECT_SOURCE_DIR}/vcbuild/ldfpu.asm - COMMENT "generate ldfpu.obj") - list(APPEND FE_SRC - ${CMAKE_CURRENT_BINARY_DIR}/ldfpu.obj - ) - endif() -endif() set(LDC_SOURCE_FILES ${LDC_GENERATED} ${FE_SRC} diff --git a/dmd2/root/longdouble.c b/dmd2/root/longdouble.c deleted file mode 100644 index d53775c81af..00000000000 --- a/dmd2/root/longdouble.c +++ /dev/null @@ -1,654 +0,0 @@ - -/* Copyright (c) 1999-2014 by Digital Mars - * All Rights Reserved, written by Rainer Schuetze - * http://www.digitalmars.com - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) - * https://github.com/D-Programming-Language/dmd/blob/master/src/root/longdouble.c - */ - -// 80 bit floating point value implementation for Microsoft compiler - -#if _MSC_VER -#include "longdouble.h" - -#include "assert.h" - -#include -#include -#include - -extern "C" -{ - // implemented in ldfpu.asm for _WIN64 - int ld_initfpu(int bits, int mask); - void ld_expl(longdouble* ld, int exp); - longdouble ld_add(longdouble ld1, longdouble ld2); - longdouble ld_sub(longdouble ld1, longdouble ld2); - longdouble ld_mul(longdouble ld1, longdouble ld2); - longdouble ld_div(longdouble ld1, longdouble ld2); - longdouble ld_mod(longdouble ld1, longdouble ld2); - bool ld_cmpb(longdouble ld1, longdouble ld2); - bool ld_cmpbe(longdouble ld1, longdouble ld2); - bool ld_cmpa(longdouble ld1, longdouble ld2); - bool ld_cmpae(longdouble ld1, longdouble ld2); - bool ld_cmpe(longdouble ld1, longdouble ld2); - bool ld_cmpne(longdouble ld1, longdouble ld2); - longdouble ld_sqrt(longdouble ld1); - longdouble ld_sin(longdouble ld1); - longdouble ld_cos(longdouble ld1); - longdouble ld_tan(longdouble ld1); -} - -bool initFPU() -{ -#ifdef _WIN64 -// int old_cw = ld_initfpu(_RC_NEAR); - int old_cw = ld_initfpu(0x300 /*_PC_64 | _RC_NEAR*/, // #defines NOT identical to CPU FPU control word! - 0xF00 /*_MCW_PC | _MCW_RC*/); -#else - int old_cw = _control87(_MCW_EM | _PC_64 | _RC_NEAR, - _MCW_EM | _MCW_PC | _MCW_RC); -#endif - _set_output_format(_TWO_DIGIT_EXPONENT); - return true; -} -static bool doInitFPU = initFPU(); - -extern "C" -{ - -#ifndef _WIN64 -double ld_read(const longdouble* pthis) -{ - double res; - __asm - { - mov eax, pthis - fld tbyte ptr [eax] - fstp res - } - return res; -} -#endif // !_WIN64 - -long long ld_readll(const longdouble* pthis) -{ -#if 1 - return ld_readull(pthis); -#elif defined _WIN64 - return ld_readll(this); -#else - longdouble* pthis = this; - long long res; - __asm - { - mov eax, pthis - fld tbyte ptr [eax] - fistp qword ptr res - } - return res; -#endif -} - -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 = pthis->exponent - 0x3fff; - unsigned long long u; - if(expo < 0 || expo > 127) - return 0; - if(expo < 64) - u = pthis->mantissa >> (63 - expo); - else - u = pthis->mantissa << (expo - 63); - if(pthis->sign) - u = ~u + 1; - return u; -#else - longdouble* pthis = this; - long long res; // cannot use unsigned, VC will not generate "fistp qword" - longdouble twoPow63 = { 1ULL << 63, 0x3fff + 63, 0 }; - __asm - { - mov eax, pthis - fld tbyte ptr [eax] - fld tbyte ptr twoPow63 - fsubp ST(1),ST(0) // move it into signed range - - lea eax, res - fistp qword ptr [eax] - } - res ^= (1LL << 63); - return res; -#endif -} - -#ifndef _WIN64 -void ld_set(longdouble* pthis, double d) -{ - __asm - { - mov eax, pthis - fld d - fstp tbyte ptr [eax] - } -} -void ld_setll(longdouble* pthis, long long d) -{ - __asm - { - fild qword ptr d - mov eax, pthis - fstp tbyte ptr [eax] - } -} -void ld_setull(longdouble* pthis, unsigned long long d) -{ - d ^= (1LL << 63); - longdouble twoPow63 = { 1ULL << 63, 0x3fff + 63, 0 }; - __asm - { - fild qword ptr d - fld tbyte ptr twoPow63 - faddp ST(1),ST(0) - mov eax, pthis - fstp tbyte ptr [eax] - } -} -#endif // !_WIN64 - -} // extern "C" - -longdouble ldexpl(longdouble ld, int exp) -{ -#ifdef _WIN64 - ld_expl(&ld, exp); -#else - __asm - { - fild dword ptr exp - fld tbyte ptr ld - fscale // ST(0) = ST(0) * (2**ST(1)) - fstp ST(1) - fstp tbyte ptr ld - } -#endif - return ld; -} - -/////////////////////////////////////////////////////////////////////// -longdouble operator+(longdouble ld1, longdouble ld2) -{ -#ifdef _WIN64 - return ld_add(ld1, ld2); -#else - longdouble res; - __asm - { - fld tbyte ptr ld1 - fld tbyte ptr ld2 - fadd - fstp tbyte ptr res; - } - return res; -#endif -} - -longdouble operator-(longdouble ld1, longdouble ld2) -{ -#ifdef _WIN64 - return ld_sub(ld1, ld2); -#else - longdouble res; - __asm - { - fld tbyte ptr ld1 - fld tbyte ptr ld2 - fsub - fstp tbyte ptr res; - } - return res; -#endif -} - -longdouble operator*(longdouble ld1, longdouble ld2) -{ -#ifdef _WIN64 - return ld_mul(ld1, ld2); -#else - longdouble res; - __asm - { - fld tbyte ptr ld1 - fld tbyte ptr ld2 - fmul - fstp tbyte ptr res; - } - return res; -#endif -} - -longdouble operator/(longdouble ld1, longdouble ld2) -{ -#ifdef _WIN64 - return ld_div(ld1, ld2); -#else - longdouble res; - __asm - { - fld tbyte ptr ld1 - fld tbyte ptr ld2 - fdiv - fstp tbyte ptr res; - } - return res; -#endif -} - -bool operator< (longdouble x, longdouble y) -{ -#ifdef _WIN64 - return ld_cmpb(x, y); -#else - short sw; - bool res; - __asm - { - fld tbyte ptr y - fld tbyte ptr x // ST = x, ST1 = y - fucomip ST(0),ST(1) - setb AL - setnp AH - and AL,AH - mov res,AL - fstp ST(0) - } - return res; -#endif -} -bool operator<=(longdouble x, longdouble y) -{ -#ifdef _WIN64 - return ld_cmpbe(x, y); -#else - short sw; - bool res; - __asm - { - fld tbyte ptr y - fld tbyte ptr x // ST = x, ST1 = y - fucomip ST(0),ST(1) - setbe AL - setnp AH - and AL,AH - mov res,AL - fstp ST(0) - } - return res; -#endif -} -bool operator> (longdouble x, longdouble y) -{ -#ifdef _WIN64 - return ld_cmpa(x, y); -#else - short sw; - bool res; - __asm - { - fld tbyte ptr y - fld tbyte ptr x // ST = x, ST1 = y - fucomip ST(0),ST(1) - seta AL - setnp AH - and AL,AH - mov res,AL - fstp ST(0) - } - return res; -#endif -} -bool operator>=(longdouble x, longdouble y) -{ -#ifdef _WIN64 - return ld_cmpae(x, y); -#else - short sw; - bool res; - __asm - { - fld tbyte ptr y - fld tbyte ptr x // ST = x, ST1 = y - fucomip ST(0),ST(1) - setae AL - setnp AH - and AL,AH - mov res,AL - fstp ST(0) - } - return res; -#endif -} -bool operator==(longdouble x, longdouble y) -{ -#ifdef _WIN64 - return ld_cmpe(x, y); -#else - short sw; - bool res; - __asm - { - fld tbyte ptr y - fld tbyte ptr x // ST = x, ST1 = y - fucomip ST(0),ST(1) - sete AL - setnp AH - and AL,AH - mov res,AL - fstp ST(0) - } - return res; -#endif -} -bool operator!=(longdouble x, longdouble y) -{ -#ifdef _WIN64 - return ld_cmpne(x, y); -#else - short sw; - bool res; - __asm - { - fld tbyte ptr y - fld tbyte ptr x // ST = x, ST1 = y - fucomip ST(0),ST(1) - setne AL - setp AH - or AL,AH - mov res,AL - fstp ST(0) - } - return res; -#endif -} - - -int _isnan(longdouble ld) -{ - return (ld.exponent == 0x7fff && ld.mantissa != 0 && ld.mantissa != (1LL << 63)); // exclude pseudo-infinity and infinity, but not FP Indefinite -} - -longdouble fabsl(longdouble ld) -{ - ld.sign = 0; - return ld; -} - -longdouble sqrtl(longdouble ld) -{ -#ifdef _WIN64 - return ld_sqrt(ld); -#else - longdouble res; - __asm - { - fld tbyte ptr ld; - fsqrt; - fstp tbyte ptr res; - } - return res; -#endif -} - -longdouble sinl (longdouble ld) -{ -#ifdef _WIN64 - return ld_sin(ld); -#else - longdouble res; - __asm - { - fld tbyte ptr ld; - fsin; // exact for |x|<=PI/4 - fstp tbyte ptr res - } - return res; -#endif -} -longdouble cosl (longdouble ld) -{ -#ifdef _WIN64 - return ld_cos(ld); -#else - longdouble res; - __asm - { - fld tbyte ptr ld; - fcos; // exact for |x|<=PI/4 - fstp tbyte ptr res; - } - return res; -#endif -} -longdouble tanl (longdouble ld) -{ -#ifdef _WIN64 - return ld_tan(ld); -#else - longdouble res; - __asm - { - fld tbyte ptr ld; - fptan; - fstp ST(0); // always 1 - fstp tbyte ptr res; - } - return res; -#endif -} - -longdouble fmodl(longdouble x, longdouble y) -{ -#ifdef _WIN64 - return ld_mod(x, y); -#else - short sw; - longdouble res; - __asm - { - fld tbyte ptr y - fld tbyte ptr x // ST = x, ST1 = y -FM1: // We don't use fprem1 because for some inexplicable - // reason we get -5 when we do _modulo(15, 10) - fprem // ST = ST % ST1 - fstsw word ptr sw - fwait - mov AH,byte ptr sw+1 // get msb of status word in AH - sahf // transfer to flags - jp FM1 // continue till ST < ST1 - fstp ST(1) // leave remainder on stack - fstp tbyte ptr res; - } - return res; -#endif -} - -////////////////////////////////////////////////////////////// - -longdouble ld_qnan = { 0xC000000000000000ULL, 0x7fff, 0 }; -longdouble ld_snan = { 0xC000000000000001ULL, 0x7fff, 0 }; -longdouble ld_inf = { 0x8000000000000000ULL, 0x7fff, 0 }; - -longdouble ld_zero = { 0, 0, 0 }; -longdouble ld_one = { 0x8000000000000000ULL, 0x3fff, 0 }; -longdouble ld_pi = { 0xc90fdaa22168c235ULL, 0x4000, 0 }; -longdouble ld_log2t = { 0xd49a784bcd1b8afeULL, 0x4000, 0 }; -longdouble ld_log2e = { 0xb8aa3b295c17f0bcULL, 0x3fff, 0 }; -longdouble ld_log2 = { 0x9a209a84fbcff799ULL, 0x3ffd, 0 }; -longdouble ld_ln2 = { 0xb17217f7d1cf79acULL, 0x3ffe, 0 }; - -longdouble ld_pi2 = ld_pi*2; -longdouble ld_piOver2 = ld_pi*0.5; -longdouble ld_piOver4 = ld_pi*0.25; - -////////////////////////////////////////////////////////////// - -#define LD_TYPE_OTHER 0 -#define LD_TYPE_ZERO 1 -#define LD_TYPE_INFINITE 2 -#define LD_TYPE_SNAN 3 -#define LD_TYPE_QNAN 4 - -int ld_type(longdouble x) -{ - if(x.exponent == 0) - return x.mantissa == 0 ? LD_TYPE_ZERO : LD_TYPE_OTHER; // dnormal if not zero - if(x.exponent != 0x7fff) - return LD_TYPE_OTHER; - if(x.mantissa == 0) - return LD_TYPE_INFINITE; - if(x.mantissa & (1LL << 63)) - return LD_TYPE_QNAN; - return LD_TYPE_SNAN; -} - -size_t ld_sprint(char* str, int fmt, longdouble x) -{ - // ensure dmc compatible strings for nan and inf - switch(ld_type(x)) - { - case LD_TYPE_QNAN: - case LD_TYPE_SNAN: - return sprintf(str, "nan"); - case LD_TYPE_INFINITE: - return sprintf(str, x.sign ? "-inf" : "inf"); - } - - // fmt is 'a','A','f' or 'g' - if(fmt != 'a' && fmt != 'A') - { - if (ldouble((unsigned long long)x) == x) - { // ((1.5 -> 1 -> 1.0) == 1.5) is false - // ((1.0 -> 1 -> 1.0) == 1.0) is true - // see http://en.cppreference.com/w/cpp/io/c/fprintf - char format[] = {'%', '#', 'L', fmt, 0}; - return sprintf(str, format, ld_read(&x)); - } - char format[] = { '%', fmt, 0 }; - return sprintf(str, format, ld_read(&x)); - } - - unsigned short exp = x.exponent; - unsigned long long mantissa = x.mantissa; - - if(ld_type(x) == LD_TYPE_ZERO) - return sprintf(str, "0x0.0L"); - - size_t len = 0; - if(x.sign) - str[len++] = '-'; - len += sprintf(str + len, mantissa & (1LL << 63) ? "0x1." : "0x0."); - mantissa = mantissa << 1; - while(mantissa) - { - int dig = (mantissa >> 60) & 0xf; - dig += dig < 10 ? '0' : fmt - 10; - str[len++] = dig; - mantissa = mantissa << 4; - } - str[len++] = 'p'; - if(exp < 0x3fff) - { - str[len++] = '-'; - exp = 0x3fff - exp; - } - else - { - str[len++] = '+'; - exp = exp - 0x3fff; - } - int exppos = len; - for(int i = 12; i >= 0; i -= 4) - { - int dig = (exp >> i) & 0xf; - if(dig != 0 || len > exppos || i == 0) - str[len++] = dig + (dig < 10 ? '0' : fmt - 10); - } - str[len] = 0; - return len; -} - -////////////////////////////////////////////////////////////// - -#if UNITTEST -static bool unittest() -{ - char buffer[32]; - ld_sprint(buffer, 'a', ld_pi); - assert(strcmp(buffer, "0x1.921fb54442d1846ap+1") == 0); - - ld_sprint(buffer, 'g', ldouble(2.0)); - assert(strcmp(buffer, "2.00000") == 0); - - ld_sprint(buffer, 'g', ldouble(1234567.89)); - assert(strcmp(buffer, "1.23457e+06") == 0); - - longdouble ldb = ldouble(0.4); - long long b = ldb; - assert(b == 0); - - b = ldouble(0.9); - assert(b == 0); - - long long x = 0x12345678abcdef78LL; - longdouble ldx = ldouble(x); - assert(ldx > 0); - long long y = ldx; - assert(x == y); - - x = -0x12345678abcdef78LL; - ldx = ldouble(x); - assert(ldx < 0); - y = ldx; - assert(x == y); - - unsigned long long u = 0x12345678abcdef78LL; - longdouble ldu = ldouble(u); - assert(ldu > 0); - unsigned long long v = ldu; - assert(u == v); - - u = 0xf234567812345678ULL; - ldu = ldouble(u); - assert(ldu > 0); - v = ldu; - assert(u == v); - - u = 0xf2345678; - ldu = ldouble(u); - ldu = ldu * ldu; - ldu = sqrt(ldu); - v = ldu; - assert(u == v); - - u = 0x123456789A; - ldu = ldouble(u); - ldu = ldu * (1LL << 23); - v = ldu; - u = u * (1LL << 23); - assert(u == v); - - return true; -} - -static bool runUnittest = unittest(); - -#endif // UNITTEST - -#endif // _MSC_VER - diff --git a/dmd2/root/longdouble.h b/dmd2/root/longdouble.h index 8f046f6077d..b7f9f6723e8 100644 --- a/dmd2/root/longdouble.h +++ b/dmd2/root/longdouble.h @@ -11,7 +11,6 @@ #ifndef __LONG_DOUBLE_H__ #define __LONG_DOUBLE_H__ -#if !_MSC_VER // has native 10 byte doubles #include typedef long double longdouble; typedef volatile long double volatile_longdouble; @@ -48,192 +47,4 @@ inline size_t ld_sprint(char* str, int fmt, longdouble x) #undef sprintf #endif -#else - -#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; - unsigned short exponent:15; // bias 0x3fff - unsigned short sign:1; - unsigned short fill:16; // for 12 byte alignment - - // no constructor to be able to use this class in a union - // use ldouble() to explicitely create a longdouble value - - 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) { 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 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? -}; - -// some optimizations are avoided by adding volatile to the longdouble -// type, but this introduces bad ambiguities when using the class implementation above -// as we are going through asm these optimizations won't kick in anyway, so "volatile" -// is not required. -typedef longdouble volatile_longdouble; - -inline longdouble ldouble(unsigned long long mantissa, int exp, int sign = 0) -{ - longdouble d; - d.mantissa = mantissa; - d.exponent = exp; - d.sign = sign; - return d; -} - -// codegen bug in VS2010/VS2012, if the set() function not inlined -// (this passed on stack, but expected in ECX; RVO?) -#if _MSC_VER >= 1600 -#define LDOUBLE_INLINE __declspec(noinline) -#else -#define LDOUBLE_INLINE inline -#endif - -template LDOUBLE_INLINE longdouble ldouble(T x) { longdouble d; d.set(x); return d; } - -#undef LDOUBLE_INLINE - -longdouble operator+(longdouble ld1, longdouble ld2); -longdouble operator-(longdouble ld1, longdouble ld2); -longdouble operator*(longdouble ld1, longdouble ld2); -longdouble operator/(longdouble ld1, longdouble ld2); - -bool operator< (longdouble ld1, longdouble ld2); -bool operator<=(longdouble ld1, longdouble ld2); -bool operator> (longdouble ld1, longdouble ld2); -bool operator>=(longdouble ld1, longdouble ld2); -bool operator==(longdouble ld1, longdouble ld2); -bool operator!=(longdouble ld1, longdouble ld2); - -inline longdouble operator-(longdouble ld1) { ld1.sign ^= 1; return ld1; } -inline longdouble operator+(longdouble ld1) { return ld1; } - -template inline longdouble operator+(longdouble ld, T x) { return ld + ldouble(x); } -template inline longdouble operator-(longdouble ld, T x) { return ld - ldouble(x); } -template inline longdouble operator*(longdouble ld, T x) { return ld * ldouble(x); } -template inline longdouble operator/(longdouble ld, T x) { return ld / ldouble(x); } - -template inline longdouble operator+(T x, longdouble ld) { return ldouble(x) + ld; } -template inline longdouble operator-(T x, longdouble ld) { return ldouble(x) - ld; } -template inline longdouble operator*(T x, longdouble ld) { return ldouble(x) * ld; } -template inline longdouble operator/(T x, longdouble ld) { return ldouble(x) / ld; } - -template inline longdouble& operator+=(longdouble& ld, T x) { return ld = ld + x; } -template inline longdouble& operator-=(longdouble& ld, T x) { return ld = ld - x; } -template inline longdouble& operator*=(longdouble& ld, T x) { return ld = ld * x; } -template inline longdouble& operator/=(longdouble& ld, T x) { return ld = ld / x; } - -template inline bool operator< (longdouble ld, T x) { return ld < ldouble(x); } -template inline bool operator<=(longdouble ld, T x) { return ld <= ldouble(x); } -template inline bool operator> (longdouble ld, T x) { return ld > ldouble(x); } -template inline bool operator>=(longdouble ld, T x) { return ld >= ldouble(x); } -template inline bool operator==(longdouble ld, T x) { return ld == ldouble(x); } -template inline bool operator!=(longdouble ld, T x) { return ld != ldouble(x); } - -template inline bool operator< (T x, longdouble ld) { return ldouble(x) < ld; } -template inline bool operator<=(T x, longdouble ld) { return ldouble(x) <= ld; } -template inline bool operator> (T x, longdouble ld) { return ldouble(x) > ld; } -template inline bool operator>=(T x, longdouble ld) { return ldouble(x) >= ld; } -template inline bool operator==(T x, longdouble ld) { return ldouble(x) == ld; } -template inline bool operator!=(T x, longdouble ld) { return ldouble(x) != ld; } - -int _isnan(longdouble ld); - -longdouble fabsl(longdouble ld); -longdouble sqrtl(longdouble ld); -longdouble sinl (longdouble ld); -longdouble cosl (longdouble ld); -longdouble tanl (longdouble ld); - -longdouble fmodl(longdouble x, longdouble y); -longdouble ldexpl(longdouble ldval, int exp); // see strtold - -inline longdouble fabs (longdouble ld) { return fabsl(ld); } -inline longdouble sqrt (longdouble ld) { return sqrtl(ld); } - -#undef LDBL_DIG -#undef LDBL_MAX -#undef LDBL_MIN -#undef LDBL_EPSILON -#undef LDBL_MANT_DIG -#undef LDBL_MAX_EXP -#undef LDBL_MIN_EXP -#undef LDBL_MAX_10_EXP -#undef LDBL_MIN_10_EXP - -#define LDBL_DIG 18 -#define LDBL_MAX ldouble(0xffffffffffffffffULL, 0x7ffe) -#define LDBL_MIN ldouble(0x8000000000000000ULL, 1) -#define LDBL_EPSILON ldouble(0x8000000000000000ULL, 0x3fff - 63) // allow denormal? -#define LDBL_MANT_DIG 64 -#define LDBL_MAX_EXP 16384 -#define LDBL_MIN_EXP (-16381) -#define LDBL_MAX_10_EXP 4932 -#define LDBL_MIN_10_EXP (-4932) - -extern longdouble ld_zero; -extern longdouble ld_one; -extern longdouble ld_pi; -extern longdouble ld_log2t; -extern longdouble ld_log2e; -extern longdouble ld_log2; -extern longdouble ld_ln2; - -extern longdouble ld_inf; -extern longdouble ld_qnan; -extern longdouble ld_snan; - -size_t ld_sprint(char* str, int fmt, longdouble x); - -#endif // !_MSC_VER - #endif // __LONG_DOUBLE_H__ diff --git a/dmd2/root/port.c b/dmd2/root/port.c index 4caeceed447..affbb024a80 100644 --- a/dmd2/root/port.c +++ b/dmd2/root/port.c @@ -177,16 +177,24 @@ static PortInitializer portinitializer; PortInitializer::PortInitializer() { +#if IN_LLVM + Port::nan = std::numeric_limits::quiet_NaN(); + Port::ldbl_nan = std::numeric_limits::quiet_NaN(); + Port::snan = std::numeric_limits::signaling_NaN(); + Port::infinity = std::numeric_limits::infinity(); + Port::ldbl_infinity = std::numeric_limits::infinity(); +#else union { unsigned long ul[2]; double d; - } nan = {{ 0, 0x7FF80000 }}; + } nan = { { 0, 0x7FF80000 } }; Port::nan = nan.d; Port::ldbl_nan = ld_qnan; Port::snan = ld_snan; Port::infinity = std::numeric_limits::infinity(); Port::ldbl_infinity = ld_inf; +#endif } int Port::isNan(double r) @@ -267,7 +275,11 @@ longdouble strtold_dm(const char *p,char **endp); longdouble Port::strtold(const char *p, char **endp) { +#if IN_LLVM + return ::strtold(p, endp); +#else return ::strtold_dm(p, endp); +#endif } #endif diff --git a/gen/complex.cpp b/gen/complex.cpp index 0be05f7eee7..bf5721eacd6 100644 --- a/gen/complex.cpp +++ b/gen/complex.cpp @@ -31,20 +31,9 @@ LLType* DtoComplexBaseType(Type* t) { switch (t->toBasetype()->ty) { default: llvm_unreachable("Unexpected complex floating point type"); - case Tcomplex32: return LLType::getFloatTy(gIR->context()); - case Tcomplex64: return LLType::getDoubleTy(gIR->context()); - case Tcomplex80: - llvm::Triple::ArchType const a = global.params.targetTriple.getArch(); - if (a == llvm::Triple::x86 || a == llvm::Triple::x86_64) - { - return LLType::getX86_FP80Ty(gIR->context()); - } - else if (a == llvm::Triple::ppc || a == llvm::Triple::ppc64) - { - return LLType::getPPC_FP128Ty(gIR->context()); - } - else - return LLType::getDoubleTy(gIR->context()); + case Tcomplex32: return DtoType(Type::basic[Tfloat32]); + case Tcomplex64: return DtoType(Type::basic[Tfloat64]); + case Tcomplex80: return DtoType(Type::basic[Tfloat80]); } } diff --git a/ir/irtype.cpp b/ir/irtype.cpp index abef6d89b52..4b8dca109b1 100644 --- a/ir/irtype.cpp +++ b/ir/irtype.cpp @@ -70,15 +70,30 @@ LLType* IrTypeBasic::getComplexType(llvm::LLVMContext& ctx, LLType* type) ////////////////////////////////////////////////////////////////////////////// -llvm::Type * IrTypeBasic::basic2llvm(Type* t) +static inline llvm::Type* getReal80Type(llvm::LLVMContext& ctx) { - LLType* t2; - - llvm::LLVMContext& ctx = llvm::getGlobalContext(); llvm::Triple::ArchType const a = global.params.targetTriple.getArch(); bool const anyX86 = (a == llvm::Triple::x86) || (a == llvm::Triple::x86_64); - // Support for doubledouble has been dropped - //bool const anyPPC = (a == llvm::Triple::ppc) || (a == llvm::Triple::ppc64); + + // only x86 has 80bit float - but no support with MS C Runtime! + if (anyX86 && +#if LDC_LLVM_VER >= 305 + !global.params.targetTriple.isWindowsMSVCEnvironment() +#else + !(global.params.targetTriple.getOS() == llvm::Triple::Win32) +#endif + ) + + return llvm::Type::getX86_FP80Ty(ctx); + + return llvm::Type::getDoubleTy(ctx); +} + +////////////////////////////////////////////////////////////////////////////// + +llvm::Type * IrTypeBasic::basic2llvm(Type* t) +{ + llvm::LLVMContext& ctx = llvm::getGlobalContext(); switch(t->ty) { @@ -120,30 +135,16 @@ llvm::Type * IrTypeBasic::basic2llvm(Type* t) case Tfloat80: case Timaginary80: - // only x86 has 80bit float - if (anyX86) - return llvm::Type::getX86_FP80Ty(ctx); - // Support for doubledouble has been dropped - // PPC has a special 128bit float - //else if (anyPPC) - // return llvm::Type::getPPC_FP128Ty(ctx); - // other platforms use 64bit reals - else - return llvm::Type::getDoubleTy(ctx); - - case Tcomplex32: { - t2 = llvm::Type::getFloatTy(ctx); - return getComplexType(ctx, t2); - } + return getReal80Type(ctx); + + case Tcomplex32: + return getComplexType(ctx, llvm::Type::getFloatTy(ctx)); case Tcomplex64: - t2 = llvm::Type::getDoubleTy(ctx); - return getComplexType(ctx, t2); + return getComplexType(ctx, llvm::Type::getDoubleTy(ctx)); case Tcomplex80: - t2 = anyX86 ? llvm::Type::getX86_FP80Ty(ctx) - : llvm::Type::getDoubleTy(ctx); - return getComplexType(ctx, t2); + return getComplexType(ctx, getReal80Type(ctx)); case Tbool: return llvm::Type::getInt1Ty(ctx); diff --git a/vcbuild/fenv.h b/vcbuild/fenv.h deleted file mode 100644 index e8ccb9ce3fa..00000000000 --- a/vcbuild/fenv.h +++ /dev/null @@ -1,5 +0,0 @@ - -#include - -#define isnan _isnan - diff --git a/vcbuild/ldfpu.asm b/vcbuild/ldfpu.asm deleted file mode 100644 index 5b2f803c9f9..00000000000 --- a/vcbuild/ldfpu.asm +++ /dev/null @@ -1,336 +0,0 @@ -;; Compiler implementation of the D programming language -;; Copyright (c) 1999-2011 by Digital Mars -;; All Rights Reserved -;; written by Rainer Schuetze -;; http://www.digitalmars.com -;; License for redistribution is by either the Artistic License -;; in artistic.txt, or the GNU General Public License in gnu.txt. -;; See the included readme.txt for details. - -;; 80 bit floating point value implementation for Microsoft compiler - -;.386 -;.model flat, c - -; Custom Build Step, including a listing file placed in intermediate directory -; debug: -; ml -c -Zi "-Fl$(IntDir)\$(InputName).lst" "-Fo$(IntDir)\$(InputName).obj" "$(InputPath)" -; release: -; ml -c "-Fl$(IntDir)\$(InputName).lst" "-Fo$(IntDir)\$(InputName).obj" "$(InputPath)" -; outputs: -; $(IntDir)\$(InputName).obj - -.data - -twoPow63 dd 0, 80000000h, 03fffh + 63 - -.code - -; double ld_read(longdouble* ld); -; rcx: ld -ld_read PROC - fld tbyte ptr [rcx] - push rax - fstp qword ptr [rsp] - movq xmm0,qword ptr [rsp] - pop rax - ret -ld_read ENDP - -; long long ld_readll(longdouble* ld); -; rcx: ld -;ld_readll PROC -; fld tbyte ptr [rcx] -; push rax -; fistp qword ptr [rsp] -; pop rax -; ret -;ld_readll ENDP - -; unsigned long long ld_readull(longdouble* ld); -; rcx: ld -;ld_readull PROC -; fld tbyte ptr [rcx] -; push rax -; lea rax,twoPow63 -; fld tbyte ptr [rax] -; fsubp ST(1),ST(0) ; move it into signed range -; fistp qword ptr [rsp] -; pop rax -; btc rax,63 -; ret -;ld_readull ENDP - -; void ld_set(longdouble* ld, double d); -; rcx: ld -; xmm1: d -ld_set PROC - push rax - movq qword ptr [rsp],xmm1 - fld qword ptr [rsp] - fstp tbyte ptr [rcx] - pop rax - ret -ld_set ENDP - -; void ld_setll(longdouble* ld, long long d); -; rcx: ld -; rdx: d -ld_setll PROC - push rdx - fild qword ptr [rsp] - fstp tbyte ptr [rcx] - pop rax - ret -ld_setll ENDP - -; void ld_setull(longdouble* ld, long long d); -; rcx: ld -; rax: d -ld_setull PROC - btc rdx,63 - push rdx - fild qword ptr [rsp] - lea rax,twoPow63 - fld tbyte ptr [rax] - faddp ST(1),ST(0) - fstp tbyte ptr [rcx] - pop rax - ret -ld_setull ENDP - -; void ld_expl(longdouble* ld, int exp); -; rcx: ld -; edx: exp -ld_expl PROC - push rdx - fild dword ptr [rsp] - fld tbyte ptr [rcx] - fscale ; ST(0) = ST(0) * (2**ST(1)) - fstp ST(1) - fstp tbyte ptr [rcx] - pop rax - ret -ld_expl ENDP - -; long_double ld_add(long_double ld1, long_double ld2); -; rcx: &res -; rdx: &ld1 -; r8: &ld2 -ld_add PROC - fld tbyte ptr [r8] - fld tbyte ptr [rdx] - fadd - fstp tbyte ptr [rcx] - mov rax,rcx - ret -ld_add ENDP - -; long_double ld_sub(long_double ld1, long_double ld2); -; rcx: &res -; rdx: &ld1 -; r8: &ld2 -ld_sub PROC - fld tbyte ptr [rdx] - fld tbyte ptr [r8] - fsub - fstp tbyte ptr [rcx] - mov rax,rcx - ret -ld_sub ENDP - -; long_double ld_mul(long_double ld1, long_double ld2); -; rcx: &res -; rdx: &ld1 -; r8: &ld2 -ld_mul PROC - fld tbyte ptr [r8] - fld tbyte ptr [rdx] - fmul - fstp tbyte ptr [rcx] - mov rax,rcx - ret -ld_mul ENDP - -; long_double ld_div(long_double ld1, long_double ld2); -; rcx: &res -; rdx: &ld1 -; r8: &ld2 -ld_div PROC - fld tbyte ptr [rdx] - fld tbyte ptr [r8] - fdiv - fstp tbyte ptr [rcx] - mov rax,rcx - ret -ld_div ENDP - -; long_double ld_mod(long_double ld1, long_double ld2); -; rcx: &res -; rdx: &ld1 -; r8: &ld2 -ld_mod PROC - push rax - fld tbyte ptr [r8] - fld tbyte ptr [rdx] ; ST = x, ST1 = y -FM1: ; We don't use fprem1 because for some inexplicable - ; reason we get -5 when we do _modulo(15, 10) - fprem ; ST = ST % ST1 - fstsw word ptr [rsp] - fwait - mov AH,byte ptr [rsp+1] ; get msb of status word in AH - sahf ; transfer to flags - jp FM1 ; continue till ST < ST1 - fstp ST(1) ; leave remainder on stack - fstp tbyte ptr [ecx] - pop rax - mov rax,rcx - ret -ld_mod ENDP - -; bool ld_cmpb(long_double x, long_double y); -; rcx: &x -; rdx: &y -ld_cmpb PROC - fld tbyte ptr [rdx] - fld tbyte ptr [rcx] - fucomip ST(0),ST(1) - setb AL - setnp AH - and AL,AH - fstp ST(0) - ret -ld_cmpb ENDP - -; bool ld_cmpbe(long_double x, long_double y); -; rcx: &x -; rdx: &y -ld_cmpbe PROC - fld tbyte ptr [rdx] - fld tbyte ptr [rcx] - fucomip ST(0),ST(1) - setbe AL - setnp AH - and AL,AH - fstp ST(0) - ret -ld_cmpbe ENDP - -; bool ld_cmpa(long_double x, long_double y); -; rcx: &x -; rdx: &y -ld_cmpa PROC - fld tbyte ptr [rdx] - fld tbyte ptr [rcx] - fucomip ST(0),ST(1) - seta AL - setnp AH - and AL,AH - fstp ST(0) - ret -ld_cmpa ENDP - -; bool ld_cmpae(long_double x, long_double y); -; rcx: &x -; rdx: &y -ld_cmpae PROC - fld tbyte ptr [rdx] - fld tbyte ptr [rcx] - fucomip ST(0),ST(1) - setae AL - setnp AH - and AL,AH - fstp ST(0) - ret -ld_cmpae ENDP - -; bool ld_cmpe(long_double x, long_double y); -; rcx: &x -; rdx: &y -ld_cmpe PROC - fld tbyte ptr [rdx] - fld tbyte ptr [rcx] - fucomip ST(0),ST(1) - sete AL - setnp AH - and AL,AH - fstp ST(0) - ret -ld_cmpe ENDP - -; bool ld_cmpne(long_double x, long_double y); -; rcx: &x -; rdx: &y -ld_cmpne PROC - fld tbyte ptr [rdx] - fld tbyte ptr [rcx] - fucomip ST(0),ST(1) - setne AL - setp AH - or AL,AH - fstp ST(0) - ret -ld_cmpne ENDP - -; long_double ld_sqrt(long_double x); -; rcx: &res -; rdx: &x -ld_sqrt PROC - fld tbyte ptr [rdx] - fsqrt - fstp tbyte ptr [rcx] - mov rax,rcx - ret -ld_sqrt ENDP - -; long_double ld_sin(long_double x); -; rcx: &res -; rdx: &x -ld_sin PROC - fld tbyte ptr [rdx] - fsin - fstp tbyte ptr [rcx] - mov rax,rcx - ret -ld_sin ENDP - -; long_double ld_cos(long_double x); -; rcx: &res -; rdx: &x -ld_cos PROC - fld tbyte ptr [rdx] - fcos - fstp tbyte ptr [rcx] - mov rax,rcx - ret -ld_cos ENDP - -; long_double ld_tan(long_double x); -; rcx: &res -; rdx: &x -ld_tan PROC - fld tbyte ptr [rdx] - fptan - fstp st(0) - fstp tbyte ptr [rcx] - mov rax,rcx - ret -ld_tan ENDP - -; int ld_initfpu(int bits, int mask) -; ecx: bits -; edx: mask -ld_initfpu PROC - push rcx - fstcw word ptr [rsp] - movzx EAX,word ptr [rsp] ; also return old CW in EAX - not EDX - and EDX,EAX - or ECX,EDX - mov dword ptr [rsp],ECX - fldcw word ptr [rsp] - pop rcx - ret -ld_initfpu ENDP - -end diff --git a/vcbuild/strtold.c b/vcbuild/strtold.c deleted file mode 100644 index 4f284c616ff..00000000000 --- a/vcbuild/strtold.c +++ /dev/null @@ -1,714 +0,0 @@ -// Copyright (C) 1985-1998 by Symantec -// Copyright (C) 2000-2011 by Digital Mars -// All Rights Reserved -// http://www.digitalmars.com -// Written by Walter Bright -/* - * This source file is made available for personal use - * only. The license is in backendlicense.txt - * For any other uses, please contact Digital Mars. - */ - -#include -#include -#include -#include -#include -#include -#if _WIN32 && __DMC__ -#include -#include -#endif -#if __linux__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun -#include -#endif - -#include "longdouble.h" - -#if _WIN32 && __DMC__ -// from \sc\src\include\setlocal.h -extern char * __cdecl __locale_decpoint; -void __pascal __set_errno (int an_errno); -#endif - -#if _WIN32 || __linux__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun - -#if 0 -/* This is for compilers that don't support hex float literals, - * and also makes it clearer what constants we're trying to use. - */ - -static longdouble negtab[] = - {1e-4096L,1e-2048L,1e-1024L,1e-512L, - 1e-256L,1e-128L,1e-64L,1e-32L,1e-16L,1e-8L,1e-4L,1e-2L,1e-1L,1.0L}; - -static longdouble postab[] = - {1e+4096L,1e+2048L,1e+1024L,1e+512L, - 1e+256L,1e+128L,1e+64L,1e+32L,1e+16L,1e+8L,1e+4L,1e+2L,1e+1L}; - -#elif (defined(__GNUC__) && __FreeBSD__ && __i386__) || _MSC_VER - -// GCC on FreeBSD/i386 incorrectly rounds long double constants to double precision. Workaround: - -// Note that the [sizeof(longdouble)] takes care of whatever the 0 padding is for the -// target platform - -static unsigned char _negtab_bytes[][sizeof(longdouble)] = - { { 0xDE,0x9F,0xCE,0xD2,0xC8,0x04,0xDD,0xA6,0xD8,0x0A,0xBF,0xBF }, - { 0xE4,0x2D,0x36,0x34,0x4F,0x53,0xAE,0xCE,0x6B,0x25,0xBF,0xBF }, - { 0xBE,0xC0,0x57,0xDA,0xA5,0x82,0xA6,0xA2,0xB5,0x32,0xBF,0xBF }, - { 0x1C,0xD2,0x23,0xDB,0x32,0xEE,0x49,0x90,0x5A,0x39,0xBF,0xBF }, - { 0x3A,0x19,0x7A,0x63,0x25,0x43,0x31,0xC0,0xAC,0x3C,0xBF,0xBF }, - { 0xA1,0xE4,0xBC,0x64,0x7C,0x46,0xD0,0xDD,0x55,0x3E,0xBF,0xBF }, - { 0xA5,0xE9,0x39,0xA5,0x27,0xEA,0x7F,0xA8,0x2A,0x3F,0xBF,0xBF }, - { 0xBA,0x94,0x39,0x45,0xAD,0x1E,0xB1,0xCF,0x94,0x3F,0xBF,0xBF }, - { 0x5B,0xE1,0x4D,0xC4,0xBE,0x94,0x95,0xE6,0xC9,0x3F,0xBF,0xBF }, - { 0xFD,0xCE,0x61,0x84,0x11,0x77,0xCC,0xAB,0xE4,0x3F,0xBF,0xBF }, - { 0x2C,0x65,0x19,0xE2,0x58,0x17,0xB7,0xD1,0xF1,0x3F,0xBF,0xBF }, - { 0x0A,0xD7,0xA3,0x70,0x3D,0x0A,0xD7,0xA3,0xF8,0x3F,0xBF,0xBF }, - { 0xCD,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xFB,0x3F,0xBF,0xBF }, - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0x3F,0xBF,0xBF } }; - -static unsigned char _postab_bytes[][sizeof(longdouble)] = - { { 0x9B,0x97,0x20,0x8A,0x02,0x52,0x60,0xC4,0x25,0x75,0x18,0x28 }, - { 0xE5,0x5D,0x3D,0xC5,0x5D,0x3B,0x8B,0x9E,0x92,0x5A,0x18,0x28 }, - { 0x17,0x0C,0x75,0x81,0x86,0x75,0x76,0xC9,0x48,0x4D,0x18,0x28 }, - { 0xC7,0x91,0x0E,0xA6,0xAE,0xA0,0x19,0xE3,0xA3,0x46,0x18,0x28 }, - { 0x8E,0xDE,0xF9,0x9D,0xFB,0xEB,0x7E,0xAA,0x51,0x43,0x18,0x28 }, - { 0xE0,0x8C,0xE9,0x80,0xC9,0x47,0xBA,0x93,0xA8,0x41,0x18,0x28 }, - { 0xD5,0xA6,0xCF,0xFF,0x49,0x1F,0x78,0xC2,0xD3,0x40,0x18,0x28 }, - { 0x9E,0xB5,0x70,0x2B,0xA8,0xAD,0xC5,0x9D,0x69,0x40,0x18,0x28 }, - { 0x00,0x00,0x00,0x04,0xBF,0xC9,0x1B,0x8E,0x34,0x40,0x18,0x28 }, - { 0x00,0x00,0x00,0x00,0x00,0x20,0xBC,0xBE,0x19,0x40,0x18,0x28 }, - { 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x9C,0x0C,0x40,0x18,0x28 }, - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC8,0x05,0x40,0x18,0x28 }, - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA0,0x02,0x40,0x18,0x28 }, - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0x3F,0x18,0x28 } }; - -static longdouble *negtab = (longdouble *) _negtab_bytes; -static longdouble *postab = (longdouble *) _postab_bytes; - -#else - -// Use exact values, computed separately, to bootstrap. -// The digits here past 17 are just for amusement value, they -// only contribute to the 'sticky' bit. - -static longdouble negtab[] = -{ - 1 / 0x62.30290145104bcd64a60a9fc025254932bb0fd922271133eeae7be4a2f9151ffff868e970c234d8f51c5563f48bd2b496d868b27518ae42404964046f87cc1d213d5d0b54f74eb9281bb6c6e435fcb457200c03a5bca35f7792959da22e8d623b3e7b21e2b6100fab123cd8a1a75409f23956d4b941c759f83557de068edd2d00bcdd9d4a52ec8721ac7867f9e974996fb03d7ecd2fdc6349af06940d48741a6c2ed4684e5ab8d9c7bd7991dc03b4f63b8afd6b25ff66e42caeee333b7000a51987ec7038aec29e6ee8cac982a4ba47440496fcbe00d313d584e857fd214495bbdf373f41fd86fe49b70a5c7d2b17e0b2544f10cd4d8bfa89d0d73df29d0176cca7c234f4e6d2767113fd01c8c1a08a138c4ef80456c02d9a0ff4f1d4e3e51cb9255858325ed8d2399faddd9e9985a2df904ff6bf5c4f2ef0650ebc692c5508c2cbd6667097aced8e437b3d7fe03b2b6341a4c954108b89bc108f19ade5b533458e0dd75a53400d03119534074e89541bae9641fdd6266a3fdcbf778900fc509ba674343dd6769f3b72b882e7282566fbc6cc3f8d6b0dd9bc96119b31a96ddeff35e836b5d298f9994b8c90918e7b9a73491260806f233b7c94ab6feba2ebd6c1d9960e2d73a130d84c4a74fde9ce4724ed5bf546a03f40a8fb126ab1c32da38338eb3acc1a67778cfbe8b12acf1b23504dcd6cd995aca6a8b492ed8aa19adb95484971870239f4cea6e9cfda20c33857b32c450c3fecb534b71bd1a45b060904788f6e50fe78d6823613c8509ee3352c90ca19cfe90afb779eea37c8ab8db59a0a80627ce41d3cc425971d582dfe6d97ee63302b8e13e25feeaf19e63d326a7eb6d1c7bf2608c4cf1cc939c1307641d9b2c39497a8fcd8e0cd9e8d7c3172826ac9df13cb3d04e8d2fca26a9ff7d8b57e27ecf57bbb9373f46fee7aab86deb3f078787e2ab608b89572dac789bf627ede440b3f251f2b2322ab312bb95893d4b850be10e02d2408206e7bb8272181327ec8fa2e8a37a2d4390caea134c53c0adf9462ea75ecf9b5d0ed4d542dc19e1faf7a872e74f984d83e2dd8d92580152f18390a2b295138753d1fa8fd5d59c89f1b095edc162e2690f3cd8f62ff42923bbd87d1cde840b464a0e137d5e9a4eb8f8cde35c88baf63b71292baf1deeca19beb77fb8af6176ca776743074fa7021b97a1e0a68173c20ee69e79dadf7eb83cadbdfea5242a8329761ffe062053ccb5b92ac50b9c175a697b2b5341743c994a4503b9af26b398c6fed037d19eef4090ee8ae0725b1655fec303297cd0c2bd9cc1110c4e9968738b909454eb2a0dcfe388f15b8c898d3967a1b6dc3a5b4811a4f04f3618ac0280f4d3295a842bcfd82373a3f8ec72af2acd5071a8309cb2130504dd97d9556a1ebcad7947e0d0e30c7ae41eb659fb878f061814f6cea9c441c2d473bfe167b1a1c304e7613b22454ab9c41ff0b0905bc13176168dde6d488052f8cf8169c84cb4bf982870097012c23481161959127142e0e80cab3e6d7af6a25743dbeabcd0f237f1a016b67b2c2dfae78e341be10d6bfdf759b8ba1e81d1f4cce7c4823da7e1e7c34c0591cc245155e93b86ae5be806c0ed3f0da6146e599574efb29b172506be82913b1bb5154e05154ef084117f89a1e908efe7ae7d4724e8d2a67c001p+13600L, - 1 / 0x9.e8b3b5dc53d5de4a74d28ce329ace526a3197bbebe3034f77154ce2bcba19648b21c11eb962b1b61b93cf2ee5ca6f7e928e61d08e2d694222771e50f30278c9836230af908b40a753b7d77cd8c6be7151aab4efac5dcd83e49d6907855eeb028af623f6f7024d2c36fa9ce9d04a487fa1fb992be221ef1bd0ad5f775677ce0de08402ad3fa140eac7d56c7c9dee0bedd8a6c038f9245b2e87c348ad803ecca8f0070f8dbb57a6a445f278b3d5cf42915e818415c7f3ef82df84658ccf45cfad379433f3389a4408f43c513ef5a83fb8886fbf56d9d4bd5f860792e55ecee70beb1810d76ce39de9ec24bcf99d01953761abd9d7389c0a244de3c195355d84eeebeee6f46eadb56c6815b785ce6b7b125ac8edb0708fd8f6cae5f5715f7915b33eb417bf03c19d7917c7ba1fc6b9681428c85744695f0e866d7efc9ac375d77c1a42f40660460944545ff87a7dc62d752f7a66a57b1ab730f203c1aa9f44484d80e2e5fc5a04779c56b8a9e110c7bcbea4ca7982da4663cfe491d0dbd21feab49869733554c36685e5510c4a656654419bd438e48ff35d6c7d6ab91bac974fb1264b4f111821fa2bca416afe609c313b41e449952fbed5a151440967abbb3a8281ed6a8f16f9210c17f94e3892ee98074ff01e3cb64f32dbb6643a7a8289c8c6c54de34c101349713b44938209ce1f3861ce0fb7fedcc235552eb57a7842d71c7fd8f66912e4ad2f869c29279498719342c12866ed6f1c850dabc98342c9e51b78db2ea50d142fd8277732ed56d55a5e5a191368b8abbb6067584ee87e354ec2e472149e28dcfb27d4d3fe30968651333e001p+6800L, - 1 / 0x3.25d9d61a05d4305d9434f4a3c62d433949ae6209d4926c3f5bd2db49ef47187094c1a6970ca7e6bd2a73c5534936a8de061e8d4649f4f3235e005b80411640114a88bc491b9fc4ed520190fba035faaba6c356e38a31b5653f445975836cb0b6c975a351a28e4262ce3ce3a0b8df68368ae26a7b7e976a3310fc8f1f9031eb0f669a20288280bda5a580d98089dc1a47fe6b7595fb101a3616b6f4654b31fb6bfdf56deeecb1b896bc8fc51a16bf3fdeb3d814b505ba34c4118ad822a51abe1de3045b7a748e1042c462be695a9f9f2a07a7e89431922bbb9fc96359861c5cd134f451218b65dc60d7233e55c7231d2b9c9fce837d1e43f61f7de16cfb896634ee0ed1440ecc2cd8194c7d1e1a140ac53515c51a88991c4e871ec29f866e7c215bf55b2b722919f001p+3400L, - 1 / 0x1c.633415d4c1d238d98cab8a978a0b1f138cb07303a269974845a71d46b099bc817343afac69be5b0e9449775c1366732a93abade4b2908ee0f95f635e85a91924c3fc0695e7fc7153329c57aebfa3edac96e14f5dbc51fb2eb21a2f221e25cfea703ed321aa1da1bf28f8733b4475b579c88976c194e6574746c40513c31e1ad9b83a8a975d96976f8f9546dc77f27267fc6cf801p+1696L, - 1 / 0x5.53f75fdcefcef46eeddc80dcc7f755bc28f265f9ef17cc5573c063ff540e3c42d35a1d153624adc666b026b2716ed595d80fcf4a6e706bde50c612152f87d8d99f72bed3875b982e7c01p+848L, - 1 / 0x2.4ee91f2603a6337f19bccdb0dac404dc08d3cff5ec2374e42f0f1538fd03df99092e953e01p+424L, - 1 / 0x18.4f03e93ff9f4daa797ed6e38ed64bf6a1f01p+208L, - 1 / 0x4.ee2d6d415b85acef81p+104L, - 1 / 0x23.86f26fc1p+48L, - 1 / 0x5.f5e1p+24L, - 1 / 0x27.10p+8L, - 1 / 0x64.p+0L, - 1 / 0xa.p+0L, -}; - -static longdouble postab[] = -{ - 0x62.30290145104bcd64a60a9fc025254932bb0fd922271133eeae7be4a2f9151ffff868e970c234d8f51c5563f48bd2b496d868b27518ae42404964046f87cc1d213d5d0b54f74eb9281bb6c6e435fcb457200c03a5bca35f7792959da22e8d623b3e7b21e2b6100fab123cd8a1a75409f23956d4b941c759f83557de068edd2d00bcdd9d4a52ec8721ac7867f9e974996fb03d7ecd2fdc6349af06940d48741a6c2ed4684e5ab8d9c7bd7991dc03b4f63b8afd6b25ff66e42caeee333b7000a51987ec7038aec29e6ee8cac982a4ba47440496fcbe00d313d584e857fd214495bbdf373f41fd86fe49b70a5c7d2b17e0b2544f10cd4d8bfa89d0d73df29d0176cca7c234f4e6d2767113fd01c8c1a08a138c4ef80456c02d9a0ff4f1d4e3e51cb9255858325ed8d2399faddd9e9985a2df904ff6bf5c4f2ef0650ebc692c5508c2cbd6667097aced8e437b3d7fe03b2b6341a4c954108b89bc108f19ade5b533458e0dd75a53400d03119534074e89541bae9641fdd6266a3fdcbf778900fc509ba674343dd6769f3b72b882e7282566fbc6cc3f8d6b0dd9bc96119b31a96ddeff35e836b5d298f9994b8c90918e7b9a73491260806f233b7c94ab6feba2ebd6c1d9960e2d73a130d84c4a74fde9ce4724ed5bf546a03f40a8fb126ab1c32da38338eb3acc1a67778cfbe8b12acf1b23504dcd6cd995aca6a8b492ed8aa19adb95484971870239f4cea6e9cfda20c33857b32c450c3fecb534b71bd1a45b060904788f6e50fe78d6823613c8509ee3352c90ca19cfe90afb779eea37c8ab8db59a0a80627ce41d3cc425971d582dfe6d97ee63302b8e13e25feeaf19e63d326a7eb6d1c7bf2608c4cf1cc939c1307641d9b2c39497a8fcd8e0cd9e8d7c3172826ac9df13cb3d04e8d2fca26a9ff7d8b57e27ecf57bbb9373f46fee7aab86deb3f078787e2ab608b89572dac789bf627ede440b3f251f2b2322ab312bb95893d4b850be10e02d2408206e7bb8272181327ec8fa2e8a37a2d4390caea134c53c0adf9462ea75ecf9b5d0ed4d542dc19e1faf7a872e74f984d83e2dd8d92580152f18390a2b295138753d1fa8fd5d59c89f1b095edc162e2690f3cd8f62ff42923bbd87d1cde840b464a0e137d5e9a4eb8f8cde35c88baf63b71292baf1deeca19beb77fb8af6176ca776743074fa7021b97a1e0a68173c20ee69e79dadf7eb83cadbdfea5242a8329761ffe062053ccb5b92ac50b9c175a697b2b5341743c994a4503b9af26b398c6fed037d19eef4090ee8ae0725b1655fec303297cd0c2bd9cc1110c4e9968738b909454eb2a0dcfe388f15b8c898d3967a1b6dc3a5b4811a4f04f3618ac0280f4d3295a842bcfd82373a3f8ec72af2acd5071a8309cb2130504dd97d9556a1ebcad7947e0d0e30c7ae41eb659fb878f061814f6cea9c441c2d473bfe167b1a1c304e7613b22454ab9c41ff0b0905bc13176168dde6d488052f8cf8169c84cb4bf982870097012c23481161959127142e0e80cab3e6d7af6a25743dbeabcd0f237f1a016b67b2c2dfae78e341be10d6bfdf759b8ba1e81d1f4cce7c4823da7e1e7c34c0591cc245155e93b86ae5be806c0ed3f0da6146e599574efb29b172506be82913b1bb5154e05154ef084117f89a1e908efe7ae7d4724e8d2a67c001p+13600L, - 0x9.e8b3b5dc53d5de4a74d28ce329ace526a3197bbebe3034f77154ce2bcba19648b21c11eb962b1b61b93cf2ee5ca6f7e928e61d08e2d694222771e50f30278c9836230af908b40a753b7d77cd8c6be7151aab4efac5dcd83e49d6907855eeb028af623f6f7024d2c36fa9ce9d04a487fa1fb992be221ef1bd0ad5f775677ce0de08402ad3fa140eac7d56c7c9dee0bedd8a6c038f9245b2e87c348ad803ecca8f0070f8dbb57a6a445f278b3d5cf42915e818415c7f3ef82df84658ccf45cfad379433f3389a4408f43c513ef5a83fb8886fbf56d9d4bd5f860792e55ecee70beb1810d76ce39de9ec24bcf99d01953761abd9d7389c0a244de3c195355d84eeebeee6f46eadb56c6815b785ce6b7b125ac8edb0708fd8f6cae5f5715f7915b33eb417bf03c19d7917c7ba1fc6b9681428c85744695f0e866d7efc9ac375d77c1a42f40660460944545ff87a7dc62d752f7a66a57b1ab730f203c1aa9f44484d80e2e5fc5a04779c56b8a9e110c7bcbea4ca7982da4663cfe491d0dbd21feab49869733554c36685e5510c4a656654419bd438e48ff35d6c7d6ab91bac974fb1264b4f111821fa2bca416afe609c313b41e449952fbed5a151440967abbb3a8281ed6a8f16f9210c17f94e3892ee98074ff01e3cb64f32dbb6643a7a8289c8c6c54de34c101349713b44938209ce1f3861ce0fb7fedcc235552eb57a7842d71c7fd8f66912e4ad2f869c29279498719342c12866ed6f1c850dabc98342c9e51b78db2ea50d142fd8277732ed56d55a5e5a191368b8abbb6067584ee87e354ec2e472149e28dcfb27d4d3fe30968651333e001p+6800L, - 0x3.25d9d61a05d4305d9434f4a3c62d433949ae6209d4926c3f5bd2db49ef47187094c1a6970ca7e6bd2a73c5534936a8de061e8d4649f4f3235e005b80411640114a88bc491b9fc4ed520190fba035faaba6c356e38a31b5653f445975836cb0b6c975a351a28e4262ce3ce3a0b8df68368ae26a7b7e976a3310fc8f1f9031eb0f669a20288280bda5a580d98089dc1a47fe6b7595fb101a3616b6f4654b31fb6bfdf56deeecb1b896bc8fc51a16bf3fdeb3d814b505ba34c4118ad822a51abe1de3045b7a748e1042c462be695a9f9f2a07a7e89431922bbb9fc96359861c5cd134f451218b65dc60d7233e55c7231d2b9c9fce837d1e43f61f7de16cfb896634ee0ed1440ecc2cd8194c7d1e1a140ac53515c51a88991c4e871ec29f866e7c215bf55b2b722919f001p+3400L, - 0x1c.633415d4c1d238d98cab8a978a0b1f138cb07303a269974845a71d46b099bc817343afac69be5b0e9449775c1366732a93abade4b2908ee0f95f635e85a91924c3fc0695e7fc7153329c57aebfa3edac96e14f5dbc51fb2eb21a2f221e25cfea703ed321aa1da1bf28f8733b4475b579c88976c194e6574746c40513c31e1ad9b83a8a975d96976f8f9546dc77f27267fc6cf801p+1696L, - 0x5.53f75fdcefcef46eeddc80dcc7f755bc28f265f9ef17cc5573c063ff540e3c42d35a1d153624adc666b026b2716ed595d80fcf4a6e706bde50c612152f87d8d99f72bed3875b982e7c01p+848L, - 0x2.4ee91f2603a6337f19bccdb0dac404dc08d3cff5ec2374e42f0f1538fd03df99092e953e01p+424L, - 0x18.4f03e93ff9f4daa797ed6e38ed64bf6a1f01p+208L, - 0x4.ee2d6d415b85acef81p+104L, - 0x23.86f26fc1p+48L, - 0x5.f5e1p+24L, - 0x27.10p+8L, - 0x64.p+0L, - 0xa.p+0L, -}; - -#endif - -/************************* - * Convert string to double. - * Terminates on first unrecognized character. - */ - -longdouble strtold_dm(const char *p,char **endp) -{ - longdouble ldval; - int exp; - long long msdec,lsdec; - unsigned long msscale; - char dot,sign; - int pow; - int ndigits; - const char *pinit = p; -#if __DMC__ - static char infinity[] = "infinity"; - static char nans[] = "nans"; -#endif - unsigned int old_cw; - -#if _WIN32 && __DMC__ - fenv_t flagp; - fegetenv(&flagp); /* Store all exceptions, and current status word */ - if (_8087) - { - // disable exceptions from occurring, set max precision, and round to nearest -#if __DMC__ - __asm - { - fstcw word ptr old_cw - mov EAX,old_cw - mov ECX,EAX - and EAX,0xf0c0 - or EAX,033fh - mov old_cw,EAX - fldcw word ptr old_cw - mov old_cw,ECX - } -#else - old_cw = _control87(_MCW_EM | _PC_64 | _RC_NEAR, - _MCW_EM | _MCW_PC | _MCW_RC); -#endif - } -#endif - - while (isspace(*p)) - p++; - sign = 0; /* indicating + */ - switch (*p) - { case '-': - sign++; - /* FALL-THROUGH */ - case '+': - p++; - } - ldval = 0.0; - dot = 0; /* if decimal point has been seen */ - exp = 0; - msdec = lsdec = 0; - msscale = 1; - ndigits = 0; - -#if __DMC__ - switch (*p) - { case 'i': - case 'I': - if (memicmp(p,infinity,8) == 0) - { p += 8; - goto L4; - } - if (memicmp(p,infinity,3) == 0) /* is it "inf"? */ - { p += 3; - L4: - ldval = HUGE_VAL; - goto L3; - } - break; - case 'n': - case 'N': - if (memicmp(p,nans,4) == 0) /* "nans"? */ - { p += 4; - ldval = NANS; - goto L5; - } - if (memicmp(p,nans,3) == 0) /* "nan"? */ - { p += 3; - ldval = NAN; - L5: - if (*p == '(') /* if (n-char-sequence) */ - goto Lerr; /* invalid input */ - goto L3; - } - } -#endif - - if (*p == '0' && (p[1] == 'x' || p[1] == 'X')) - { int guard = 0; - int anydigits = 0; - - p += 2; - while (1) - { int i = *p; - - while (isxdigit(i)) - { - anydigits = 1; - i = isalpha(i) ? ((i & ~0x20) - ('A' - 10)) : i - '0'; - if (ndigits < 16) - { - msdec = msdec * 16 + i; - if (msdec) - ndigits++; - } - else if (ndigits == 16) - { - while (msdec >= 0) - { - exp--; - msdec <<= 1; - i <<= 1; - if (i & 0x10) - msdec |= 1; - } - guard = i << 4; - ndigits++; - exp += 4; - } - else - { - guard |= i; - exp += 4; - } - exp -= dot; - i = *++p; - } -#if _WIN32 && __DMC__ - if (i == *__locale_decpoint && !dot) -#else - if (i == '.' && !dot) -#endif - { p++; - dot = 4; - } - else - break; - } - - // Round up if (guard && (sticky || odd)) - if (guard & 0x80 && (guard & 0x7F || msdec & 1)) - { - msdec++; - if (msdec == 0) // overflow - { msdec = 0x8000000000000000LL; - exp++; - } - } - - if (anydigits == 0) // if error (no digits seen) - goto Lerr; - if (*p == 'p' || *p == 'P') - { - char sexp; - int e; - - sexp = 0; - switch (*++p) - { case '-': sexp++; - case '+': p++; - } - ndigits = 0; - e = 0; - while (isdigit(*p)) - { - if (e < 0x7FFFFFFF / 10 - 10) // prevent integer overflow - { - e = e * 10 + *p - '0'; - } - p++; - ndigits = 1; - } - exp += (sexp) ? -e : e; - if (!ndigits) // if no digits in exponent - goto Lerr; - - if (msdec) - { -#if __DMC__ - // The 8087 has no instruction to load an - // unsigned long long - if (msdec < 0) - { - *(long long *)&ldval = msdec; - ((unsigned short *)&ldval)[4] = 0x3FFF + 63; - } - else - { // But does for a signed one - __asm - { - fild qword ptr msdec - fstp tbyte ptr ldval - } - } -#else - int e2 = 0x3FFF + 63; - - // left justify mantissa - while (msdec >= 0) - { msdec <<= 1; - e2--; - } - - // Stuff mantissa directly into long double - *(long long *)&ldval = msdec; - ((unsigned short *)&ldval)[4] = e2; -#endif - -#if 0 - if (0) - { int i; - printf("msdec = x%llx, ldval = %Lg\n", msdec, ldval); - for (i = 0; i < 5; i++) - printf("%04x ",((unsigned short *)&ldval)[i]); - printf("\n"); - printf("%llx\n",ldval); - } -#endif - // Exponent is power of 2, not power of 10 -#if _WIN32 && __DMC__ - __asm - { - fild dword ptr exp - fld tbyte ptr ldval - fscale // ST(0) = ST(0) * (2**ST(1)) - fstp ST(1) - fstp tbyte ptr ldval - } -#else - ldval = ldexpl(ldval,exp); -#endif - } - goto L6; - } - else - goto Lerr; // exponent is required - } - else - { - while (1) - { int i = *p; - - while (isdigit(i)) - { - ndigits = 1; /* must have at least 1 digit */ - if (msdec < (0x7FFFFFFFFFFFLL-10)/10) - msdec = msdec * 10 + (i - '0'); - else if (msscale < (0xFFFFFFFF-10)/10) - { lsdec = lsdec * 10 + (i - '0'); - msscale *= 10; - } - else - { - exp++; - } - exp -= dot; - i = *++p; - } -#if _WIN32 && __DMC__ - if (i == *__locale_decpoint && !dot) -#else - if (i == '.' && !dot) -#endif - { p++; - dot++; - } - else - break; - } - if (!ndigits) // if error (no digits seen) - goto Lerr; // return 0.0 - } - if (*p == 'e' || *p == 'E') - { - char sexp; - int e; - - sexp = 0; - switch (*++p) - { case '-': sexp++; - case '+': p++; - } - ndigits = 0; - e = 0; - while (isdigit(*p)) - { - if (e < 0x7FFFFFFF / 10 - 10) // prevent integer overflow - { - e = e * 10 + *p - '0'; - } - p++; - ndigits = 1; - } - exp += (sexp) ? -e : e; - if (!ndigits) // if no digits in exponent - goto Lerr; // return 0.0 - } - -#if _WIN32 && __DMC__ - __asm - { - fild qword ptr msdec - mov EAX,msscale - cmp EAX,1 - je La1 - fild long ptr msscale - fmul - fild qword ptr lsdec - fadd - La1: - fstp tbyte ptr ldval - } -#else - ldval = msdec; - if (msscale != 1) /* if stuff was accumulated in lsdec */ - ldval = ldval * msscale + lsdec; -#endif - if (ldval) - { unsigned u; - - u = 0; - pow = 4096; - -#if _WIN32 && __DMC__ - //printf("msdec = x%x, lsdec = x%x, msscale = x%x\n",msdec,lsdec,msscale); - //printf("dval = %g, x%llx, exp = %d\n",dval,dval,exp); - __asm fld tbyte ptr ldval -#endif - - while (exp > 0) - { - while (exp >= pow) - { -#if _WIN32 && __DMC__ - __asm - { - mov EAX,u - imul EAX,10 - fld tbyte ptr postab[EAX] - fmul - } -#else - ldval *= postab[u]; -#endif - exp -= pow; - } - pow >>= 1; - u++; - } -#if _WIN32 && __DMC__ - __asm fstp tbyte ptr ldval -#endif - while (exp < 0) - { while (exp <= -pow) - { -#if _WIN32 && __DMC__ - __asm - { - mov EAX,u - imul EAX,10 - fld tbyte ptr ldval - fld tbyte ptr negtab[EAX] - fmul - fstp tbyte ptr ldval - } -#else - ldval *= negtab[u]; -#endif - if (ldval == 0) -#if _WIN32 && __DMC__ - __set_errno (ERANGE); -#else - errno = ERANGE; -#endif - exp += pow; - } - pow >>= 1; - u++; - } -#if 0 - if (0) - { int i; - for (i = 0; i < 5; i++) - printf("%04x ",ldval.value[i]); - printf("\n"); - printf("%llx\n",dval); - } -#endif - } - L6: // if overflow occurred - if (ldval == HUGE_VAL) -#if _WIN32 && __DMC__ - __set_errno (ERANGE); // range error -#else - errno = ERANGE; -#endif - - L1: - if (endp) - { - *endp = (char *) p; - } - L3: -#if _WIN32 && __DMC__ - fesetenv(&flagp); // reset floating point environment - if (_8087) - { - __asm - { - xor EAX,EAX - fstsw AX - fclex - fldcw word ptr old_cw - } - } -#endif - - return (sign) ? -ldval : ldval; - - Lerr: - p = pinit; - goto L1; -} - -#else - -longdouble strtold_dm(const char *p,char **endp) -{ - return strtod(p, endp); -} - -#endif - -/************************* Test ************************************/ - -#if 0 - -#include -#include -#include - -longdouble strtold_dm(const char *p,char **endp); - -struct longdouble -{ - unsigned short value[5]; -}; - -void main() -{ - longdouble ld; - struct longdouble x; - int i; - - errno = 0; -// ld = strtold_dm("0x1.FFFFFFFFFFFFFFFEp16383", NULL); - ld = strtold_dm("0x1.FFFFFFFFFFFFFFFEp-16382", NULL); - x = *(struct longdouble *)&ld; - for (i = 4; i >= 0; i--) - { - printf("%04x ", x.value[i]); - } - printf("\t%d\n", errno); - - ld = strtold_dm("1.0e5", NULL); - x = *(struct longdouble *)&ld; - for (i = 4; i >= 0; i--) - { - printf("%04x ", x.value[i]); - } - printf("\n"); -} - -#endif - -/************************* Bigint ************************************/ - -#if 0 - -/* This program computes powers of 10 exactly. - * Used to generate postab[]. - */ - - -#include -#include -#include - -#define NDIGITS 4096 - -void times10(unsigned *a) -{ - int i; - - for (i = 0; i < NDIGITS; i++) - { - a[i] *= 10; - if (i) - { - a[i] += a[i - 1] >> 8; - a[i - 1] &= 0xFF; - } - } -} - -void print(unsigned *a) -{ - int i; - int p; - int j; - - for (i = NDIGITS; i; ) - { - --i; - if (a[i]) - break; - } - - printf("0x%x.", a[i]); - p = i * 8; - i--; - for (j = 0; j < i; j++) - if (a[j]) - break; - for (; i >= j; i--) - { - printf("%02x", a[i]); - } - printf("p+%d", p); -} - -void main() -{ - unsigned a[NDIGITS]; - int i; - int j; - - static longdouble tab[] = - { - 0x62.30290145104bcd64a60a9fc025254932bb0fd922271133eeae7be4a2f9151ffff868e970c234d8f51c5563f48bd2b496d868b27518ae42404964046f87cc1d213d5d0b54f74eb9281bb6c6e435fcb457200c03a5bca35f7792959da22e8d623b3e7b21e2b6100fab123cd8a1a75409f23956d4b941c759f83557de068edd2d00bcdd9d4a52ec8721ac7867f9e974996fb03d7ecd2fdc6349af06940d48741a6c2ed4684e5ab8d9c7bd7991dc03b4f63b8afd6b25ff66e42caeee333b7000a51987ec7038aec29e6ee8cac982a4ba47440496fcbe00d313d584e857fd214495bbdf373f41fd86fe49b70a5c7d2b17e0b2544f10cd4d8bfa89d0d73df29d0176cca7c234f4e6d2767113fd01c8c1a08a138c4ef80456c02d9a0ff4f1d4e3e51cb9255858325ed8d2399faddd9e9985a2df904ff6bf5c4f2ef0650ebc692c5508c2cbd6667097aced8e437b3d7fe03b2b6341a4c954108b89bc108f19ade5b533458e0dd75a53400d03119534074e89541bae9641fdd6266a3fdcbf778900fc509ba674343dd6769f3b72b882e7282566fbc6cc3f8d6b0dd9bc96119b31a96ddeff35e836b5d298f9994b8c90918e7b9a73491260806f233b7c94ab6feba2ebd6c1d9960e2d73a130d84c4a74fde9ce4724ed5bf546a03f40a8fb126ab1c32da38338eb3acc1a67778cfbe8b12acf1b23504dcd6cd995aca6a8b492ed8aa19adb95484971870239f4cea6e9cfda20c33857b32c450c3fecb534b71bd1a45b060904788f6e50fe78d6823613c8509ee3352c90ca19cfe90afb779eea37c8ab8db59a0a80627ce41d3cc425971d582dfe6d97ee63302b8e13e25feeaf19e63d326a7eb6d1c7bf2608c4cf1cc939c1307641d9b2c39497a8fcd8e0cd9e8d7c3172826ac9df13cb3d04e8d2fca26a9ff7d8b57e27ecf57bbb9373f46fee7aab86deb3f078787e2ab608b89572dac789bf627ede440b3f251f2b2322ab312bb95893d4b850be10e02d2408206e7bb8272181327ec8fa2e8a37a2d4390caea134c53c0adf9462ea75ecf9b5d0ed4d542dc19e1faf7a872e74f984d83e2dd8d92580152f18390a2b295138753d1fa8fd5d59c89f1b095edc162e2690f3cd8f62ff42923bbd87d1cde840b464a0e137d5e9a4eb8f8cde35c88baf63b71292baf1deeca19beb77fb8af6176ca776743074fa7021b97a1e0a68173c20ee69e79dadf7eb83cadbdfea5242a8329761ffe062053ccb5b92ac50b9c175a697b2b5341743c994a4503b9af26b398c6fed037d19eef4090ee8ae0725b1655fec303297cd0c2bd9cc1110c4e9968738b909454eb2a0dcfe388f15b8c898d3967a1b6dc3a5b4811a4f04f3618ac0280f4d3295a842bcfd82373a3f8ec72af2acd5071a8309cb2130504dd97d9556a1ebcad7947e0d0e30c7ae41eb659fb878f061814f6cea9c441c2d473bfe167b1a1c304e7613b22454ab9c41ff0b0905bc13176168dde6d488052f8cf8169c84cb4bf982870097012c23481161959127142e0e80cab3e6d7af6a25743dbeabcd0f237f1a016b67b2c2dfae78e341be10d6bfdf759b8ba1e81d1f4cce7c4823da7e1e7c34c0591cc245155e93b86ae5be806c0ed3f0da6146e599574efb29b172506be82913b1bb5154e05154ef084117f89a1e908efe7ae7d4724e8d2a67c001p+13600L, - 0x9.e8b3b5dc53d5de4a74d28ce329ace526a3197bbebe3034f77154ce2bcba19648b21c11eb962b1b61b93cf2ee5ca6f7e928e61d08e2d694222771e50f30278c9836230af908b40a753b7d77cd8c6be7151aab4efac5dcd83e49d6907855eeb028af623f6f7024d2c36fa9ce9d04a487fa1fb992be221ef1bd0ad5f775677ce0de08402ad3fa140eac7d56c7c9dee0bedd8a6c038f9245b2e87c348ad803ecca8f0070f8dbb57a6a445f278b3d5cf42915e818415c7f3ef82df84658ccf45cfad379433f3389a4408f43c513ef5a83fb8886fbf56d9d4bd5f860792e55ecee70beb1810d76ce39de9ec24bcf99d01953761abd9d7389c0a244de3c195355d84eeebeee6f46eadb56c6815b785ce6b7b125ac8edb0708fd8f6cae5f5715f7915b33eb417bf03c19d7917c7ba1fc6b9681428c85744695f0e866d7efc9ac375d77c1a42f40660460944545ff87a7dc62d752f7a66a57b1ab730f203c1aa9f44484d80e2e5fc5a04779c56b8a9e110c7bcbea4ca7982da4663cfe491d0dbd21feab49869733554c36685e5510c4a656654419bd438e48ff35d6c7d6ab91bac974fb1264b4f111821fa2bca416afe609c313b41e449952fbed5a151440967abbb3a8281ed6a8f16f9210c17f94e3892ee98074ff01e3cb64f32dbb6643a7a8289c8c6c54de34c101349713b44938209ce1f3861ce0fb7fedcc235552eb57a7842d71c7fd8f66912e4ad2f869c29279498719342c12866ed6f1c850dabc98342c9e51b78db2ea50d142fd8277732ed56d55a5e5a191368b8abbb6067584ee87e354ec2e472149e28dcfb27d4d3fe30968651333e001p+6800L, - 0x3.25d9d61a05d4305d9434f4a3c62d433949ae6209d4926c3f5bd2db49ef47187094c1a6970ca7e6bd2a73c5534936a8de061e8d4649f4f3235e005b80411640114a88bc491b9fc4ed520190fba035faaba6c356e38a31b5653f445975836cb0b6c975a351a28e4262ce3ce3a0b8df68368ae26a7b7e976a3310fc8f1f9031eb0f669a20288280bda5a580d98089dc1a47fe6b7595fb101a3616b6f4654b31fb6bfdf56deeecb1b896bc8fc51a16bf3fdeb3d814b505ba34c4118ad822a51abe1de3045b7a748e1042c462be695a9f9f2a07a7e89431922bbb9fc96359861c5cd134f451218b65dc60d7233e55c7231d2b9c9fce837d1e43f61f7de16cfb896634ee0ed1440ecc2cd8194c7d1e1a140ac53515c51a88991c4e871ec29f866e7c215bf55b2b722919f001p+3400L, - 0x1c.633415d4c1d238d98cab8a978a0b1f138cb07303a269974845a71d46b099bc817343afac69be5b0e9449775c1366732a93abade4b2908ee0f95f635e85a91924c3fc0695e7fc7153329c57aebfa3edac96e14f5dbc51fb2eb21a2f221e25cfea703ed321aa1da1bf28f8733b4475b579c88976c194e6574746c40513c31e1ad9b83a8a975d96976f8f9546dc77f27267fc6cf801p+1696L, - 0x5.53f75fdcefcef46eeddc80dcc7f755bc28f265f9ef17cc5573c063ff540e3c42d35a1d153624adc666b026b2716ed595d80fcf4a6e706bde50c612152f87d8d99f72bed3875b982e7c01p+848L, - 0x2.4ee91f2603a6337f19bccdb0dac404dc08d3cff5ec2374e42f0f1538fd03df99092e953e01p+424L, - 0x18.4f03e93ff9f4daa797ed6e38ed64bf6a1f01p+208L, - 0x4.ee2d6d415b85acef81p+104L, - 0x23.86f26fc1p+48L, - 0x5.f5e1p+24L, - 0x27.10p+8L, - 0x64.p+0L, - 0xa.p+0L, - }; - - for (j = 1; j <= 4096; j *= 2) - { - printf("%4d: ", j); - memset(a, 0, sizeof(a)); - a[0] = 1; - for (i = 0; i < j; i++) - times10(a); - print(a); - printf("L,\n"); - } - - for (i = 0; i < 13; i++) - { - printf("tab[%d] = %Lg\n", i, tab[i]); - } -} - -#endif - diff --git a/vcbuild/warnings.h b/vcbuild/warnings.h deleted file mode 100644 index 19d930220ab..00000000000 --- a/vcbuild/warnings.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma warning(disable:4996) // This function or variable may be unsafe. -#pragma warning(disable:4127) // conditional expression is constant -#pragma warning(disable:4101) // unreferenced local variable -#pragma warning(disable:4100) // unreferenced formal parameter -#pragma warning(disable:4146) // unary minus operator applied to unsigned type, result still unsigned -#pragma warning(disable:4244) // conversion from 'int' to 'unsigned short', possible loss of data -#pragma warning(disable:4245) // conversion from 'int' to 'unsigned int', signed/unsigned mismatch -#pragma warning(disable:4018) // signed/unsigned mismatch -#pragma warning(disable:4389) // signed/unsigned mismatch -#pragma warning(disable:4505) // unreferenced local function has been removed -#pragma warning(disable:4701) // potentially uninitialized local variable 'm' used -#pragma warning(disable:4201) // nonstandard extension used : nameless struct/union -#pragma warning(disable:4189) // local variable is initialized but not referenced -#pragma warning(disable:4102) // unreferenced label -#pragma warning(disable:4800) // forcing value to bool 'true' or 'false' (performance warning) -#pragma warning(disable:4804) // '+=' : unsafe use of type 'bool' in operation -#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 -#pragma warning(disable:4063) // case '0' is not a valid value for switch of enum -#pragma warning(disable:4305) // 'initializing' : truncation from 'double' to 'float' -#pragma warning(disable:4309) // 'initializing' : truncation of constant value -#pragma warning(disable:4310) // cast truncates constant value -#pragma warning(disable:4806) // '^' : unsafe operation: no value of type 'bool' promoted to type 'int' can equal the given constant -#pragma warning(disable:4060) // switch statement contains no 'case' or 'default' labels -#pragma warning(disable:4099) // type name first seen using 'struct' now seen using 'class' -#pragma warning(disable:4725) // instruction may be inaccurate on some Pentiums - -#ifdef _WIN64 -#pragma warning(disable:4366) // The result of the unary '&' operator may be unaligned -#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int', possible loss of data -#pragma warning(disable:4310) // cast truncates constant value -#endif - -#define LITTLE_ENDIAN 1 -#define __pascal -#define MARS 1 -#define UNITTEST 1 -#define _M_I86 1 -#define DM_TARGET_CPU_X86 1