From patchwork Thu Jan 30 14:57:46 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Krebbel X-Patchwork-Id: 315382 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id CF1D62C0245 for ; Fri, 31 Jan 2014 01:58:09 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=cTsG3UF1+2fJdBlgUIJZhbIBXdR1LbFd5IOH2Vhwhxe6vXQJHbEhM phMDmjDUSpY/lTbMaPb0ATO3+HK6xv2H0/gTtDT1m15oO92QwjfgHm7ePjclBnob T3P6rFkOqYXPlAx7rLhHQjU700Nnu8v6qzcZZuuTliiNUPFIUZUxQQ= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=dY0CEyRbIW8LVgu0KWW/PUxVpFo=; b=DdYyGGvCvuUVwoY8e0h1 ghz3IpaYDT+FTcejy33a8j40YR1c4yS2l7NR+7Plp96KFC26OyaAs26LiVZQsOEn L2vY+Z7DrARhbGzRjdYgyuXtzNaXgc5TOQn59rw6Dfz6NMPiAqfzzuTi6xeXVUhz 4ZtGqE+Po6GubFS5s+sI9AI= Received: (qmail 18564 invoked by alias); 30 Jan 2014 14:58:01 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 18549 invoked by uid 89); 30 Jan 2014 14:58:01 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: e06smtp12.uk.ibm.com Received: from e06smtp12.uk.ibm.com (HELO e06smtp12.uk.ibm.com) (195.75.94.108) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Thu, 30 Jan 2014 14:57:59 +0000 Received: from /spool/local by e06smtp12.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 30 Jan 2014 14:57:55 -0000 Received: from d06dlp03.portsmouth.uk.ibm.com (9.149.20.15) by e06smtp12.uk.ibm.com (192.168.101.142) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 30 Jan 2014 14:57:53 -0000 Received: from b06cxnps4076.portsmouth.uk.ibm.com (d06relay13.portsmouth.uk.ibm.com [9.149.109.198]) by d06dlp03.portsmouth.uk.ibm.com (Postfix) with ESMTP id DE3201B0805F for ; Thu, 30 Jan 2014 14:57:21 +0000 (GMT) Received: from d06av09.portsmouth.uk.ibm.com (d06av09.portsmouth.uk.ibm.com [9.149.37.250]) by b06cxnps4076.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id s0UEvavx655626 for ; Thu, 30 Jan 2014 14:57:36 GMT Received: from d06av09.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av09.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id s0UEvmIQ014336 for ; Thu, 30 Jan 2014 07:57:48 -0700 Received: from bart (dyn-9-152-212-89.boeblingen.de.ibm.com [9.152.212.89]) by d06av09.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with SMTP id s0UEvlJ6014258 for ; Thu, 30 Jan 2014 07:57:47 -0700 Received: by bart (sSMTP sendmail emulation); Thu, 30 Jan 2014 15:57:46 +0100 Date: Thu, 30 Jan 2014 15:57:46 +0100 From: Andreas Krebbel To: gcc-patches@gcc.gnu.org Subject: [PATCH] S/390: Throw FE_INVALID exception in the fp2int libgcc routines Message-ID: <20140130145746.GA30339@bart> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 14013014-8372-0000-0000-0000087B4FD8 X-IsSubscribed: yes Hi, our IEEE float to int conversion routines in libgcc do not throw the FE_INVALID exceptions according to C99 Annex F. Fixed with the attached patch. This fixes the Glibc test-ldouble tests on s390: < Failure: llrint (inf): Exception "Invalid operation" not set < Failure: llrint (-inf): Exception "Invalid operation" not set < Failure: llrint (qNaN): Exception "Invalid operation" not set < Failure: llrint_tonearest (inf): Exception "Invalid operation" not set < Failure: llrint_tonearest (-inf): Exception "Invalid operation" not set < Failure: llrint_tonearest (qNaN): Exception "Invalid operation" not set < Failure: llrint_towardzero (inf): Exception "Invalid operation" not set < Failure: llrint_towardzero (-inf): Exception "Invalid operation" not set < Failure: llrint_towardzero (qNaN): Exception "Invalid operation" not set < Failure: llrint_downward (inf): Exception "Invalid operation" not set < Failure: llrint_downward (-inf): Exception "Invalid operation" not set < Failure: llrint_downward (qNaN): Exception "Invalid operation" not set < Failure: llrint_upward (inf): Exception "Invalid operation" not set < Failure: llrint_upward (-inf): Exception "Invalid operation" not set < Failure: llrint_upward (qNaN): Exception "Invalid operation" not set < Failure: llround (inf): Exception "Invalid operation" not set < Failure: llround (-inf): Exception "Invalid operation" not set < Failure: llround (qNaN): Exception "Invalid operation" not set Glibc BZ: https://sourceware.org/bugzilla/show_bug.cgi?id=16449 I'll commit the patch after waiting a few days for comments. Bye, -Andreas- 2014-01-30 Andreas Krebbel * 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. commit da26827014daa447835f41bf07f3e3eb3ffe0c75 Author: Andreas Krebbel Date: Wed Jan 29 10:13:51 2014 +0100 S/390: libgcc: Throw INVALID exception for float->int conversions to implement C99 Annex F.4. diff --git a/libgcc/config/s390/32/_fixdfdi.c b/libgcc/config/s390/32/_fixdfdi.c index 1c6954c..7178c01 100644 --- a/libgcc/config/s390/32/_fixdfdi.c +++ b/libgcc/config/s390/32/_fixdfdi.c @@ -46,6 +46,12 @@ union double_long { UDItype_x ll; }; +static __inline__ void +fexceptdiv (float d, float e) +{ + __asm__ __volatile__ ("debr %0,%1" : : "f" (d), "f" (e) ); +} + DItype_x __fixdfdi (double a1); /* convert double to int */ @@ -73,7 +79,11 @@ __fixdfdi (double a1) /* NaN */ if ((EXPD(dl1) == 0x7ff) && (FRACD_LL(dl1) != 0)) /* NaN */ - return 0x8000000000000000ULL; + { + /* C99 Annex F.4 requires an "invalid" exception to be thrown. */ + fexceptdiv (0.0, 0.0); + return 0x8000000000000000ULL; + } /* Number big number & +/- inf */ @@ -81,6 +91,8 @@ __fixdfdi (double a1) l = (long long)1<<63; if (!SIGND(dl1)) l--; + /* C99 Annex F.4 requires an "invalid" exception to be thrown. */ + fexceptdiv (0.0, 0.0); return l; } diff --git a/libgcc/config/s390/32/_fixsfdi.c b/libgcc/config/s390/32/_fixsfdi.c index eaabd18..cea3b84 100644 --- a/libgcc/config/s390/32/_fixsfdi.c +++ b/libgcc/config/s390/32/_fixsfdi.c @@ -43,6 +43,12 @@ union float_long USItype_x l; }; +static __inline__ void +fexceptdiv (float d, float e) +{ + __asm__ __volatile__ ("debr %0,%1" : : "f" (d), "f" (e) ); +} + DItype_x __fixsfdi (float a1); /* convert double to int */ @@ -70,7 +76,11 @@ __fixsfdi (float a1) /* NaN */ if ((EXP(fl1) == 0xff) && (FRAC(fl1) != 0)) /* NaN */ - return 0x8000000000000000ULL; + { + /* C99 Annex F.4 requires an "invalid" exception to be thrown. */ + fexceptdiv (0.0, 0.0); + return 0x8000000000000000ULL; + } /* Number big number & +/- inf */ @@ -78,6 +88,8 @@ __fixsfdi (float a1) l = (long long)1<<63; if (!SIGN(fl1)) l--; + /* C99 Annex F.4 requires an "invalid" exception to be thrown. */ + fexceptdiv (0.0, 0.0); return l; } diff --git a/libgcc/config/s390/32/_fixtfdi.c b/libgcc/config/s390/32/_fixtfdi.c index 51807d1..d17c516 100644 --- a/libgcc/config/s390/32/_fixtfdi.c +++ b/libgcc/config/s390/32/_fixtfdi.c @@ -50,6 +50,12 @@ union double_long { UDItype_x ll[2]; /* 64 bit parts: 0 upper, 1 lower */ }; +static __inline__ void +fexceptdiv (float d, float e) +{ + __asm__ __volatile__ ("debr %0,%1" : : "f" (d), "f" (e) ); +} + DItype_x __fixtfdi (long double a1); /* convert double to unsigned int */ @@ -77,7 +83,11 @@ __fixtfdi (long double a1) /* NaN: All exponent bits set and a nonzero fraction. */ if ((EXPD(dl1) == 0x7fff) && !FRACD_ZERO_P (dl1)) - return 0x8000000000000000ULL; + { + /* C99 Annex F.4 requires an "invalid" exception to be thrown. */ + fexceptdiv (0.0, 0.0); + return 0x8000000000000000ULL; + } /* One extra bit is needed for the unit bit which is appended by MANTD_HIGH_LL on the left of the matissa. */ @@ -90,6 +100,8 @@ __fixtfdi (long double a1) or more. */ if (exp >= 0) { + /* C99 Annex F.4 requires an "invalid" exception to be thrown. */ + fexceptdiv (0.0, 0.0); l = 1ULL << 63; /* long long min */ return SIGND (dl1) ? l : l - 1; } diff --git a/libgcc/config/s390/32/_fixunsdfdi.c b/libgcc/config/s390/32/_fixunsdfdi.c index 7786bdc..4179b3f 100644 --- a/libgcc/config/s390/32/_fixunsdfdi.c +++ b/libgcc/config/s390/32/_fixunsdfdi.c @@ -46,6 +46,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 */ @@ -73,13 +79,20 @@ __fixunsdfdi (double a1) /* 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); diff --git a/libgcc/config/s390/32/_fixunssfdi.c b/libgcc/config/s390/32/_fixunssfdi.c index b007cf6..9dd3154 100644 --- a/libgcc/config/s390/32/_fixunssfdi.c +++ b/libgcc/config/s390/32/_fixunssfdi.c @@ -43,6 +43,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 */ @@ -70,13 +76,20 @@ __fixunssfdi (float a1) /* NaN */ if ((EXP(fl1) == 0xff) && (FRAC(fl1) != 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 >= 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); diff --git a/libgcc/config/s390/32/_fixunstfdi.c b/libgcc/config/s390/32/_fixunstfdi.c index cf4fbdb..00c22bf 100644 --- a/libgcc/config/s390/32/_fixunstfdi.c +++ b/libgcc/config/s390/32/_fixunstfdi.c @@ -50,6 +50,12 @@ union double_long { UDItype_x ll[2]; /* 64 bit parts: 0 upper, 1 lower */ }; +static __inline__ void +fexceptdiv (float d, float e) +{ + __asm__ __volatile__ ("debr %0,%1" : : "f" (d), "f" (e) ); +} + UDItype_x __fixunstfdi (long double a1); /* convert double to unsigned int */ @@ -78,16 +84,25 @@ __fixunstfdi (long double a1) /* NaN: All exponent bits set and a nonzero fraction. */ if ((EXPD(dl1) == 0x7fff) && !FRACD_ZERO_P (dl1)) - return 0x0ULL; + { + /* C99 Annex F.4 requires an "invalid" exception to be thrown. */ + fexceptdiv (0.0, 0.0); + return 0x0ULL; + } /* 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 the result would still need a left shift it will be too + large to be represented. Infinities have all exponent bits set + and will end up here as well. */ if (exp > 0) - return 0xFFFFFFFFFFFFFFFFULL; + { + /* C99 Annex F.4 requires an "invalid" exception to be thrown. */ + fexceptdiv (0.0, 0.0); + return 0xFFFFFFFFFFFFFFFFULL; + } l = MANTD_LOW_LL (dl1) >> (HIGH_LL_FRAC_BITS + 1) | MANTD_HIGH_LL (dl1) << (64 - (HIGH_LL_FRAC_BITS + 1));