Blame sysdeps/generic/math_private.h

Packit Service 82fcde
/*
Packit Service 82fcde
 * ====================================================
Packit Service 82fcde
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Packit Service 82fcde
 *
Packit Service 82fcde
 * Developed at SunPro, a Sun Microsystems, Inc. business.
Packit Service 82fcde
 * Permission to use, copy, modify, and distribute this
Packit Service 82fcde
 * software is freely granted, provided that this notice
Packit Service 82fcde
 * is preserved.
Packit Service 82fcde
 * ====================================================
Packit Service 82fcde
 */
Packit Service 82fcde
Packit Service 82fcde
/*
Packit Service 82fcde
 * from: @(#)fdlibm.h 5.1 93/09/24
Packit Service 82fcde
 */
Packit Service 82fcde
Packit Service 82fcde
#ifndef _MATH_PRIVATE_H_
Packit Service 82fcde
#define _MATH_PRIVATE_H_
Packit Service 82fcde
Packit Service 82fcde
#include <endian.h>
Packit Service 82fcde
#include <stdint.h>
Packit Service 82fcde
#include <sys/types.h>
Packit Service 82fcde
#include <fenv.h>
Packit Service 82fcde
#include <get-rounding-mode.h>
Packit Service 82fcde
Packit Service 82fcde
/* Gather machine dependent _Floatn support.  */
Packit Service 82fcde
#include <bits/floatn.h>
Packit Service 82fcde
Packit Service 82fcde
/* The original fdlibm code used statements like:
Packit Service 82fcde
	n0 = ((*(int*)&one)>>29)^1;		* index of high word *
Packit Service 82fcde
	ix0 = *(n0+(int*)&x);			* high word of x *
Packit Service 82fcde
	ix1 = *((1-n0)+(int*)&x);		* low word of x *
Packit Service 82fcde
   to dig two 32 bit words out of the 64 bit IEEE floating point
Packit Service 82fcde
   value.  That is non-ANSI, and, moreover, the gcc instruction
Packit Service 82fcde
   scheduler gets it wrong.  We instead use the following macros.
Packit Service 82fcde
   Unlike the original code, we determine the endianness at compile
Packit Service 82fcde
   time, not at run time; I don't see much benefit to selecting
Packit Service 82fcde
   endianness at run time.  */
Packit Service 82fcde
Packit Service 82fcde
/* A union which permits us to convert between a double and two 32 bit
Packit Service 82fcde
   ints.  */
