/* Private floating point rounding and exceptions handling. PowerPC version.
- Copyright (C) 2013-2017 Free Software Foundation, Inc.
+ Copyright (C) 2013-2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
- <http://www.gnu.org/licenses/>. */
+ <https://www.gnu.org/licenses/>. */
-#ifndef FENV_PRIVATE_H
-#define FENV_PRIVATE_H 1
+#ifndef POWERPC_FENV_PRIVATE_H
+#define POWERPC_FENV_PRIVATE_H 1
#include <fenv.h>
#include <fenv_libc.h>
| _FPU_MASK_XM | _FPU_MASK_IM)
/* Mask the rounding mode bits. */
-#define _FPU_MASK_RN (~0x3)
+#define _FPU_MASK_RN 0xfffffffffffffffcLL
-/* Mask everything but the rounding moded and non-IEEE arithmetic flags. */
-#define _FPU_MASK_NOT_RN_NI 0xffffffff00000007LL
+/* Mask everything but the rounding modes and non-IEEE arithmetic flags. */
+#define _FPU_MASK_NOT_RN_NI 0xffffffff00000807LL
/* Mask restore rounding mode and exception enabled. */
-#define _FPU_MASK_TRAPS_RN 0xffffffff1fffff00LL
+#define _FPU_MASK_TRAPS_RN 0xffffffffffffff00LL
-/* Mask exception enable but fraction rounded/inexact and FP result/CC
- bits. */
-#define _FPU_MASK_FRAC_INEX_RET_CC 0xffffffff1ff80fff
+/* Mask FP result flags, preserve fraction rounded/inexact bits. */
+#define _FPU_MASK_FRAC_INEX_RET_CC 0xfffffffffff80fffLL
static __always_inline void
__libc_feholdbits_ppc (fenv_t *envp, unsigned long long mask,
static __always_inline void
libc_feresetround_ppc (fenv_t *envp)
{
- __libc_femergeenv_ppc (envp, _FPU_MASK_TRAPS_RN, _FPU_MASK_FRAC_INEX_RET_CC);
+ fenv_union_t new = { .fenv = *envp };
+ fegetenv_and_set_rn (new.l & FPSCR_RN_MASK);
}
static __always_inline int
static __always_inline void
libc_feholdsetround_ppc_ctx (struct rm_ctx *ctx, int r)
+{
+ fenv_union_t old;
+
+ ctx->env = old.fenv = fegetenv_and_set_rn (r);
+ ctx->updated_status = (r != (old.l & FPSCR_RN_MASK));
+}
+
+static __always_inline void
+libc_feholdsetround_noex_ppc_ctx (struct rm_ctx *ctx, int r)
{
fenv_union_t old, new;
old.fenv = fegetenv_register ();
- new.l = (old.l & _FPU_MASK_TRAPS_RN) | r;
+ new.l = (old.l & ~(FPSCR_ENABLES_MASK|FPSCR_RN_MASK)) | r;
ctx->env = old.fenv;
if (__glibc_unlikely (new.l != old.l))
#define libc_feholdsetround_ctx libc_feholdsetround_ppc_ctx
#define libc_feholdsetroundf_ctx libc_feholdsetround_ppc_ctx
#define libc_feholdsetroundl_ctx libc_feholdsetround_ppc_ctx
+#define libc_feholdsetround_noex_ctx libc_feholdsetround_noex_ppc_ctx
+#define libc_feholdsetround_noexf_ctx libc_feholdsetround_noex_ppc_ctx
+#define libc_feholdsetround_noexl_ctx libc_feholdsetround_noex_ppc_ctx
#define libc_feresetround_ctx libc_feresetround_ppc_ctx
#define libc_feresetroundf_ctx libc_feresetround_ppc_ctx
#define libc_feresetroundl_ctx libc_feresetround_ppc_ctx
#define libc_feupdateenvf_ctx libc_feupdateenv_ppc_ctx
#define libc_feupdateenvl_ctx libc_feupdateenv_ppc_ctx
+#include_next <fenv_private.h>
+
#endif