From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11661 invoked by alias); 15 Jun 2012 19:27:01 -0000 Received: (qmail 11646 invoked by uid 22791); 15 Jun 2012 19:27:00 -0000 X-SWARE-Spam-Status: No, hits=-5.0 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,KHOP_RCVD_TRUST,KHOP_THREADED,RCVD_IN_DNSWL_LOW,RCVD_IN_HOSTKARMA_YE X-Spam-Check-By: sourceware.org Received: from mail-pb0-f41.google.com (HELO mail-pb0-f41.google.com) (209.85.160.41) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 15 Jun 2012 19:26:47 +0000 Received: by pbbrp2 with SMTP id rp2so6192541pbb.0 for ; Fri, 15 Jun 2012 12:26:46 -0700 (PDT) Received: by 10.68.225.170 with SMTP id rl10mr23324798pbc.13.1339788047979; Fri, 15 Jun 2012 12:20:47 -0700 (PDT) Received: from anchor.twiddle.home ([173.160.232.49]) by mx.google.com with ESMTPS id tm2sm14126864pbc.69.2012.06.15.12.20.47 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 15 Jun 2012 12:20:47 -0700 (PDT) From: Richard Henderson To: libc-ports@sourceware.org Subject: [PATCH 6/7] [BZ #13848] alpha: Fix s_nearbyint implementation. Date: Fri, 15 Jun 2012 19:27:00 -0000 Message-Id: <1339788037-29519-7-git-send-email-rth@twiddle.net> In-Reply-To: <1339788037-29519-1-git-send-email-rth@twiddle.net> References: <1339788037-29519-1-git-send-email-rth@twiddle.net> X-IsSubscribed: yes Mailing-List: contact libc-ports-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: libc-ports-owner@sourceware.org X-SW-Source: 2012-06/txt/msg00063.txt.bz2 --- sysdeps/alpha/fpu/s_nearbyint.c | 31 ++++++++++++++++--------------- sysdeps/alpha/fpu/s_nearbyintf.c | 35 +++++++++++++++++++++-------------- 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/sysdeps/alpha/fpu/s_nearbyint.c b/sysdeps/alpha/fpu/s_nearbyint.c index 1f89260..4589bfc 100644 --- a/sysdeps/alpha/fpu/s_nearbyint.c +++ b/sysdeps/alpha/fpu/s_nearbyint.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007 Free Software Foundation, Inc. +/* Copyright (C) 2000-2012 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Richard Henderson. @@ -19,22 +19,23 @@ #include #include -#ifdef _IEEE_FP_INEXACT -#error "Don't compile with -mieee-with-inexact" -#endif double __nearbyint (double x) { - double two52 = copysign (0x1.0p52, x); - double r; - - r = x + two52; - r = r - two52; - - /* nearbyint(-0.1) == -0, and in general we'll always have the same sign - as our input. */ - return copysign (r, x); + if (isless (fabs (x), 9007199254740992.0)) /* 1 << DBL_MANT_DIG */ + { + double tmp1, new_x; + __asm ("cvttq/svd %2,%1\n\t" + "cvtqt/d %1,%0\n\t" + : "=f"(new_x), "=&f"(tmp1) + : "f"(x)); + + /* nearbyint(-0.1) == -0, and in general we'll always have the same + sign as our input. */ + x = copysign(new_x, x); + } + return x; } weak_alias (__nearbyint, nearbyint) @@ -42,6 +43,6 @@ weak_alias (__nearbyint, nearbyint) strong_alias (__nearbyint, __nearbyintl) weak_alias (__nearbyint, nearbyintl) #endif -#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) -compat_symbol (libm, __nearbyint, nearbyintl, GLIBC_2_1); +#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) +compat_symbol (libm, __nearbyint, nearbyintl, GLIBC_2_0); #endif diff --git a/sysdeps/alpha/fpu/s_nearbyintf.c b/sysdeps/alpha/fpu/s_nearbyintf.c index efea959..871b9f6 100644 --- a/sysdeps/alpha/fpu/s_nearbyintf.c +++ b/sysdeps/alpha/fpu/s_nearbyintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007 Free Software Foundation, Inc. +/* Copyright (C) 2007-2012 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Richard Henderson. @@ -18,22 +18,29 @@ #include -#ifdef _IEEE_FP_INEXACT -#error "Don't compile with -mieee-with-inexact" -#endif - float __nearbyintf (float x) { - float two23 = copysignf (0x1.0p23, x); - float r; - - r = x + two23; - r = r - two23; - - /* nearbyint(-0.1) == -0, and in general we'll always have the same sign - as our input. */ - return copysign (r, x); + if (isless (fabsf (x), 16777216.0f)) /* 1 << FLT_MANT_DIG */ + { + /* Note that Alpha S_Floating is stored in registers in a + restricted T_Floating format, so we don't even need to + convert back to S_Floating in the end. The initial + conversion to T_Floating is needed to handle denormals. */ + + float tmp1, tmp2, new_x; + + __asm ("cvtst/s %3,%2\n\t" + "cvttq/svd %2,%1\n\t" + "cvtqt/d %1,%0\n\t" + : "=f"(new_x), "=&f"(tmp1), "=&f"(tmp2) + : "f"(x)); + + /* nearbyintf(-0.1) == -0, and in general we'll always have the same + sign as our input. */ + x = copysignf(new_x, x); + } + return x; } weak_alias (__nearbyintf, nearbyintf) -- 1.7.7.6