diff options
author | Ian Bolton <ian.bolton@arm.com> | 2014-04-16 23:41:04 +0100 |
---|---|---|
committer | Marcus Shawcroft <marcus.shawcroft@arm.com> | 2014-04-17 08:30:07 +0100 |
commit | bc93ab2946efe008bb0ce2d4d3c212bd01384fca (patch) | |
tree | f0da440783d480a31a2cf7716248a912d79c58aa | |
parent | 7e0b6763e96ef9706ea9ecc7fad83fc97b837913 (diff) | |
download | glibc-bc93ab2946efe008bb0ce2d4d3c212bd01384fca.tar glibc-bc93ab2946efe008bb0ce2d4d3c212bd01384fca.tar.gz glibc-bc93ab2946efe008bb0ce2d4d3c212bd01384fca.tar.bz2 glibc-bc93ab2946efe008bb0ce2d4d3c212bd01384fca.zip |
[AArch64] Define HAVE_RM_CTX and related hooks.
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | sysdeps/aarch64/fpu/math_private.h | 55 |
2 files changed, 67 insertions, 0 deletions
@@ -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 dbf203df6a..7424952f8b 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 |