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:
Andreas Krebbel 2008-01-30 08:00:51 +00:00 committed by Andreas Krebbel
parent a99d95a270
commit 393c005884
4 changed files with 77 additions and 14 deletions

View File

@ -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

View File

@ -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));

View File

@ -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

View 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;
}