From patchwork Fri Jul 3 13:38:15 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Stefan Liebler X-Patchwork-Id: 7482 Received: (qmail 94680 invoked by alias); 3 Jul 2015 13:38:53 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 94657 invoked by uid 89); 3 Jul 2015 13:38:51 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.2 required=5.0 tests=BAYES_50, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: e06smtp14.uk.ibm.com X-MailFrom: stli@linux.vnet.ibm.com X-RcptTo: libc-alpha@sourceware.org From: Stefan Liebler To: libc-alpha@sourceware.org Cc: Stefan Liebler Subject: [PATCH 01/27] [BZ #18610] S390: Fix handling of DXC-byte in FPC-register. Date: Fri, 3 Jul 2015 15:38:15 +0200 Message-Id: <1435930721-27922-2-git-send-email-stli@linux.vnet.ibm.com> In-Reply-To: <1435930721-27922-1-git-send-email-stli@linux.vnet.ibm.com> References: <1435930721-27922-1-git-send-email-stli@linux.vnet.ibm.com> MIME-Version: 1.0 X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15070313-0017-0000-0000-0000049D9676 On s390, the DXC(data-exception-code)-byte in FPC(floating-point-control)- register contains a code of the last occured exception. If bits 6 and 7 of DXC-byte are zero, the bits 0-5 correspond to the ieee-exception flag bits. The current implementation always uses these bits as ieee-exception flag bits. fetestexcept() reports any exception after the first usage of a vector-instruction in a process, because it raises an "vector instruction exception" with DXC-code 0xFE. This patch fixes the handling of the DXC-byte. The DXC-Byte is only handled if bits 6 and 7 are zero. The #define _FPU_RESERVED is extended by the DXC-Byte. Otherwise the tests math/test-fpucw-static and math/test-fpucw-ieee-static fails, because DXC-Byte contains the vector instruction exception when reaching main(). This exception was triggered by strrchr() call in __init_misc(). __init_misc() is called after __setfpucw () in __libc_init_first(). The field __ieee_instruction_pointer in struct fenv_t is renamed to __unused because it is a relict from commit "Remove PTRACE_PEEKUSER" (87b9b50f0d4b92248905e95a06a13c513dc45e59) and isn´t used anymore. ChangeLog: [BZ #18610] * sysdeps/s390/fpu/bits/fenv.h (fenv_t): Rename __ieee_instruction_pointer to __unused. * sysdeps/s390/fpu/fesetenv.c (__fesetenv): Remove usage of __ieee_instruction_pointer. * sysdeps/s390/fpu/fclrexcpt.c (feclearexcept): Fix dxc-field handling. * sysdeps/s390/fpu/fgetexcptflg.c (fegetexceptflag): Likewise. * sysdeps/s390/fpu/fsetexcptflg.c (fesetexceptflag): Likewise. * sysdeps/s390/fpu/ftestexcept.c (fetestexcept): Likewise. * sysdeps/s390/fpu/fpu_control.h (_FPU_RESERVED): Mark dxc-field as reserved. --- sysdeps/s390/fpu/bits/fenv.h | 6 ++++-- sysdeps/s390/fpu/fclrexcpt.c | 7 ++++++- sysdeps/s390/fpu/fesetenv.c | 2 -- sysdeps/s390/fpu/fgetexcptflg.c | 8 +++++++- sysdeps/s390/fpu/fpu_control.h | 6 +++--- sysdeps/s390/fpu/fsetexcptflg.c | 15 ++++++++++++--- sysdeps/s390/fpu/ftestexcept.c | 12 +++++++++--- 7 files changed, 41 insertions(+), 15 deletions(-) diff --git a/sysdeps/s390/fpu/bits/fenv.h b/sysdeps/s390/fpu/bits/fenv.h index 052b2b6..e5b0117 100644 --- a/sysdeps/s390/fpu/bits/fenv.h +++ b/sysdeps/s390/fpu/bits/fenv.h @@ -77,8 +77,10 @@ typedef unsigned int fexcept_t; /* size of fpc */ typedef struct { fexcept_t __fpc; - void *__ieee_instruction_pointer; - /* failing instruction for ieee exceptions */ + void *__unused; + /* The field __unused (formerly __ieee_instruction_pointer) is a relict from + commit "Remove PTRACE_PEEKUSER" (87b9b50f0d4b92248905e95a06a13c513dc45e59) + and isn´t used anymore. */ } fenv_t; /* If the default argument is used we use this value. */ diff --git a/sysdeps/s390/fpu/fclrexcpt.c b/sysdeps/s390/fpu/fclrexcpt.c index dd13808..7f42084 100644 --- a/sysdeps/s390/fpu/fclrexcpt.c +++ b/sysdeps/s390/fpu/fclrexcpt.c @@ -29,7 +29,12 @@ feclearexcept (int excepts) _FPU_GETCW (temp); /* Clear the relevant bits. */ - temp &= ~((excepts << FPC_DXC_SHIFT)|(excepts << FPC_FLAGS_SHIFT)); + temp &= ~(excepts << FPC_FLAGS_SHIFT); + if ((temp & FPC_NOT_FPU_EXCEPTION) == 0) + /* Bits 6, 7 of dxc-byte are zero, + thus bits 0-5 of dxc-byte correspond to the flag-bits. + Clear the relevant bits in flags and dxc-field. */ + temp &= ~(excepts << FPC_DXC_SHIFT); /* Put the new data in effect. */ _FPU_SETCW (temp); diff --git a/sysdeps/s390/fpu/fesetenv.c b/sysdeps/s390/fpu/fesetenv.c index 467716a..bcfba5c 100644 --- a/sysdeps/s390/fpu/fesetenv.c +++ b/sysdeps/s390/fpu/fesetenv.c @@ -32,12 +32,10 @@ __fesetenv (const fenv_t *envp) if (envp == FE_DFL_ENV) { env.__fpc = _FPU_DEFAULT; - env.__ieee_instruction_pointer = 0; } else if (envp == FE_NOMASK_ENV) { env.__fpc = FPC_EXCEPTION_MASK; - env.__ieee_instruction_pointer = 0; } else env = (*envp); diff --git a/sysdeps/s390/fpu/fgetexcptflg.c b/sysdeps/s390/fpu/fgetexcptflg.c index c14dc15..0a5a081 100644 --- a/sysdeps/s390/fpu/fgetexcptflg.c +++ b/sysdeps/s390/fpu/fgetexcptflg.c @@ -27,7 +27,13 @@ fegetexceptflag (fexcept_t *flagp, int excepts) /* Get the current exceptions. */ _FPU_GETCW (temp); - newexcepts = (excepts << FPC_DXC_SHIFT) | (excepts << FPC_FLAGS_SHIFT); + newexcepts = excepts << FPC_FLAGS_SHIFT; + if ((temp & FPC_NOT_FPU_EXCEPTION) == 0) + /* Bits 6, 7 of dxc-byte are zero, + thus bits 0-5 of dxc-byte correspond to the flag-bits. + Evaluate flags and last dxc-exception-code. */ + newexcepts |= excepts << FPC_DXC_SHIFT; + *flagp = temp & newexcepts; /* Success. */ diff --git a/sysdeps/s390/fpu/fpu_control.h b/sysdeps/s390/fpu/fpu_control.h index 098f0d0..1f663b3 100644 --- a/sysdeps/s390/fpu/fpu_control.h +++ b/sysdeps/s390/fpu/fpu_control.h @@ -19,12 +19,12 @@ . */ #ifndef _FPU_CONTROL_H -# define _FPU_CONTROL_H +#define _FPU_CONTROL_H -# include +#include /* These bits are reserved are not changed. */ -# define _FPU_RESERVED 0x070700FC +#define _FPU_RESERVED 0x0707FFFC /* The fdlibm code requires no interrupts for exceptions. Don't change the rounding mode, it would break long double I/O! */ diff --git a/sysdeps/s390/fpu/fsetexcptflg.c b/sysdeps/s390/fpu/fsetexcptflg.c index cbe9f34..4ccc249 100644 --- a/sysdeps/s390/fpu/fsetexcptflg.c +++ b/sysdeps/s390/fpu/fsetexcptflg.c @@ -24,16 +24,25 @@ int fesetexceptflag (const fexcept_t *flagp, int excepts) { - fexcept_t temp,newexcepts; + fexcept_t temp, newexcepts; /* Get the current environment. We have to do this since we cannot separately set the status word. */ _FPU_GETCW (temp); /* Install the new exception bits in the Accrued Exception Byte. */ excepts = excepts & FE_ALL_EXCEPT; - newexcepts = (excepts << FPC_DXC_SHIFT) | (excepts << FPC_FLAGS_SHIFT); + newexcepts = excepts << FPC_FLAGS_SHIFT; temp &= ~newexcepts; - temp |= *flagp & newexcepts; + if ((temp & FPC_NOT_FPU_EXCEPTION) == 0) + /* Bits 6, 7 of dxc-byte are zero, + thus bits 0-5 of dxc-byte correspond to the flag-bits. + Clear given exceptions in dxc-field. */ + temp &= ~(excepts << FPC_DXC_SHIFT); + + /* Integrate dxc-byte of flagp into flags. The dxc-byte of flagp contains + either an ieee-exception or 0 (see fegetexceptflag). */ + temp |= (*flagp | ((*flagp >> FPC_DXC_SHIFT) << FPC_FLAGS_SHIFT)) + & newexcepts; /* Store the new status word (along with the rest of the environment. Possibly new exceptions are set but they won't get executed unless diff --git a/sysdeps/s390/fpu/ftestexcept.c b/sysdeps/s390/fpu/ftestexcept.c index 6889632..55b7c4a 100644 --- a/sysdeps/s390/fpu/ftestexcept.c +++ b/sysdeps/s390/fpu/ftestexcept.c @@ -23,11 +23,17 @@ int fetestexcept (int excepts) { - fexcept_t temp; + fexcept_t temp, res; /* Get current exceptions. */ _FPU_GETCW (temp); - temp = (temp >> FPC_DXC_SHIFT) | (temp >> FPC_FLAGS_SHIFT); - return temp & excepts & FE_ALL_EXCEPT; + res = temp >> FPC_FLAGS_SHIFT; + if ((temp & FPC_NOT_FPU_EXCEPTION) == 0) + /* Bits 6, 7 of dxc-byte are zero, + thus bits 0-5 of dxc-byte correspond to the flag-bits. + Evaluate flags and last dxc-exception-code. */ + res |= temp >> FPC_DXC_SHIFT; + + return res & excepts & FE_ALL_EXCEPT; } libm_hidden_def (fetestexcept)