/* Internal libc stuff for floating point environment routines.
- Copyright (C) 1997-2013 Free Software Foundation, Inc.
+ Copyright (C) 1997-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
#include <ldsodefs.h>
#include <sysdep.h>
-extern const fenv_t *__fe_nomask_env (void) attribute_hidden;
+extern const fenv_t *__fe_nomask_env_priv (void);
extern const fenv_t *__fe_mask_env (void) attribute_hidden;
/* Equivalent to fegetenv, but returns a fenv_t instead of taking a
pointer. */
-#define fegetenv_register() \
- ({ fenv_t env; asm volatile ("mffs %0" : "=f" (env)); env; })
+#define fegetenv_register() __builtin_mffs()
/* Equivalent to fesetenv, but takes a fenv_t instead of a pointer. */
#define fesetenv_register(env) \
"mtfsf 0xff,%0,1,0; " \
".machine pop" : : "f" (d)); \
else \
- asm volatile ("mtfsf 0xff,%0" : : "f" (d)); \
+ __builtin_mtfsf (0xff, d); \
} while(0)
/* This very handy macro:
#define relax_fenv_state() \
do { \
if (GLRO(dl_hwcap) & PPC_FEATURE_HAS_DFP) \
- asm (".machine push; .machine \"power6\"; " \
+ asm volatile (".machine push; .machine \"power6\"; " \
"mtfsfi 7,0,1; .machine pop"); \
- asm ("mtfsfi 7,0"); \
+ asm volatile ("mtfsfi 7,0"); \
} while(0)
/* Set/clear a particular FPSCR bit (for instance,
static inline int
-__fegetround (void)
-{
- int result;
- asm volatile ("mcrfs 7,7\n\t"
- "mfcr %0" : "=r"(result) : : "cr7");
- return result & 3;
-}
-
-static inline int
-__fesetround (int round)
+__fesetround_inline (int round)
{
if ((unsigned int) round < 2)
{
return 0;
}
+/* Same as __fesetround_inline, however without runtime check to use DFP
+ mtfsfi syntax (as relax_fenv_state) or if round value is valid. */
+static inline void
+__fesetround_inline_nocheck (const int round)
+{
+ asm volatile ("mtfsfi 7,%0" : : "i" (round));
+}
+
/* Definitions of all the FPSCR bit numbers */
enum {
FPSCR_FX = 0, /* exception summary */
/* the remaining two least-significant bits keep the rounding mode */
};
+static inline int
+fenv_reg_to_exceptions (unsigned long long l)
+{
+ int result = 0;
+ if (l & (1 << (31 - FPSCR_XE)))
+ result |= FE_INEXACT;
+ if (l & (1 << (31 - FPSCR_ZE)))
+ result |= FE_DIVBYZERO;
+ if (l & (1 << (31 - FPSCR_UE)))
+ result |= FE_UNDERFLOW;
+ if (l & (1 << (31 - FPSCR_OE)))
+ result |= FE_OVERFLOW;
+ if (l & (1 << (31 - FPSCR_VE)))
+ result |= FE_INVALID;
+ return result;
+}
+
#ifdef _ARCH_PWR6
/* Not supported in ISA 2.05. Provided for source compat only. */
# define FPSCR_NI 29