summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Bolton <ian.bolton@arm.com>2014-04-16 23:41:04 +0100
committerWill Newton <will.newton@linaro.org>2014-06-06 11:33:03 +0100
commitb06b4ebf35c49d28bc2cd2e63597c25d897b9103 (patch)
treec23c50af0916843dbea64f80117c283a177f9e94
parent8e7f3adea429becf8fb44115e2e7beb5539a315e (diff)
Define HAVE_RM_CTX and related hooks.
-rw-r--r--libc/ports/ChangeLog.aarch64.linaro12
-rw-r--r--libc/ports/sysdeps/aarch64/fpu/math_private.h55
2 files changed, 67 insertions, 0 deletions
diff --git a/libc/ports/ChangeLog.aarch64.linaro b/libc/ports/ChangeLog.aarch64.linaro
index b8e7e14a6..f986a55cc 100644
--- a/libc/ports/ChangeLog.aarch64.linaro
+++ b/libc/ports/ChangeLog.aarch64.linaro
@@ -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 Ian Bolton <ian.bolton@arm.com>
Wilco Dijkstra <wilco.dijkstra@arm.com>
diff --git a/libc/ports/sysdeps/aarch64/fpu/math_private.h b/libc/ports/sysdeps/aarch64/fpu/math_private.h
index dbf203df6..7424952f8 100644
--- a/libc/ports/sysdeps/aarch64/fpu/math_private.h
+++ b/libc/ports/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