diff options
author | krebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-01-30 08:00:51 +0000 |
---|---|---|
committer | krebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-01-30 08:00:51 +0000 |
commit | 365b8932ed9ea077ec66ca18ada47aad2e600b96 (patch) | |
tree | 4acc05569093f04c2196aa7a4d7d564d139579f1 /gcc/config/s390/fixdfdi.h | |
parent | 8d39570e68562ab8144f974b7719e39a851d1b4e (diff) | |
download | gcc-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.h | 34 |
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)); |