about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--sysdeps/aarch64/fpu/feenablxcpt.c13
-rw-r--r--sysdeps/aarch64/fpu/fesetenv.c10
3 files changed, 29 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 51020ec5c7..88b70f1a7c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2014-03-07  Marcus Shawcroft  <marcus.shawcroft@arm.com>
+
+	* sysdeps/aarch64/fpu/feenablxcpt.c (feenableexcept): Detect and
+	error absence of trapping exception support.
+	* sysdeps/aarch64/fpu/fesetenv.c (fesetenv): Likewise.
+
 2014-03-07  Joseph Myers  <joseph@codesourcery.com>
 
 	* catgets/Makefile (tests-special): Add $(objpfx)sample.SJIS.cat.
diff --git a/sysdeps/aarch64/fpu/feenablxcpt.c b/sysdeps/aarch64/fpu/feenablxcpt.c
index d97699981f..07a4bbb58e 100644
--- a/sysdeps/aarch64/fpu/feenablxcpt.c
+++ b/sysdeps/aarch64/fpu/feenablxcpt.c
@@ -35,5 +35,18 @@ feenableexcept (int excepts)
 
   _FPU_SETCW (fpcr);
 
+  /* Trapping exceptions are optional in AArch64 the relevant enable
+     bits in FPCR are RES0 hence the absence of support can be
+     detected by reading back the FPCR and comparing with the required
+     value.  */
+  if (excepts)
+    {
+      fpu_control_t updated_fpcr;
+
+      _FPU_GETCW (updated_fpcr);
+      if (((updated_fpcr >> FE_EXCEPT_SHIFT) & excepts) != excepts)
+	return -1;
+    }
+
   return original_excepts;
 }
diff --git a/sysdeps/aarch64/fpu/fesetenv.c b/sysdeps/aarch64/fpu/fesetenv.c
index 443c705d22..a2434e37b0 100644
--- a/sysdeps/aarch64/fpu/fesetenv.c
+++ b/sysdeps/aarch64/fpu/fesetenv.c
@@ -24,6 +24,7 @@ fesetenv (const fenv_t *envp)
 {
   fpu_control_t fpcr;
   fpu_fpsr_t fpsr;
+  fpu_control_t updated_fpcr;
 
   _FPU_GETCW (fpcr);
   _FPU_GETFPSR (fpsr);
@@ -51,6 +52,15 @@ fesetenv (const fenv_t *envp)
 
   _FPU_SETCW (fpcr);
 
+  /* Trapping exceptions are optional in AArch64 the relevant enable
+     bits in FPCR are RES0 hence the absence of support can be
+     detected by reading back the FPCR and comparing with the required
+     value.  */
+
+  _FPU_GETCW (updated_fpcr);
+  if ((updated_fpcr & fpcr) != fpcr)
+    return 1;
+
   return 0;
 }