Blame sysdeps/mips/math_private.h

Packit 6c4009
/* Internal math stuff.  MIPS version.
Packit 6c4009
   Copyright (C) 2013-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#ifndef MIPS_MATH_PRIVATE_H
Packit 6c4009
#define MIPS_MATH_PRIVATE_H 1
Packit 6c4009
Packit 6c4009
/* Inline functions to speed up the math library implementation.  The
Packit 6c4009
   default versions of these routines are in generic/math_private.h
Packit 6c4009
   and call fesetround, feholdexcept, etc.  These routines use inlined
Packit 6c4009
   code instead.  */
Packit 6c4009
Packit 6c4009
#ifdef __mips_hard_float
Packit 6c4009
Packit 6c4009
# include <fenv.h>
Packit 6c4009
# include <fenv_libc.h>
Packit 6c4009
# include <fpu_control.h>
Packit 6c4009
Packit 6c4009
# define _FPU_MASK_ALL (_FPU_MASK_V | _FPU_MASK_Z | _FPU_MASK_O \
Packit 6c4009
			|_FPU_MASK_U | _FPU_MASK_I | FE_ALL_EXCEPT)
Packit 6c4009
Packit 6c4009
static __always_inline void
Packit 6c4009
libc_feholdexcept_mips (fenv_t *envp)
Packit 6c4009
{
Packit 6c4009
  fpu_control_t cw;
Packit 6c4009
Packit 6c4009
  /* Save the current state.  */
Packit 6c4009
  _FPU_GETCW (cw);
Packit 6c4009
  envp->__fp_control_register = cw;
Packit 6c4009
Packit 6c4009
  /* Clear all exception enable bits and flags.  */
Packit 6c4009
  cw &= ~(_FPU_MASK_ALL);
Packit 6c4009
  _FPU_SETCW (cw);
Packit 6c4009
}
Packit 6c4009
# define libc_feholdexcept libc_feholdexcept_mips
Packit 6c4009
# define libc_feholdexceptf libc_feholdexcept_mips
Packit 6c4009
# define libc_feholdexceptl libc_feholdexcept_mips
Packit 6c4009
Packit 6c4009
static __always_inline void
Packit 6c4009
libc_fesetround_mips (int round)
Packit 6c4009
{
Packit 6c4009
  fpu_control_t cw;
Packit 6c4009
Packit 6c4009
  /* Get current state.  */
Packit 6c4009
  _FPU_GETCW (cw);
Packit 6c4009
Packit 6c4009
  /* Set rounding bits.  */
Packit 6c4009
  cw &= ~_FPU_RC_MASK;
Packit 6c4009
  cw |= round;
Packit 6c4009
Packit 6c4009
  /* Set new state.  */
Packit 6c4009
  _FPU_SETCW (cw);
Packit 6c4009
}
Packit 6c4009
# define libc_fesetround libc_fesetround_mips
Packit 6c4009
# define libc_fesetroundf libc_fesetround_mips
Packit 6c4009
# define libc_fesetroundl libc_fesetround_mips
Packit 6c4009
Packit 6c4009
static __always_inline void
Packit 6c4009
libc_feholdexcept_setround_mips (fenv_t *envp, int round)
Packit 6c4009
{
Packit 6c4009
  fpu_control_t cw;
Packit 6c4009
Packit 6c4009
  /* Save the current state.  */
Packit 6c4009
  _FPU_GETCW (cw);
Packit 6c4009
  envp->__fp_control_register = cw;
Packit 6c4009
Packit 6c4009
  /* Clear all exception enable bits and flags.  */
Packit 6c4009
  cw &= ~(_FPU_MASK_ALL);
Packit 6c4009
Packit 6c4009
  /* Set rounding bits.  */
Packit 6c4009
  cw &= ~_FPU_RC_MASK;
Packit 6c4009
  cw |= round;
Packit 6c4009
Packit 6c4009
  /* Set new state.  */
Packit 6c4009
  _FPU_SETCW (cw);
Packit 6c4009
}
Packit 6c4009
# define libc_feholdexcept_setround libc_feholdexcept_setround_mips
Packit 6c4009
# define libc_feholdexcept_setroundf libc_feholdexcept_setround_mips
Packit 6c4009
# define libc_feholdexcept_setroundl libc_feholdexcept_setround_mips
Packit 6c4009
Packit 6c4009
# define libc_feholdsetround libc_feholdexcept_setround_mips
Packit 6c4009
# define libc_feholdsetroundf libc_feholdexcept_setround_mips
Packit 6c4009
# define libc_feholdsetroundl libc_feholdexcept_setround_mips
Packit 6c4009
Packit 6c4009
static __always_inline void
Packit 6c4009
libc_fesetenv_mips (fenv_t *envp)
Packit 6c4009
{
Packit 6c4009
  fpu_control_t cw __attribute__ ((unused));
Packit 6c4009
Packit 6c4009
  /* Read current state to flush fpu pipeline.  */
Packit 6c4009
  _FPU_GETCW (cw);
Packit 6c4009
Packit 6c4009
  _FPU_SETCW (envp->__fp_control_register);
Packit 6c4009
}
Packit 6c4009
# define libc_fesetenv libc_fesetenv_mips
Packit 6c4009
# define libc_fesetenvf libc_fesetenv_mips
Packit 6c4009
# define libc_fesetenvl libc_fesetenv_mips
Packit 6c4009
Packit 6c4009
static __always_inline int
Packit 6c4009
libc_feupdateenv_test_mips (fenv_t *envp, int excepts)
Packit 6c4009
{
Packit 6c4009
  /* int ret = fetestexcept (excepts); feupdateenv (envp); return ret; */
Packit 6c4009
  int cw, temp;
Packit 6c4009
Packit 6c4009
  /* Get current control word.  */
Packit 6c4009
  _FPU_GETCW (cw);
Packit 6c4009
Packit 6c4009
  /* Set flag bits (which are accumulative), and *also* set the
Packit 6c4009
     cause bits.  The setting of the cause bits is what actually causes
Packit 6c4009
     the hardware to generate the exception, if the corresponding enable
Packit 6c4009
     bit is set as well.  */
Packit 6c4009
  temp = cw & FE_ALL_EXCEPT;
Packit 6c4009
  temp |= envp->__fp_control_register | (temp << CAUSE_SHIFT);
Packit 6c4009
Packit 6c4009
  /* Set new state.  */
Packit 6c4009
  _FPU_SETCW (temp);
Packit 6c4009
Packit 6c4009
  return cw & excepts & FE_ALL_EXCEPT;
Packit 6c4009
}
Packit 6c4009
# define libc_feupdateenv_test libc_feupdateenv_test_mips
Packit 6c4009
# define libc_feupdateenv_testf libc_feupdateenv_test_mips
Packit 6c4009
# define libc_feupdateenv_testl libc_feupdateenv_test_mips
Packit 6c4009
Packit 6c4009
static __always_inline void
Packit 6c4009
libc_feupdateenv_mips (fenv_t *envp)
Packit 6c4009
{
Packit 6c4009
  libc_feupdateenv_test_mips (envp, 0);
Packit 6c4009
}
Packit 6c4009
# define libc_feupdateenv libc_feupdateenv_mips
Packit 6c4009
# define libc_feupdateenvf libc_feupdateenv_mips
Packit 6c4009
# define libc_feupdateenvl libc_feupdateenv_mips
Packit 6c4009
Packit 6c4009
# define libc_feresetround libc_feupdateenv_mips
Packit 6c4009
# define libc_feresetroundf libc_feupdateenv_mips
Packit 6c4009
# define libc_feresetroundl libc_feupdateenv_mips
Packit 6c4009
Packit 6c4009
static __always_inline int
Packit 6c4009
libc_fetestexcept_mips (int excepts)
Packit 6c4009
{
Packit 6c4009
  int cw;
Packit 6c4009
Packit 6c4009
  /* Get current control word.  */
Packit 6c4009
  _FPU_GETCW (cw);
Packit 6c4009
Packit 6c4009
  return cw & excepts & FE_ALL_EXCEPT;
Packit 6c4009
}
Packit 6c4009
# define libc_fetestexcept libc_fetestexcept_mips
Packit 6c4009
# define libc_fetestexceptf libc_fetestexcept_mips
Packit 6c4009
# define libc_fetestexceptl libc_fetestexcept_mips
Packit 6c4009
Packit 6c4009
/*  Enable support for rounding mode context.  */
Packit 6c4009
# define HAVE_RM_CTX 1
Packit 6c4009
Packit 6c4009
static __always_inline void
Packit 6c4009
libc_feholdexcept_setround_mips_ctx (struct rm_ctx *ctx, int round)
Packit 6c4009
{
Packit 6c4009
  fpu_control_t old, new;
Packit 6c4009
Packit 6c4009
  /* Save the current state.  */
Packit 6c4009
  _FPU_GETCW (old);
Packit 6c4009
  ctx->env.__fp_control_register = old;
Packit 6c4009
Packit 6c4009
  /* Clear all exception enable bits and flags.  */
Packit 6c4009
  new = old & ~(_FPU_MASK_ALL);
Packit 6c4009
Packit 6c4009
  /* Set rounding bits.  */
Packit 6c4009
  new = (new & ~_FPU_RC_MASK) | round;
Packit 6c4009
Packit 6c4009
  if (__glibc_unlikely (new != old))
Packit 6c4009
    {
Packit 6c4009
      _FPU_SETCW (new);
Packit 6c4009
      ctx->updated_status = true;
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    ctx->updated_status = false;
Packit 6c4009
}
Packit 6c4009
# define libc_feholdexcept_setround_ctx   libc_feholdexcept_setround_mips_ctx
Packit 6c4009
# define libc_feholdexcept_setroundf_ctx  libc_feholdexcept_setround_mips_ctx
Packit 6c4009
# define libc_feholdexcept_setroundl_ctx  libc_feholdexcept_setround_mips_ctx
Packit 6c4009
Packit 6c4009
static __always_inline void
Packit 6c4009
libc_fesetenv_mips_ctx (struct rm_ctx *ctx)
Packit 6c4009
{
Packit 6c4009
  libc_fesetenv_mips (&ctx->env);
Packit 6c4009
}
Packit 6c4009
# define libc_fesetenv_ctx                libc_fesetenv_mips_ctx
Packit 6c4009
# define libc_fesetenvf_ctx               libc_fesetenv_mips_ctx
Packit 6c4009
# define libc_fesetenvl_ctx               libc_fesetenv_mips_ctx
Packit 6c4009
Packit 6c4009
static __always_inline void
Packit 6c4009
libc_feupdateenv_mips_ctx (struct rm_ctx *ctx)
Packit 6c4009
{
Packit 6c4009
  if (__glibc_unlikely (ctx->updated_status))
Packit 6c4009
    libc_feupdateenv_test_mips (&ctx->env, 0);
Packit 6c4009
}
Packit 6c4009
# define libc_feupdateenv_ctx             libc_feupdateenv_mips_ctx
Packit 6c4009
# define libc_feupdateenvf_ctx            libc_feupdateenv_mips_ctx
Packit 6c4009
# define libc_feupdateenvl_ctx            libc_feupdateenv_mips_ctx
Packit 6c4009
# define libc_feresetround_ctx            libc_feupdateenv_mips_ctx
Packit 6c4009
# define libc_feresetroundf_ctx           libc_feupdateenv_mips_ctx
Packit 6c4009
# define libc_feresetroundl_ctx           libc_feupdateenv_mips_ctx
Packit 6c4009
Packit 6c4009
static __always_inline void
Packit 6c4009
libc_feholdsetround_mips_ctx (struct rm_ctx *ctx, int round)
Packit 6c4009
{
Packit 6c4009
  fpu_control_t old, new;
Packit 6c4009
Packit 6c4009
  /* Save the current state.  */
Packit 6c4009
  _FPU_GETCW (old);
Packit 6c4009
  ctx->env.__fp_control_register = old;
Packit 6c4009
Packit 6c4009
  /* Set rounding bits.  */
Packit 6c4009
  new = (old & ~_FPU_RC_MASK) | round;
Packit 6c4009
Packit 6c4009
  if (__glibc_unlikely (new != old))
Packit 6c4009
    {
Packit 6c4009
      _FPU_SETCW (new);
Packit 6c4009
      ctx->updated_status = true;
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    ctx->updated_status = false;
Packit 6c4009
}
Packit 6c4009
# define libc_feholdsetround_ctx          libc_feholdsetround_mips_ctx
Packit 6c4009
# define libc_feholdsetroundf_ctx         libc_feholdsetround_mips_ctx
Packit 6c4009
# define libc_feholdsetroundl_ctx         libc_feholdsetround_mips_ctx
Packit 6c4009
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#include_next <math_private.h>
Packit 6c4009
Packit 6c4009
#endif