diff options
author | krebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-02-07 10:14:24 +0000 |
---|---|---|
committer | krebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-02-07 10:14:24 +0000 |
commit | fc1cd0120e978d0f7155b5a2058e460fd078c0b0 (patch) | |
tree | bd57e14f45de42cc9484512765bf1e00c671e867 /libgcc/config/s390/32/_fixunsdfdi.c | |
parent | be2c7f8f8bace931b3c47d28f07c8f0eb6f8f9dd (diff) | |
download | ppe42-gcc-fc1cd0120e978d0f7155b5a2058e460fd078c0b0.tar.gz ppe42-gcc-fc1cd0120e978d0f7155b5a2058e460fd078c0b0.zip |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@207596 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgcc/config/s390/32/_fixunsdfdi.c')
-rw-r--r-- | libgcc/config/s390/32/_fixunsdfdi.c | 46 |
1 files changed, 35 insertions, 11 deletions
diff --git a/libgcc/config/s390/32/_fixunsdfdi.c b/libgcc/config/s390/32/_fixunsdfdi.c index 84cc8bc1a38..0a249611a23 100644 --- a/libgcc/config/s390/32/_fixunsdfdi.c +++ b/libgcc/config/s390/32/_fixunsdfdi.c @@ -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,28 +68,44 @@ __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 */ - return 0x0ULL; + { + /* 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) { - return 0xFFFFFFFFFFFFFFFFULL; - } + if (exp >= 12) + { + /* C99 Annex F.4 requires an "invalid" exception to be thrown. */ + fexceptdiv (0.0, 0.0); + return 0xFFFFFFFFFFFFFFFFULL; + } l = MANTD_LL(dl1); |