From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14011 invoked by alias); 30 Aug 2012 19:56:37 -0000 Received: (qmail 13995 invoked by uid 22791); 30 Aug 2012 19:56:35 -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,TW_XC X-Spam-Check-By: sourceware.org Received: from mail-wi0-f171.google.com (HELO mail-wi0-f171.google.com) (209.85.212.171) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 30 Aug 2012 19:56:18 +0000 Received: by wibhq4 with SMTP id hq4so577597wib.12 for ; Thu, 30 Aug 2012 12:56:17 -0700 (PDT) Received: by 10.216.135.147 with SMTP id u19mr3492315wei.12.1346356575879; Thu, 30 Aug 2012 12:56:15 -0700 (PDT) Received: from anchor.twiddle.home ([173.160.232.49]) by mx.google.com with ESMTPS id t8sm2355677wiy.3.2012.08.30.12.56.12 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 30 Aug 2012 12:56:15 -0700 (PDT) Message-ID: <503FC55A.9080907@twiddle.net> Date: Thu, 30 Aug 2012 19:56:00 -0000 From: Richard Henderson User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:14.0) Gecko/20120717 Thunderbird/14.0 MIME-Version: 1.0 To: "Joseph S. Myers" CC: libc-alpha@sourceware.org, libc-ports@sourceware.org, Andreas Krebbel , "Ryan S. Arnold" , Mike Frysinger , Carlos O'Donell Subject: Re: Make strtod respect the rounding mode (bug 14518) References: In-Reply-To: Content-Type: multipart/mixed; boundary="------------030701070104000909020004" 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-08/txt/msg00171.txt.bz2 This is a multi-part message in MIME format. --------------030701070104000909020004 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-length: 1009 On 08/29/2012 04:45 PM, Joseph S. Myers wrote: > * This patch does not update the alpha port. alpha maintainers may > wish to add a definition of _FPU_GETCW to fpu_control.h, or to add > bits/rounding-mode.h for alpha (I don't know why its fpu_control.h > doesn't define _FPU_GETCW when it has the other macros needed). I'm not sure why we implement as much of fpu_control.h as we do. It's somewhat unfortunate that it exists in its current form at all, because it's all very biased toward binary compatibility with the x86 fpcr format. While I *could* commit a patch like the following, I'd like an opinion on whether the existing defines could be trashed and the file re-imagined as something more friendly for native. Given of course that at present there cannot be any users since the actual _FPU_G/SETCW macros do not exist. Or whether the file should be trashed and I'll just implement bits/rounding-mode.h. Which honestly seems like it'd be the most efficient for the use in question. r~ --------------030701070104000909020004 Content-Type: text/x-patch; name="0001-alpha-Implement-_FPU_GETCW-and-_FPU_SETCW.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="0001-alpha-Implement-_FPU_GETCW-and-_FPU_SETCW.patch" Content-length: 6834 >From 6a480a617d97dec79140ff449197773c45714024 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 30 Aug 2012 12:06:05 -0700 Subject: [PATCH] alpha: Implement _FPU_GETCW and _FPU_SETCW --- ports/ChangeLog.alpha | 6 +++ ports/sysdeps/alpha/Makefile | 1 + ports/sysdeps/alpha/fpu/Versions | 4 ++ ports/sysdeps/alpha/fpu/fpu_control.h | 15 ++++++- ports/sysdeps/alpha/fpu/fpucw.c | 77 +++++++++++++++++++++++++++++++++++ 5 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 ports/sysdeps/alpha/fpu/fpucw.c diff --git a/ports/ChangeLog.alpha b/ports/ChangeLog.alpha index 9589dd3..12bc4fb 100644 --- a/ports/ChangeLog.alpha +++ b/ports/ChangeLog.alpha @@ -1,5 +1,11 @@ 2012-08-30 Richard Henderson + * sysdeps/alpha/fpu/fpucw.c: New file. + * sysdeps/alpha/Makefile [math] (sysdep_routines): Add it. + * sysdeps/alpha/fpu/fpu_control.h (__fpu_getcw): Declare. + (__fpu_setcw, _FPU_GETCW, _FPU_SETCW): Declare + * sysdeps/alpha/fpu/Versions (__fpu_getcw, __fpu_setcw): Add for 2.17. + * sysdeps/alpha/fpu/s_isnan.c: Define all aliases in terms of the original __isnan symbol. diff --git a/ports/sysdeps/alpha/Makefile b/ports/sysdeps/alpha/Makefile index 1a80db8..75ad30e 100644 --- a/ports/sysdeps/alpha/Makefile +++ b/ports/sysdeps/alpha/Makefile @@ -43,6 +43,7 @@ CFLAGS-s_fma.c = -mieee-with-inexact CFLAGS-s_fmaf.c = -mieee-with-inexact # This test tries to check for inexact being raised by arithmetic. CFLAGS-test-misc.c += -mieee-with-inexact +sysdep_routines += fpucw endif # Build everything with full IEEE math support, and with dynamic rounding; diff --git a/ports/sysdeps/alpha/fpu/Versions b/ports/sysdeps/alpha/fpu/Versions index c9b0e03..ad4eae6 100644 --- a/ports/sysdeps/alpha/fpu/Versions +++ b/ports/sysdeps/alpha/fpu/Versions @@ -3,6 +3,10 @@ libc { # functions used in other libraries __ieee_get_fp_control; __ieee_set_fp_control; } + GLIBC_2.17 { + # functions implementing fpu_control.h + __fpu_getcw; __fpu_setcw; + } } libm { GLIBC_2.3.4 { diff --git a/ports/sysdeps/alpha/fpu/fpu_control.h b/ports/sysdeps/alpha/fpu/fpu_control.h index 4027300..68f06ef 100644 --- a/ports/sysdeps/alpha/fpu/fpu_control.h +++ b/ports/sysdeps/alpha/fpu/fpu_control.h @@ -1,5 +1,5 @@ /* FPU control word bits. Alpha-mapped-to-Intel version. - Copyright (C) 1996, 1998, 2000, 2002 Free Software Foundation, Inc. + Copyright (C) 1996-2012 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Olaf Flebbe. @@ -80,7 +80,6 @@ #define _FPU_RESERVED 0xF0C0 /* Reserved bits in cw */ - /* Now two recommended cw */ /* Linux default: @@ -102,4 +101,16 @@ typedef unsigned int fpu_control_t; /* Default control word set at startup. */ extern fpu_control_t __fpu_control; +/* Internal functions for accessing the hardware control word. */ +extern fpu_control_t __fpu_getcw(void); +extern void __fpu_setcw(fpu_control_t); + +/* The "standard" macros for accessing the hardware control word. + The x86 port which we are emulating uses __asm__ in these macros, + which implies the macro is syntactically a statement and not an + expression. Mirror this restriction here by wrapping the calls + within a do/while statement. */ +#define _FPU_GETCW(cw) do { (cw) = __fpu_getcw(); } while (0) +#define _FPU_SETCW(cw) do { __fpu_setcw(cw); } while (0) + #endif /* _ALPHA_FPU_CONTROL */ diff --git a/ports/sysdeps/alpha/fpu/fpucw.c b/ports/sysdeps/alpha/fpu/fpucw.c new file mode 100644 index 0000000..bcab24a --- /dev/null +++ b/ports/sysdeps/alpha/fpu/fpucw.c @@ -0,0 +1,77 @@ +/* Manipulate the fpu environment in an x86 compatible way. + Copyright (C) 2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include + + +#define REPLACE(S, F, T) \ + ((F) > (T) \ + ? ((S) >> __builtin_ctzl((F) / (T))) & (T) \ + : ((S) & (F)) << __builtin_ctzl((T) / (F))) + +fpu_control_t +__fpu_getcw(void) +{ + unsigned long int fpcr, swcr, retl; + + /* Get status from software and hardware. Note that we don't need an + excb because the callsys is an implied trap barrier. */ + swcr = __ieee_get_fp_control (); + __asm__ __volatile__ ("mf_fpcr %0" : "=f" (fpcr)); + + /* Extract the rounding mode. */ + retl = ((fpcr >> FPCR_ROUND_SHIFT) & 3) << 10; + + /* Extract the Alpha "enabled" exceptions to x86 "masked" exceptions. */ + retl |= REPLACE(~swcr, FE_INVALID >> SWCR_ENABLE_SHIFT, _FPU_MASK_IM); + retl |= REPLACE(~swcr, FE_DENORMAL >> SWCR_ENABLE_SHIFT, _FPU_MASK_DM); + retl |= REPLACE(~swcr, FE_DIVBYZERO >> SWCR_ENABLE_SHIFT, _FPU_MASK_ZM); + retl |= REPLACE(~swcr, FE_OVERFLOW >> SWCR_ENABLE_SHIFT, _FPU_MASK_OM); + retl |= REPLACE(~swcr, FE_UNDERFLOW >> SWCR_ENABLE_SHIFT, _FPU_MASK_UM); + retl |= REPLACE(~swcr, FE_INEXACT >> SWCR_ENABLE_SHIFT, _FPU_MASK_PM); + + return retl; +} + +void +__fpu_setcw(fpu_control_t cw) +{ + unsigned long int fpcr, swcr, cwl = cw; + + /* Get status from software and hardware. Note that we don't need an + excb because the callsys is an implied trap barrier. */ + swcr = __ieee_get_fp_control (); + __asm__ __volatile__ ("mf_fpcr %0" : "=f" (fpcr)); + + fpcr &= ~FPCR_ROUND_MASK; + fpcr |= ((cwl >> 10) & 3ul) << FPCR_ROUND_SHIFT; + + swcr &= ~SWCR_ENABLE_MASK; + swcr |= REPLACE(~cwl, _FPU_MASK_IM, FE_INVALID >> SWCR_ENABLE_SHIFT); + swcr |= REPLACE(~cwl, _FPU_MASK_DM, FE_DENORMAL >> SWCR_ENABLE_SHIFT); + swcr |= REPLACE(~cwl, _FPU_MASK_ZM, FE_DIVBYZERO >> SWCR_ENABLE_SHIFT); + swcr |= REPLACE(~cwl, _FPU_MASK_OM, FE_OVERFLOW >> SWCR_ENABLE_SHIFT); + swcr |= REPLACE(~cwl, _FPU_MASK_UM, FE_UNDERFLOW >> SWCR_ENABLE_SHIFT); + swcr |= REPLACE(~cwl, _FPU_MASK_PM, FE_INEXACT >> SWCR_ENABLE_SHIFT); + + /* Install the new rounding mode and exception enable mask. Note that + the system call is the implied trap barrier for our modification. */ + __asm__ __volatile__ ("mt_fpcr %0" : : "f" (fpcr)); + __ieee_set_fp_control (swcr); +} -- 1.7.11.4 --------------030701070104000909020004--