mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-04-17 17:29:02 +02:00
Merged dmd 2.059beta
This commit is contained in:
@@ -152,10 +152,10 @@ typedef char dchar;
|
||||
struct Dchar
|
||||
{
|
||||
static dchar *inc(dchar *p) { return p + 1; }
|
||||
static dchar *dec(dchar *pstart, dchar *p) { return p - 1; }
|
||||
static dchar *dec(dchar *pstart, dchar *p) { (void)pstart; return p - 1; }
|
||||
static int len(const dchar *p) { return strlen(p); }
|
||||
static int get(dchar *p) { return *p & 0xFF; }
|
||||
static int getprev(dchar *pstart, dchar *p) { return p[-1] & 0xFF; }
|
||||
static int getprev(dchar *pstart, dchar *p) { (void)pstart; return p[-1] & 0xFF; }
|
||||
static dchar *put(dchar *p, unsigned c) { *p = c; return p + 1; }
|
||||
static int cmp(dchar *s1, dchar *s2) { return strcmp(s1, s2); }
|
||||
static int memcmp(const dchar *s1, const dchar *s2, int nchars) { return ::memcmp(s1, s2, nchars); }
|
||||
|
||||
636
dmd2/root/longdouble.c
Normal file
636
dmd2/root/longdouble.c
Normal file
@@ -0,0 +1,636 @@
|
||||
|
||||
// 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
|
||||
|
||||
#if _MSC_VER
|
||||
#include "longdouble.h"
|
||||
|
||||
#include "assert.h"
|
||||
|
||||
#include <float.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
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
|
||||
return true;
|
||||
}
|
||||
static bool doInitFPU = initFPU();
|
||||
|
||||
#ifndef _WIN64
|
||||
extern "C"
|
||||
{
|
||||
|
||||
double ld_read(const longdouble* pthis)
|
||||
{
|
||||
double res;
|
||||
__asm
|
||||
{
|
||||
mov eax, pthis
|
||||
fld tbyte ptr [eax]
|
||||
fstp res
|
||||
}
|
||||
return res;
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
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]
|
||||
}
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
#endif // !_WIN64
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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 = { 0x8000000000000000ULL, 0x7fff, 0 };
|
||||
longdouble ld_snan = { 0x0000000000000001ULL, 0x7fff, 0 };
|
||||
longdouble ld_inf = { 0x0000000000000000ULL, 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;
|
||||
}
|
||||
|
||||
int ld_sprint(char* str, int fmt, longdouble x)
|
||||
{
|
||||
// fmt is 'a','A','f' or 'g'
|
||||
if(fmt != 'a' && fmt != 'A')
|
||||
{
|
||||
char format[] = { '%', fmt, 0 };
|
||||
return sprintf(str, format, ld_read(&x));
|
||||
}
|
||||
|
||||
unsigned short exp = x.exponent;
|
||||
unsigned long long mantissa = x.mantissa;
|
||||
|
||||
switch(ld_type(x))
|
||||
{
|
||||
case LD_TYPE_ZERO:
|
||||
return sprintf(str, "0x0.0L");
|
||||
case LD_TYPE_QNAN:
|
||||
case LD_TYPE_SNAN:
|
||||
return sprintf(str, "NAN");
|
||||
case LD_TYPE_INFINITE:
|
||||
return sprintf(str, x.sign ? "-INF" : "INF");
|
||||
}
|
||||
|
||||
int 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);
|
||||
|
||||
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
|
||||
|
||||
254
dmd2/root/longdouble.h
Normal file
254
dmd2/root/longdouble.h
Normal file
@@ -0,0 +1,254 @@
|
||||
|
||||
// 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
|
||||
|
||||
#ifndef __LONG_DOUBLE_H__
|
||||
#define __LONG_DOUBLE_H__
|
||||
|
||||
#if IN_GCC
|
||||
#include "d-gcc-real.h"
|
||||
typedef real_t longdouble;
|
||||
|
||||
template<typename T> longdouble ldouble(T x) { return (longdouble) x; }
|
||||
inline int ld_sprint(char* str, int fmt, longdouble x)
|
||||
{
|
||||
if(fmt == 'a' || fmt == 'A')
|
||||
return x.formatHex(buffer, 46); // don't know the size here, but 46 is the max
|
||||
return x.format(buffer, 46);
|
||||
}
|
||||
|
||||
#elif !_MSC_VER // has native 10 byte doubles
|
||||
#include <stdio.h>
|
||||
typedef long double longdouble;
|
||||
typedef volatile long double volatile_longdouble;
|
||||
|
||||
// also used from within C code, so use a #define rather than a template
|
||||
// template<typename T> longdouble ldouble(T x) { return (longdouble) x; }
|
||||
#define ldouble(x) ((longdouble)(x))
|
||||
|
||||
inline int ld_sprint(char* str, int fmt, longdouble x)
|
||||
{
|
||||
char sfmt[4] = "%Lg";
|
||||
sfmt[2] = fmt;
|
||||
return sprintf(str, sfmt, x);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <float.h>
|
||||
#include <limits>
|
||||
|
||||
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<typename T> 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;
|
||||
}
|
||||
template<typename T> inline longdouble ldouble(T x) { longdouble d; d.set(x); return d; }
|
||||
//template<typename T> inline longdouble ldouble(volatile T x) { longdouble d; d.set(x); return d; }
|
||||
|
||||
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<typename T> inline longdouble operator+(longdouble ld, T x) { return ld + ldouble(x); }
|
||||
template<typename T> inline longdouble operator-(longdouble ld, T x) { return ld - ldouble(x); }
|
||||
template<typename T> inline longdouble operator*(longdouble ld, T x) { return ld * ldouble(x); }
|
||||
template<typename T> inline longdouble operator/(longdouble ld, T x) { return ld / ldouble(x); }
|
||||
|
||||
template<typename T> inline longdouble operator+(T x, longdouble ld) { return ldouble(x) + ld; }
|
||||
template<typename T> inline longdouble operator-(T x, longdouble ld) { return ldouble(x) - ld; }
|
||||
template<typename T> inline longdouble operator*(T x, longdouble ld) { return ldouble(x) * ld; }
|
||||
template<typename T> inline longdouble operator/(T x, longdouble ld) { return ldouble(x) / ld; }
|
||||
|
||||
template<typename T> inline longdouble& operator+=(longdouble& ld, T x) { return ld = ld + x; }
|
||||
template<typename T> inline longdouble& operator-=(longdouble& ld, T x) { return ld = ld - x; }
|
||||
template<typename T> inline longdouble& operator*=(longdouble& ld, T x) { return ld = ld * x; }
|
||||
template<typename T> inline longdouble& operator/=(longdouble& ld, T x) { return ld = ld / x; }
|
||||
|
||||
template<typename T> inline bool operator< (longdouble ld, T x) { return ld < ldouble(x); }
|
||||
template<typename T> inline bool operator<=(longdouble ld, T x) { return ld <= ldouble(x); }
|
||||
template<typename T> inline bool operator> (longdouble ld, T x) { return ld > ldouble(x); }
|
||||
template<typename T> inline bool operator>=(longdouble ld, T x) { return ld >= ldouble(x); }
|
||||
template<typename T> inline bool operator==(longdouble ld, T x) { return ld == ldouble(x); }
|
||||
template<typename T> inline bool operator!=(longdouble ld, T x) { return ld != ldouble(x); }
|
||||
|
||||
template<typename T> inline bool operator< (T x, longdouble ld) { return ldouble(x) < ld; }
|
||||
template<typename T> inline bool operator<=(T x, longdouble ld) { return ldouble(x) <= ld; }
|
||||
template<typename T> inline bool operator> (T x, longdouble ld) { return ldouble(x) > ld; }
|
||||
template<typename T> inline bool operator>=(T x, longdouble ld) { return ldouble(x) >= ld; }
|
||||
template<typename T> inline bool operator==(T x, longdouble ld) { return ldouble(x) == ld; }
|
||||
template<typename T> 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;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CLASS numeric_limits<longdouble>
|
||||
template<> class _CRTIMP2_PURE std::numeric_limits<longdouble>
|
||||
: public _Num_float_base
|
||||
{ // limits for type long double
|
||||
public:
|
||||
typedef longdouble _Ty;
|
||||
|
||||
static _Ty (__CRTDECL min)() _THROW0() { return LDBL_MIN; }
|
||||
static _Ty (__CRTDECL max)() _THROW0() { return LDBL_MAX; }
|
||||
static _Ty __CRTDECL epsilon() _THROW0() { return LDBL_EPSILON; }
|
||||
static _Ty __CRTDECL round_error() _THROW0() { return ldouble(0.5); }
|
||||
static _Ty __CRTDECL denorm_min() _THROW0() { return ldouble(0x0000000000000001ULL, 1); }
|
||||
static _Ty __CRTDECL infinity() _THROW0() { return ld_inf; }
|
||||
static _Ty __CRTDECL quiet_NaN() _THROW0() { return ld_qnan; }
|
||||
static _Ty __CRTDECL signaling_NaN() _THROW0() { return ld_snan; }
|
||||
|
||||
_STCONS(int, digits, LDBL_MANT_DIG);
|
||||
_STCONS(int, digits10, LDBL_DIG);
|
||||
_STCONS(int, max_exponent, (int)LDBL_MAX_EXP);
|
||||
_STCONS(int, max_exponent10, (int)LDBL_MAX_10_EXP);
|
||||
_STCONS(int, min_exponent, (int)LDBL_MIN_EXP);
|
||||
_STCONS(int, min_exponent10, (int)LDBL_MIN_10_EXP);
|
||||
};
|
||||
|
||||
//_STCONSDEF(numeric_limits<longdouble>, int, digits)
|
||||
//_STCONSDEF(numeric_limits<longdouble>, int, digits10)
|
||||
//_STCONSDEF(numeric_limits<longdouble>, int, max_exponent)
|
||||
//_STCONSDEF(numeric_limits<longdouble>, int, max_exponent10)
|
||||
//_STCONSDEF(numeric_limits<longdouble>, int, min_exponent)
|
||||
//_STCONSDEF(numeric_limits<longdouble>, int, min_exponent10)
|
||||
|
||||
int ld_sprint(char* str, int fmt, longdouble x);
|
||||
|
||||
#endif // !_MSC_VER
|
||||
|
||||
#endif // __LONG_DOUBLE_H__
|
||||
@@ -19,8 +19,10 @@ struct Lstring
|
||||
{
|
||||
unsigned length;
|
||||
|
||||
#ifndef IN_GCC
|
||||
// Disable warning about nonstandard extension
|
||||
#pragma warning (disable : 4200)
|
||||
#endif
|
||||
dchar string[];
|
||||
|
||||
static Lstring zero; // 0 length string
|
||||
|
||||
179
dmd2/root/port.c
179
dmd2/root/port.c
@@ -17,14 +17,14 @@ 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;
|
||||
longdouble Port::ldbl_max = LDBL_MAX;
|
||||
|
||||
int Port::isNan(double r)
|
||||
{
|
||||
return ::isnan(r);
|
||||
}
|
||||
|
||||
int Port::isNan(long double r)
|
||||
int Port::isNan(longdouble r)
|
||||
{
|
||||
return ::isnan(r);
|
||||
}
|
||||
@@ -37,7 +37,7 @@ int Port::isSignallingNan(double r)
|
||||
return isNan(r) && !((((unsigned char*)&r)[6]) & 8);
|
||||
}
|
||||
|
||||
int Port::isSignallingNan(long double r)
|
||||
int Port::isSignallingNan(longdouble 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.
|
||||
@@ -70,7 +70,7 @@ double Port::pow(double x, double y)
|
||||
return ::pow(x, y);
|
||||
}
|
||||
|
||||
long double Port::fmodl(long double x, long double y)
|
||||
longdouble Port::fmodl(longdouble x, longdouble y)
|
||||
{
|
||||
return ::fmodl(x, y);
|
||||
}
|
||||
@@ -140,7 +140,7 @@ double Port::infinity = 1 / zero;
|
||||
|
||||
double Port::dbl_max = DBL_MAX;
|
||||
double Port::dbl_min = DBL_MIN;
|
||||
long double Port::ldbl_max = LDBL_MAX;
|
||||
longdouble Port::ldbl_max = LDBL_MAX;
|
||||
|
||||
struct PortInitializer
|
||||
{
|
||||
@@ -151,7 +151,7 @@ static PortInitializer portinitializer;
|
||||
|
||||
PortInitializer::PortInitializer()
|
||||
{
|
||||
Port::infinity = std::numeric_limits<long double>::infinity();
|
||||
Port::infinity = std::numeric_limits<double>::infinity();
|
||||
}
|
||||
|
||||
int Port::isNan(double r)
|
||||
@@ -159,7 +159,7 @@ int Port::isNan(double r)
|
||||
return ::_isnan(r);
|
||||
}
|
||||
|
||||
int Port::isNan(long double r)
|
||||
int Port::isNan(longdouble r)
|
||||
{
|
||||
return ::_isnan(r);
|
||||
}
|
||||
@@ -172,7 +172,7 @@ int Port::isSignallingNan(double r)
|
||||
return isNan(r) && !((((unsigned char*)&r)[6]) & 8);
|
||||
}
|
||||
|
||||
int Port::isSignallingNan(long double r)
|
||||
int Port::isSignallingNan(longdouble r)
|
||||
{
|
||||
/* MSVC doesn't have 80 bit long doubles
|
||||
*/
|
||||
@@ -206,7 +206,7 @@ double Port::pow(double x, double y)
|
||||
return ::pow(x, y);
|
||||
}
|
||||
|
||||
long double Port::fmodl(long double x, long double y)
|
||||
longdouble Port::fmodl(longdouble x, longdouble y)
|
||||
{
|
||||
return ::fmodl(x, y);
|
||||
}
|
||||
@@ -351,7 +351,7 @@ double Port::nan = copysign(NAN, 1.0);
|
||||
double Port::infinity = 1 / zero;
|
||||
double Port::dbl_max = 1.7976931348623157e308;
|
||||
double Port::dbl_min = 5e-324;
|
||||
long double Port::ldbl_max = LDBL_MAX;
|
||||
longdouble Port::ldbl_max = LDBL_MAX;
|
||||
|
||||
struct PortInitializer
|
||||
{
|
||||
@@ -366,9 +366,9 @@ PortInitializer::PortInitializer()
|
||||
|
||||
#if __FreeBSD__ && __i386__
|
||||
// LDBL_MAX comes out as infinity. Fix.
|
||||
static unsigned char x[sizeof(long double)] =
|
||||
static unsigned char x[sizeof(longdouble)] =
|
||||
{ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x7F };
|
||||
Port::ldbl_max = *(long double *)&x[0];
|
||||
Port::ldbl_max = *(longdouble *)&x[0];
|
||||
// FreeBSD defaults to double precision. Switch to extended precision.
|
||||
fpsetprec(FP_PE);
|
||||
#endif
|
||||
@@ -388,7 +388,7 @@ int Port::isNan(double r)
|
||||
#endif
|
||||
}
|
||||
|
||||
int Port::isNan(long double r)
|
||||
int Port::isNan(longdouble r)
|
||||
{
|
||||
#if __APPLE__
|
||||
return __inline_isnan(r);
|
||||
@@ -408,7 +408,7 @@ int Port::isSignallingNan(double r)
|
||||
return isNan(r) && !((((unsigned char*)&r)[6]) & 8);
|
||||
}
|
||||
|
||||
int Port::isSignallingNan(long double r)
|
||||
int Port::isSignallingNan(longdouble 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.
|
||||
@@ -454,7 +454,7 @@ double Port::pow(double x, double y)
|
||||
return ::pow(x, y);
|
||||
}
|
||||
|
||||
long double Port::fmodl(long double x, long double y)
|
||||
longdouble Port::fmodl(longdouble x, longdouble y)
|
||||
{
|
||||
#if __FreeBSD__ || __OpenBSD__
|
||||
return ::fmod(x, y); // hack for now, fix later
|
||||
@@ -532,7 +532,7 @@ 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;
|
||||
longdouble Port::ldbl_max = LDBL_MAX;
|
||||
|
||||
struct PortInitializer
|
||||
{
|
||||
@@ -546,7 +546,7 @@ 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;
|
||||
volatile longdouble foo;
|
||||
foo = NAN;
|
||||
if (signbit(foo)) // signbit sometimes, not always, set
|
||||
foo = -foo; // turn off sign bit
|
||||
@@ -558,7 +558,7 @@ int Port::isNan(double r)
|
||||
return isnan(r);
|
||||
}
|
||||
|
||||
int Port::isNan(long double r)
|
||||
int Port::isNan(longdouble r)
|
||||
{
|
||||
return isnan(r);
|
||||
}
|
||||
@@ -571,7 +571,7 @@ int Port::isSignallingNan(double r)
|
||||
return isNan(r) && !((((unsigned char*)&r)[6]) & 8);
|
||||
}
|
||||
|
||||
int Port::isSignallingNan(long double r)
|
||||
int Port::isSignallingNan(longdouble 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.
|
||||
@@ -653,144 +653,3 @@ char *Port::strupr(char *s)
|
||||
|
||||
#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
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
// Portable wrapper around compiler/system specific things.
|
||||
// The idea is to minimize #ifdef's in the app code.
|
||||
|
||||
#include "longdouble.h"
|
||||
|
||||
#ifndef TYPEDEFS
|
||||
#define TYPEDEFS
|
||||
|
||||
@@ -20,7 +22,7 @@ typedef __int64 longlong;
|
||||
typedef unsigned __int64 ulonglong;
|
||||
|
||||
// According to VC 8.0 docs, long double is the same as double
|
||||
#define strtold strtod
|
||||
longdouble strtold(const char *p,char **endp);
|
||||
#define strtof strtod
|
||||
|
||||
#else
|
||||
@@ -38,7 +40,7 @@ struct Port
|
||||
static double infinity;
|
||||
static double dbl_max;
|
||||
static double dbl_min;
|
||||
static long double ldbl_max;
|
||||
static longdouble ldbl_max;
|
||||
|
||||
#if !defined __HAIKU__ || __OpenBSD__
|
||||
#elif __GNUC__
|
||||
@@ -49,10 +51,10 @@ struct Port
|
||||
#undef signbit
|
||||
#endif
|
||||
static int isNan(double);
|
||||
static int isNan(long double);
|
||||
static int isNan(longdouble);
|
||||
|
||||
static int isSignallingNan(double);
|
||||
static int isSignallingNan(long double);
|
||||
static int isSignallingNan(longdouble);
|
||||
|
||||
static int isFinite(double);
|
||||
static int isInfinity(double);
|
||||
@@ -61,7 +63,7 @@ struct Port
|
||||
static double floor(double);
|
||||
static double pow(double x, double y);
|
||||
|
||||
static long double fmodl(long double x, long double y);
|
||||
static longdouble fmodl(longdouble x, longdouble y);
|
||||
|
||||
static ulonglong strtoull(const char *p, char **pend, int base);
|
||||
|
||||
|
||||
@@ -29,6 +29,13 @@
|
||||
#include <utime.h>
|
||||
#endif
|
||||
|
||||
#if _MSC_VER
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
/*********************************
|
||||
* #include <stdlib.h>
|
||||
* int response_expand(int *pargc,char ***pargv);
|
||||
|
||||
@@ -1533,7 +1533,7 @@ void File::stat()
|
||||
void File::checkoffset(size_t offset, size_t nbytes)
|
||||
{
|
||||
if (offset > len || offset + nbytes > len)
|
||||
error("Corrupt file '%s': offset x%zx off end of file",toChars(),offset);
|
||||
error("Corrupt file '%s': offset x%llx off end of file",toChars(),(ulonglong)offset);
|
||||
}
|
||||
|
||||
char *File::toChars()
|
||||
@@ -1802,7 +1802,7 @@ void OutBuffer::align(unsigned size)
|
||||
// The compiler shipped with Visual Studio 2005 (and possible
|
||||
// other versions) does not support C99 printf format specfiers
|
||||
// such as %z and %j
|
||||
#if _MSC_VER
|
||||
#if 0 && _MSC_VER
|
||||
using std::string;
|
||||
using std::wstring;
|
||||
|
||||
@@ -1821,7 +1821,7 @@ search_and_replace(S& str, const S& what, const S& replacement)
|
||||
#define WORKAROUND_C99_SPECIFIERS_BUG(S,tmp,f) \
|
||||
S tmp = f; \
|
||||
search_and_replace(fmt, S("%z"), S("%l")); \
|
||||
search_and_replace(fmt, S("%j"), S("%i")); \
|
||||
search_and_replace(fmt, S("%j"), S("%l")); \
|
||||
f = tmp.c_str();
|
||||
#else
|
||||
#define WORKAROUND_C99_SPECIFIERS_BUG(S,tmp,f)
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
typedef size_t hash_t;
|
||||
|
||||
#include "longdouble.h"
|
||||
#include "dchar.h"
|
||||
|
||||
char *wchar2ascii(wchar_t *);
|
||||
@@ -32,9 +33,6 @@ int wcharIsAscii(wchar_t *, unsigned len);
|
||||
|
||||
int bstrcmp(unsigned char *s1, unsigned char *s2);
|
||||
char *bstr2str(unsigned char *b);
|
||||
void error(const char *format, ...);
|
||||
void error(const wchar_t *format, ...);
|
||||
void warning(const char *format, ...);
|
||||
|
||||
#ifndef TYPEDEFS
|
||||
#define TYPEDEFS
|
||||
@@ -43,7 +41,7 @@ void warning(const char *format, ...);
|
||||
#include <float.h> // for _isnan
|
||||
#include <malloc.h> // for alloca
|
||||
// According to VC 8.0 docs, long double is the same as double
|
||||
#define strtold strtod
|
||||
longdouble strtold(const char *p,char **endp);
|
||||
#define strtof strtod
|
||||
#define isnan _isnan
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if __sun&&__SVR4
|
||||
#if __sun&&__SVR4 || _MSC_VER
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user