ARC: hardware floating point support

Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
This commit is contained in:
Vineet Gupta 2019-11-04 16:20:37 -08:00
parent fd9dec20c8
commit 3ab8611a22
20 changed files with 711 additions and 0 deletions

View File

@ -0,0 +1,36 @@
/* Clear given exceptions in current floating-point environment.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
#include <fenv.h>
#include <fpu_control.h>
int
feclearexcept (int excepts)
{
unsigned int fpsr;
_FPU_GETS (fpsr);
/* Clear the relevant bits, FWE is preserved. */
fpsr &= ~excepts;
_FPU_SETS (fpsr);
return 0;
}
libm_hidden_def (feclearexcept)

View File

@ -0,0 +1,37 @@
/* Store current floating-point environment.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
#include <fenv.h>
#include <fpu_control.h>
int
__fegetenv (fenv_t *envp)
{
unsigned int fpcr;
unsigned int fpsr;
_FPU_GETCW (fpcr);
_FPU_GETS (fpsr);
envp->__fpcr = fpcr;
envp->__fpsr = fpsr;
return 0;
}
libm_hidden_def (__fegetenv)
weak_alias (__fegetenv, fegetenv)
libm_hidden_weak (fegetenv)

View File

@ -0,0 +1,31 @@
/* Store current floating-point control modes.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
#include <fenv.h>
#include <fpu_control.h>
int
fegetmode (femode_t *modep)
{
unsigned int fpcr;
_FPU_GETCW (fpcr);
*modep = fpcr;
return 0;
}

View File

@ -0,0 +1,32 @@
/* Return current rounding direction.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
#include <fenv.h>
#include <fenv_private.h>
int
__fegetround (void)
{
unsigned int fpcr;
_FPU_GETCW (fpcr);
return (fpcr >> __FPU_RND_SHIFT) & __FPU_RND_MASK;
}
libm_hidden_def (__fegetround)
weak_alias (__fegetround, fegetround)
libm_hidden_weak (fegetround)

View File

@ -0,0 +1,43 @@
/* Store current floating-point environment and clear exceptions.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
#include <fenv.h>
#include <fenv_private.h>
int
__feholdexcept (fenv_t *envp)
{
unsigned int fpcr;
unsigned int fpsr;
_FPU_GETCW (fpcr);
_FPU_GETS (fpsr);
envp->__fpcr = fpcr;
envp->__fpsr = fpsr;
fpsr &= ~FE_ALL_EXCEPT;
_FPU_SETCW (fpcr);
_FPU_SETS (fpsr);
return 0;
}
libm_hidden_def (__feholdexcept)
weak_alias (__feholdexcept, feholdexcept)
libm_hidden_weak (feholdexcept)

View File

@ -0,0 +1,48 @@
/* Install given floating-point environment (doesnot raise exceptions).
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
#include <fenv.h>
#include <fpu_control.h>
int
__fesetenv (const fenv_t *envp)
{
unsigned int fpcr;
unsigned int fpsr;
if (envp == FE_DFL_ENV)
{
fpcr = _FPU_DEFAULT;
fpsr = _FPU_FPSR_DEFAULT;
}
else
{
/* No need to mask out reserved bits as they are IoW. */
fpcr = envp->__fpcr;
fpsr = envp->__fpsr;
}
_FPU_SETCW (fpcr);
_FPU_SETS (fpsr);
/* Success. */
return 0;
}
libm_hidden_def (__fesetenv)
weak_alias (__fesetenv, fesetenv)
libm_hidden_weak (fesetenv)

View File

@ -0,0 +1,32 @@
/* Set given exception flags.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
#include <fenv.h>
#include <fpu_control.h>
int
fesetexcept (int excepts)
{
unsigned int fpsr;
_FPU_GETS (fpsr);
fpsr |= excepts;
_FPU_SETS (fpsr);
return 0;
}

View File

@ -0,0 +1,40 @@
/* Install given floating-point control modes.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
#include <fenv.h>
#include <fpu_control.h>
int
fesetmode (const femode_t *modep)
{
unsigned int fpcr;
if (modep == FE_DFL_MODE)
{
fpcr = _FPU_DEFAULT;
}
else
{
/* No need to mask out reserved bits as they are IoW. */
fpcr = *modep;
}
_FPU_SETCW (fpcr);
return 0;
}

