Skip to content

Commit

Permalink
Add longdouble Port::nan and Port::infinity.
Browse files Browse the repository at this point in the history
  • Loading branch information
ibuclaw committed Jun 18, 2013
1 parent 7fd8bb0 commit f564497
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 22 deletions.
2 changes: 1 addition & 1 deletion src/constfold.c
Expand Up @@ -603,7 +603,7 @@ Expression *Pow(Type *type, Expression *e1, Expression *e2)
// x ^^ y for x < 0 and y not an integer is not defined
if (e1->toReal() < 0.0)
{
e = new RealExp(loc, ldouble(Port::nan), type);
e = new RealExp(loc, Port::ldbl_nan, type);
}
else if (e2->toReal() == 0.5)
{
Expand Down
4 changes: 2 additions & 2 deletions src/mtype.c
Expand Up @@ -2875,7 +2875,7 @@ Expression *TypeBasic::getProperty(Loc loc, Identifier *ident, int flag)
case Tfloat64:
case Tfloat80:
{
fvalue = Port::nan;
fvalue = Port::ldbl_nan;
goto Lfvalue;
}
}
Expand All @@ -2893,7 +2893,7 @@ Expression *TypeBasic::getProperty(Loc loc, Identifier *ident, int flag)
case Tfloat32:
case Tfloat64:
case Tfloat80:
fvalue = Port::infinity;
fvalue = Port::ldbl_infinity;
goto Lfvalue;
}
}
Expand Down
91 changes: 74 additions & 17 deletions src/root/port.c
Expand Up @@ -16,7 +16,11 @@
#include <wchar.h>

double Port::nan = NAN;
longdouble Port::ldbl_nan = NAN;

double Port::infinity = INFINITY;
longdouble Port::ldbl_infinity = INFINITY;

double Port::dbl_max = DBL_MAX;
double Port::dbl_min = DBL_MIN;
longdouble Port::ldbl_max = LDBL_MAX;
Expand Down Expand Up @@ -119,13 +123,11 @@ longdouble Port::strtold(const char *buffer, char **endp)
#include <stdlib.h>
#include <limits> // for std::numeric_limits

static unsigned long nanarray[2]= { 0xFFFFFFFF, 0x7FFFFFFF };
//static unsigned long nanarray[2] = {0,0x7FF80000 };
double Port::nan = (*(double *)nanarray);
double Port::nan;
longdouble Port::ldbl_nan;

//static unsigned long infinityarray[2] = {0,0x7FF00000 };
static double zero = 0;
double Port::infinity = 1 / zero;
double Port::infinity;
longdouble Port::ldbl_infinity;

double Port::dbl_max = DBL_MAX;
double Port::dbl_min = DBL_MIN;
Expand All @@ -140,7 +142,15 @@ static PortInitializer portinitializer;

PortInitializer::PortInitializer()
{
union {
unsigned long ul[2];
double d;
} nan = {{ 0xFFFFFFFF, 0x7FFFFFFF }};

Port::nan = nan.d;
Port::ldbl_nan = ld_qnan;
Port::infinity = std::numeric_limits<double>::infinity();
Port::ldbl_infinity = ld_inf;
}

int Port::isNan(double r)
Expand Down Expand Up @@ -224,9 +234,13 @@ longdouble Port::strtold(const char *p, char **endp)
#include <float.h>
#include <assert.h>

double Port::nan;
longdouble Port::ldbl_nan;

static double zero = 0;
double Port::nan = copysign(NAN, 1.0);
double Port::infinity = 1 / zero;
longdouble Port::ldbl_infinity = 1 / zero;

double Port::dbl_max = 1.7976931348623157e308;
double Port::dbl_min = 5e-324;
longdouble Port::ldbl_max = LDBL_MAX;
Expand All @@ -240,7 +254,21 @@ static PortInitializer portinitializer;

