summaryrefslogtreecommitdiff
path: root/gcc/config/s390/fixdfdi.h
diff options
context:
space:
mode:
authorkrebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4>2008-01-30 08:00:51 +0000
committerkrebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4>2008-01-30 08:00:51 +0000
commit365b8932ed9ea077ec66ca18ada47aad2e600b96 (patch)
tree4acc05569093f04c2196aa7a4d7d564d139579f1 /gcc/config/s390/fixdfdi.h
parent8d39570e68562ab8144f974b7719e39a851d1b4e (diff)
downloadgcc-365b8932ed9ea077ec66ca18ada47aad2e600b96.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@131957 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/s390/fixdfdi.h')
-rw-r--r--gcc/config/s390/fixdfdi.h34
1 files changed, 20 insertions, 14 deletions
diff --git a/gcc/config/s390/fixdfdi.h b/gcc/config/s390/fixdfdi.h
index f3e48ac8f9d..865bf46b99f 100644
--- a/gcc/config/s390/fixdfdi.h
+++ b/gcc/config/s390/fixdfdi.h
@@ -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));