about summary refs log tree commit diff
path: root/sysdeps/s390/fpu/ftestexcept.c
diff options
context:
space:
mode:
authorStefan Liebler <stli@linux.vnet.ibm.com>2015-08-26 10:26:18 +0200
committerAndreas Krebbel <krebbel@linux.vnet.ibm.com>2015-08-26 10:26:18 +0200
commit5d96fe8c0dc3450bafe6c2aae2dabc76819df3e0 (patch)
treed1b8a2905087b2a7d23d0d0947347667afa800b1 /sysdeps/s390/fpu/ftestexcept.c
parentf97194930886838796546646e26a49bb5899075b (diff)
downloadglibc-5d96fe8c0dc3450bafe6c2aae2dabc76819df3e0.tar.gz
glibc-5d96fe8c0dc3450bafe6c2aae2dabc76819df3e0.tar.xz
glibc-5d96fe8c0dc3450bafe6c2aae2dabc76819df3e0.zip
S390: Fix handling of DXC-byte in FPC-register.
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.
Diffstat (limited to 'sysdeps/s390/fpu/ftestexcept.c')
-rw-r--r--sysdeps/s390/fpu/ftestexcept.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/sysdeps/s390/fpu/ftestexcept.c b/sysdeps/s390/fpu/ftestexcept.c
index 6889632a5b..55b7c4a332 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)