Add macros and inline functions to mips math_private.h file.

This is a patch to the MIPS math_private.h file to define HAVE_RM_CTX and
implement the ctx macros.  I also defined a few other macros and inline
functions that I skipped the first time.
This commit is contained in:
Steve Ellcey 2014-02-26 14:19:20 -08:00
parent f067bf1f33
commit 5b456e9d61
2 changed files with 169 additions and 8 deletions

View File

@ -1,3 +1,44 @@
2014-02-26 Steve Ellcey <sellcey@mips.com>
* sysdeps/mips/math_private.h (_FPU_MASK_ALL) New.
(libc_feholdexcept_mips): Use _FPU_MASK_ALL.
(libc_feholdexcept_setround_mips): Ditto.
(libc_feholdsetround): New.
(libc_feholdsetroundf): New.
(libc_feholdsetroundl): New.
(libc_feupdateenv_test_mips): New.
(libc_feupdateenv_test): New.
(libc_feupdateenv_testf): New.
(libc_feupdateenv_testl): New.
(libc_feresetround): New.
(libc_feresetroundf): New.
(libc_feresetroundl): New.
(libc_fetestexcept_mips): New.
(libc_fetestexcept): New.
(libc_fetestexceptf): New.
(libc_fetestexceptl): New.
(HAVE_RM_CTX): New.
(libc_feholdexcept_setround_mips_ctx): New.
(libc_feholdexcept_setround_ctx): New.
(libc_feholdexcept_setroundf_ctx): New.
(libc_feholdexcept_setroundl_ctx): New.
(libc_fesetenv_mips_ctx): New.
(libc_fesetenv_ctx): New.
(libc_fesetenv_ctxf): New.
(libc_fesetenv_ctxl): New.
(libc_feupdateenv_mips_ctx): New.
(libc_feupdateenv_ctx): New.
(libc_feupdateenvf_ctx): New.
(libc_feupdateenvl_ctx): New.
(libc_feholdsetround_mips_ctx): New.
(libc_feholdsetround_ctx): New.
(libc_feholdsetroundf_ctx): New.
(libc_feholdsetroundl_ctx): New.
(libc_feresetround_mips_ctx): New.
(libc_feresetround_ctx): New.
(libc_feresetroundf_ctx): New.
(libc_feresetroundl_ctx): New.
2014-02-26 Carlos O'Donell <carlos@redhat.com> 2014-02-26 Carlos O'Donell <carlos@redhat.com>
* manual/ipc.texi (Semaphores): Use @Theglibc{}. * manual/ipc.texi (Semaphores): Use @Theglibc{}.

View File

