diff mbox series

powerpc: Add enable exception bits

Message ID 20180627204954.31355-1-tuliom@linux.ibm.com
State New
Headers show
Series powerpc: Add enable exception bits | expand

Commit Message

Tulio Magno Quites Machado Filho June 27, 2018, 8:49 p.m. UTC
The POWER ISA defines bits 56:60 (bits 24:28 in a 32-bit FPSCR) as
control for the 5 exceptions available: invalid operation, overflow,
underflow, zero divide and inexact.

2018-06-27  Tulio Magno Quites Machado Filho  <tuliom@linux.ibm.com>

	* sysdeps/powerpc/bits/fenv.h [__USE_GNU]: Add
	FE_INVALID_ENABLE, FE_OVERFLOW_ENABLE, FE_UNDERFLOW_ENABLE,
	FE_DIVBYZERO_ENABLE and FE_INEXACT_ENABLE.
	* sysdeps/powerpc/fpu/Makefile [$(subdir) == math](tests): Add
	test-ppc-fenv-bits.
	* sysdeps/powerpc/fpu/test-ppc-fenv-bits.c: New file.

Signed-off-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
---
 sysdeps/powerpc/bits/fenv.h              | 27 ++++++++++++-
 sysdeps/powerpc/fpu/Makefile             |  1 +
 sysdeps/powerpc/fpu/test-ppc-fenv-bits.c | 68 ++++++++++++++++++++++++++++++++
 3 files changed, 95 insertions(+), 1 deletion(-)
 create mode 100644 sysdeps/powerpc/fpu/test-ppc-fenv-bits.c

Comments

Joseph Myers June 27, 2018, 9:01 p.m. UTC | #1
On Wed, 27 Jun 2018, Tulio Magno Quites Machado Filho wrote:

> The POWER ISA defines bits 56:60 (bits 24:28 in a 32-bit FPSCR) as
> control for the 5 exceptions available: invalid operation, overflow,
> underflow, zero divide and inexact.
> 
> 2018-06-27  Tulio Magno Quites Machado Filho  <tuliom@linux.ibm.com>
> 
> 	* sysdeps/powerpc/bits/fenv.h [__USE_GNU]: Add
> 	FE_INVALID_ENABLE, FE_OVERFLOW_ENABLE, FE_UNDERFLOW_ENABLE,
> 	FE_DIVBYZERO_ENABLE and FE_INEXACT_ENABLE.

