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/_fixunssfdi.c | |
parent | be2c7f8f8bace931b3c47d28f07c8f0eb6f8f9dd (diff) | |
download | gcc-fc1cd0120e978d0f7155b5a2058e460fd078c0b0.tar.gz |
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/_fixunssfdi.c')
-rw-r--r-- | libgcc/config/s390/32/_fixunssfdi.c | 50 |
1 files changed, 36 insertions, 14 deletions
diff --git a/libgcc/config/s390/32/_fixunssfdi.c b/libgcc/config/s390/32/_fixunssfdi.c index aeb477a4ee8..7aeed28a0bd 100644 --- a/libgcc/config/s390/32/_fixunssfdi.c +++ b/libgcc/config/s390/32/_fixunssfdi.c @@ -26,11 +26,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #ifndef __s390x__ -#define EXP(fp) (((fp.l) >> 23) & 0xFF) -#define EXCESS 126 +#define EXPONENT_BIAS 127 +#define MANTISSA_BITS 23 +#define EXP(fp) (((fp.l) >> MANTISSA_BITS) & 0xFF) #define SIGNBIT 0x80000000 #define SIGN(fp) ((fp.l) & SIGNBIT) -#define HIDDEN (1 << 23) +#define HIDDEN (1 << MANTISSA_BITS) #define MANT(fp) (((fp.l) & 0x7FFFFF) | HIDDEN) #define FRAC(fp) ((fp.l) & 0x7FFFFF) @@ -45,6 +46,12 @@ union float_long USItype_x l; }; +static __inline__ void +fexceptdiv (float d, float e) +{ + __asm__ __volatile__ ("debr %0,%1" : : "f" (d), "f" (e) ); +} + UDItype_x __fixunssfdi (float a1); /* convert float to unsigned int */ @@ -57,30 +64,45 @@ __fixunssfdi (float a1) fl1.f = a1; - /* +/- 0, denormalized, negative */ - - if (!EXP (fl1) || SIGN(fl1)) + /* +/- 0, denormalized */ + if (!EXP (fl1)) return 0; - exp = EXP (fl1) - EXCESS - 24; + /* Negative. */ + if (SIGN (fl1)) + { + /* Value is <= -1.0 + C99 Annex F.4 requires an "invalid" exception to be thrown. */ + if (EXP (fl1) >= EXPONENT_BIAS) + fexceptdiv (0.0, 0.0); + return 0; + } - /* number < 1 */ + exp = EXP (fl1) - EXPONENT_BIAS - MANTISSA_BITS; + /* number < 1 */ if (exp < -24) return 0; /* NaN */ - if ((EXP(fl1) == 0xff) && (FRAC(fl1) != 0)) /* NaN */ - return 0x0ULL; + if ((EXP (fl1) == 0xff) && (FRAC (fl1) != 0)) /* NaN */ + { + /* C99 Annex F.4 requires an "invalid" exception to be thrown. */ + fexceptdiv (0.0, 0.0); + return 0x0ULL; + } /* Number big number & + inf */ - if (exp >= 41) { - return 0xFFFFFFFFFFFFFFFFULL; - } + if (exp >= 41) + { + /* C99 Annex F.4 requires an "invalid" exception to be thrown. */ + fexceptdiv (0.0, 0.0); + return 0xFFFFFFFFFFFFFFFFULL; + } - l = MANT(fl1); + l = MANT (fl1); if (exp > 0) l <<= exp; |