PortInitializer::PortInitializer()
{
union
{ unsigned int ui[2];
double d;
} nan = {{ 0, 0x7FF80000 }};

Port::nan = nan.d;
assert(!signbit(Port::nan));

union
{ unsigned int ui[4];
longdouble ld;
} ldbl_nan = {{ 0, 0xC0000000, 0x7FFF, 0}};

Port::ldbl_nan = ldbl_nan.ld;
assert(!signbit(Port::ldbl_nan));
}

int Port::isNan(double r)
Expand Down Expand Up @@ -371,9 +399,13 @@ longdouble Port::strtold(const char *p, char **endp)
#include <float.h>
#include <assert.h>

double Port::nan;
longdouble Port::ldbl_nan;

static double zero = 0;
double Port::nan = copysign(NAN, 1.0);
double Port::infinity = 1 / zero;
longdouble Port::ldbl_infinity = 1 / zero;

double Port::dbl_max = 1.7976931348623157e308;
double Port::dbl_min = 5e-324;
longdouble Port::ldbl_max = LDBL_MAX;
Expand All @@ -387,8 +419,22 @@ static PortInitializer portinitializer;

PortInitializer::PortInitializer()
{
union
{ unsigned int ui[2];
double d;
} nan = {{ 0, 0x7FF80000 }};

Port::nan = nan.d;
assert(!signbit(Port::nan));

union
{ unsigned int ui[4];
longdouble ld;
} ldbl_nan = {{ 0, 0xC0000000, 0x7FFF, 0}};

Port::ldbl_nan = ldbl_nan.ld;
assert(!signbit(Port::ldbl_nan));

#if __FreeBSD__ && __i386__
// LDBL_MAX comes out as infinity. Fix.
static unsigned char x[sizeof(longdouble)] =
Expand Down Expand Up @@ -554,9 +600,13 @@ longdouble Port::strtold(const char *p, char **endp)
#include <float.h>
#include <ieeefp.h>

double Port::nan;
longdouble Port::ldbl_nan;

static double zero = 0;
double Port::nan = NAN;
double Port::infinity = 1 / zero;
longdouble Port::ldbl_infinity = 1 / zero;

double Port::dbl_max = 1.7976931348623157e308;
double Port::dbl_min = 5e-324;
longdouble Port::ldbl_max = LDBL_MAX;
Expand All @@ -570,14 +620,21 @@ static PortInitializer portinitializer;

PortInitializer::PortInitializer()
{
// gcc nan's have the sign bit set by default, so turn it off
// Need the volatile to prevent gcc from doing incorrect
// constant folding.
volatile longdouble foo;
foo = NAN;
if (signbit(foo)) // signbit sometimes, not always, set
foo = -foo; // turn off sign bit
Port::nan = foo;
union
{ unsigned int ui[2];
double d;
} nan = {{ 0, 0x7FF80000 }};

Port::nan = nan.d;
assert(!signbit(Port::nan));

union
{ unsigned int ui[4];
longdouble ld;
} ldbl_nan = {{ 0, 0xC0000000, 0x7FFF, 0}};

Port::ldbl_nan = ldbl_nan.ld;
assert(!signbit(Port::ldbl_nan));
}

int Port::isNan(double r)
Expand Down
9 changes: 7 additions & 2 deletions src/root/port.h
Expand Up @@ -10,9 +10,10 @@
// Portable wrapper around compiler/system specific things.
// The idea is to minimize #ifdef's in the app code.

#include "longdouble.h"

#include <stdlib.h> // for alloca
#include <stdint.h>

#include "longdouble.h"

#if _MSC_VER
#include <alloca.h>
Expand All @@ -26,7 +27,11 @@ typedef unsigned long long ulonglong;
struct Port
{
static double nan;
static longdouble ldbl_nan;

static double infinity;
static longdouble ldbl_infinity;

static double dbl_max;
static double dbl_min;
static longdouble ldbl_max;
Expand Down

0 comments on commit f564497

Please sign in to comment.