@ -37,6 +37,9 @@
# include <fenv_libc.h> # include <fenv_libc.h>
# include <fpu_control.h> # include <fpu_control.h>
# define _FPU_MASK_ALL (_FPU_MASK_V | _FPU_MASK_Z | _FPU_MASK_O \
|_FPU_MASK_U | _FPU_MASK_I | FE_ALL_EXCEPT)
static __always_inline void static __always_inline void
libc_feholdexcept_mips (fenv_t *envp) libc_feholdexcept_mips (fenv_t *envp)
{ {
@ -47,7 +50,7 @@ libc_feholdexcept_mips (fenv_t *envp)
envp->__fp_control_register = cw; envp->__fp_control_register = cw;
/* Clear all exception enable bits and flags. */ /* Clear all exception enable bits and flags. */
cw &= ~(_FPU_MASK_V|_FPU_MASK_Z|_FPU_MASK_O|_FPU_MASK_U|_FPU_MASK_I|FE_ALL_EXCEPT); cw &= ~(_FPU_MASK_ALL);
_FPU_SETCW (cw); _FPU_SETCW (cw);
} }
# define libc_feholdexcept libc_feholdexcept_mips # define libc_feholdexcept libc_feholdexcept_mips
@ -83,7 +86,7 @@ libc_feholdexcept_setround_mips (fenv_t *envp, int round)
envp->__fp_control_register = cw; envp->__fp_control_register = cw;
/* Clear all exception enable bits and flags. */ /* Clear all exception enable bits and flags. */
cw &= ~(_FPU_MASK_V|_FPU_MASK_Z|_FPU_MASK_O|_FPU_MASK_U|_FPU_MASK_I|FE_ALL_EXCEPT); cw &= ~(_FPU_MASK_ALL);
/* Set rounding bits. */ /* Set rounding bits. */
cw &= ~_FPU_RC_MASK; cw &= ~_FPU_RC_MASK;
@ -96,6 +99,10 @@ libc_feholdexcept_setround_mips (fenv_t *envp, int round)
# define libc_feholdexcept_setroundf libc_feholdexcept_setround_mips # define libc_feholdexcept_setroundf libc_feholdexcept_setround_mips
# define libc_feholdexcept_setroundl libc_feholdexcept_setround_mips # define libc_feholdexcept_setroundl libc_feholdexcept_setround_mips
# define libc_feholdsetround libc_feholdexcept_setround_mips
# define libc_feholdsetroundf libc_feholdexcept_setround_mips
# define libc_feholdsetroundl libc_feholdexcept_setround_mips
static __always_inline void static __always_inline void
libc_fesetenv_mips (fenv_t *envp) libc_fesetenv_mips (fenv_t *envp)
{ {
@ -110,28 +117,141 @@ libc_fesetenv_mips (fenv_t *envp)
# define libc_fesetenvf libc_fesetenv_mips # define libc_fesetenvf libc_fesetenv_mips
# define libc_fesetenvl libc_fesetenv_mips # define libc_fesetenvl libc_fesetenv_mips
static __always_inline void static __always_inline int
libc_feupdateenv_mips (fenv_t *envp) libc_feupdateenv_test_mips (fenv_t *envp, int excepts)
{ {
int temp; /* int ret = fetestexcept (excepts); feupdateenv (envp); return ret; */
int cw, temp;
/* Save current exceptions. */ /* Get current control word. */
_FPU_GETCW (temp); _FPU_GETCW (cw);
/* Set flag bits (which are accumulative), and *also* set the /* Set flag bits (which are accumulative), and *also* set the
cause bits. The setting of the cause bits is what actually causes cause bits. The setting of the cause bits is what actually causes
the hardware to generate the exception, if the corresponding enable the hardware to generate the exception, if the corresponding enable
bit is set as well. */ bit is set as well. */
temp &= FE_ALL_EXCEPT; temp = cw & FE_ALL_EXCEPT;
temp |= envp->__fp_control_register | (temp << CAUSE_SHIFT); temp |= envp->__fp_control_register | (temp << CAUSE_SHIFT);
/* Set new state. */ /* Set new state. */
_FPU_SETCW (temp); _FPU_SETCW (temp);
return cw & excepts & FE_ALL_EXCEPT;
}
# define libc_feupdateenv_test libc_feupdateenv_test_mips
# define libc_feupdateenv_testf libc_feupdateenv_test_mips
# define libc_feupdateenv_testl libc_feupdateenv_test_mips
static __always_inline void
libc_feupdateenv_mips (fenv_t *envp)
{
libc_feupdateenv_test_mips (envp, 0);
} }
# define libc_feupdateenv libc_feupdateenv_mips # define libc_feupdateenv libc_feupdateenv_mips
# define libc_feupdateenvf libc_feupdateenv_mips # define libc_feupdateenvf libc_feupdateenv_mips
# define libc_feupdateenvl libc_feupdateenv_mips # define libc_feupdateenvl libc_feupdateenv_mips
# define libc_feresetround libc_feupdateenv_mips
# define libc_feresetroundf libc_feupdateenv_mips
# define libc_feresetroundl libc_feupdateenv_mips
static __always_inline int
libc_fetestexcept_mips (int excepts)
{
int cw;
/* Get current control word. */
_FPU_GETCW (cw);
return cw & excepts & FE_ALL_EXCEPT;
}
# define libc_fetestexcept libc_fetestexcept_mips
# define libc_fetestexceptf libc_fetestexcept_mips
# define libc_fetestexceptl libc_fetestexcept_mips
/* Enable support for rounding mode context. */
# define HAVE_RM_CTX 1
static __always_inline void
libc_feholdexcept_setround_mips_ctx (struct rm_ctx *ctx, int round)
{
fpu_control_t old, new;
/* Save the current state. */
_FPU_GETCW (old);
ctx->env.__fp_control_register = old;
/* Clear all exception enable bits and flags. */
new = old & ~(_FPU_MASK_ALL);
/* Set rounding bits. */
new = (new & ~_FPU_RC_MASK) | round;
if (__glibc_unlikely (new != old))
{
_FPU_SETCW (new);
ctx->updated_status = true;
}
else
ctx->updated_status = false;
}
# define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_mips_ctx
# define libc_feholdexcept_setroundf_ctx libc_feholdexcept_setround_mips_ctx
# define libc_feholdexcept_setroundl_ctx libc_feholdexcept_setround_mips_ctx
static __always_inline void
libc_fesetenv_mips_ctx (struct rm_ctx *ctx)
{
libc_fesetenv_mips (&ctx->env);
}
# define libc_fesetenv_ctx libc_fesetenv_mips_ctx
# define libc_fesetenvf_ctx libc_fesetenv_mips_ctx
# define libc_fesetenvl_ctx libc_fesetenv_mips_ctx
static __always_inline void
libc_feupdateenv_mips_ctx (struct rm_ctx *ctx)
{
if (__glibc_unlikely (ctx->updated_status))
libc_feupdateenv_test_mips (&ctx->env, 0);
}
# define libc_feupdateenv_ctx libc_feupdateenv_mips_ctx
# define libc_feupdateenvf_ctx libc_feupdateenv_mips_ctx
# define libc_feupdateenvl_ctx libc_feupdateenv_mips_ctx
static __always_inline void
libc_feholdsetround_mips_ctx (struct rm_ctx *ctx, int round)
{
fpu_control_t old, new;
/* Save the current state. */
_FPU_GETCW (old);
ctx->env.__fp_control_register = old;
/* Set rounding bits. */
new = (old & ~_FPU_RC_MASK) | round;
if (__glibc_unlikely (new != old))
{
_FPU_SETCW (new);
ctx->updated_status = true;
}
else
ctx->updated_status = false;
}
# define libc_feholdsetround_ctx libc_feholdsetround_mips_ctx
# define libc_feholdsetroundf_ctx libc_feholdsetround_mips_ctx
# define libc_feholdsetroundl_ctx libc_feholdsetround_mips_ctx
static __always_inline void
libc_feresetround_mips_ctx (struct rm_ctx *ctx)
{
if (__glibc_unlikely (ctx->updated_status))
_FPU_SETCW (ctx->env);
}
# define libc_feresetround_ctx libc_feresetround_mips_ctx
# define libc_feresetroundf_ctx libc_feresetround_mips_ctx
# define libc_feresetroundl_ctx libc_feresetround_mips_ctx
#endif #endif
#include_next <math_private.h> #include_next <math_private.h>