_fixdfdi.c: Throw invalid exception if number cannot be represented.
2014-02-07 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> * config/s390/32/_fixdfdi.c: Throw invalid exception if number cannot be represented. * config/s390/32/_fixsfdi.c: Likewise. * config/s390/32/_fixtfdi.c: Likewise. * config/s390/32/_fixunsdfdi.c: Likewise. * config/s390/32/_fixunssfdi.c: Likewise. * config/s390/32/_fixunstfdi.c: Likewise. 2014-02-07 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> * gcc.target/s390/fp2int1.c: New testcase. From-SVN: r207596
This commit is contained in:
parent
32cab212f2
commit
ce245ec69e
@ -1,3 +1,7 @@
|
||||
2014-02-07 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
|
||||
|
||||
* gcc.target/s390/fp2int1.c: New testcase.
|
||||
|
||||
2014-02-07 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR middle-end/60092
|
||||
|
95
gcc/testsuite/gcc.target/s390/fp2int1.c
Normal file
95
gcc/testsuite/gcc.target/s390/fp2int1.c
Normal file
@ -0,0 +1,95 @@
|
||||
/* Test for the 32 bit fp to 64 bit int conversion routines.
|
||||
|
||||
On S/390 32 bit we use our own implementations in order to be IEEE
|
||||
complaint as we are with our machine instructions. These missed to
|
||||
throw FE_INVALID exceptions in a bunch of cases. */
|
||||
|
||||
/* { dg-do run { target s390-*-* } } */
|
||||
/* { dg-options "-O3 -mesa" } */
|
||||
/* { dg-require-effective-target fenv_exceptions } */
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <fenv.h>
|
||||
|
||||
#define INFINITYf (__builtin_inff())
|
||||
#define INFINITY (__builtin_inf())
|
||||
#define INFINITYl (__builtin_infl())
|
||||
#define NANf (__builtin_nanf (""))
|
||||
#define NAN (__builtin_nan (""))
|
||||
#define NANl (__builtin_nanl (""))
|
||||
|
||||
#define TESTEXCEPT_FUNC(FUNC, TYPE_FROM, TYPE_TO) \
|
||||
TYPE_TO \
|
||||
__attribute__((noinline)) FUNC (TYPE_FROM a) \
|
||||
{ \
|
||||
asm volatile ("" : : "f" (a)); \
|
||||
return (TYPE_TO)a; \
|
||||
}
|
||||
|
||||
#define TESTEXCEPT(FUNC, EXCEPT, EXPECT, VALUE, TYPE_TO) \
|
||||
{ \
|
||||
TYPE_TO b; \
|
||||
feclearexcept (FE_ALL_EXCEPT); \
|
||||
b = FUNC (VALUE); \
|
||||
if ((fetestexcept (EXCEPT) & (EXCEPT)) != EXPECT) \
|
||||
{ \
|
||||
printf ("FAIL in line: %d\n", __LINE__); \
|
||||
abort (); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define TESTEXCEPT_FUNC_ALLFLOATS(FUNC, TYPE_TO) \
|
||||
TESTEXCEPT_FUNC (FUNC##_f, float, TYPE_TO); \
|
||||
TESTEXCEPT_FUNC (FUNC##_d, double, TYPE_TO); \
|
||||
TESTEXCEPT_FUNC (FUNC##_l, long double, TYPE_TO); \
|
||||
|
||||
#define TESTEXCEPT_ALLFLOATS(FUNC, EXCEPT, EXPECT, VALUE, TYPE_TO) \
|
||||
TESTEXCEPT (FUNC##_f, EXCEPT, EXPECT, VALUE##f, TYPE_TO); \
|
||||
TESTEXCEPT (FUNC##_d, EXCEPT, EXPECT, VALUE, TYPE_TO); \
|
||||
TESTEXCEPT (FUNC##_l, EXCEPT, EXPECT, VALUE##l, TYPE_TO); \
|
||||
|
||||
TESTEXCEPT_FUNC_ALLFLOATS (a, unsigned long long);
|
||||
TESTEXCEPT_FUNC_ALLFLOATS (u, long long);
|
||||
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
/* Prevent getting signals. */
|
||||
fedisableexcept (FE_INVALID);
|
||||
|
||||
/* To unsigned long long */
|
||||
|
||||
TESTEXCEPT_ALLFLOATS (a, FE_INVALID, FE_INVALID, INFINITY, unsigned long long);
|
||||
TESTEXCEPT_ALLFLOATS (a, FE_INVALID, FE_INVALID, -INFINITY, unsigned long long);
|
||||
TESTEXCEPT_ALLFLOATS (a, FE_INVALID, FE_INVALID, NAN, unsigned long long);
|
||||
TESTEXCEPT_ALLFLOATS (a, FE_INVALID, FE_INVALID, -NAN, unsigned long long);
|
||||
|
||||
/* Negative values >-1.0 must not cause FE_INVALID. */
|
||||
TESTEXCEPT_ALLFLOATS (a, FE_INVALID, 0, -0x0.ffffffp0, unsigned long long);
|
||||
/* -1.0 instead must. */
|
||||
TESTEXCEPT_ALLFLOATS (a, FE_INVALID, FE_INVALID, -0x1.0p+0, unsigned long long);
|
||||
TESTEXCEPT_ALLFLOATS (a, FE_INVALID, 0, 0x1.0p+63, unsigned long long);
|
||||
TESTEXCEPT_ALLFLOATS (a, FE_INVALID, FE_INVALID, 0x1.0p+64, unsigned long long);
|
||||
|
||||
/* To signed long long */
|
||||
|
||||
TESTEXCEPT_ALLFLOATS (u, FE_INVALID, FE_INVALID, INFINITY, long long);
|
||||
TESTEXCEPT_ALLFLOATS (u, FE_INVALID, FE_INVALID, -INFINITY, long long);
|
||||
TESTEXCEPT_ALLFLOATS (u, FE_INVALID, FE_INVALID, NAN, long long);
|
||||
TESTEXCEPT_ALLFLOATS (u, FE_INVALID, FE_INVALID, -NAN, long long);
|
||||
|
||||
TESTEXCEPT_ALLFLOATS (u, FE_INVALID, 0, -0x1.0p+63, long long);
|
||||
TESTEXCEPT_ALLFLOATS (u, FE_INVALID, FE_INVALID, -0x1.1p+63, long long);
|
||||
TESTEXCEPT_ALLFLOATS (u, FE_INVALID, 0, 0x0.fffffp+63, long long);
|
||||
TESTEXCEPT_ALLFLOATS (u, FE_INVALID, FE_INVALID, 0x1.0p+63, long long);
|
||||
|
||||
/* If there are additional bits which would not make it into the
|
||||
integer value no exception is supposed to occur. */
|
||||
TESTEXCEPT (u_l, FE_INVALID, 0, -0x1.000000000000000123p+63l, long long);
|
||||
TESTEXCEPT (u_l, FE_INVALID, FE_INVALID, -0x1.000000000000000223p+63l, long long);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,3 +1,13 @@
|
||||
2014-02-07 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
|
||||
|
||||
* config/s390/32/_fixdfdi.c: Throw invalid exception if number
|
||||
cannot be represented.
|
||||
* config/s390/32/_fixsfdi.c: Likewise.
|
||||
* config/s390/32/_fixtfdi.c: Likewise.
|
||||
* config/s390/32/_fixunsdfdi.c: Likewise.
|
||||
* config/s390/32/_fixunssfdi.c: Likewise.
|
||||
* config/s390/32/_fixunstfdi.c: Likewise.
|
||||
|
||||
2014-02-07 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* configure.ac (libgcc_cv_mips_hard_float): New.
|
||||
|
@ -27,12 +27,16 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
#ifndef __s390x__
|
||||
|
||||
#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF)
|
||||
#define EXCESSD 1022
|
||||
#define EXPONENT_BIAS 1023
|
||||
#define MANTISSA_BITS 52
|
||||
#define PRECISION (MANTISSA_BITS + 1)
|
||||
#define SIGNBIT 0x80000000
|
||||
#define SIGND(fp) ((fp.l.upper) & SIGNBIT)
|
||||
#define SIGN(fp) ((fp.l.upper) & SIGNBIT)
|
||||
#define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
|
||||
#define FRACD_LL(fp) (fp.ll & (HIDDEND_LL-1))
|
||||
#define HIDDEND_LL ((UDItype_x)1 << 52)
|
||||
#define HIDDEND_LL ((UDItype_x)1 << MANTISSA_BITS)
|
||||
#define LLONG_MAX 9223372036854775807LL
|
||||
#define LLONG_MIN (-LLONG_MAX - 1LL)
|
||||
|
||||
typedef int DItype_x __attribute__ ((mode (DI)));
|
||||
typedef unsigned int UDItype_x __attribute__ ((mode (DI)));
|
||||
@ -48,6 +52,12 @@ union double_long {
|
||||
UDItype_x ll;
|
||||
};
|
||||
|
||||
static __inline__ void
|
||||
fexceptdiv (float d, float e)
|
||||
{
|
||||
__asm__ __volatile__ ("debr %0,%1" : : "f" (d), "f" (e) );
|
||||
}
|
||||
|
||||
DItype_x __fixdfdi (double a1);
|
||||
|
||||
/* convert double to int */
|
||||
@ -61,29 +71,33 @@ __fixdfdi (double a1)
|
||||
dl1.d = a1;
|
||||
|
||||
/* +/- 0, denormalized */
|
||||
|
||||
if (!EXPD (dl1))
|
||||
return 0;
|
||||
|
||||
exp = EXPD (dl1) - EXCESSD - 53;
|
||||
/* The exponent - considered the binary point at the right end of
|
||||
the mantissa. */
|
||||
exp = EXPD (dl1) - EXPONENT_BIAS - MANTISSA_BITS;
|
||||
|
||||
/* number < 1 */
|
||||
|
||||
if (exp < -53)
|
||||
if (exp <= -PRECISION)
|
||||
return 0;
|
||||
|
||||
/* NaN */
|
||||
|
||||
if ((EXPD(dl1) == 0x7ff) && (FRACD_LL(dl1) != 0)) /* NaN */
|
||||
{
|
||||
/* C99 Annex F.4 requires an "invalid" exception to be thrown. */
|
||||
fexceptdiv (0.0, 0.0);
|
||||
return 0x8000000000000000ULL;
|
||||
}
|
||||
|
||||
/* Number big number & +/- inf */
|
||||
|
||||
if (exp >= 11) {
|
||||
l = (long long)1<<63;
|
||||
if (!SIGND(dl1))
|
||||
l--;
|
||||
return l;
|
||||
/* Don't throw an exception for -1p+63 */
|
||||
if (!SIGN (dl1) || exp > 11 || FRACD_LL (dl1) != 0)
|
||||
/* C99 Annex F.4 requires an "invalid" exception to be thrown. */
|
||||
fexceptdiv (0.0, 0.0);
|
||||
return SIGN (dl1) ? LLONG_MIN : LLONG_MAX;
|
||||
}
|
||||
|
||||
l = MANTD_LL(dl1);
|
||||
@ -94,6 +108,6 @@ __fixdfdi (double a1)
|
||||
else
|
||||
l >>= -exp;
|
||||
|
||||
return (SIGND (dl1) ? -l : l);
|
||||
return (SIGN (dl1) ? -l : l);
|
||||
}
|
||||
#endif /* !__s390x__ */
|
||||
|
@ -26,13 +26,17 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
|
||||
#ifndef __s390x__
|
||||
|
||||
#define EXP(fp) (((fp.l) >> 23) & 0xFF)
|
||||
#define EXCESS 126
|
||||
#define EXPONENT_BIAS 127
|
||||
#define MANTISSA_BITS 23
|
||||
#define EXP(fp) (((fp.l) >> MANTISSA_BITS) & 0xFF)
|
||||
#define PRECISION (MANTISSA_BITS + 1)
|
||||
#define SIGNBIT 0x80000000
|
||||
#define SIGN(fp) ((fp.l) & SIGNBIT)
|
||||
#define HIDDEN (1 << 23)
|
||||
#define HIDDEN (1 << MANTISSA_BITS)
|
||||
#define MANT(fp) (((fp.l) & 0x7FFFFF) | HIDDEN)
|
||||
#define FRAC(fp) ((fp.l) & 0x7FFFFF)
|
||||
#define LLONG_MAX 9223372036854775807LL
|
||||
#define LLONG_MIN (-LLONG_MAX - 1LL)
|
||||
|
||||
typedef int DItype_x __attribute__ ((mode (DI)));
|
||||
typedef unsigned int UDItype_x __attribute__ ((mode (DI)));
|
||||
@ -45,6 +49,12 @@ union float_long
|
||||
USItype_x l;
|
||||
};
|
||||
|
||||
static __inline__ void
|
||||
fexceptdiv (float d, float e)
|
||||
{
|
||||
__asm__ __volatile__ ("debr %0,%1" : : "f" (d), "f" (e) );
|
||||
}
|
||||
|
||||
DItype_x __fixsfdi (float a1);
|
||||
|
||||
/* convert double to int */
|
||||
@ -58,29 +68,31 @@ __fixsfdi (float a1)
|
||||
fl1.f = a1;
|
||||
|
||||
/* +/- 0, denormalized */
|
||||
|
||||
if (!EXP (fl1))
|
||||
return 0;
|
||||
|
||||
exp = EXP (fl1) - EXCESS - 24;
|
||||
exp = EXP (fl1) - EXPONENT_BIAS - MANTISSA_BITS;
|
||||
|
||||
/* number < 1 */
|
||||
|
||||
if (exp < -24)
|
||||
if (exp <= -PRECISION)
|
||||
return 0;
|
||||
|
||||
/* NaN */
|
||||
|
||||
if ((EXP (fl1) == 0xff) && (FRAC (fl1) != 0)) /* NaN */
|
||||
{
|
||||
/* C99 Annex F.4 requires an "invalid" exception to be thrown. */
|
||||
fexceptdiv (0.0, 0.0);
|
||||
return 0x8000000000000000ULL;
|
||||
}
|
||||
|
||||
/* Number big number & +/- inf */
|
||||
|
||||
if (exp >= 40) {
|
||||
l = (long long)1<<63;
|
||||
if (!SIGN(fl1))
|
||||
l--;
|
||||
return l;
|
||||
/* Don't throw an exception for -1p+63 */
|
||||
if (!SIGN (fl1) || exp > 40 || FRAC (fl1) != 0)
|
||||
/* C99 Annex F.4 requires an "invalid" exception to be thrown. */
|
||||
fexceptdiv (0.0, 0.0);
|
||||
return SIGN (fl1) ? LLONG_MIN : LLONG_MAX;
|
||||
}
|
||||
|
||||
l = MANT (fl1);
|
||||
|
@ -31,13 +31,15 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
#define MANTISSA_BITS 112
|
||||
#define PRECISION (MANTISSA_BITS + 1)
|
||||
#define SIGNBIT 0x80000000
|
||||
#define SIGND(fp) ((fp.l.i[0]) & SIGNBIT)
|
||||
#define SIGN(fp) ((fp.l.i[0]) & SIGNBIT)
|
||||
#define MANTD_HIGH_LL(fp) ((fp.ll[0] & HIGH_LL_FRAC_MASK) | HIGH_LL_UNIT_BIT)
|
||||
#define MANTD_LOW_LL(fp) (fp.ll[1])
|
||||
#define FRACD_ZERO_P(fp) (!fp.ll[1] && !(fp.ll[0] & HIGH_LL_FRAC_MASK))
|
||||
#define HIGH_LL_FRAC_BITS 48
|
||||
#define HIGH_LL_UNIT_BIT ((UDItype_x)1 << HIGH_LL_FRAC_BITS)
|
||||
#define HIGH_LL_FRAC_MASK (HIGH_LL_UNIT_BIT - 1)
|
||||
#define LLONG_MAX 9223372036854775807LL
|
||||
#define LLONG_MIN (-LLONG_MAX - 1LL)
|
||||
|
||||
typedef int DItype_x __attribute__ ((mode (DI)));
|
||||
typedef unsigned int UDItype_x __attribute__ ((mode (DI)));
|
||||
@ -52,6 +54,12 @@ union double_long {
|
||||
UDItype_x ll[2]; /* 64 bit parts: 0 upper, 1 lower */
|
||||
};
|
||||
|
||||
static __inline__ void
|
||||
fexceptdiv (float d, float e)
|
||||
{
|
||||
__asm__ __volatile__ ("debr %0,%1" : : "f" (d), "f" (e) );
|
||||
}
|
||||
|
||||
DItype_x __fixtfdi (long double a1);
|
||||
|
||||
/* convert double to unsigned int */
|
||||
@ -79,7 +87,11 @@ __fixtfdi (long double a1)
|
||||
|
||||
/* NaN: All exponent bits set and a nonzero fraction. */
|
||||
if ((EXPD(dl1) == 0x7fff) && !FRACD_ZERO_P (dl1))
|
||||
{
|
||||
/* C99 Annex F.4 requires an "invalid" exception to be thrown. */
|
||||
fexceptdiv (0.0, 0.0);
|
||||
return 0x8000000000000000ULL;
|
||||
}
|
||||
|
||||
/* One extra bit is needed for the unit bit which is appended by
|
||||
MANTD_HIGH_LL on the left of the matissa. */
|
||||
@ -92,13 +104,19 @@ __fixtfdi (long double a1)
|
||||
or more. */
|
||||
if (exp >= 0)
|
||||
{
|
||||
l = 1ULL << 63; /* long long min */
|
||||
return SIGND (dl1) ? l : l - 1;
|
||||
/* Don't throw an exception for -1p+63 */
|
||||
if (!SIGN (dl1)
|
||||
|| exp > 0
|
||||
|| MANTD_LOW_LL (dl1) >> (HIGH_LL_FRAC_BITS + 1)
|
||||
|| (dl1.ll[0] & HIGH_LL_FRAC_MASK))
|
||||
/* C99 Annex F.4 requires an "invalid" exception to be thrown. */
|
||||
fexceptdiv (0.0, 0.0);
|
||||
return SIGN (dl1) ? LLONG_MIN : LLONG_MAX;
|
||||
}
|
||||
|
||||
l = MANTD_LOW_LL (dl1) >> (HIGH_LL_FRAC_BITS + 1)
|
||||
| MANTD_HIGH_LL (dl1) << (64 - (HIGH_LL_FRAC_BITS + 1));
|
||||
|
||||
return SIGND (dl1) ? -(l >> -exp) : l >> -exp;
|
||||
return SIGN (dl1) ? -(l >> -exp) : l >> -exp;
|
||||
}
|
||||
#endif /* !__s390x__ */
|
||||
|
@ -27,9 +27,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
#ifndef __s390x__
|
||||
|
||||
#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF)
|
||||
#define EXCESSD 1022
|
||||
#define EXPONENT_BIAS 1023
|
||||
#define MANTISSA_BITS 52
|
||||
#define PRECISION (MANTISSA_BITS + 1)
|
||||
#define SIGNBIT 0x80000000
|
||||
#define SIGND(fp) ((fp.l.upper) & SIGNBIT)
|
||||
#define SIGN(fp) ((fp.l.upper) & SIGNBIT)
|
||||
#define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
|
||||
#define FRACD_LL(fp) (fp.ll & (HIDDEND_LL-1))
|
||||
#define HIDDEND_LL ((UDItype_x)1 << 52)
|
||||
@ -48,6 +50,12 @@ union double_long {
|
||||
UDItype_x ll;
|
||||
};
|
||||
|
||||
static __inline__ void
|
||||
fexceptdiv (float d, float e)
|
||||
{
|
||||
__asm__ __volatile__ ("debr %0,%1" : : "f" (d), "f" (e) );
|
||||
}
|
||||
|
||||
UDItype_x __fixunsdfdi (double a1);
|
||||
|
||||
/* convert double to unsigned int */
|
||||
@ -60,26 +68,42 @@ __fixunsdfdi (double a1)
|
||||
|
||||
dl1.d = a1;
|
||||
|
||||
/* +/- 0, denormalized, negative */
|
||||
|
||||
if (!EXPD (dl1) || SIGND(dl1))
|
||||
/* +/- 0, denormalized */
|
||||
if (!EXPD (dl1))
|
||||
return 0;
|
||||
|
||||
exp = EXPD (dl1) - EXCESSD - 53;
|
||||
/* Negative. */
|
||||
if (SIGN (dl1))
|
||||
{
|
||||
/* Value is <= -1.0
|
||||
C99 Annex F.4 requires an "invalid" exception to be thrown. */
|
||||
if (EXPD (dl1) >= EXPONENT_BIAS)
|
||||
fexceptdiv (0.0, 0.0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
exp = EXPD (dl1) - EXPONENT_BIAS - MANTISSA_BITS;
|
||||
|
||||
/* number < 1 */
|
||||
|
||||
if (exp < -53)
|
||||
if (exp < -PRECISION)
|
||||
return 0;
|
||||
|
||||
/* NaN */
|
||||
|
||||
if ((EXPD(dl1) == 0x7ff) && (FRACD_LL(dl1) != 0)) /* NaN */
|
||||
{
|
||||
/* C99 Annex F.4 requires an "invalid" exception to be thrown. */
|
||||
fexceptdiv (0.0, 0.0);
|
||||
return 0x0ULL;
|
||||
}
|
||||
|
||||
/* Number big number & + inf */
|
||||
|
||||
if (exp >= 12) {
|
||||
if (exp >= 12)
|
||||
{
|
||||
/* C99 Annex F.4 requires an "invalid" exception to be thrown. */
|
||||
fexceptdiv (0.0, 0.0);
|
||||
return 0xFFFFFFFFFFFFFFFFULL;
|
||||
}
|
||||
|
||||
|
@ -26,11 +26,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
|
||||
#ifndef __s390x__
|
||||
|
||||
#define EXP(fp) (((fp.l) >> 23) & 0xFF)
|
||||
#define EXCESS 126
|
||||
#define EXPONENT_BIAS 127
|
||||
#define MANTISSA_BITS 23
|
||||
#define EXP(fp) (((fp.l) >> MANTISSA_BITS) & 0xFF)
|
||||
#define SIGNBIT 0x80000000
|
||||
#define SIGN(fp) ((fp.l) & SIGNBIT)
|
||||
#define HIDDEN (1 << 23)
|
||||
#define HIDDEN (1 << MANTISSA_BITS)
|
||||
#define MANT(fp) (((fp.l) & 0x7FFFFF) | HIDDEN)
|
||||
#define FRAC(fp) ((fp.l) & 0x7FFFFF)
|
||||
|
||||
@ -45,6 +46,12 @@ union float_long
|
||||
USItype_x l;
|
||||
};
|
||||
|
||||
static __inline__ void
|
||||
fexceptdiv (float d, float e)
|
||||
{
|
||||
__asm__ __volatile__ ("debr %0,%1" : : "f" (d), "f" (e) );
|
||||
}
|
||||
|
||||
UDItype_x __fixunssfdi (float a1);
|
||||
|
||||
/* convert float to unsigned int */
|
||||
@ -57,26 +64,41 @@ __fixunssfdi (float a1)
|
||||
|
||||
fl1.f = a1;
|
||||
|
||||
/* +/- 0, denormalized, negative */
|
||||
|
||||
if (!EXP (fl1) || SIGN(fl1))
|
||||
/* +/- 0, denormalized */
|
||||
if (!EXP (fl1))
|
||||
return 0;
|
||||
|
||||
exp = EXP (fl1) - EXCESS - 24;
|
||||
/* Negative. */
|
||||
if (SIGN (fl1))
|
||||
{
|
||||
/* Value is <= -1.0
|
||||
C99 Annex F.4 requires an "invalid" exception to be thrown. */
|
||||
if (EXP (fl1) >= EXPONENT_BIAS)
|
||||
fexceptdiv (0.0, 0.0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
exp = EXP (fl1) - EXPONENT_BIAS - MANTISSA_BITS;
|
||||
|
||||
/* number < 1 */
|
||||
|
||||
if (exp < -24)
|
||||
return 0;
|
||||
|
||||
/* NaN */
|
||||
|
||||
if ((EXP (fl1) == 0xff) && (FRAC (fl1) != 0)) /* NaN */
|
||||
{
|
||||
/* C99 Annex F.4 requires an "invalid" exception to be thrown. */
|
||||
fexceptdiv (0.0, 0.0);
|
||||
return 0x0ULL;
|
||||
}
|
||||
|
||||
/* Number big number & + inf */
|
||||
|
||||
if (exp >= 41) {
|
||||
if (exp >= 41)
|
||||
{
|
||||
/* C99 Annex F.4 requires an "invalid" exception to be thrown. */
|
||||
fexceptdiv (0.0, 0.0);
|
||||
return 0xFFFFFFFFFFFFFFFFULL;
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,12 @@ union double_long {
|
||||
UDItype_x ll[2]; /* 64 bit parts: 0 upper, 1 lower */
|
||||
};
|
||||
|
||||
static __inline__ void
|
||||
fexceptdiv (float d, float e)
|
||||
{
|
||||
__asm__ __volatile__ ("debr %0,%1" : : "f" (d), "f" (e) );
|
||||
}
|
||||
|
||||
UDItype_x __fixunstfdi (long double a1);
|
||||
|
||||
/* convert double to unsigned int */
|
||||
@ -64,10 +70,20 @@ __fixunstfdi (long double a1)
|
||||
|
||||
dl1.d = a1;
|
||||
|
||||
/* +/- 0, denormalized, negative */
|
||||
if (!EXPD (dl1) || SIGND(dl1))
|
||||
/* +/- 0, denormalized */
|
||||
if (!EXPD (dl1))
|
||||
return 0;
|
||||
|
||||
/* Negative. */
|
||||
if (SIGND (dl1))
|
||||
{
|
||||
/* Value is <= -1.0
|
||||
C99 Annex F.4 requires an "invalid" exception to be thrown. */
|
||||
if (EXPD (dl1) >= EXPONENT_BIAS)
|
||||
fexceptdiv (0.0, 0.0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The exponent - considered the binary point at the right end of
|
||||
the mantissa. */
|
||||
exp = EXPD (dl1) - EXPONENT_BIAS - MANTISSA_BITS;
|
||||
@ -80,16 +96,25 @@ __fixunstfdi (long double a1)
|
||||
|
||||
/* NaN: All exponent bits set and a nonzero fraction. */
|
||||
if ((EXPD(dl1) == 0x7fff) && !FRACD_ZERO_P (dl1))
|
||||
return 0x0ULL;
|
||||
{
|
||||
/* C99 Annex F.4 requires an "invalid" exception to be thrown. */
|
||||
fexceptdiv (0.0, 0.0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* One extra bit is needed for the unit bit which is appended by
|
||||
MANTD_HIGH_LL on the left of the matissa. */
|
||||
exp += HIGH_LL_FRAC_BITS + 1;
|
||||
|
||||
/* If the result would still need a left shift it will be too large
|
||||
to be represented. */
|
||||
/* If the result would still need a left shift it will be too
|
||||
large to be represented. Infinities have all exponent bits set
|
||||
and will end up here as well. */
|
||||
if (exp > 0)
|
||||
{
|
||||
/* C99 Annex F.4 requires an "invalid" exception to be thrown. */
|
||||
fexceptdiv (0.0, 0.0);
|
||||
return 0xFFFFFFFFFFFFFFFFULL;
|
||||
}
|
||||
|
||||
l = MANTD_LOW_LL (dl1) >> (HIGH_LL_FRAC_BITS + 1)
|
||||
| MANTD_HIGH_LL (dl1) << (64 - (HIGH_LL_FRAC_BITS + 1));
|
||||
|
Loading…
Reference in New Issue
Block a user