diff options
author | Marcus Shawcroft <marcus.shawcroft@linaro.org> | 2012-11-09 17:53:51 +0000 |
---|---|---|
committer | Marcus Shawcroft <marcus.shawcroft@linaro.org> | 2012-11-09 17:54:04 +0000 |
commit | 554066b83b1a0d14e6e7a24a45ef3f65342aae76 (patch) | |
tree | 5425871b9ce8abc1ae10dbc711b2b287b139e40a /ports/sysdeps/aarch64/fpu | |
parent | 2c1adbcb765ae5ce9114970324590bbb735c5051 (diff) | |
download | glibc-554066b83b1a0d14e6e7a24a45ef3f65342aae76.tar.gz glibc-554066b83b1a0d14e6e7a24a45ef3f65342aae76.tar.xz glibc-554066b83b1a0d14e6e7a24a45ef3f65342aae76.zip |
AArch64 Port
Diffstat (limited to 'ports/sysdeps/aarch64/fpu')
-rw-r--r-- | ports/sysdeps/aarch64/fpu/fclrexcpt.c | 36 | ||||
-rw-r--r-- | ports/sysdeps/aarch64/fpu/fedisblxcpt.c | 39 | ||||
-rw-r--r-- | ports/sysdeps/aarch64/fpu/feenablxcpt.c | 39 | ||||
-rw-r--r-- | ports/sysdeps/aarch64/fpu/fegetenv.c | 33 | ||||
-rw-r--r-- | ports/sysdeps/aarch64/fpu/fegetexcept.c | 28 | ||||
-rw-r--r-- | ports/sysdeps/aarch64/fpu/fegetround.c | 28 | ||||
-rw-r--r-- | ports/sysdeps/aarch64/fpu/feholdexcpt.c | 47 | ||||
-rw-r--r-- | ports/sysdeps/aarch64/fpu/fesetenv.c | 57 | ||||
-rw-r--r-- | ports/sysdeps/aarch64/fpu/fesetround.c | 46 | ||||
-rw-r--r-- | ports/sysdeps/aarch64/fpu/feupdateenv.c | 38 | ||||
-rw-r--r-- | ports/sysdeps/aarch64/fpu/fgetexcptflg.c | 33 | ||||
-rw-r--r-- | ports/sysdeps/aarch64/fpu/fpu_control.h | 81 | ||||
-rw-r--r-- | ports/sysdeps/aarch64/fpu/fraiseexcpt.c | 92 | ||||
-rw-r--r-- | ports/sysdeps/aarch64/fpu/fsetexcptflg.c | 39 | ||||
-rw-r--r-- | ports/sysdeps/aarch64/fpu/ftestexcept.c | 32 | ||||
-rw-r--r-- | ports/sysdeps/aarch64/fpu/get-rounding-mode.h | 38 | ||||
-rw-r--r-- | ports/sysdeps/aarch64/fpu/s_fma.c | 2 |
17 files changed, 708 insertions, 0 deletions
diff --git a/ports/sysdeps/aarch64/fpu/fclrexcpt.c b/ports/sysdeps/aarch64/fpu/fclrexcpt.c new file mode 100644 index 0000000000..75c23f6358 --- /dev/null +++ b/ports/sysdeps/aarch64/fpu/fclrexcpt.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1997-2012 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 + <http://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +feclearexcept (int excepts) +{ + fpu_fpsr_t fpsr; + + excepts &= FE_ALL_EXCEPT; + + _FPU_GETFPSR (fpsr); + fpsr = (fpsr & ~FE_ALL_EXCEPT) | (fpsr & FE_ALL_EXCEPT & ~excepts); + + _FPU_SETFPSR (fpsr); + + return 0; +} +libm_hidden_def (feclearexcept) diff --git a/ports/sysdeps/aarch64/fpu/fedisblxcpt.c b/ports/sysdeps/aarch64/fpu/fedisblxcpt.c new file mode 100644 index 0000000000..12aca3453a --- /dev/null +++ b/ports/sysdeps/aarch64/fpu/fedisblxcpt.c @@ -0,0 +1,39 @@ +/* Copyright (C) 2001-2012 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 + <http://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +fedisableexcept (int excepts) +{ + fpu_control_t fpcr; + int original_excepts; + + _FPU_GETCW (fpcr); + + original_excepts = (fpcr >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT; + + excepts &= FE_ALL_EXCEPT; + + fpcr &= ~(excepts << FE_EXCEPT_SHIFT); + + _FPU_SETCW (fpcr); + + return original_excepts; +} diff --git a/ports/sysdeps/aarch64/fpu/feenablxcpt.c b/ports/sysdeps/aarch64/fpu/feenablxcpt.c new file mode 100644 index 0000000000..e70f349ff0 --- /dev/null +++ b/ports/sysdeps/aarch64/fpu/feenablxcpt.c @@ -0,0 +1,39 @@ +/* Copyright (C) 2001-2012 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 + <http://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +feenableexcept (int excepts) +{ + fpu_control_t fpcr; + int original_excepts; + + _FPU_GETCW (fpcr); + + original_excepts = (fpcr >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT; + + excepts &= FE_ALL_EXCEPT; + + fpcr |= (excepts << FE_EXCEPT_SHIFT); + + _FPU_SETCW (fpcr); + + return original_excepts; +} diff --git a/ports/sysdeps/aarch64/fpu/fegetenv.c b/ports/sysdeps/aarch64/fpu/fegetenv.c new file mode 100644 index 0000000000..3725d6c85e --- /dev/null +++ b/ports/sysdeps/aarch64/fpu/fegetenv.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1997-2012 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 + <http://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +fegetenv (fenv_t *envp) +{ + fpu_control_t fpcr; + fpu_fpsr_t fpsr; + _FPU_GETCW (fpcr); + _FPU_GETFPSR (fpsr); + envp->__fpcr = fpcr; + envp->__fpsr = fpsr; + return 0; +} +libm_hidden_def (fegetenv) diff --git a/ports/sysdeps/aarch64/fpu/fegetexcept.c b/ports/sysdeps/aarch64/fpu/fegetexcept.c new file mode 100644 index 0000000000..7217e78e59 --- /dev/null +++ b/ports/sysdeps/aarch64/fpu/fegetexcept.c @@ -0,0 +1,28 @@ +/* Copyright (C) 2001-2012 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 + <http://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +fegetexcept (void) +{ + fpu_control_t fpcr; + _FPU_GETCW (fpcr); + return (fpcr >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT; +} diff --git a/ports/sysdeps/aarch64/fpu/fegetround.c b/ports/sysdeps/aarch64/fpu/fegetround.c new file mode 100644 index 0000000000..969a86463e --- /dev/null +++ b/ports/sysdeps/aarch64/fpu/fegetround.c @@ -0,0 +1,28 @@ +/* Copyright (C) 1997-2012 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 + <http://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +fegetround (void) +{ + fpu_control_t fpcr; + _FPU_GETCW (fpcr); + return fpcr & FE_TOWARDZERO; +} diff --git a/ports/sysdeps/aarch64/fpu/feholdexcpt.c b/ports/sysdeps/aarch64/fpu/feholdexcpt.c new file mode 100644 index 0000000000..8c045271dd --- /dev/null +++ b/ports/sysdeps/aarch64/fpu/feholdexcpt.c @@ -0,0 +1,47 @@ +/* Copyright (C) 1997-2012 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 + <http://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +feholdexcept (fenv_t *envp) +{ + fpu_fpsr_t fpsr; + fpu_control_t fpcr; + + _FPU_GETCW (fpcr); + envp->__fpcr = fpcr; + + _FPU_GETFPSR (fpsr); + envp->__fpsr = fpsr; + + /* Now set all exceptions to non-stop. */ + fpcr &= ~(FE_ALL_EXCEPT << FE_EXCEPT_SHIFT); + + /* And clear all exception flags. */ + fpsr &= ~FE_ALL_EXCEPT; + + _FPU_SETFPSR (fpsr); + + _FPU_SETCW (fpcr); + + return 0; +} + +libm_hidden_def (feholdexcept) diff --git a/ports/sysdeps/aarch64/fpu/fesetenv.c b/ports/sysdeps/aarch64/fpu/fesetenv.c new file mode 100644 index 0000000000..ec7da21ac3 --- /dev/null +++ b/ports/sysdeps/aarch64/fpu/fesetenv.c @@ -0,0 +1,57 @@ +/* Copyright (C) 1997-2012 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 + <http://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +fesetenv (const fenv_t *envp) +{ + fpu_control_t fpcr; + fpu_fpsr_t fpsr; + + _FPU_GETCW (fpcr); + _FPU_GETFPSR (fpsr); + + fpcr &= _FPU_RESERVED; + fpsr &= _FPU_FPSR_RESERVED; + + if (envp == FE_DFL_ENV) + { + fpcr |= _FPU_DEFAULT; + fpsr |= _FPU_FPSR_DEFAULT; + } + else if (envp == FE_NOMASK_ENV) + { + fpcr |= _FPU_FPCR_IEEE; + fpsr |= _FPU_FPSR_IEEE; + } + else + { + fpcr |= envp->__fpcr & ~_FPU_RESERVED; + fpsr |= envp->__fpsr & ~_FPU_FPSR_RESERVED; + } + + _FPU_SETFPSR (fpsr); + + _FPU_SETCW (fpcr); + + return 0; +} + +libm_hidden_def (fesetenv) diff --git a/ports/sysdeps/aarch64/fpu/fesetround.c b/ports/sysdeps/aarch64/fpu/fesetround.c new file mode 100644 index 0000000000..ef142b3a46 --- /dev/null +++ b/ports/sysdeps/aarch64/fpu/fesetround.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1997-2012 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 + <http://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +fesetround (int round) +{ + fpu_control_t fpcr; + + switch (round) + { + case FE_TONEAREST: + case FE_UPWARD: + case FE_DOWNWARD: + case FE_TOWARDZERO: + _FPU_GETCW (fpcr); + fpcr = (fpcr & ~FE_TOWARDZERO) | round; + + _FPU_SETCW (fpcr); + return 0; + + default: + return 1; + } + + return 1; +} + +libm_hidden_def (fesetround) diff --git a/ports/sysdeps/aarch64/fpu/feupdateenv.c b/ports/sysdeps/aarch64/fpu/feupdateenv.c new file mode 100644 index 0000000000..6e14e79a3f --- /dev/null +++ b/ports/sysdeps/aarch64/fpu/feupdateenv.c @@ -0,0 +1,38 @@ +/* Copyright (C) 2009-2012 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 + <http://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +feupdateenv (const fenv_t *envp) +{ + fpu_fpsr_t fpsr; + + /* Get the current exception state. */ + _FPU_GETFPSR (fpsr); + + /* Install new environment. */ + fesetenv (envp); + + /* Raise the saved exceptions. */ + feraiseexcept (fpsr & FE_ALL_EXCEPT); + + return 0; +} +libm_hidden_def (feupdateenv) diff --git a/ports/sysdeps/aarch64/fpu/fgetexcptflg.c b/ports/sysdeps/aarch64/fpu/fgetexcptflg.c new file mode 100644 index 0000000000..49aefedfe7 --- /dev/null +++ b/ports/sysdeps/aarch64/fpu/fgetexcptflg.c @@ -0,0 +1,33 @@ +/* Copyright (C) 2001-2012 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 + <http://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +fegetexceptflag (fexcept_t *flagp, int excepts) +{ + fpu_fpsr_t fpsr; + + /* Get the current exceptions. */ + _FPU_GETFPSR (fpsr); + + *flagp = fpsr & excepts & FE_ALL_EXCEPT; + + return 0; +} diff --git a/ports/sysdeps/aarch64/fpu/fpu_control.h b/ports/sysdeps/aarch64/fpu/fpu_control.h new file mode 100644 index 0000000000..fdf590edc2 --- /dev/null +++ b/ports/sysdeps/aarch64/fpu/fpu_control.h @@ -0,0 +1,81 @@ +/* Copyright (C) 1996-2012 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 + <http://www.gnu.org/licenses/>. */ + +#ifndef _AARCH64_FPU_CONTROL_H +#define _AARCH64_FPU_CONTROL_H + +/* Macros for accessing the FPCR and FPSR. */ + +#define _FPU_GETCW(fpcr) \ + __asm__ __volatile__ ("mrs %0, fpcr" : "=r" (fpcr)) + +#define _FPU_SETCW(fpcr) \ + { \ + __asm__ __volatile__ ("msr fpcr, %0" : : "r" (fpcr)); \ + __asm__ __volatile__ ("isb"); \ + } + +#define _FPU_GETFPSR(fpsr) \ + __asm__ __volatile__ ("mrs %0, fpsr" : "=r" (fpsr)) + +#define _FPU_SETFPSR(fpsr) \ + __asm__ __volatile__ ("msr fpsr, %0" : : "r" (fpsr)) + +/* Reserved bits should be preserved when modifying register + contents. These two masks indicate which bits in each of FPCR and + FPSR should not be changed. */ + +#define _FPU_RESERVED 0xfe0fe0ff +#define _FPU_FPSR_RESERVED 0x0fffffe0 + +#define _FPU_DEFAULT 0x00000000 +#define _FPU_FPSR_DEFAULT 0x00000000 + +/* Layout of FPCR and FPSR: + + | | | | | | | | + 0 0 0 0 1 1 1 0 0 0 0 0 1 0 0 0 1 1 1 0 0 0 0 0 1 1 1 0 0 0 0 0 + s s s s s s s s s s s + c c c c c c c c c c c c + N Z C V Q A D F R R S S S L L L I U U I U O D I I U U I U O D I + C H N Z M M T T B E E E D N N X F F Z O D N N X F F Z O + P O O R R Z N N N E K K E E E E E C K K C C C C C + D D I I P + E E D D + E E + */ +#define _FPU_FPCR_MASK_IXE 0x1000 +#define _FPU_FPCR_MASK_UFE 0x0800 +#define _FPU_FPCR_MASK_OFE 0x0400 +#define _FPU_FPCR_MASK_DZE 0x0200 +#define _FPU_FPCR_MASK_IOE 0x0100 + +#define _FPU_FPCR_IEEE \ + (_FPU_DEFAULT | _FPU_FPCR_MASK_IXE | \ + _FPU_FPCR_MASK_UFE | _FPU_FPCR_MASK_OFE | \ + _FPU_FPCR_MASK_DZE | _FPU_FPCR_MASK_IOE) + +#define _FPU_FPSR_IEEE 0 + +typedef unsigned int fpu_control_t; +typedef unsigned int fpu_fpsr_t; + +/* Default control word set at startup. */ +extern fpu_control_t __fpu_control; + +#endif diff --git a/ports/sysdeps/aarch64/fpu/fraiseexcpt.c b/ports/sysdeps/aarch64/fpu/fraiseexcpt.c new file mode 100644 index 0000000000..ad5b73ae3a --- /dev/null +++ b/ports/sysdeps/aarch64/fpu/fraiseexcpt.c @@ -0,0 +1,92 @@ +/* Copyright (C) 1997-2012 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 + <http://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> +#include <float.h> + +int +feraiseexcept (int excepts) +{ + int fpsr; + const float fp_zero = 0.0; + const float fp_one = 1.0; + const float fp_max = FLT_MAX; + const float fp_min = FLT_MIN; + const float fp_1e32 = 1.0e32f; + const float fp_two = 2.0; + const float fp_three = 3.0; + + /* Raise exceptions represented by EXCEPTS. But we must raise only + one signal at a time. It is important that if the OVERFLOW or + UNDERFLOW exception and the inexact exception are given at the + same time, the OVERFLOW or UNDERFLOW exception precedes the + INEXACT exception. + + After each exception we read from the FPSR, to force the + exception to be raised immediately. */ + + if (FE_INVALID & excepts) + __asm__ __volatile__ ( + "ldr s0, %1\n\t" + "fdiv s0, s0, s0\n\t" + "mrs %0, fpsr" : "=r" (fpsr) + : "m" (fp_zero) + : "d0"); + + if (FE_DIVBYZERO & excepts) + __asm__ __volatile__ ( + "ldr s0, %1\n\t" + "ldr s1, %2\n\t" + "fdiv s0, s0, s1\n\t" + "mrs %0, fpsr" : "=r" (fpsr) + : "m" (fp_one), "m" (fp_zero) + : "d0", "d1"); + + if (FE_OVERFLOW & excepts) + /* There's no way to raise overflow without also raising inexact. */ + __asm__ __volatile__ ( + "ldr s0, %1\n\t" + "ldr s1, %2\n\t" + "fadd s0, s0, s1\n\t" + "mrs %0, fpsr" : "=r" (fpsr) + : "m" (fp_max), "m" (fp_1e32) + : "d0", "d1"); + + if (FE_UNDERFLOW & excepts) + __asm__ __volatile__ ( + "ldr s0, %1\n\t" + "ldr s1, %2\n\t" + "fdiv s0, s0, s1\n\t" + "mrs %0, fpsr" : "=r" (fpsr) + : "m" (fp_min), "m" (fp_three) + : "d0", "d1"); + + if (FE_INEXACT & excepts) + __asm__ __volatile__ ( + "ldr s0, %1\n\t" + "ldr s1, %2\n\t" + "fdiv s0, s0, s1\n\t" + "mrs %0, fpsr" : "=r" (fpsr) + : "m" (fp_two), "m" (fp_three) + : "d0", "d1"); + + return 0; +} + +libm_hidden_def (feraiseexcept) diff --git a/ports/sysdeps/aarch64/fpu/fsetexcptflg.c b/ports/sysdeps/aarch64/fpu/fsetexcptflg.c new file mode 100644 index 0000000000..142cd14e92 --- /dev/null +++ b/ports/sysdeps/aarch64/fpu/fsetexcptflg.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1997-2012 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 + <http://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <math.h> +#include <fpu_control.h> + +int +fesetexceptflag (const fexcept_t *flagp, int excepts) +{ + fpu_fpsr_t fpsr; + + /* Get the current environment. */ + _FPU_GETFPSR (fpsr); + + /* Set the desired exception mask. */ + fpsr &= ~(excepts & FE_ALL_EXCEPT); + fpsr |= (*flagp & excepts & FE_ALL_EXCEPT); + + /* Save state back to the FPU. */ + _FPU_SETFPSR (fpsr); + + return 0; +} diff --git a/ports/sysdeps/aarch64/fpu/ftestexcept.c b/ports/sysdeps/aarch64/fpu/ftestexcept.c new file mode 100644 index 0000000000..e0d4c2e58d --- /dev/null +++ b/ports/sysdeps/aarch64/fpu/ftestexcept.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1997-2012 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 + <http://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +fetestexcept (int excepts) +{ + fpu_fpsr_t fpsr; + + /* Get current exceptions. */ + _FPU_GETFPSR (fpsr); + + return fpsr & excepts & FE_ALL_EXCEPT; +} +libm_hidden_def (fetestexcept) diff --git a/ports/sysdeps/aarch64/fpu/get-rounding-mode.h b/ports/sysdeps/aarch64/fpu/get-rounding-mode.h new file mode 100644 index 0000000000..4c29b325dc --- /dev/null +++ b/ports/sysdeps/aarch64/fpu/get-rounding-mode.h @@ -0,0 +1,38 @@ +/* Determine floating-point rounding mode within libc. AArch64 version. + + Copyright (C) 2012 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 + <http://www.gnu.org/licenses/>. */ + +#ifndef _AARCH64_GET_ROUNDING_MODE_H +#define _AARCH64_GET_ROUNDING_MODE_H 1 + +#include <fenv.h> +#include <fpu_control.h> + +/* Return the floating-point rounding mode. */ + +static inline int +get_rounding_mode (void) +{ + fpu_control_t fpcr; + + _FPU_GETCW (fpcr); + return fpcr & FE_TOWARDZERO; +} + +#endif /* get-rounding-mode.h */ diff --git a/ports/sysdeps/aarch64/fpu/s_fma.c b/ports/sysdeps/aarch64/fpu/s_fma.c new file mode 100644 index 0000000000..8f62605870 --- /dev/null +++ b/ports/sysdeps/aarch64/fpu/s_fma.c @@ -0,0 +1,2 @@ +/* Always use dbl-64 version because long double is emulated in software. */ +#include <sysdeps/ieee754/dbl-64/s_fma.c> |