View File

@ -0,0 +1,40 @@
/* Set current rounding direction.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
#include <fenv.h>
#include <fenv_private.h>
int
__fesetround (int round)
{
unsigned int fpcr;
_FPU_GETCW (fpcr);
if (((fpcr >> __FPU_RND_SHIFT) & __FPU_RND_MASK) != round)
{
fpcr &= ~(__FPU_RND_MASK << __FPU_RND_SHIFT);
fpcr |= (round & __FPU_RND_MASK) << __FPU_RND_SHIFT;
_FPU_SETCW (fpcr);
}
return 0;
}
libm_hidden_def (__fesetround)
weak_alias (__fesetround, fesetround)
libm_hidden_weak (fesetround)

View File

@ -0,0 +1,51 @@
/* Install given floating-point environment and raise exceptions,
without clearing currently raised exceptions.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
#include <fenv.h>
#include <fpu_control.h>
int
__feupdateenv (const fenv_t *envp)
{
unsigned int fpcr;
unsigned int fpsr;
_FPU_GETS (fpsr);
if (envp == FE_DFL_ENV)
{
fpcr = _FPU_DEFAULT;
}
else
{
fpcr = envp->__fpcr;
/* currently raised exceptions need to be preserved. */
fpsr |= envp->__fpsr;
}
_FPU_SETCW (fpcr);
_FPU_SETS (fpsr);
/* Success. */
return 0;
}
libm_hidden_def (__feupdateenv)
weak_alias (__feupdateenv, feupdateenv)
libm_hidden_weak (feupdateenv)

View File

@ -0,0 +1,31 @@
/* Store current representation for exceptions, ARC version.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
#include <fenv.h>
#include <fenv_private.h>
int
fegetexceptflag (fexcept_t *flagp, int excepts)
{
unsigned int fpsr;
_FPU_GETS (fpsr);
*flagp = fpsr & excepts;
return 0;
}

View File

@ -0,0 +1,39 @@
/* Raise given exceptions.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
#include <fenv.h>
#include <fpu_control.h>
#include <float.h>
#include <math.h>
int
__feraiseexcept (int excepts)
{
unsigned int fpsr;
/* currently raised exceptions are not cleared. */
_FPU_GETS (fpsr);
fpsr |= excepts;
_FPU_SETS (fpsr);
return 0;
}
libm_hidden_def (__feraiseexcept)
weak_alias (__feraiseexcept, feraiseexcept)
libm_hidden_weak (feraiseexcept)

View File

@ -0,0 +1,38 @@
/* Set floating-point environment exception handling, ARC version.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
#include <fenv.h>
#include <fpu_control.h>
int
fesetexceptflag (const fexcept_t *flagp, int excepts)
{
unsigned int fpsr;
_FPU_GETS (fpsr);
/* Clear the bits first. */
fpsr &= ~excepts;
/* Now set those bits, copying them over from @flagp. */
fpsr |= *flagp & excepts;
_FPU_SETS (fpsr);
return 0;
}

View File