Packit Service 82fcde
Packit Service 82fcde
#if __FLOAT_WORD_ORDER == __BIG_ENDIAN
Packit Service 82fcde
Packit Service 82fcde
typedef union
Packit Service 82fcde
{
Packit Service 82fcde
  double value;
Packit Service 82fcde
  struct
Packit Service 82fcde
  {
Packit Service 82fcde
    uint32_t msw;
Packit Service 82fcde
    uint32_t lsw;
Packit Service 82fcde
  } parts;
Packit Service 82fcde
  uint64_t word;
Packit Service 82fcde
} ieee_double_shape_type;
Packit Service 82fcde
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#if __FLOAT_WORD_ORDER == __LITTLE_ENDIAN
Packit Service 82fcde
Packit Service 82fcde
typedef union
Packit Service 82fcde
{
Packit Service 82fcde
  double value;
Packit Service 82fcde
  struct
Packit Service 82fcde
  {
Packit Service 82fcde
    uint32_t lsw;
Packit Service 82fcde
    uint32_t msw;
Packit Service 82fcde
  } parts;
Packit Service 82fcde
  uint64_t word;
Packit Service 82fcde
} ieee_double_shape_type;
Packit Service 82fcde
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* Get two 32 bit ints from a double.  */
Packit Service 82fcde
Packit Service 82fcde
#define EXTRACT_WORDS(ix0,ix1,d)				\
Packit Service 82fcde
do {								\
Packit Service 82fcde
  ieee_double_shape_type ew_u;					\
Packit Service 82fcde
  ew_u.value = (d);						\
Packit Service 82fcde
  (ix0) = ew_u.parts.msw;					\
Packit Service 82fcde
  (ix1) = ew_u.parts.lsw;					\
Packit Service 82fcde
} while (0)
Packit Service 82fcde
Packit Service 82fcde
/* Get the more significant 32 bit int from a double.  */
Packit Service 82fcde
Packit Service 82fcde
#ifndef GET_HIGH_WORD
Packit Service 82fcde
# define GET_HIGH_WORD(i,d)					\
Packit Service 82fcde
do {								\
Packit Service 82fcde
  ieee_double_shape_type gh_u;					\
Packit Service 82fcde
  gh_u.value = (d);						\
Packit Service 82fcde
  (i) = gh_u.parts.msw;						\
Packit Service 82fcde
} while (0)
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* Get the less significant 32 bit int from a double.  */
Packit Service 82fcde
Packit Service 82fcde
#ifndef GET_LOW_WORD
Packit Service 82fcde
# define GET_LOW_WORD(i,d)					\
Packit Service 82fcde
do {								\
Packit Service 82fcde
  ieee_double_shape_type gl_u;					\
Packit Service 82fcde
  gl_u.value = (d);						\
Packit Service 82fcde
  (i) = gl_u.parts.lsw;						\
Packit Service 82fcde
} while (0)
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* Get all in one, efficient on 64-bit machines.  */
Packit Service 82fcde
#ifndef EXTRACT_WORDS64
Packit Service 82fcde
# define EXTRACT_WORDS64(i,d)					\
Packit Service 82fcde
do {								\
Packit Service 82fcde
  ieee_double_shape_type gh_u;					\
Packit Service 82fcde
  gh_u.value = (d);						\
Packit Service 82fcde
  (i) = gh_u.word;						\
Packit Service 82fcde
} while (0)
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* Set a double from two 32 bit ints.  */
Packit Service 82fcde
#ifndef INSERT_WORDS
Packit Service 82fcde
# define INSERT_WORDS(d,ix0,ix1)				\
Packit Service 82fcde
do {								\
Packit Service 82fcde
  ieee_double_shape_type iw_u;					\
Packit Service 82fcde
  iw_u.parts.msw = (ix0);					\
Packit Service 82fcde
  iw_u.parts.lsw = (ix1);					\
Packit Service 82fcde
  (d) = iw_u.value;						\
Packit Service 82fcde
} while (0)
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* Get all in one, efficient on 64-bit machines.  */
Packit Service 82fcde
#ifndef INSERT_WORDS64
Packit Service 82fcde
# define INSERT_WORDS64(d,i)					\
Packit Service 82fcde
do {								\
Packit Service 82fcde
  ieee_double_shape_type iw_u;					\
Packit Service 82fcde
  iw_u.word = (i);						\
Packit Service 82fcde
  (d) = iw_u.value;						\
Packit Service 82fcde
} while (0)
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* Set the more significant 32 bits of a double from an int.  */
Packit Service 82fcde
#ifndef SET_HIGH_WORD
Packit Service 82fcde
#define SET_HIGH_WORD(d,v)					\
Packit Service 82fcde
do {								\
Packit Service 82fcde
  ieee_double_shape_type sh_u;					\
Packit Service 82fcde
  sh_u.value = (d);						\
Packit Service 82fcde
  sh_u.parts.msw = (v);						\
Packit Service 82fcde
  (d) = sh_u.value;						\
Packit Service 82fcde
} while (0)
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* Set the less significant 32 bits of a double from an int.  */
Packit Service 82fcde
#ifndef SET_LOW_WORD
Packit Service 82fcde
# define SET_LOW_WORD(d,v)					\
Packit Service 82fcde
do {								\
Packit Service 82fcde
  ieee_double_shape_type sl_u;					\
Packit Service 82fcde
  sl_u.value = (d);						\
Packit Service 82fcde
  sl_u.parts.lsw = (v);						\
Packit Service 82fcde
  (d) = sl_u.value;						\
Packit Service 82fcde
} while (0)
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* A union which permits us to convert between a float and a 32 bit
Packit Service 82fcde
   int.  */
