fixdfdi.h (__fixunstfdi, __fixtfdi): Rearrange the overflow check to make it easier to read.
2008-01-30 Andreas Krebbel <krebbel1@de.ibm.com> * config/s390/fixdfdi.h (__fixunstfdi, __fixtfdi): Rearrange the overflow check to make it easier to read. (__fixtfdi): Change the type of the ll member in union long_double to UDItype_x. 2008-01-30 Andreas Krebbel <krebbel1@de.ibm.com> * gcc.target/s390/tf_to_di-1.c: New testcase. From-SVN: r131957
This commit is contained in:
parent
a99d95a270
commit
393c005884
@ -1,3 +1,10 @@
|
||||
2008-01-30 Andreas Krebbel <krebbel1@de.ibm.com>
|
||||
|
||||
* config/s390/fixdfdi.h (__fixunstfdi, __fixtfdi): Rearrange
|
||||
the overflow check to make it easier to read.
|
||||
(__fixtfdi): Change the type of the ll member in union
|
||||
long_double to UDItype_x.
|
||||
|
||||
2008-01-30 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/34969
|
||||
|
@ -77,13 +77,15 @@ __fixunstfdi (long double a1)
|
||||
if ((EXPD(dl1) == 0x7fff) && !FRACD_ZERO_P (dl1))
|
||||
return 0x0ULL;
|
||||
|
||||
/* If the upper ll part of the mantissa isn't
|
||||
zeroed out after shifting the number would be to large. */
|
||||
if (exp >= -HIGH_LL_FRAC_BITS)
|
||||
return 0xFFFFFFFFFFFFFFFFULL;
|
||||
|
||||
/* 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 (exp > 0)
|
||||
return 0xFFFFFFFFFFFFFFFFULL;
|
||||
|
||||
l = MANTD_LOW_LL (dl1) >> (HIGH_LL_FRAC_BITS + 1)
|
||||
| MANTD_HIGH_LL (dl1) << (64 - (HIGH_LL_FRAC_BITS + 1));
|
||||
|
||||
@ -117,7 +119,7 @@ union double_long {
|
||||
struct {
|
||||
SItype_x i[4]; /* 32 bit parts: 0 upper ... 3 lowest */
|
||||
} l;
|
||||
DItype_x ll[2]; /* 64 bit parts: 0 upper, 1 lower */
|
||||
UDItype_x ll[2]; /* 64 bit parts: 0 upper, 1 lower */
|
||||
};
|
||||
|
||||
DItype_x __fixtfdi (long double a1);
|
||||
@ -136,7 +138,7 @@ __fixtfdi (long double a1)
|
||||
if (!EXPD (dl1))
|
||||
return 0;
|
||||
|
||||
/* The exponent - considered the binary point at the right end of
|
||||
/* The exponent - considered the binary point at the right end of
|
||||
the mantissa. */
|
||||
exp = EXPD (dl1) - EXPONENT_BIAS - MANTISSA_BITS;
|
||||
|
||||
@ -149,17 +151,21 @@ __fixtfdi (long double a1)
|
||||
if ((EXPD(dl1) == 0x7fff) && !FRACD_ZERO_P (dl1))
|
||||
return 0x8000000000000000ULL;
|
||||
|
||||
/* If the upper ll part of the mantissa isn't
|
||||
zeroed out after shifting the number would be to large. */
|
||||
if (exp >= -HIGH_LL_FRAC_BITS)
|
||||
/* 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. Compared to the unsigned variant we have to
|
||||
take care that there is still space for the sign bit to be
|
||||
applied. So we can only go on if there is a right-shift by one
|
||||
or more. */
|
||||
if (exp >= 0)
|
||||
{
|
||||
l = (long long)1 << 63; /* long int min */
|
||||
l = 1ULL << 63; /* long long min */
|
||||
return SIGND (dl1) ? l : l - 1;
|
||||
}
|
||||
|
||||
/* The extra bit is needed for the sign bit. */
|
||||
exp += HIGH_LL_FRAC_BITS + 1;
|
||||
|
||||
l = MANTD_LOW_LL (dl1) >> (HIGH_LL_FRAC_BITS + 1)
|
||||
| MANTD_HIGH_LL (dl1) << (64 - (HIGH_LL_FRAC_BITS + 1));
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
2008-01-30 Andreas Krebbel <krebbel1@de.ibm.com>
|
||||
|
||||
* gcc.target/s390/tf_to_di-1.c: New testcase.
|
||||
|
||||
2008-01-30 Paul Thomas <pault@gcc.gnu.org>
|
||||
|
||||
PR fortran/34975
|
||||
|
46
gcc/testsuite/gcc.target/s390/tf_to_di-1.c
Normal file
46
gcc/testsuite/gcc.target/s390/tf_to_di-1.c
Normal file
@ -0,0 +1,46 @@
|
||||
/* { dg-options "-O0 -mlong-double-128" } */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void
|
||||
check_ll (long double ld, long long ll)
|
||||
{
|
||||
if ((long long)ld != ll)
|
||||
{
|
||||
printf ("ld: %Lf expect: %lld result: %lld\n",
|
||||
ld, ll, (long long)ld);
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
check_ull (long double ld, unsigned long long ull)
|
||||
{
|
||||
if ((unsigned long long)ld != ull)
|
||||
{
|
||||
printf ("ld: %Lf expect: %llu result: %llu\n",
|
||||
ld, ull, (unsigned long long)ld);
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
const long long ll_max = (long long)((1ULL << 63) - 1);
|
||||
const long long ll_min = -ll_max - 1;
|
||||
|
||||
check_ll (206.23253, 206LL);
|
||||
check_ull (206.23253, 206ULL);
|
||||
check_ll ((long double)ll_max, ll_max);
|
||||
check_ull ((long double)ll_max, ll_max);
|
||||
check_ll ((long double)ll_min, ll_min);
|
||||
check_ll (0.0, 0);
|
||||
check_ull (0.0, 0);
|
||||
check_ll (-1.0, -1);
|
||||
check_ll ((long double)0xffffffffffffffffULL, ll_max);
|
||||
check_ull ((long double)0xffffffffffffffffULL, 0xffffffffffffffffULL);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user