bca718
commit 656b84c2ef525e3b69802c9057c5897e327b0332
bca718
Author: Wilco Dijkstra <wdijkstr@arm.com>
bca718
Date:   Thu Aug 7 16:29:55 2014 +0000
bca718
bca718
    This patch adds new function libc_feholdsetround_noex_aarch64_ctx, enabling
bca718
    further optimization. libc_feholdsetround_aarch64_ctx now only needs to
bca718
    read the FPCR in the typical case, avoiding a redundant FPSR read.
bca718
    Performance results show a good improvement (5-10% on sin()) on cores with
bca718
    expensive FPCR/FPSR instructions.
bca718
bca718
diff --git a/ports/sysdeps/aarch64/fpu/math_private.h b/ports/sysdeps/aarch64/fpu/math_private.h
bca718
index 023c9d0..b13c030 100644
bca718
--- a/ports/sysdeps/aarch64/fpu/math_private.h
bca718
+++ b/ports/sysdeps/aarch64/fpu/math_private.h
bca718
@@ -228,12 +228,9 @@ static __always_inline void
bca718
 libc_feholdsetround_aarch64_ctx (struct rm_ctx *ctx, int r)
bca718
 {
bca718
   fpu_control_t fpcr;
bca718
-  fpu_fpsr_t fpsr;
bca718
   int round;
bca718
 
bca718
   _FPU_GETCW (fpcr);
bca718
-  _FPU_GETFPSR (fpsr);
bca718
-  ctx->env.__fpsr = fpsr;
bca718
 
bca718
   /* Check whether rounding modes are different.  */
bca718
   round = (fpcr ^ r) & _FPU_FPCR_RM_MASK;
bca718
@@ -264,6 +261,33 @@ libc_feresetround_aarch64_ctx (struct rm_ctx *ctx)
bca718
 #define libc_feresetroundl_ctx		libc_feresetround_aarch64_ctx
bca718
 
bca718
 static __always_inline void
bca718
+libc_feholdsetround_noex_aarch64_ctx (struct rm_ctx *ctx, int r)
bca718
+{
bca718
+  fpu_control_t fpcr;
bca718
+  fpu_fpsr_t fpsr;
bca718
+  int round;
bca718
+
bca718
+  _FPU_GETCW (fpcr);
bca718
+  _FPU_GETFPSR (fpsr);
bca718
+  ctx->env.__fpsr = fpsr;
bca718
+
bca718
+  /* Check whether rounding modes are different.  */
bca718
+  round = (fpcr ^ r) & _FPU_FPCR_RM_MASK;
bca718
+  ctx->updated_status = round != 0;
bca718
+
bca718
+  /* Set the rounding mode if changed.  */
bca718
+  if (__glibc_unlikely (round != 0))
bca718
+    {
bca718
+      ctx->env.__fpcr = fpcr;
bca718
+      _FPU_SETCW (fpcr ^ round);
bca718
+    }
bca718
+}
bca718
+
bca718
+#define libc_feholdsetround_noex_ctx	libc_feholdsetround_noex_aarch64_ctx
bca718
+#define libc_feholdsetround_noexf_ctx	libc_feholdsetround_noex_aarch64_ctx
bca718
+#define libc_feholdsetround_noexl_ctx	libc_feholdsetround_noex_aarch64_ctx
bca718
+
bca718
+static __always_inline void
bca718
 libc_feresetround_noex_aarch64_ctx (struct rm_ctx *ctx)
bca718
 {
bca718
   /* Restore the rounding mode if updated.  */