Packit Service 82fcde
Packit Service 82fcde
typedef union
Packit Service 82fcde
{
Packit Service 82fcde
  float value;
Packit Service 82fcde
  uint32_t word;
Packit Service 82fcde
} ieee_float_shape_type;
Packit Service 82fcde
Packit Service 82fcde
/* Get a 32 bit int from a float.  */
Packit Service 82fcde
#ifndef GET_FLOAT_WORD
Packit Service 82fcde
# define GET_FLOAT_WORD(i,d)					\
Packit Service 82fcde
do {								\
Packit Service 82fcde
  ieee_float_shape_type gf_u;					\
Packit Service 82fcde
  gf_u.value = (d);						\
Packit Service 82fcde
  (i) = gf_u.word;						\
Packit Service 82fcde
} while (0)
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* Set a float from a 32 bit int.  */
Packit Service 82fcde
#ifndef SET_FLOAT_WORD
Packit Service 82fcde
# define SET_FLOAT_WORD(d,i)					\
Packit Service 82fcde
do {								\
Packit Service 82fcde
  ieee_float_shape_type sf_u;					\
Packit Service 82fcde
  sf_u.word = (i);						\
Packit Service 82fcde
  (d) = sf_u.value;						\
Packit Service 82fcde
} while (0)
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* We need to guarantee an expansion of name when building
Packit Service 82fcde
   ldbl-128 files as another type (e.g _Float128).  */
Packit Service 82fcde
#define mathx_hidden_def(name) hidden_def(name)
Packit Service 82fcde
Packit Service 82fcde
/* Get long double macros from a separate header.  */
Packit Service 82fcde
#include <math_ldbl.h>
Packit Service 82fcde
Packit Service 82fcde
/* Include function declarations for each floating-point.  */
Packit Service 82fcde
#define _Mdouble_ double
Packit Service 82fcde
#define _MSUF_
Packit Service 82fcde
#include <math_private_calls.h>
Packit Service 82fcde
#undef _MSUF_
Packit Service 82fcde
#undef _Mdouble_
Packit Service 82fcde
Packit Service 82fcde
#define _Mdouble_ float
Packit Service 82fcde
#define _MSUF_ f
Packit Service 82fcde
#define __MATH_DECLARING_FLOAT
Packit Service 82fcde
#include <math_private_calls.h>
Packit Service 82fcde
#undef __MATH_DECLARING_FLOAT
Packit Service 82fcde
#undef _MSUF_
Packit Service 82fcde
#undef _Mdouble_
Packit Service 82fcde
Packit Service 82fcde
#define _Mdouble_ long double
Packit Service 82fcde
#define _MSUF_ l
Packit Service 82fcde
#define __MATH_DECLARING_LONG_DOUBLE
Packit Service 82fcde
#include <math_private_calls.h>
Packit Service 82fcde
#undef __MATH_DECLARING_LONG_DOUBLE
Packit Service 82fcde
#undef _MSUF_
Packit Service 82fcde
#undef _Mdouble_
Packit Service 82fcde
Packit Service 82fcde
#if __HAVE_DISTINCT_FLOAT128
Packit Service 82fcde
# define _Mdouble_ _Float128
Packit Service 82fcde
# define _MSUF_ f128
Packit Service 82fcde
# define __MATH_DECLARING_FLOATN
Packit Service 82fcde
# include <math_private_calls.h>
Packit Service 82fcde
# undef __MATH_DECLARING_FLOATN
Packit Service 82fcde
# undef _MSUF_
Packit Service 82fcde
# undef _Mdouble_
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#if __HAVE_DISTINCT_FLOAT128
Packit Service 82fcde
Packit Service 82fcde
/* __builtin_isinf_sign is broken in GCC < 7 for float128.  */
Packit Service 82fcde
# if ! __GNUC_PREREQ (7, 0)
Packit Service 82fcde
#  include <ieee754_float128.h>
Packit Service 82fcde
extern inline int
Packit Service 82fcde
__isinff128 (_Float128 x)
Packit Service 82fcde
{
Packit Service 82fcde
  int64_t hx, lx;
Packit Service 82fcde
  GET_FLOAT128_WORDS64 (hx, lx, x);
Packit Service 82fcde
  lx |= (hx & 0x7fffffffffffffffLL) ^ 0x7fff000000000000LL;
Packit Service 82fcde
  lx |= -lx;
Packit Service 82fcde
  return ~(lx >> 63) & (hx >> 62);
Packit Service 82fcde
}
Packit Service 82fcde
# endif
Packit Service 82fcde
Packit Service 82fcde
extern inline _Float128
Packit Service 82fcde
fabsf128 (_Float128 x)
Packit Service 82fcde
{
Packit Service 82fcde
  return __builtin_fabsf128 (x);
Packit Service 82fcde
}
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Prototypes for functions of the IBM Accurate Mathematical Library.  */
Packit Service 82fcde
extern double __exp1 (double __x, double __xx);
Packit Service 82fcde
extern double __sin (double __x);
Packit Service 82fcde
extern double __cos (double __x);
Packit Service 82fcde
extern int __branred (double __x, double *__a, double *__aa);
Packit Service 82fcde
extern void __doasin (double __x, double __dx, double __v[]);
Packit Service 82fcde
extern void __dubsin (double __x, double __dx, double __v[]);
Packit Service 82fcde
extern void __dubcos (double __x, double __dx, double __v[]);
Packit Service 82fcde
extern double __sin32 (double __x, double __res, double __res1);
Packit Service 82fcde
extern double __cos32 (double __x, double __res, double __res1);
Packit Service 82fcde
extern double __mpsin (double __x, double __dx, bool __range_reduce);
Packit Service 82fcde
extern double __mpcos (double __x, double __dx, bool __range_reduce);
Packit Service 82fcde
extern void __docos (double __x, double __dx, double __v[]);
Packit Service 82fcde
Packit Service 82fcde
/* The standards only specify one variant of the fenv.h interfaces.
Packit Service 82fcde
   But at least for some architectures we can be more efficient if we
Packit Service 82fcde
   know what operations are going to be performed.  Therefore we
Packit Service 82fcde
   define additional interfaces.  By default they refer to the normal
Packit Service 82fcde
   interfaces.  */
