[COMMITTED,AArch64] Define HAVE_RM_CTX and related hooks.

Message ID 1397722819-27264-1-git-send-email-marcus.shawcroft@arm.com
State Committed
Headers

Commit Message

Marcus Shawcroft April 17, 2014, 8:20 a.m. UTC
  Hi, The attached patch by Wilco and Ian B @ARM provides a definition
of HAVE_RM_CTX and related hooks for AArch64.

Cheers
/Marcus


---
 ChangeLog                          |   12 ++++++++
 sysdeps/aarch64/fpu/math_private.h |   55 ++++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+)
  

Patch

diff --git a/ChangeLog b/ChangeLog
index 2bbd47a..ac40659 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@ 
+2014-04-17  Ian Bolton  <ian.bolton@arm.com>
+	    Wilco Dijkstra  <wilco.dijkstra@arm.com>
+
+	* sysdeps/aarch64/fpu/math_private.h (HAVE_RM_CTX)
+	(libc_feholdsetround_aarch64_ctx)
+	(libc_feholdsetround_ctx, libc_feholdsetroundf_ctx)
+	(libc_feholdsetroundl_ctx, libc_feresetround_aarch64_ctx)
+	(libc_feresetround_ctx, libc_feresetroundf_ctx)
+	(libc_feresetroundl_ctx, libc_feresetround_noex_aarch64_ctx)
+	(libc_feresetround_noex_ctx, libc_feresetround_noexf_ctx)
+	(libc_feresetround_noexl_ctx): Define.
+
 2014-04-16  Richard Henderson  <rth@redhat.com>
 
 	* sysdeps/unix/sysv/linux/alpha/nptl/pthread_once.c: Remove.
diff --git a/sysdeps/aarch64/fpu/math_private.h b/sysdeps/aarch64/fpu/math_private.h
index dbf203d..7424952 100644
--- a/sysdeps/aarch64/fpu/math_private.h
+++ b/sysdeps/aarch64/fpu/math_private.h
@@ -209,6 +209,61 @@  libc_feresetround_aarch64 (fenv_t *envp)
 #define libc_feresetroundf libc_feresetround_aarch64
 #define libc_feresetroundl libc_feresetround_aarch64
 
+/* We have support for rounding mode context.  */
+#define HAVE_RM_CTX 1
+
+static __always_inline void
+libc_feholdsetround_aarch64_ctx (struct rm_ctx *ctx, int r)
+{
+  fpu_control_t fpcr, fpsr, round;
+
+  _FPU_GETCW (fpcr);
+  _FPU_GETFPSR (fpsr);
+  ctx->env.__fpsr = fpsr;
+
+  /* Check whether rounding modes are different.  */
+  round = (fpcr ^ r) & FE_TOWARDZERO;
+  ctx->updated_status = round != 0;
+
+  /* Set the rounding mode if changed.  */
+  if (__glibc_unlikely (round != 0))
+    {
+      ctx->env.__fpcr = fpcr;
+      _FPU_SETCW (fpcr ^ round);
+    }
+}
+
+#define libc_feholdsetround_ctx		libc_feholdsetround_aarch64_ctx
+#define libc_feholdsetroundf_ctx	libc_feholdsetround_aarch64_ctx
+#define libc_feholdsetroundl_ctx	libc_feholdsetround_aarch64_ctx
+
+static __always_inline void
+libc_feresetround_aarch64_ctx (struct rm_ctx *ctx)
+{
+  /* Restore the rounding mode if updated.  */
+  if (__glibc_unlikely (ctx->updated_status))
+    _FPU_SETCW (ctx->env.__fpcr);
+}
+
+#define libc_feresetround_ctx		libc_feresetround_aarch64_ctx
+#define libc_feresetroundf_ctx		libc_feresetround_aarch64_ctx
+#define libc_feresetroundl_ctx		libc_feresetround_aarch64_ctx
+
+static __always_inline void
+libc_feresetround_noex_aarch64_ctx (struct rm_ctx *ctx)
+{
+  /* Restore the rounding mode if updated.  */
+  if (__glibc_unlikely (ctx->updated_status))
+    _FPU_SETCW (ctx->env.__fpcr);
+
+  /* Write new FPSR to restore exception flags.  */
+  _FPU_SETFPSR (ctx->env.__fpsr);
+}
+
+#define libc_feresetround_noex_ctx	libc_feresetround_noex_aarch64_ctx
+#define libc_feresetround_noexf_ctx	libc_feresetround_noex_aarch64_ctx
+#define libc_feresetround_noexl_ctx	libc_feresetround_noex_aarch64_ctx
+
 #include_next <math_private.h>
 
 #endif