Blame sysdeps/generic/math_private.h

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