#ifdef __APPLE_CC__
#if __APPLE_CC__ > 930
#include "math.h"
#include "fenv_private.h"
#include "fp_private.h"
static const double rintFactor = 6.7553994410557440000e+15;
static const double oneOverLn2 = 1.4426950408889633000e+00;
static const double ln2Head = 6.9314718055994530000e-01;
static const double ln2Tail = 2.3190468138462996000e-17;
static const double maxExp = 7.0978271289338397000e+02;
static const double minExp = -7.4513321910194122000e+02;
static const double maxExp2 = 1024.0;
static const double minNormExp2 = -1022.0;
static const double minExp2 = -1075.0;
static const double denormal = 2.9387358770557188000e-39;
static const double oneOverDenorm = 3.402823669209384635e+38;
static const hexdouble infinity = HEXDOUBLE(0x7ff00000, 0x00000000);
static const double cm1 = 8.3333336309523691e-03;
static const double c0 = 4.1666668402777808000e-02;
static const double c1 = 1.6666666666666655000e-01;
static const double c2 = 4.9999999999999955000e-01;
static const double cc4 = 0.5000000000000000000;
static const double cc3 = 0.16666666666663809522820;
static const double cc2 = 0.04166666666666111110939;
static const double cc1 = 0.008333338095239329810170;
static const double cc0 = 0.001388889583333492938381;
extern const unsigned long int expTable[];
struct expTableEntry
{
double x;
double f;
};
static const double kMinNormal = 2.2250738585072014e-308; static const double kMaxNormal = 1.7976931348623157e308;
#if !defined(BUILDING_FOR_CARBONCORE_LEGACY)
#ifdef notdef
double exp ( double x )
{
hexdouble scale, xInHex, yInHex, OldEnvironment;
register double d, y, yTail, z, zTail, z2, temp1, temp2, power, result;
register long int i;
struct expTableEntry *tablePointer = ( struct expTableEntry * ) expTable + 177;
xInHex.d = x;
if ( ( xInHex.i.hi & 0x7ff00000 ) < 0x40800000ul )
{ if ( ( ( xInHex.i.hi & 0x7fffffff ) | xInHex.i.lo ) == 0x0ul )
return 1.0;
scale.d = 0.0;
FEGETENVD ( OldEnvironment.d ); FESETENVD ( 0.0 );
yInHex.d = x * oneOverLn2 + rintFactor;
scale.i.hi = ( yInHex.i.lo + 1023 ) << 20;
yInHex.d -= rintFactor;
y = x - ln2Head * yInHex.d;
yTail = ln2Tail * yInHex.d;
xInHex.d = 512.0 * y + rintFactor;
i = xInHex.i.lo;
d = y - tablePointer[i].x;
z = d - yTail;
zTail = d - z - yTail;
z2 = z * z;
temp1 = cm1 * z2 + c1;
temp2 = c0 * z2 + c2;
OldEnvironment.i.lo |= FE_INEXACT; temp1 = temp1 * z + temp2;
temp2 = temp1 * z2 + z;
result = scale.d * tablePointer[i].f;
temp1 = result * ( temp2 + ( zTail + zTail * temp2 ) );
result += temp1;
FESETENVD ( OldEnvironment.d );
return result;
}
if ( ( x <= maxExp ) && ( x > minExp ) )
{
scale.d = 0.0;
FEGETENVD ( OldEnvironment.d ); FESETENVD ( 0.0 );
yInHex.d = x * oneOverLn2 + rintFactor;
if ( x >= 512.0 )
{
power = 2.0;
scale.i.hi = ( yInHex.i.lo + 1022 ) << 20;
}
else
{
power = denormal;
scale.i.hi = ( yInHex.i.lo + 1023+128 ) << 20;
}
yInHex.d -= rintFactor;
y = x - ln2Head * yInHex.d;
yTail = ln2Tail * yInHex.d;
xInHex.d = 512.0 * y + rintFactor;
i = xInHex.i.lo;
d = y - tablePointer[i].x;
z = d - yTail;
zTail = d - z - yTail;
z2 = z * z;
temp1 = cm1 * z2 + c1;
temp2 = c0 * z2 + c2;
OldEnvironment.i.lo |= FE_INEXACT; temp1 = temp1 * z + temp2;
temp2 = temp1 * z2 + z;
result = scale.d * tablePointer[i].f;
temp1 = result * ( temp2 + ( zTail + zTail * temp2 ) );
result = ( result + temp1 ) * power;
FESETENVD ( OldEnvironment.d );
return result;
}
else if ( x != x )
return x;
else if ( x == infinity.d )
return infinity.d;
else if ( x == -infinity.d )
return +0.0;
else if ( x > maxExp )
{
FEGETENVD ( OldEnvironment.d ); result = infinity.d;
OldEnvironment.i.lo |= FE_INEXACT | FE_OVERFLOW;
FESETENVD ( OldEnvironment.d );
return result;
}
else
{
FEGETENVD ( OldEnvironment.d ); result = +0.0;
OldEnvironment.i.lo |= FE_INEXACT | FE_UNDERFLOW;
FESETENVD ( OldEnvironment.d );
return result;
}
}
#else
double exp ( double x )
{
hexdouble scale, xInHex, yInHex;
register double d, y, yTail, z, zTail, z2, temp1, temp2, power, result;
register long int i;
register struct expTableEntry *tablePointer, *pT;
register double FPR_oneOverLn2, FPR_rintFactor, FPR_ln2Head, FPR_ln2Tail, FPR_h, FPR_z, FPR_512, FPR_scale;
register double FPR_env, FPR_x, FPR_f, FPR_cm1, FPR_c0, FPR_c1, FPR_c2;
FPR_x = __FABS( x );
FPR_z = 0.0; FPR_512 = 512.0;
FPR_oneOverLn2 = oneOverLn2; FPR_rintFactor = rintFactor;
FPR_ln2Head = ln2Head; FPR_ln2Tail = ln2Tail;
tablePointer = ( struct expTableEntry * ) expTable + 177;
FEGETENVD ( FPR_env ); __ENSURE( FPR_z, FPR_512, FPR_oneOverLn2 ); __ENSURE( FPR_ln2Head, FPR_ln2Tail, FPR_rintFactor );
FESETENVD ( FPR_z );
FPR_h = __FMADD( x, FPR_oneOverLn2, FPR_rintFactor );
yInHex.d = FPR_h;
FPR_h -= FPR_rintFactor;
if ( FPR_x < FPR_512 )
{
if ( x != FPR_z )
{
scale.i.hi = ( yInHex.i.lo + 1023 ) << 20; scale.i.lo = 0;
y = __FNMSUB( FPR_ln2Head, FPR_h, x ); yTail = __FMUL( FPR_ln2Tail, FPR_h );
xInHex.d = __FMADD( FPR_512, y, FPR_rintFactor );
__ORI_NOOP;
__ORI_NOOP;
__ORI_NOOP;
i = xInHex.i.lo;
pT = &(tablePointer[i]);
FPR_x = pT->x; FPR_f = pT->f;
d = y - FPR_x;
z = d - yTail;
FPR_cm1 = cm1; FPR_c1 = c1;
FPR_c0 = c0; FPR_c2 = c2;
z2 = __FMUL( z, z ); zTail = d - z - yTail;
temp1 = __FMADD( FPR_cm1, z2, FPR_c1 ); temp2 = __FMADD( FPR_c0, z2, FPR_c2 );
temp1 = __FMADD( temp1, z, temp2 );
FPR_scale = scale.d;
temp2 = __FMADD( temp1, z2, z );
temp1 = __FMADD( zTail, temp2, zTail ); result = __FMUL( FPR_scale, FPR_f );
temp1 = temp1 + temp2;
result = __FMADD( result, temp1, result );
FESETENVD ( FPR_env );
__PROG_INEXACT( FPR_oneOverLn2 );
return result;
}
else
{
FESETENVD ( FPR_env );
return 1.0;
}
}
if ( ( x <= maxExp ) && ( x > minExp ) )
{
if ( x >= FPR_512 )
{
power = 2.0;
scale.i.hi = ( yInHex.i.lo + 1022 ) << 20; scale.i.lo = 0;
}
else
{
power = denormal;
scale.i.hi = ( yInHex.i.lo + 1023+128 ) << 20; scale.i.lo = 0;
}
y = __FNMSUB( FPR_ln2Head, FPR_h, x ); yTail = __FMUL( FPR_ln2Tail, FPR_h );
FPR_scale = scale.d;
xInHex.d = __FMADD( FPR_512, y, FPR_rintFactor );
__ORI_NOOP;
__ORI_NOOP;
__ORI_NOOP;
i = xInHex.i.lo;
pT = &(tablePointer[i]);
FPR_x = pT->x; FPR_f = pT->f;
d = y - FPR_x; result = __FMUL( FPR_scale, FPR_f );
z = d - yTail;
FPR_cm1 = cm1; FPR_c1 = c1;
FPR_c0 = c0; FPR_c2 = c2;
z2 = __FMUL( z, z ); zTail = d - z - yTail;
temp1 = __FMADD( FPR_cm1, z2, FPR_c1 ); temp2 = __FMADD( FPR_c0, z2, FPR_c2 );
temp1 = __FMADD( temp1, z, temp2 );
temp2 = __FMADD( temp1, z2, z );
temp1 = __FMADD( zTail, temp2, zTail );
temp1 = temp1 + temp2;
result = __FMADD( result, temp1, result );
result = __FMUL( result, power );
FESETENVD ( FPR_env );
__PROG_INEXACT( FPR_oneOverLn2 );
return result;
}
FESETENVD ( FPR_env );
if ( x != x )
return x;
else if ( x == infinity.d )
return infinity.d;
else if ( x == -infinity.d )
return FPR_z;
else if ( x > maxExp )
{
__PROG_OF_INEXACT( kMaxNormal );
return infinity.d;
}
else
{
__PROG_UF_INEXACT( kMinNormal );
return FPR_z;
}
}
#endif
#ifdef notdef
double expm1 ( double x )
{
hexdouble scale, invScale, xInHex, yInHex, OldEnvironment;
register double d, y, yTail, z, zTail, z2, temp1, temp2, power, result, f;
register long int i;
unsigned long int xpower;
struct expTableEntry *tablePointer = ( struct expTableEntry * ) expTable + 177;
xInHex.d = x;
xpower = xInHex.i.hi & 0x7ff00000;
if ( xpower < 0x40800000ul )
{ scale.d = 0.0;
invScale.d = 0.0;
FEGETENVD ( OldEnvironment.d ); FESETENVD ( 0.0 );
if ( xpower < 0x3c800000ul )
{ if ( x == 0.0 )
{
}
else
{
if ( xpower == 0x0ul )
OldEnvironment.i.lo |= FE_INEXACT + FE_UNDERFLOW; else
OldEnvironment.i.lo |= FE_INEXACT; }
FESETENVD ( OldEnvironment.d );
return x;
}
yInHex.d = x * oneOverLn2 + rintFactor;
scale.i.hi = ( yInHex.i.lo + 1023 ) << 20;
yInHex.d -= rintFactor;
y = x - ln2Head * yInHex.d;
invScale.i.hi = 0x7fe00000 - scale.i.hi;
yTail = ln2Tail * yInHex.d;
xInHex.d = 512.0 * y + rintFactor;
i = xInHex.i.lo;
d = y - tablePointer[i].x;
z = d - yTail;
zTail = d - z - yTail;
z2 = z * z;
temp1 = cc0 * z2 + cc2;
temp2 = cc1 * z2 + cc3;
#if 0
if ( yInHex.d != x ) OldEnvironment.i.lo |= FE_INEXACT; #else
OldEnvironment.i.lo |= FE_INEXACT; #endif
temp1 = temp1 * z2 + cc4;
temp2 = temp1 + temp2 * z;
temp1 = temp2 * z2 + z;
d = tablePointer[i].f - invScale.d;
temp2 = temp1 + ( zTail + zTail * temp1 );
result = ( d + tablePointer[i].f * temp2 ) * scale.d;
FESETENVD ( OldEnvironment.d );
return result;
}
if ( ( x <= maxExp ) && ( x > minExp ) )
{
scale.d = 0.0;
invScale.d = 0.0;
FEGETENVD ( OldEnvironment.d ); FESETENVD ( 0.0 );
yInHex.d = x * oneOverLn2 + rintFactor;
if ( x >= 512.0 )
{
power = 2.0;
f = 0.5;
scale.i.hi = ( yInHex.i.lo + 1022 ) << 20;
}
else
{
power = denormal;
f = oneOverDenorm;
scale.i.hi = ( yInHex.i.lo + 1023+128 ) << 20;
if ( scale.i.hi < ( 168<<20 ) )
{
OldEnvironment.i.lo |= FE_INEXACT; FESETENVD ( OldEnvironment.d );
return -1.0;
}
}
invScale.i.hi = 0x7fe00000 - scale.i.hi;
yInHex.d -= rintFactor;
y = x - ln2Head * yInHex.d;
yTail = ln2Tail * yInHex.d;
xInHex.d = 512.0 * y + rintFactor;
i = xInHex.i.lo;
d = y - tablePointer[i].x;
z = d - yTail;
zTail = d - z - yTail;
z2 = z * z;
temp1 = cc0 * z2 + cc2;
temp2 = cc1 * z2 + cc3;
#if 0
if ( yInHex.d != x )
OldEnvironment.i.lo |= FE_INEXACT; #else
OldEnvironment.i.lo |= FE_INEXACT; #endif
temp1 = temp1 * z2 + cc4;
temp2 = temp1 + temp2 * z;
temp1 = temp2 * z2 + z;
d = tablePointer[i].f - f * invScale.d;
temp2 = temp1 + ( zTail + zTail * temp1 );
result = ( ( d + tablePointer[i].f * temp2 ) * scale.d ) * power;
FESETENVD ( OldEnvironment.d );
return result;
}
else if ( x != x )
return x;
else if ( x == infinity.d )
return infinity.d;
else if ( x == -infinity.d )
return -1.0;
else if ( x > maxExp )
{
FEGETENVD ( OldEnvironment.d ); result = infinity.d;
OldEnvironment.i.lo |= FE_INEXACT | FE_OVERFLOW;
FESETENVD ( OldEnvironment.d );
return result;
}
else
{
FEGETENVD ( OldEnvironment.d ); result = -1.0;
#if 0
OldEnvironment.i.lo |= FE_INEXACT | FE_UNDERFLOW;
#else
OldEnvironment.i.lo |= FE_INEXACT;
#endif
FESETENVD ( OldEnvironment.d );
return result;
}
}
#else
static const hexdouble k2M55 = HEXDOUBLE(0x3c800000, 0x00000000);
double expm1 ( double x )
{
hexdouble scale, invScale, xInHex, yInHex;
register double d, y, yTail, z, zTail, z2, temp1, temp2, power, result, f;
register long int i;
register struct expTableEntry *tablePointer, *pT;
register double FPR_oneOverLn2, FPR_rintFactor, FPR_ln2Head, FPR_ln2Tail, FPR_h, FPR_z, FPR_512, FPR_scale;
register double FPR_env, FPR_x, FPR_f, FPR_cc0, FPR_cc1, FPR_cc2, FPR_cc3, FPR_cc4, FPR_iscale;
FPR_x = __FABS( x );
FPR_z = 0.0; FPR_512 = 512.0;
FPR_oneOverLn2 = oneOverLn2; FPR_rintFactor = rintFactor;
FPR_ln2Head = ln2Head; FPR_ln2Tail = ln2Tail;
tablePointer = ( struct expTableEntry * ) expTable + 177;
FEGETENVD ( FPR_env ); __ENSURE( FPR_z, FPR_512, FPR_oneOverLn2 ); __ENSURE( FPR_ln2Head, FPR_ln2Tail, FPR_rintFactor );
FESETENVD ( FPR_z );
FPR_h = __FMADD( x, FPR_oneOverLn2, FPR_rintFactor );
yInHex.d = FPR_h;
FPR_h -= FPR_rintFactor;
if ( FPR_x < FPR_512 )
{
if ( FPR_x < k2M55.d )
{
FESETENVD ( FPR_env );
if ( x == FPR_z )
{
}
else
{
if ( FPR_x < kMinNormal )
__PROG_UF_INEXACT( kMinNormal );
else
__PROG_INEXACT( FPR_oneOverLn2 );
}
return x;
}
scale.i.hi = ( yInHex.i.lo + 1023 ) << 20; scale.i.lo = 0;
y = __FNMSUB( FPR_ln2Head, FPR_h, x ); yTail = __FMUL( FPR_ln2Tail, FPR_h );
xInHex.d = __FMADD( FPR_512, y, FPR_rintFactor );
invScale.i.hi = 0x7fe00000 - scale.i.hi; invScale.i.lo = 0;
i = xInHex.i.lo;
pT = &(tablePointer[i]);
FPR_x = pT->x; FPR_f = pT->f;
d = y - FPR_x;
FPR_cc4 = cc4;
z = d - yTail;
FPR_cc0 = cc0; FPR_cc2 = cc2;
FPR_cc1 = cc1; FPR_cc3 = cc3;
z2 = __FMUL( z, z ); zTail = d - z - yTail;
temp1 = __FMADD( FPR_cc0, z2, FPR_cc2 ); temp2 = __FMADD( FPR_cc1, z2, FPR_cc3 );
temp1 = __FMADD( temp1, z2, FPR_cc4 );
temp2 = __FMADD( temp2, z, temp1 );
FPR_iscale = invScale.d;
temp1 = __FMADD( temp2, z2, z );
temp2 = __FMADD( zTail, temp1, zTail );
temp2 = temp1 + temp2; d = FPR_f - FPR_iscale;
FPR_scale = scale.d;
temp1 = __FMADD( FPR_f, temp2, d );
result = __FMUL( temp1, FPR_scale );
FESETENVD ( FPR_env );
__PROG_INEXACT( FPR_oneOverLn2 );
return result;
}
if ( ( x <= maxExp ) && ( x > minExp ) )
{
if ( x >= FPR_512 )
{
power = 2.0;
f = 0.5;
scale.i.hi = ( yInHex.i.lo + 1022 ) << 20; scale.i.lo = 0;
}
else
{
power = denormal;
f = oneOverDenorm;
scale.i.hi = ( yInHex.i.lo + 1023+128 ) << 20; scale.i.lo = 0;
if ( scale.i.hi < ( 168<<20 ) )
{
FESETENVD ( FPR_env );
__PROG_INEXACT( FPR_oneOverLn2 );
return -1.0;
}
}
y = __FNMSUB( FPR_ln2Head, FPR_h, x ); yTail = __FMUL( FPR_ln2Tail, FPR_h );
FPR_scale = scale.d;
xInHex.d = __FMADD( FPR_512, y, FPR_rintFactor );
invScale.i.hi = 0x7fe00000 - scale.i.hi; invScale.i.lo = 0;
i = xInHex.i.lo;
pT = &(tablePointer[i]);
FPR_x = pT->x; FPR_f = pT->f;
d = y - FPR_x;
FPR_iscale = invScale.d; FPR_cc4 = cc4;
z = d - yTail;
FPR_cc0 = cc0; FPR_cc2 = cc2;
FPR_cc1 = cc1; FPR_cc3 = cc3;
z2 = __FMUL( z, z ); zTail = d - z - yTail;
temp1 = __FMADD( FPR_cc0, z2, FPR_cc2 ); temp2 = __FMADD( FPR_cc1, z2, FPR_cc3 );
temp1 = __FMADD( temp1, z2, FPR_cc4 ); d = __FNMSUB( f, FPR_iscale, FPR_f );
temp2 = __FMADD( temp2, z, temp1 );
temp1 = __FMADD( temp2, z2, z );
temp2 = __FMADD( zTail, temp1, zTail );
temp2 = temp1 + temp2;
temp1 = __FMADD( FPR_f, temp2, d );
result = __FMUL( temp1, FPR_scale );
result = __FMUL( result, power );
FESETENVD ( FPR_env );
__PROG_INEXACT( FPR_oneOverLn2 );
return result;
}
FESETENVD ( FPR_env );
if ( x != x )
return x;
else if ( x == infinity.d )
return infinity.d;
else if ( x == -infinity.d )
return -1.0;
else if ( x > maxExp )
{
__PROG_OF_INEXACT( kMaxNormal );
return infinity.d;
}
else
{
#if 0
__PROG_UF_INEXACT( kMinNormal );
#else
__PROG_INEXACT( FPR_oneOverLn2 );
#endif
return -1.0;
}
}
#endif
#else
#ifdef notdef
double exp2 ( double x )
{
hexdouble scale, xInHex, yInHex, OldEnvironment;
register double d, y, yTail, z, zTail, z2, temp1, temp2, power, result;
register long int i;
struct expTableEntry *tablePointer = ( struct expTableEntry * ) expTable + 177;
xInHex.d = x;
if ( ( xInHex.i.hi & 0x7ff00000 ) < 0x40800000ul )
{ if ( ( ( xInHex.i.hi & 0x7fffffff ) | xInHex.i.lo ) == 0x0ul )
return 1.0;
scale.d = 0.0;
FEGETENVD ( OldEnvironment.d ); FESETENVD ( 0.0 );
yInHex.d = x + rintFactor;
scale.i.hi = ( yInHex.i.lo + 1023 ) << 20;
yInHex.d -= rintFactor;
y = ln2Head * ( x - yInHex.d );
yTail = ln2Tail * ( x - yInHex.d );
xInHex.d = 512.0 * y + rintFactor;
i = xInHex.i.lo;
d = y - tablePointer[i].x;
z = d - yTail;
zTail = d - z - yTail;
z2 = z * z;
temp1 = cm1 * z2 + c1;
temp2 = c0 * z2 + c2;
if ( yInHex.d != x ) OldEnvironment.i.lo |= FE_INEXACT; temp1 = temp1 * z + temp2;
temp2 = temp1 * z2 + z;
result = scale.d * tablePointer[i].f;
temp1 = result * ( temp2 + ( zTail + zTail * temp2 ) );
result += temp1;
FESETENVD ( OldEnvironment.d );
return result;
}
if ( ( x < maxExp2 ) && ( x > minExp2 ) )
{
scale.d = 0.0;
FEGETENVD ( OldEnvironment.d ); FESETENVD ( 0.0 );
if (x < minNormExp2)
OldEnvironment.i.lo |= FE_UNDERFLOW; yInHex.d = x + rintFactor;
if ( x >= 512.0 )
{
power = 2.0;
scale.i.hi = ( yInHex.i.lo + 1022 ) << 20;
}
else
{
power = denormal;
scale.i.hi = ( yInHex.i.lo + 1023+128 ) << 20;
}
yInHex.d -= rintFactor;
y = ln2Head * ( x - yInHex.d );
yTail = ln2Tail * ( x - yInHex.d );
xInHex.d = 512.0 * y + rintFactor;
i = xInHex.i.lo;
d = y - tablePointer[i].x;
z = d - yTail;
zTail = d - z - yTail;
z2 = z * z;
temp1 = cm1 * z2 + c1;
temp2 = c0 * z2 + c2;
if ( yInHex.d != x ) OldEnvironment.i.lo |= FE_INEXACT; temp1 = temp1 * z + temp2;
temp2 = temp1 * z2 + z;
result = scale.d * tablePointer[i].f;
temp1 = result * ( temp2 + ( zTail + zTail * temp2 ) );
result = ( result + temp1 ) * power;
FESETENVD ( OldEnvironment.d );
return result;
}
else if ( x != x )
return x;
else if ( x == infinity.d )
return infinity.d;
else if ( x == -infinity.d )
return +0.0;
else if ( x > maxExp )
{
FEGETENVD ( OldEnvironment.d ); result = infinity.d;
OldEnvironment.i.lo |= FE_INEXACT | FE_OVERFLOW;
FESETENVD ( OldEnvironment.d );
return result;
}
else
{
FEGETENVD ( OldEnvironment.d ); result = +0.0;
OldEnvironment.i.lo |= FE_INEXACT | FE_UNDERFLOW;
FESETENVD ( OldEnvironment.d );
return result;
}
}
#else
double exp2 ( double x )
{
hexdouble OldEnvironment, scale, xInHex, yInHex;
register double d, y, yTail, z, zTail, z2, temp1, temp2, power, result;
register long int i;
register struct expTableEntry *tablePointer, *pT;
register double FPR_oneOverLn2, FPR_rintFactor, FPR_ln2Head, FPR_ln2Tail, FPR_h, FPR_z, FPR_512, FPR_scale;
register double FPR_env, FPR_diff, FPR_x, FPR_f, FPR_cm1, FPR_c0, FPR_c1, FPR_c2;
FPR_x = __FABS( x );
FPR_z = 0.0; FPR_512 = 512.0;
FPR_oneOverLn2 = oneOverLn2; FPR_rintFactor = rintFactor;
FPR_ln2Head = ln2Head; FPR_ln2Tail = ln2Tail;
tablePointer = ( struct expTableEntry * ) expTable + 177;
FEGETENVD ( FPR_env ); __ENSURE( FPR_z, FPR_512, FPR_oneOverLn2 ); __ENSURE( FPR_ln2Head, FPR_ln2Tail, FPR_rintFactor );
FESETENVD ( FPR_z );
FPR_h = x + FPR_rintFactor;
yInHex.d = FPR_h;
FPR_h -= FPR_rintFactor;
FPR_diff = x - FPR_h;
if ( FPR_x < FPR_512 )
{
if ( FPR_x != FPR_z )
{
scale.i.hi = ( yInHex.i.lo + 1023 ) << 20; scale.i.lo = 0;
y = __FMUL( FPR_ln2Head, FPR_diff ); yTail = __FMUL( FPR_ln2Tail, FPR_diff );
xInHex.d = __FMADD( FPR_512, y, FPR_rintFactor );
__ORI_NOOP;
__ORI_NOOP;
__ORI_NOOP;
i = xInHex.i.lo;
pT = &(tablePointer[i]);
FPR_x = pT->x; FPR_f = pT->f;
d = y - FPR_x;
z = d - yTail;
FPR_cm1 = cm1; FPR_c1 = c1;
FPR_c0 = c0; FPR_c2 = c2;
z2 = __FMUL( z, z ); zTail = d - z - yTail;
temp1 = __FMADD( FPR_cm1, z2, FPR_c1 ); temp2 = __FMADD( FPR_c0, z2, FPR_c2 );
temp1 = __FMADD( temp1, z, temp2 );
temp2 = __FMADD( temp1, z2, z );
FPR_scale = scale.d;
temp1 = __FMADD( zTail, temp2, zTail );
temp1 = temp1 + temp2; result = __FMUL( FPR_scale, FPR_f );
result = __FMADD( result, temp1, result );
FESETENVD ( FPR_env );
if ( FPR_diff != FPR_z)
__PROG_INEXACT( FPR_oneOverLn2 );
return result;
}
else
{
FESETENVD ( FPR_env );
return 1.0;
}
}
if ( ( x < maxExp2 ) && ( x > minExp2 ) )
{
if ( x >= FPR_512 )
{
power = 2.0;
scale.i.hi = ( yInHex.i.lo + 1022 ) << 20; scale.i.lo = 0;
}
else
{
power = denormal;
scale.i.hi = ( yInHex.i.lo + 1023+128 ) << 20; scale.i.lo = 0;
}
FPR_diff = x - FPR_h;
FPR_scale = scale.d;
y = __FMUL( FPR_ln2Head, FPR_diff ); yTail = __FMUL( FPR_ln2Tail, FPR_diff );
xInHex.d = __FMADD( FPR_512, y, FPR_rintFactor );
__ORI_NOOP;
__ORI_NOOP;
__ORI_NOOP;
i = xInHex.i.lo;
pT = &(tablePointer[i]);
FPR_x = pT->x; FPR_f = pT->f;
d = y - FPR_x; result = __FMUL( FPR_scale, FPR_f );
z = d - yTail;
FPR_cm1 = cm1; FPR_c1 = c1;
FPR_c0 = c0; FPR_c2 = c2;
z2 = __FMUL( z, z ); zTail = d - z - yTail;
temp1 = __FMADD( FPR_cm1, z2, FPR_c1 ); temp2 = __FMADD( FPR_c0, z2, FPR_c2 );
temp1 = __FMADD( temp1, z, temp2 );
temp2 = __FMADD( temp1, z2, z );
temp1 = __FMADD( zTail, temp2, zTail );
temp1 = temp1 + temp2;
result = __FMADD( result, temp1, result );
result = __FMUL( result, power );
FESETENVD ( FPR_env );
if ( x < minNormExp2 )
{
OldEnvironment.d = FPR_env;
OldEnvironment.i.lo |= FE_UNDERFLOW;
if ( FPR_h != x )
OldEnvironment.i.lo |= FE_INEXACT;
FESETENVD ( OldEnvironment.d );
}
else if ( FPR_h != x )
__PROG_INEXACT( FPR_oneOverLn2 );
return result;
}
FESETENVD ( FPR_env );
if ( x != x )
return x;
else if ( x == infinity.d )
return infinity.d;
else if ( x == -infinity.d )
return FPR_z;
else if ( x > maxExp )
{
__PROG_OF_INEXACT( kMaxNormal );
return infinity.d;
}
else
{
__PROG_UF_INEXACT( kMinNormal );
return FPR_z;
}
}
#endif
#endif
#else
#warning A higher version than gcc-932 is required.
#endif
#endif