I don't think it's the job of fenv.h to enumerate all bits in the FPSCR 
(that's more appropriate in fpu_control.h).  Rather, it enumerates bits 
that are useful in arguments to the fenv.h interfaces.  The *_ENABLE 
values are not relevant to the fenv.h interfaces, since feenableexcept 
(etc.) deals with converting the FE_* flag bits into appropriate values 
for enabling exception traps.
Tulio Magno Quites Machado Filho June 27, 2018, 10:10 p.m. UTC | #2
Joseph Myers <joseph@codesourcery.com> writes:

> On Wed, 27 Jun 2018, Tulio Magno Quites Machado Filho wrote:
>
>> The POWER ISA defines bits 56:60 (bits 24:28 in a 32-bit FPSCR) as
>> control for the 5 exceptions available: invalid operation, overflow,
>> underflow, zero divide and inexact.
>> 
>> 2018-06-27  Tulio Magno Quites Machado Filho  <tuliom@linux.ibm.com>
>> 
>> 	* sysdeps/powerpc/bits/fenv.h [__USE_GNU]: Add
>> 	FE_INVALID_ENABLE, FE_OVERFLOW_ENABLE, FE_UNDERFLOW_ENABLE,
>> 	FE_DIVBYZERO_ENABLE and FE_INEXACT_ENABLE.
>
> I don't think it's the job of fenv.h to enumerate all bits in the FPSCR 
> (that's more appropriate in fpu_control.h).  Rather, it enumerates bits 
> that are useful in arguments to the fenv.h interfaces.  The *_ENABLE 
> values are not relevant to the fenv.h interfaces, since feenableexcept 
> (etc.) deals with converting the FE_* flag bits into appropriate values 
> for enabling exception traps.

Ack.

Thanks!
diff mbox series

Patch

diff --git a/sysdeps/powerpc/bits/fenv.h b/sysdeps/powerpc/bits/fenv.h
index 39a75ebeec..a9e78b90d2 100644
--- a/sysdeps/powerpc/bits/fenv.h
+++ b/sysdeps/powerpc/bits/fenv.h
@@ -100,12 +100,37 @@  enum
     /* Conversion-to-integer of a NaN or a number too large or too small.  */
     FE_INVALID_INTEGER_CONVERSION =
 # define FE_INVALID_INTEGER_CONVERSION	(1 << (31 - 23))
-      FE_INVALID_INTEGER_CONVERSION
+      FE_INVALID_INTEGER_CONVERSION,
 
 # define FE_ALL_INVALID \
         (FE_INVALID_SNAN | FE_INVALID_ISI | FE_INVALID_IDI | FE_INVALID_ZDZ \
 	 | FE_INVALID_IMZ | FE_INVALID_COMPARE | FE_INVALID_SOFTWARE \
 	 | FE_INVALID_SQRT | FE_INVALID_INTEGER_CONVERSION)
+
+    /* Enable invalid operation exception.  */
+    FE_INVALID_ENABLE =
+# define FE_INVALID_ENABLE	(1 << (31 - 24))
+      FE_INVALID_ENABLE,
+
+    /* Enable overflow exception.  */
+    FE_OVERFLOW_ENABLE =
+# define FE_OVERFLOW_ENABLE	(1 << (31 - 25))
+      FE_OVERFLOW_ENABLE,
+
+    /* Enable underflow exception.  */
+    FE_UNDERFLOW_ENABLE =
+# define FE_UNDERFLOW_ENABLE	(1 << (31 - 26))
+      FE_UNDERFLOW_ENABLE,
+
+    /* Enable zero divide exception.  */
+    FE_DIVBYZERO_ENABLE =
+# define FE_DIVBYZERO_ENABLE	(1 << (31 - 27))
+      FE_DIVBYZERO_ENABLE,
+
+    /* Enable inexact operation exception.  */
+    FE_INEXACT_ENABLE =
+# define FE_INEXACT_ENABLE	(1 << (31 - 28))
+      FE_INEXACT_ENABLE
 #endif
   };
 
diff --git a/sysdeps/powerpc/fpu/Makefile b/sysdeps/powerpc/fpu/Makefile
index 53470a9cf2..591a5537a7 100644
--- a/sysdeps/powerpc/fpu/Makefile
+++ b/sysdeps/powerpc/fpu/Makefile
@@ -1,5 +1,6 @@ 
 ifeq ($(subdir),math)
 libm-support += fenv_const fe_nomask fe_mask t_sqrt
+tests += test-ppc-fenv-bits
 endif
 
 ifeq ($(subdir),stdlib)
diff --git a/sysdeps/powerpc/fpu/test-ppc-fenv-bits.c b/sysdeps/powerpc/fpu/test-ppc-fenv-bits.c
new file mode 100644
index 0000000000..1af1fd21f4
--- /dev/null
+++ b/sysdeps/powerpc/fpu/test-ppc-fenv-bits.c
@@ -0,0 +1,68 @@ 
+/* Test if feenableexcept() does match with FPSCR registers.
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <support/check.h>
+
+typedef union
+{
+  double f;
+  uint64_t l;
+} fpscr_t;
+
+
+#define get_fpscr()					\
+  ({ fpscr_t fpscr; asm volatile ("mffs %0" : "=f" (fpscr.f)); fpscr.l; })
+
+void
+test_flag (uint64_t fpscr_flag, int fe_flag, const char * flag_name)
+{
+  uint64_t fpscr;
+  feenableexcept (fe_flag);
+  fpscr = get_fpscr ();
+  if (fpscr == fpscr_flag)
+    printf ("Pass: Flag \"%s\" is set\n", flag_name);
+  else
+    {
+      support_record_failure ();
+      printf ("Fail: Flag \"%s\" is not set\n", flag_name);
+    }
+  fedisableexcept (fe_flag);
+}
+
+int
+do_test (void)
+{
+  uint64_t fpscr;
+
+  fpscr = get_fpscr ();
+  if (fpscr != 0)
+    FAIL_EXIT (1, "Fail: The FPSCR is not 0\n");
+
+  test_flag (FE_INVALID_ENABLE, FE_INVALID, "INVALID_ENABLE");
+  test_flag (FE_OVERFLOW_ENABLE, FE_OVERFLOW, "OVERFLOW_ENABLE");
+  test_flag (FE_UNDERFLOW_ENABLE, FE_UNDERFLOW, "UNDERFLOW_ENABLE");
+  test_flag (FE_DIVBYZERO_ENABLE, FE_DIVBYZERO, "DIVBYZERO_ENABLE");
+  test_flag (FE_INEXACT_ENABLE, FE_INEXACT, "INEXACT_ENABLE");
+  return 0;
+}
+
+#include <support/test-driver.c>