コード例 #1
0
ファイル: spe-raise.c プロジェクト: Drakey83/steamlink-sdk
int
__FERAISEEXCEPT_INTERNAL (int excepts)
{
  unsigned long f;

  f = fegetenv_register ();
  f |= (excepts & SPEFSCR_ALL_EXCEPT);
  fesetenv_register (f);

  /* Force the operations that cause the exceptions.  */
  if ((SPEFSCR_FINVS & excepts) != 0)
    /* 0 / 0 */
    asm volatile ("efsdiv %0,%0,%1" : : "r" (0), "r" (0));

  if ((SPEFSCR_FDBZS & excepts) != 0)
    /* 1.0 / 0.0 */
    asm volatile ("efsdiv %0,%0,%1" : : "r" (1.0F), "r" (0));

  if ((SPEFSCR_FOVFS & excepts) != 0)
    /* Largest normalized number plus itself.  */
    asm volatile ("efsadd %0,%0,%1" : : "r" (0x7f7fffff), "r" (0x7f7fffff));

  if ((SPEFSCR_FUNFS & excepts) != 0)
    /* Smallest normalized number times itself.  */
    asm volatile ("efsmul %0,%0,%1" : : "r" (0x800000), "r" (0x800000));

  if ((SPEFSCR_FINXS & excepts) != 0)
    /* Smallest normalized minus 1.0 raises the inexact flag.  */
    asm volatile ("efssub %0,%0,%1" : : "r" (0x00800000), "r" (1.0F));

  /* Success.  */
  return 0;
}
コード例 #2
0
ファイル: fsetexcptflg.c プロジェクト: riscv/riscv-glibc
int
__fesetexceptflag (const fexcept_t *flagp, int excepts)
{
  unsigned long old_spefscr, spefscr;
  fexcept_t flag;
  int excepts_spe = __fexcepts_to_spe (excepts);

  /* Get the current state.  */
  old_spefscr = fegetenv_register ();

  /* Ignore exceptions not listed in 'excepts'.  */
  flag = *flagp & excepts_spe;

  /* Replace the exception status */
  spefscr = (old_spefscr & ~excepts_spe) | flag;

  /* Store the new status word (along with the rest of the environment).  */
  fesetenv_register (spefscr);

  /* If the state of the "invalid" or "underflow" flag has changed,
     inform the kernel.  */
  if (((spefscr ^ old_spefscr) & (SPEFSCR_FINVS | SPEFSCR_FUNFS)) != 0)
    __fe_note_change ();

  /* Success.  */
  return 0;
}
コード例 #3
0
int
fedisableexcept (int excepts)
{
  fenv_union_t fe;
  int result;

  result = fegetexcept ();

  if ((excepts & FE_ALL_INVALID) == FE_ALL_INVALID)
    excepts = (excepts | FE_INVALID) & ~ FE_ALL_INVALID;

  fe.fenv = fegetenv_register ();
  if (excepts & FE_INEXACT)
    fe.l[1] &= ~(1 << (31 - FPSCR_XE));
  if (excepts & FE_DIVBYZERO)
    fe.l[1] &= ~(1 << (31 - FPSCR_ZE));
  if (excepts & FE_UNDERFLOW)
    fe.l[1] &= ~(1 << (31 - FPSCR_UE));
  if (excepts & FE_OVERFLOW)
    fe.l[1] &= ~(1 << (31 - FPSCR_OE));
  if (excepts & FE_INVALID)
    fe.l[1] &= ~(1 << (31 - FPSCR_VE));
  fesetenv_register (fe.fenv);

  if ((fegetexcept () & excepts) != 0)
    result = -1;
  return result;
}
コード例 #4
0
ファイル: fedisblxcpt.c プロジェクト: riscv/riscv-glibc
int
fedisableexcept (int excepts)
{
  int result = 0, pflags, r;
  INTERNAL_SYSCALL_DECL (err);

  r = INTERNAL_SYSCALL (prctl, err, 2, PR_GET_FPEXC, &pflags);
  if (INTERNAL_SYSCALL_ERROR_P (r, err))
    return -1;

  /* Save old enable bits.  */
  result = __fexcepts_from_prctl (pflags);

  pflags &= ~__fexcepts_to_prctl (excepts);
  r = INTERNAL_SYSCALL (prctl, err, 2, PR_SET_FPEXC,
			pflags | PR_FP_EXC_SW_ENABLE);
  if (INTERNAL_SYSCALL_ERROR_P (r, err))
    return -1;

  /* If disabling signals for "inexact", also disable trapping to the
     kernel.  */
  if ((excepts & FE_INEXACT) != 0)
    {
      unsigned long fpescr;

      fpescr = fegetenv_register ();
      fpescr &= ~SPEFSCR_FINXE;
      fesetenv_register (fpescr);
    }

  return result;
}
コード例 #5
0
ファイル: atomic-feclearexcept.c プロジェクト: ensc/dietlibc
void
__atomic_feclearexcept (void)
{
    unsigned int fpescr, old_fpescr;

    /* Get the current state.  */
    old_fpescr = fpescr = fegetenv_register ();

    /* Clear the relevant bits.  */
    fpescr &= ~SPEFSCR_ALL_EXCEPT;

    /* Put the new state in effect.  */
    fesetenv_register (fpescr);

    /* Let the kernel know if the "invalid" or "underflow" bit was
       cleared.  */
    if (old_fpescr & (SPEFSCR_FINVS | SPEFSCR_FUNFS))
    {
        int pflags __attribute__ ((__unused__)), r;

        r = prctl(PR_GET_FPEXC, (unsigned long)&pflags);
        if (r < 0)
            abort ();
    }
}
コード例 #6
0
ファイル: feholdexcpt.c プロジェクト: JamesLinus/glibc-mips
int
__feholdexcept (fenv_t *envp)
{
  fenv_union_t u;
  INTERNAL_SYSCALL_DECL (err);
  int r;

  /* Get the current state.  */
  r = INTERNAL_SYSCALL (prctl, err, 2, PR_GET_FPEXC, &u.l[0]);
  if (INTERNAL_SYSCALL_ERROR_P (r, err))
    return -1;

  u.l[1] = fegetenv_register ();
  *envp = u.fenv;

  /* Clear everything except for the rounding mode and trapping to the
     kernel.  */
  u.l[0] &= ~(PR_FP_EXC_DIV
	      | PR_FP_EXC_OVF
	      | PR_FP_EXC_UND
	      | PR_FP_EXC_RES
	      | PR_FP_EXC_INV);
  u.l[1] &= SPEFSCR_FRMC | (SPEFSCR_ALL_EXCEPT_ENABLE & ~SPEFSCR_FINXE);

  /* Put the new state in effect.  */
  fesetenv_register (u.l[1]);
  r = INTERNAL_SYSCALL (prctl, err, 2, PR_SET_FPEXC,
			u.l[0] | PR_FP_EXC_SW_ENABLE);
  if (INTERNAL_SYSCALL_ERROR_P (r, err))
    return -1;

  return 0;
}
コード例 #7
0
ファイル: fesetenv.c プロジェクト: mbref/eglibc-microblaze
int
__fesetenv (const fenv_t *envp)
{
  fenv_union_t u;
  INTERNAL_SYSCALL_DECL (err);

  u.fenv = *envp;
  INTERNAL_SYSCALL (prctl, err, 2, PR_SET_FPEXC, &u.l[0]);
  fesetenv_register (u.l[1]);

  /* Success.  */
  return 0;
}
コード例 #8
0
int
feholdexcept (fenv_t *envp)
{
  fenv_union_t u;

  /* Get the current state.  */
  u.fenv = *envp = fegetenv_register ();

  /* Clear everything except for the rounding mode and non-IEEE arithmetic
     flag.  */
  u.l[1] = u.l[1] & 7;

  /* Put the new state in effect.  */
  fesetenv_register (u.fenv);

  return 0;
}
コード例 #9
0
ファイル: spe-raise.c プロジェクト: OPSF/uClinux
int
__FERAISEEXCEPT_INTERNAL (int excepts)
{
  unsigned long f;

  f = fegetenv_register ();
  f |= (excepts & FE_ALL_EXCEPT);
  fesetenv_register (f);

  /* Force the operations that cause the exceptions.  */
  if ((FE_INVALID & excepts) != 0)
    {
      /* ?? Does not set sticky bit ?? */
      /* 0 / 0 */
      asm volatile ("efsdiv %0,%0,%1" : : "r" (0), "r" (0));
    }

  if ((FE_DIVBYZERO & excepts) != 0)
    {
      /* 1.0 / 0.0 */
      asm volatile ("efsdiv %0,%0,%1" : : "r" (1.0F), "r" (0));
    }

  if ((FE_OVERFLOW & excepts) != 0)
    {
      /* ?? Does not set sticky bit ?? */
      /* Largest normalized number plus itself.  */
      asm volatile ("efsadd %0,%0,%1" : : "r" (0x7f7fffff), "r" (0x7f7fffff));
    }

  if ((FE_UNDERFLOW & excepts) != 0)
    {
      /* ?? Does not set sticky bit ?? */
      /* Smallest normalized number times itself.  */
      asm volatile ("efsmul %0,%0,%1" : : "r" (0x800000), "r" (0x800000));
    }

  if ((FE_INEXACT & excepts) != 0)
    {
      /* Smallest normalized minus 1.0 raises the inexact flag.  */
      asm volatile ("efssub %0,%0,%1" : : "r" (0x00800000), "r" (1.0F));
    }

  /* Success.  */
  return 0;
}
コード例 #10
0
ファイル: fesetenv.c プロジェクト: JamesLinus/glibc-mips
int
__fesetenv (const fenv_t *envp)
{
  fenv_union_t u;
  INTERNAL_SYSCALL_DECL (err);
  int r;

  u.fenv = *envp;

  fesetenv_register (u.l[1]);
  r = INTERNAL_SYSCALL (prctl, err, 2, PR_SET_FPEXC,
			u.l[0] | PR_FP_EXC_SW_ENABLE);
  if (INTERNAL_SYSCALL_ERROR_P (r, err))
    return -1;

  /* Success.  */
  return 0;
}
コード例 #11
0
ファイル: feholdexcpt.c プロジェクト: mbref/eglibc-microblaze
int
feholdexcept (fenv_t *envp)
{
  fenv_union_t u;
  INTERNAL_SYSCALL_DECL (err);


  /* Get the current state.  */
  INTERNAL_SYSCALL (prctl, err, 2, PR_GET_FPEXC, &u.l[0]);
  u.l[1] = fegetenv_register ();
  *envp = u.fenv;

  /* Clear everything except for the rounding mode.  */
  u.l[1] &= 3;

  /* Put the new state in effect.  */
  fesetenv_register (u.l[1]);

  return 0;
}
コード例 #12
0
ファイル: fclrexcpt.c プロジェクト: JamesLinus/glibc-mips
int
__feclearexcept (int excepts)
{
  unsigned int fpescr;
  int excepts_spe = __fexcepts_to_spe (excepts);

  /* Get the current state.  */
  fpescr = fegetenv_register ();

  /* Clear the relevant bits.  */
  fpescr &= ~excepts_spe;

  /* Put the new state in effect.  */
  fesetenv_register (fpescr);

  /* Let the kernel know if the "invalid" or "underflow" bit was
     cleared.  */
  if (excepts & (FE_INVALID | FE_UNDERFLOW))
    __fe_note_change ();

  /* Success.  */
  return 0;
}
コード例 #13
0
ファイル: fsetexcptflg.c プロジェクト: Jaden-J/uClibc
int
__fesetexceptflag (const fexcept_t *flagp, int excepts)
{
  unsigned long spefscr;
  fexcept_t flag;

  /* Get the current state.  */
  spefscr = fegetenv_register ();

  /* Ignore exceptions not listed in 'excepts'.  */
  flag = *flagp & excepts;

  /* Replace the exception status */
  spefscr = (spefscr & ~FE_ALL_EXCEPT) | flag;

  /* Store the new status word (along with the rest of the environment).
     This may cause floating-point exceptions if the restored state
     requests it.  */
  fesetenv_register (spefscr);
  feraiseexcept (spefscr & FE_ALL_EXCEPT);

  /* Success.  */
  return 0;
}