@ -0,0 +1,33 @@
/* Test exception in current environment.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
#include <fenv.h>
#include <fpu_control.h>
#include <fenv_private.h>
#include <stdio.h>
int
fetestexcept (int excepts)
{
unsigned int fpsr;
_FPU_GETS (fpsr);
return fpsr & excepts;
}
libm_hidden_def (fetestexcept)

View File

@ -0,0 +1,4 @@
#define USE_FMA_BUILTIN 1
#define USE_FMAF_BUILTIN 1
#define USE_FMAL_BUILTIN 0
#define USE_FMAF128_BUILTIN 0

View File

@ -0,0 +1,4 @@
#define USE_SQRT_BUILTIN 1
#define USE_SQRTF_BUILTIN 1
#define USE_SQRTL_BUILTIN 0
#define USE_SQRTF128_BUILTIN 0

106
sysdeps/arc/fpu_control.h Normal file
View File

@ -0,0 +1,106 @@
/* FPU control word bits. ARC version.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
#ifndef _FPU_CONTROL_H
#define _FPU_CONTROL_H
/* ARC FPU control register bits.
[ 0] -> IVE: Enable invalid operation exception.
if 0, soft exception: status register IV flag set.
if 1, hardware exception trap (not supported in Linux yet).
[ 1] -> DZE: Enable division by zero exception.
if 0, soft exception: status register IV flag set.
if 1, hardware exception: (not supported in Linux yet).
[9:8] -> RM: Rounding Mode:
00 - Rounding toward zero.
01 - Rounding to nearest (default).
10 - Rounding (up) toward plus infinity.
11 - Rounding (down)toward minus infinity.
ARC FPU status register bits.
[ 0] -> IV: flag invalid operation.
[ 1] -> DZ: flag division by zero.
[ 2] -> OV: flag Overflow operation.
[ 3] -> UV: flag Underflow operation.
[ 4] -> IX: flag Inexact operation.
[31] -> FWE: Flag Write Enable.
If 1, above flags writable explicitly (clearing),
else IoW and only writable indirectly via bits [12:7]. */
#include <features.h>
#if !defined(__ARC_FPU_SP__) && !defined(__ARC_FPU_DP__)
# define _FPU_RESERVED 0xffffffff
# define _FPU_DEFAULT 0x00000000
typedef unsigned int fpu_control_t;
# define _FPU_GETCW(cw) (cw) = 0
# define _FPU_SETCW(cw) (void) (cw)
# define _FPU_GETS(cw) (cw) = 0
# define _FPU_SETS(cw) (void) (cw)
extern fpu_control_t __fpu_control;
#else
#define _FPU_RESERVED 0
/* The fdlibm code requires strict IEEE double precision arithmetic,
and no interrupts for exceptions, rounding to nearest.
So only RM set to b'01. */
# define _FPU_DEFAULT 0x00000100
/* Actually default needs to have FWE bit as 1 but that is already
ingrained into _FPU_SETS macro below. */
#define _FPU_FPSR_DEFAULT 0x00000000
#define __FPU_RND_SHIFT 8
#define __FPU_RND_MASK 0x3
/* Type of the control word. */
typedef unsigned int fpu_control_t;
/* Macros for accessing the hardware control word. */
# define _FPU_GETCW(cw) __asm__ volatile ("lr %0, [0x300]" : "=r" (cw))
# define _FPU_SETCW(cw) __asm__ volatile ("sr %0, [0x300]" : : "r" (cw))
/* Macros for accessing the hardware status word.
FWE bit is special as it controls if actual status bits could be wrritten
explicitly (other than FPU instructions). We handle it here to keep the
callers agnostic of it:
- clear it out when reporting status bits
- always set it when changing status bits. */
# define _FPU_GETS(cw) \
__asm__ volatile ("lr %0, [0x301] \r\n" \
"bclr %0, %0, 31 \r\n" \
: "=r" (cw))
# define _FPU_SETS(cw) \
do { \
unsigned int __tmp = 0x80000000 | (cw); \
__asm__ volatile ("sr %0, [0x301] \r\n" \
: : "r" (__tmp)); \
} while (0)
/* Default control word set at startup. */
extern fpu_control_t __fpu_control;
#endif
#endif /* fpu_control.h */

View File

@ -0,0 +1,38 @@
/* Determine floating-point rounding mode within libc. ARC version.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
#ifndef _ARC_GET_ROUNDING_MODE_H
#define _ARC_GET_ROUNDING_MODE_H 1
#include <fenv.h>
#include <fpu_control.h>
static inline int
get_rounding_mode (void)
{
#if defined(__ARC_FPU_SP__) || defined(__ARC_FPU_DP__)
unsigned int fpcr;
_FPU_GETCW (fpcr);
return (fpcr >> __FPU_RND_SHIFT) & __FPU_RND_MASK;
#else
return FE_TONEAREST;
#endif
}
#endif /* get-rounding-mode.h */

View File

@ -0,0 +1,27 @@
/* Configuration for math tests: support for enabling exception traps.
ARC version.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#ifndef ARC_MATH_TESTS_TRAP_H
#define ARC_MATH_TESTS_TRAP_H 1
/* Trapping exceptions are optional on ARC
and not supported in Linux kernel just yet. */
#define EXCEPTION_ENABLE_SUPPORTED(EXCEPT) ((EXCEPT) == 0)
#endif /* math-tests-trap.h. */

1
sysdeps/arc/tininess.h Normal file
View File

@ -0,0 +1 @@
#define TININESS_AFTER_ROUNDING 1