Packit Service 82fcde
Packit Service 82fcde
static __always_inline void
Packit Service 82fcde
default_libc_feholdexcept (fenv_t *e)
Packit Service 82fcde
{
Packit Service 82fcde
  (void) __feholdexcept (e);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
#ifndef libc_feholdexcept
Packit Service 82fcde
# define libc_feholdexcept  default_libc_feholdexcept
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef libc_feholdexceptf
Packit Service 82fcde
# define libc_feholdexceptf default_libc_feholdexcept
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef libc_feholdexceptl
Packit Service 82fcde
# define libc_feholdexceptl default_libc_feholdexcept
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
static __always_inline void
Packit Service 82fcde
default_libc_fesetround (int r)
Packit Service 82fcde
{
Packit Service 82fcde
  (void) __fesetround (r);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
#ifndef libc_fesetround
Packit Service 82fcde
# define libc_fesetround  default_libc_fesetround
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef libc_fesetroundf
Packit Service 82fcde
# define libc_fesetroundf default_libc_fesetround
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef libc_fesetroundl
Packit Service 82fcde
# define libc_fesetroundl default_libc_fesetround
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
static __always_inline void
Packit Service 82fcde
default_libc_feholdexcept_setround (fenv_t *e, int r)
Packit Service 82fcde
{
Packit Service 82fcde
  __feholdexcept (e);
Packit Service 82fcde
  __fesetround (r);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
#ifndef libc_feholdexcept_setround
Packit Service 82fcde
# define libc_feholdexcept_setround  default_libc_feholdexcept_setround
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef libc_feholdexcept_setroundf
Packit Service 82fcde
# define libc_feholdexcept_setroundf default_libc_feholdexcept_setround
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef libc_feholdexcept_setroundl
Packit Service 82fcde
# define libc_feholdexcept_setroundl default_libc_feholdexcept_setround
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#ifndef libc_feholdsetround_53bit
Packit Service 82fcde
# define libc_feholdsetround_53bit libc_feholdsetround
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#ifndef libc_fetestexcept
Packit Service 82fcde
# define libc_fetestexcept  fetestexcept
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef libc_fetestexceptf
Packit Service 82fcde
# define libc_fetestexceptf fetestexcept
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef libc_fetestexceptl
Packit Service 82fcde
# define libc_fetestexceptl fetestexcept
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
static __always_inline void
Packit Service 82fcde
default_libc_fesetenv (fenv_t *e)
Packit Service 82fcde
{
Packit Service 82fcde
  (void) __fesetenv (e);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
#ifndef libc_fesetenv
Packit Service 82fcde
# define libc_fesetenv  default_libc_fesetenv
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef libc_fesetenvf
Packit Service 82fcde
# define libc_fesetenvf default_libc_fesetenv
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef libc_fesetenvl
Packit Service 82fcde
# define libc_fesetenvl default_libc_fesetenv
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
static __always_inline void
Packit Service 82fcde
default_libc_feupdateenv (fenv_t *e)
Packit Service 82fcde
{
Packit Service 82fcde
  (void) __feupdateenv (e);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
#ifndef libc_feupdateenv
Packit Service 82fcde
# define libc_feupdateenv  default_libc_feupdateenv
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef libc_feupdateenvf
Packit Service 82fcde
# define libc_feupdateenvf default_libc_feupdateenv
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef libc_feupdateenvl
Packit Service 82fcde
# define libc_feupdateenvl default_libc_feupdateenv
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#ifndef libc_feresetround_53bit
Packit Service 82fcde
# define libc_feresetround_53bit libc_feresetround
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
static __always_inline int
Packit Service 82fcde
default_libc_feupdateenv_test (fenv_t *e, int ex)
Packit Service 82fcde
{
Packit Service 82fcde
  int ret = fetestexcept (ex);
Packit Service 82fcde
  __feupdateenv (e);
Packit Service 82fcde
  return ret;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
#ifndef libc_feupdateenv_test
Packit Service 82fcde
# define libc_feupdateenv_test  default_libc_feupdateenv_test
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef libc_feupdateenv_testf
Packit Service 82fcde
# define libc_feupdateenv_testf default_libc_feupdateenv_test
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef libc_feupdateenv_testl
Packit Service 82fcde
# define libc_feupdateenv_testl default_libc_feupdateenv_test
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* Save and set the rounding mode.  The use of fenv_t to store the old mode
Packit Service 82fcde
   allows a target-specific version of this function to avoid converting the
Packit Service 82fcde
   rounding mode from the fpu format.  By default we have no choice but to
Packit Service 82fcde
   manipulate the entire env.  */
Packit Service 82fcde
Packit Service 82fcde
#ifndef libc_feholdsetround
Packit Service 82fcde
# define libc_feholdsetround  libc_feholdexcept_setround
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef libc_feholdsetroundf
Packit Service 82fcde
# define libc_feholdsetroundf libc_feholdexcept_setroundf
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef libc_feholdsetroundl
Packit Service 82fcde
# define libc_feholdsetroundl libc_feholdexcept_setroundl
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* ... and the reverse.  */
Packit Service 82fcde
Packit Service 82fcde
#ifndef libc_feresetround
Packit Service 82fcde
# define libc_feresetround  libc_feupdateenv
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef libc_feresetroundf
Packit Service 82fcde
# define libc_feresetroundf libc_feupdateenvf
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef libc_feresetroundl
Packit Service 82fcde
# define libc_feresetroundl libc_feupdateenvl
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* ... and a version that also discards exceptions.  */
Packit Service 82fcde
Packit Service 82fcde
#ifndef libc_feresetround_noex
Packit Service 82fcde
# define libc_feresetround_noex  libc_fesetenv
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef libc_feresetround_noexf
Packit Service 82fcde
# define libc_feresetround_noexf libc_fesetenvf
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef libc_feresetround_noexl
Packit Service 82fcde
# define libc_feresetround_noexl libc_fesetenvl
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#ifndef HAVE_RM_CTX
Packit Service 82fcde
# define HAVE_RM_CTX 0
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Default implementation using standard fenv functions.
Packit Service 82fcde
   Avoid unnecessary rounding mode changes by first checking the
Packit Service 82fcde
   current rounding mode.  Note the use of __glibc_unlikely is
Packit Service 82fcde
   important for performance.  */
Packit Service 82fcde
Packit Service 82fcde
static __always_inline void
Packit Service 82fcde
default_libc_feholdsetround_ctx (struct rm_ctx *ctx, int round)
Packit Service 82fcde
{
Packit Service 82fcde
  ctx->updated_status = false;
Packit Service 82fcde
Packit Service 82fcde
  /* Update rounding mode only if different.  */
Packit Service 82fcde
  if (__glibc_unlikely (round != get_rounding_mode ()))
Packit Service 82fcde
    {
Packit Service 82fcde
      ctx->updated_status = true;
Packit Service 82fcde
      __fegetenv (&ctx->env);
Packit Service 82fcde
      __fesetround (round);
Packit Service 82fcde
    }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static __always_inline void
Packit Service 82fcde
default_libc_feresetround_ctx (struct rm_ctx *ctx)
Packit Service 82fcde
{
Packit Service 82fcde
  /* Restore the rounding mode if updated.  */
Packit Service 82fcde
  if (__glibc_unlikely (ctx->updated_status))
Packit Service 82fcde
    __feupdateenv (&ctx->env);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static __always_inline void
Packit Service 82fcde
default_libc_feholdsetround_noex_ctx (struct rm_ctx *ctx, int round)
Packit Service 82fcde
{
Packit Service 82fcde
  /* Save exception flags and rounding mode, and disable exception
Packit Service 82fcde
     traps.  */
Packit Service 82fcde
  __feholdexcept (&ctx->env);
Packit Service 82fcde
Packit Service 82fcde
  /* Update rounding mode only if different.  */
Packit Service 82fcde
  if (__glibc_unlikely (round != get_rounding_mode ()))
Packit Service 82fcde
    __fesetround (round);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static __always_inline void
Packit Service 82fcde
default_libc_feresetround_noex_ctx (struct rm_ctx *ctx)
Packit Service 82fcde
{
Packit Service 82fcde
  /* Restore exception flags and rounding mode.  */
Packit Service 82fcde
  __fesetenv (&ctx->env);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
#if HAVE_RM_CTX
Packit Service 82fcde
/* Set/Restore Rounding Modes only when necessary.  If defined, these functions
Packit Service 82fcde
   set/restore floating point state only if the state needed within the lexical
Packit Service 82fcde
   block is different from the current state.  This saves a lot of time when
Packit Service 82fcde
   the floating point unit is much slower than the fixed point units.  */
Packit Service 82fcde
Packit Service 82fcde
# ifndef libc_feholdsetround_noex_ctx
Packit Service 82fcde
#   define libc_feholdsetround_noex_ctx  libc_feholdsetround_ctx
Packit Service 82fcde
# endif
Packit Service 82fcde
# ifndef libc_feholdsetround_noexf_ctx
Packit Service 82fcde
#   define libc_feholdsetround_noexf_ctx libc_feholdsetroundf_ctx
Packit Service 82fcde
# endif
Packit Service 82fcde
# ifndef libc_feholdsetround_noexl_ctx
Packit Service 82fcde
#   define libc_feholdsetround_noexl_ctx libc_feholdsetroundl_ctx
Packit Service 82fcde
# endif
Packit Service 82fcde
Packit Service 82fcde
# ifndef libc_feresetround_noex_ctx
Packit Service 82fcde
#   define libc_feresetround_noex_ctx  libc_fesetenv_ctx
Packit Service 82fcde
# endif
Packit Service 82fcde
# ifndef libc_feresetround_noexf_ctx
Packit Service 82fcde
#   define libc_feresetround_noexf_ctx libc_fesetenvf_ctx
Packit Service 82fcde
# endif
Packit Service 82fcde
# ifndef libc_feresetround_noexl_ctx
Packit Service 82fcde
#   define libc_feresetround_noexl_ctx libc_fesetenvl_ctx
Packit Service 82fcde
# endif
Packit Service 82fcde
Packit Service 82fcde
#else
Packit Service 82fcde
Packit Service 82fcde
# define libc_feholdsetround_ctx      default_libc_feholdsetround_ctx
Packit Service 82fcde
# define libc_feresetround_ctx        default_libc_feresetround_ctx
Packit Service 82fcde
# define libc_feholdsetround_noex_ctx default_libc_feholdsetround_noex_ctx
Packit Service 82fcde
# define libc_feresetround_noex_ctx   default_libc_feresetround_noex_ctx
Packit Service 82fcde
Packit Service 82fcde
# define libc_feholdsetroundf_ctx libc_feholdsetround_ctx
Packit Service 82fcde
# define libc_feholdsetroundl_ctx libc_feholdsetround_ctx
Packit Service 82fcde
# define libc_feresetroundf_ctx   libc_feresetround_ctx
Packit Service 82fcde
# define libc_feresetroundl_ctx   libc_feresetround_ctx
Packit Service 82fcde
Packit Service 82fcde
# define libc_feholdsetround_noexf_ctx libc_feholdsetround_noex_ctx
Packit Service 82fcde
# define libc_feholdsetround_noexl_ctx libc_feholdsetround_noex_ctx
Packit Service 82fcde
# define libc_feresetround_noexf_ctx   libc_feresetround_noex_ctx
Packit Service 82fcde
# define libc_feresetround_noexl_ctx   libc_feresetround_noex_ctx
Packit Service 82fcde
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#ifndef libc_feholdsetround_53bit_ctx
Packit Service 82fcde
#  define libc_feholdsetround_53bit_ctx libc_feholdsetround_ctx
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef libc_feresetround_53bit_ctx
Packit Service 82fcde
#  define libc_feresetround_53bit_ctx libc_feresetround_ctx
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#define SET_RESTORE_ROUND_GENERIC(RM,ROUNDFUNC,CLEANUPFUNC) \
Packit Service 82fcde
  struct rm_ctx ctx __attribute__((cleanup (CLEANUPFUNC ## _ctx))); \
Packit Service 82fcde
  ROUNDFUNC ## _ctx (&ctx, (RM))
Packit Service 82fcde
Packit Service 82fcde
/* Set the rounding mode within a lexical block.  Restore the rounding mode to
Packit Service 82fcde
   the value at the start of the block.  The exception mode must be preserved.
Packit Service 82fcde
   Exceptions raised within the block must be set in the exception flags.
Packit Service 82fcde
   Non-stop mode may be enabled inside the block.  */
Packit Service 82fcde
Packit Service 82fcde
#define SET_RESTORE_ROUND(RM) \
Packit Service 82fcde
  SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround, libc_feresetround)
Packit Service 82fcde
#define SET_RESTORE_ROUNDF(RM) \
Packit Service 82fcde
  SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundf, libc_feresetroundf)
Packit Service 82fcde
#define SET_RESTORE_ROUNDL(RM) \
Packit Service 82fcde
  SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundl, libc_feresetroundl)
Packit Service 82fcde
Packit Service 82fcde
/* Set the rounding mode within a lexical block.  Restore the rounding mode to
Packit Service 82fcde
   the value at the start of the block.  The exception mode must be preserved.
Packit Service 82fcde
   Exceptions raised within the block must be discarded, and exception flags
Packit Service 82fcde
   are restored to the value at the start of the block.
Packit Service 82fcde
   Non-stop mode must be enabled inside the block.  */
Packit Service 82fcde
Packit Service 82fcde
#define SET_RESTORE_ROUND_NOEX(RM) \
Packit Service 82fcde
  SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_noex, \
Packit Service 82fcde
			     libc_feresetround_noex)
Packit Service 82fcde
#define SET_RESTORE_ROUND_NOEXF(RM) \
Packit Service 82fcde
  SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_noexf, \
Packit Service 82fcde
			     libc_feresetround_noexf)
Packit Service 82fcde
#define SET_RESTORE_ROUND_NOEXL(RM) \
Packit Service 82fcde
  SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_noexl, \
Packit Service 82fcde
			     libc_feresetround_noexl)
Packit Service 82fcde
Packit Service 82fcde
/* Like SET_RESTORE_ROUND, but also set rounding precision to 53 bits.  */
Packit Service 82fcde
#define SET_RESTORE_ROUND_53BIT(RM) \
Packit Service 82fcde
  SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_53bit,	      \
Packit Service 82fcde
			     libc_feresetround_53bit)
Packit Service 82fcde
Packit Service 82fcde
/* When no floating-point exceptions are defined in <fenv.h>, make
Packit Service 82fcde
   feraiseexcept ignore its argument so that unconditional
Packit Service 82fcde
   feraiseexcept calls do not cause errors for undefined exceptions.
Packit Service 82fcde
   Define it to expand to a void expression so that any calls testing
Packit Service 82fcde
   the result of feraiseexcept do produce errors.  */
Packit Service 82fcde
#if FE_ALL_EXCEPT == 0
Packit Service 82fcde
# define feraiseexcept(excepts) ((void) 0)
Packit Service 82fcde
# define __feraiseexcept(excepts) ((void) 0)
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* Similarly, most <fenv.h> functions have trivial implementations in
Packit Service 82fcde
   the absence of support for floating-point exceptions and rounding
Packit Service 82fcde
   modes.  */
Packit Service 82fcde
Packit Service 82fcde
#if !FE_HAVE_ROUNDING_MODES
Packit Service 82fcde
# if FE_ALL_EXCEPT == 0
Packit Service 82fcde
extern inline int
Packit Service 82fcde
fegetenv (fenv_t *__e)
Packit Service 82fcde
{
Packit Service 82fcde
  return 0;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
extern inline int
Packit Service 82fcde
__fegetenv (fenv_t *__e)
Packit Service 82fcde
{
Packit Service 82fcde
  return 0;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
extern inline int
Packit Service 82fcde
feholdexcept (fenv_t *__e)
Packit Service 82fcde
{
Packit Service 82fcde
  return 0;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
extern inline int
Packit Service 82fcde
__feholdexcept (fenv_t *__e)
Packit Service 82fcde
{
Packit Service 82fcde
  return 0;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
extern inline int
Packit Service 82fcde
fesetenv (const fenv_t *__e)
Packit Service 82fcde
{
Packit Service 82fcde
  return 0;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
extern inline int
Packit Service 82fcde
__fesetenv (const fenv_t *__e)
Packit Service 82fcde
{
Packit Service 82fcde
  return 0;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
extern inline int
Packit Service 82fcde
feupdateenv (const fenv_t *__e)
Packit Service 82fcde
{
Packit Service 82fcde
  return 0;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
extern inline int
Packit Service 82fcde
__feupdateenv (const fenv_t *__e)
Packit Service 82fcde
{
Packit Service 82fcde
  return 0;
Packit Service 82fcde
}
Packit Service 82fcde
# endif
Packit Service 82fcde
Packit Service 82fcde
extern inline int
Packit Service 82fcde
fegetround (void)
Packit Service 82fcde
{
Packit Service 82fcde
  return FE_TONEAREST;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
extern inline int
Packit Service 82fcde
__fegetround (void)
Packit Service 82fcde
{
Packit Service 82fcde
  return FE_TONEAREST;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
extern inline int
Packit Service 82fcde
fesetround (int __d)
Packit Service 82fcde
{
Packit Service 82fcde
  return 0;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
extern inline int
Packit Service 82fcde
__fesetround (int __d)
Packit Service 82fcde
{
Packit Service 82fcde
  return 0;
Packit Service 82fcde
}
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#endif /* _MATH_PRIVATE_H_ */