diff --git a/src/system/libroot/posix/glibc/arch/arm/Jamfile b/src/system/libroot/posix/glibc/arch/arm/Jamfile
index 56ef3e16cc..fc6e101675 100644
--- a/src/system/libroot/posix/glibc/arch/arm/Jamfile
+++ b/src/system/libroot/posix/glibc/arch/arm/Jamfile
@@ -3,15 +3,16 @@ SubDir HAIKU_TOP src system libroot posix glibc arch arm ;
SubDirSysHdrs $(HAIKU_TOP) src system libroot posix glibc include arch $(TARGET_ARCH) ;
SubDirSysHdrs $(HAIKU_TOP) src system libroot posix glibc include arch generic ;
SubDirSysHdrs $(HAIKU_TOP) src system libroot posix glibc include ;
-SubDirSysHdrs $(HAIKU_TOP) src system libroot posix glibc libio ;
SubDirSysHdrs $(HAIKU_TOP) src system libroot posix glibc stdlib ;
SubDirSysHdrs $(HAIKU_TOP) src system libroot posix glibc math ;
+SubDirSysHdrs $(HAIKU_TOP) src system libroot posix glibc libio ;
SubDirSysHdrs $(HAIKU_TOP) src system libroot posix glibc ;
SubDirHdrs $(HAIKU_TOP) src system libroot posix glibc arch generic ;
UsePrivateHeaders libroot ;
+
if $(OPTIM) = -O0 {
OPTIM = -O ;
}
@@ -21,67 +22,116 @@ DEBUG = 0 ;
SubDirCcFlags -D_GNU_SOURCE -D_IEEE_LIBM ;
+# Note: There is no *l() support yet. Our compiler says sizeof(long double) = 8,
+# while there are only 96 and 128 bit implementation in glibc.
local genericSources =
lshift.c rshift.c submul_1.c
- s_finite.c s_finitef.c
add_n.c sub_n.c
addmul_1.c mul_1.c
-
- cmp.c dbl2mpn.c divrem.c
- mpn2dbl.c mpn2flt.c mpn2ldbl.c
- mul.c mul_n.c
- s_isinf.c s_isinff.c
- s_isnan.c s_isnanf.c
- s_signbit.c s_signbitf.c
- s_nan.c s_nanf.c
- e_hypot.c e_hypotf.c
- w_hypot.c w_hypotf.c
- s_fpclassify.c s_fpclassifyf.c
- s_clog.c s_clogf.c
- s_log1p.c s_log1pf.c
- s_csqrt.c s_csqrtf.c
- s_floor.c s_floorf.c
- s_ceil.c s_ceilf.c
- s_modf.c
- w_powf.c e_powf.c
- w_pow.c e_pow.c slowpow.c
- w_exp.c e_exp.c slowexp.c
- s_frexp.c s_expm1.c
- dosincos.c
- doasin.c
- sincos32.c
branred.c
+ cmp.c dbl2mpn.c divrem.c
+ doasin.c dosincos.c
halfulp.c
- mpa.c mplog.c mpexp.c
- s_sin.c
- s_atan.c s_atanf.c
- s_tan.c
- e_asin.c e_asinl.c
- w_asin.c
- e_log10.c w_log10.c
- e_logf.c e_logl.c
- e_acos.c w_acos.c
- e_atan2.c
- w_atan2.c mpatan2.c mpatan.c mptan.c mpsqrt.c w_sqrt.c w_sqrtf.c
- e_sqrtl.c
- e_fmod.c w_fmod.c
- e_log.c w_log.c
- e_cosh.c w_cosh.c
- e_sinh.c w_sinh.c
- s_cosf.c k_cosf.c
- s_sinf.c k_sinf.c
- s_ldexp.c s_ldexpf.c
- s_scalbnf.c s_scalbn.c
- s_copysign.c s_copysignf.c
- s_tanh.c s_tanf.c k_tanf.c
- s_lround.c s_lroundf.c s_round.c s_roundf.c
- s_rint.c s_rintf.c s_lrintf.c
- e_fmodf.c w_fmodf.c
- e_atan2f.c w_atan2f.c
- e_rem_pio2f.c k_rem_pio2f.c
-
memrchr.c
+ mpa.c mpatan.c mpatan2.c mpexp.c mplog.c mpn2dbl.c
+ mpn2flt.c mpn2ldbl.c mpsqrt.c mptan.c
+ mul.c mul_n.c
+ sincos32.c
+ slowexp.c
+ slowpow.c
+
+ e_acos.c e_acosf.c # e_acosl.c
+ e_acosh.c e_acoshf.c # e_acoshl.c
+ e_asin.c e_asinf.c # e_asinl.c
+ e_atan2.c e_atan2f.c # e_atan2l.c
+ e_atanh.c e_atanhf.c # e_atanhl.c
+ e_cosh.c e_coshf.c # e_coshl.c
+ e_exp.c e_expf.c
+ e_fmod.c e_fmodf.c # e_fmodl.c
+ e_gamma_r.c e_gammaf_r.c
+ e_hypot.c e_hypotf.c # e_hypotl.c
+ e_j0.c e_j0f.c
+ e_j1.c e_j1f.c
+ e_jn.c e_jnf.c
+ e_lgamma_r.c e_lgammaf_r.c
+ e_log.c e_logf.c
+ e_log10.c e_log10f.c
+ e_pow.c e_powf.c # e_powl.c
+ e_rem_pio2f.c
+ e_remainder.c e_remainderf.c # e_remainderl.c
+ e_scalb.c e_scalbf.c # e_scalbl.c
+ e_sinh.c e_sinhf.c # e_sinhl.c
+ k_cos.c k_cosf.c
+ k_sin.c k_sinf.c
+ k_rem_pio2.c k_rem_pio2f.c # k_rem_pio2l.c
+ k_tan.c k_tanf.c
+ s_asinh.c s_asinhf.c # s_asinhl.c
+ s_atan.c s_atanf.c # s_atanl.c
+ s_cbrt.c s_cbrtf.c # s_cbrtl.c
+ s_ceil.c s_ceilf.c # s_ceill.c
+ s_cos.c s_cosf.c
+ s_copysign.c s_copysignf.c
+ s_erf.c s_erff.c # s_erfl.c
+ s_expm1f.c s_expm1.c
+ s_finite.c s_finitef.c # s_finitel.c
+ s_clog.c s_clogf.c # s_clogl.c
+ s_csqrt.c s_csqrtf.c # s_csqrtl.c
+ s_floor.c s_floorf.c # s_floorl.c
+ s_fabs.c s_fabsf.c
+ s_fdim.c s_fdimf.c
+ s_fma.c s_fmaf.c # s_fmal.c
+ s_fmax.c s_fmaxf.c
+ s_fmin.c s_fminf.c
+ s_fpclassify.c s_fpclassifyf.c # s_fpclassifyl.c
+ s_frexp.c s_frexpf.c # s_frexpl.c
+ s_ilogb.c s_ilogbf.c
+ s_isinf.c s_isinff.c # s_isinfl.c
+ s_isnan.c s_isnanf.c
+ s_ldexp.c s_ldexpf.c # s_ldexpl.c
+ s_llrint.c s_llrintf.c # s_llrintl.c
+ s_log1p.c s_log1pf.c
+ s_logb.c s_logbf.c # s_logbl.c
+ s_lrint.c s_lrintf.c # s_lrintl.c
+ s_lround.c s_lroundf.c
+ s_modf.c s_modff.c # s_modfl.c
+ s_nan.c s_nanf.c # s_nanl.c
+ # s_nexttoward.c s_nexttowardf.c s_nexttowardl.c
+ s_round.c s_roundf.c # s_roundl.c
+ s_rint.c s_rintf.c
+ s_scalbn.c s_scalbnf.c # s_scalbnl.c
+ s_signbit.c s_signbitf.c # s_signbitl.c
+ s_significand.c s_significandf.c
+ s_signgam.c
+ s_sin.c s_sinf.c # s_sinl.c
+ s_sincos.c s_sincosf.c
+ s_tan.c s_tanf.c
+ s_tanh.c s_tanhf.c
+ s_trunc.c s_truncf.c
+ t_exp.c
+ w_acos.c w_acosf.c # w_acosl.c
+ w_acosh.c w_acoshf.c # w_acoshl.c
+ w_atan2.c w_atan2f.c # w_atan2l.c
+ w_asin.c w_asinf.c # w_asinl.c
+ w_atanh.c w_atanhf.c # w_atanhl.c
+ w_cosh.c w_coshf.c # w_coshl.c
+ w_drem.c w_dremf.c # w_dreml.c
+ w_exp.c w_expf.c # w_expl.c
+ w_fmod.c w_fmodf.c # w_fmodl.c
+ w_hypot.c w_hypotf.c # w_hypotl.c
+ w_j0.c w_j0f.c
+ w_j1.c w_j1f.c
+ w_jn.c w_jnf.c
+ w_lgamma.c w_lgammaf.c
+ w_lgamma_r.c w_lgammaf_r.c
+ w_log.c w_logf.c # w_logl.c
+ w_log10.c w_log10f.c # w_log10l.c
+ w_pow.c w_powf.c # w_powl.c
+ w_remainder.c w_remainderf.c # w_remainderl.c
+ w_scalb.c w_scalbf.c # w_scalbl.c
+ w_sinh.c w_sinhf.c # w_sinhl.c
+ w_sqrt.c w_sqrtf.c
+ w_tgamma.c w_tgammaf.c # w_tgammal.c
;
local architectureObject ;
@@ -93,15 +143,16 @@ for architectureObject in [ MultiArchSubDirSetup arm ] {
$(genericSources)
;
- MergeObject <$(architecture)>posix_gnu_arch_$(TARGET_ARCH)_others.o :
- e_sqrt.c
- e_sqrtf.c
+ MergeObject <$(architecture)>posix_gnu_arch_$(TARGET_ARCH)_other.o :
+ e_sqrt.c e_sqrtf.c # e_sqrtl.c
+
+ feholdexcpt.c fesetenv.c fesetround.c fraiseexcpt.c
;
MergeObjectFromObjects <$(architecture)>posix_gnu_arch_$(TARGET_ARCH).o
: :
<$(architecture)>posix_gnu_arch_$(TARGET_ARCH)_generic.o
- <$(architecture)>posix_gnu_arch_$(TARGET_ARCH)_others.o
+ <$(architecture)>posix_gnu_arch_$(TARGET_ARCH)_other.o
;
SEARCH on [ FGristFiles $(genericSources) ]
diff --git a/src/system/libroot/posix/glibc/arch/arm/feholdexcpt.c b/src/system/libroot/posix/glibc/arch/arm/feholdexcpt.c
new file mode 100644
index 0000000000..8c146af1c4
--- /dev/null
+++ b/src/system/libroot/posix/glibc/arch/arm/feholdexcpt.c
@@ -0,0 +1,35 @@
+/* Store current floating-point environment and clear exceptions.
+ Copyright (C) 1997-2018 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
+ . */
+
+#include
+#include
+
+
+int
+__feholdexcept (fenv_t *envp)
+{
+ /* Fail if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return 1;
+
+ libc_feholdexcept_vfp (envp);
+ return 0;
+}
+libm_hidden_def (__feholdexcept)
+weak_alias (__feholdexcept, feholdexcept)
+libm_hidden_weak (feholdexcept)
diff --git a/src/system/libroot/posix/glibc/arch/arm/fesetenv.c b/src/system/libroot/posix/glibc/arch/arm/fesetenv.c
new file mode 100644
index 0000000000..6c3475a479
--- /dev/null
+++ b/src/system/libroot/posix/glibc/arch/arm/fesetenv.c
@@ -0,0 +1,66 @@
+/* Install given floating-point environment.
+ Copyright (C) 2004-2018 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
+ . */
+
+#include
+#include
+#include
+
+
+int
+__fesetenv (const fenv_t *envp)
+{
+ fpu_control_t fpscr, new_fpscr, updated_fpscr;
+
+ /* Fail if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return 1;
+
+ _FPU_GETCW (fpscr);
+
+ if ((envp != FE_DFL_ENV) && (envp != FE_NOMASK_ENV))
+ {
+ /* The new FPSCR is valid, so don't merge the reserved flags. */
+ new_fpscr = envp->__cw;
+
+ /* Write new FPSCR if different (ignoring NZCV flags). */
+ if (((fpscr ^ new_fpscr) & ~_FPU_MASK_NZCV) != 0)
+ _FPU_SETCW (new_fpscr);
+
+ return 0;
+ }
+
+ /* Preserve the reserved FPSCR flags. */
+ new_fpscr = fpscr & _FPU_RESERVED;
+ new_fpscr |= (envp == FE_DFL_ENV) ? _FPU_DEFAULT : _FPU_IEEE;
+
+ if (((new_fpscr ^ fpscr) & ~_FPU_MASK_NZCV) != 0)
+ {
+ _FPU_SETCW (new_fpscr);
+
+ /* Not all VFP architectures support trapping exceptions, so
+ test whether the relevant bits were set and fail if not. */
+ _FPU_GETCW (updated_fpscr);
+
+ return new_fpscr & ~updated_fpscr;
+ }
+
+ return 0;
+}
+libm_hidden_def (__fesetenv)
+weak_alias (__fesetenv, fesetenv)
+libm_hidden_weak (fesetenv)
diff --git a/src/system/libroot/posix/glibc/arch/arm/fesetround.c b/src/system/libroot/posix/glibc/arch/arm/fesetround.c
new file mode 100644
index 0000000000..379dfdca9d
--- /dev/null
+++ b/src/system/libroot/posix/glibc/arch/arm/fesetround.c
@@ -0,0 +1,39 @@
+/* Set current rounding direction.
+ Copyright (C) 2004-2018 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
+ . */
+
+#include
+#include
+
+
+int
+__fesetround (int round)
+{
+ /* FE_TONEAREST is the only supported rounding mode
+ if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return (round == FE_TONEAREST) ? 0 : 1;
+
+ if (round & ~_FPU_MASK_RM)
+ return 1;
+
+ libc_fesetround_vfp (round);
+ return 0;
+}
+libm_hidden_def (__fesetround)
+weak_alias (__fesetround, fesetround)
+libm_hidden_weak (fesetround)
diff --git a/src/system/libroot/posix/glibc/arch/arm/fraiseexcpt.c b/src/system/libroot/posix/glibc/arch/arm/fraiseexcpt.c
new file mode 100644
index 0000000000..2558b21204
--- /dev/null
+++ b/src/system/libroot/posix/glibc/arch/arm/fraiseexcpt.c
@@ -0,0 +1,107 @@
+/* Raise given exceptions.
+ Copyright (C) 2004-2018 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
+ . */
+
+#include
+#include
+#include
+#include
+
+
+int
+__feraiseexcept (int excepts)
+{
+ /* Fail if a VFP unit isn't present unless nothing needs to be done. */
+ if (!ARM_HAVE_VFP)
+ return (excepts != 0);
+ else
+ {
+ fpu_control_t fpscr;
+ const float fp_zero = 0.0, fp_one = 1.0, fp_max = FLT_MAX,
+ fp_min = FLT_MIN, fp_1e32 = 1.0e32f, fp_two = 2.0,
+ fp_three = 3.0;
+
+ /* Raise exceptions represented by EXPECTS. But we must raise only
+ one signal at a time. It is important that if the overflow/underflow
+ exception and the inexact exception are given at the same time,
+ the overflow/underflow exception follows the inexact exception. After
+ each exception we read from the fpscr, to force the exception to be
+ raised immediately. */
+
+ /* There are additional complications because this file may be compiled
+ without VFP support enabled, and we also can't assume that the
+ assembler has VFP instructions enabled. To get around this we use the
+ generic coprocessor mnemonics and avoid asking GCC to put float values
+ in VFP registers. */
+
+ /* First: invalid exception. */
+ if (FE_INVALID & excepts)
+ __asm__ __volatile__ (
+ "ldc p10, cr0, %1\n\t" /* flds s0, %1 */
+ "cdp p10, 8, cr0, cr0, cr0, 0\n\t" /* fdivs s0, s0, s0 */
+ "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr) /* fmrx %0, fpscr */
+ : "m" (fp_zero)
+ : "s0");
+
+ /* Next: division by zero. */
+ if (FE_DIVBYZERO & excepts)
+ __asm__ __volatile__ (
+ "ldc p10, cr0, %1\n\t" /* flds s0, %1 */
+ "ldcl p10, cr0, %2\n\t" /* flds s1, %2 */
+ "cdp p10, 8, cr0, cr0, cr0, 1\n\t" /* fdivs s0, s0, s1 */
+ "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr) /* fmrx %0, fpscr */
+ : "m" (fp_one), "m" (fp_zero)
+ : "s0", "s1");
+
+ /* Next: overflow. */
+ if (FE_OVERFLOW & excepts)
+ /* There's no way to raise overflow without also raising inexact. */
+ __asm__ __volatile__ (
+ "ldc p10, cr0, %1\n\t" /* flds s0, %1 */
+ "ldcl p10, cr0, %2\n\t" /* flds s1, %2 */
+ "cdp p10, 3, cr0, cr0, cr0, 1\n\t" /* fadds s0, s0, s1 */
+ "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr) /* fmrx %0, fpscr */
+ : "m" (fp_max), "m" (fp_1e32)
+ : "s0", "s1");
+
+ /* Next: underflow. */
+ if (FE_UNDERFLOW & excepts)
+ __asm__ __volatile__ (
+ "ldc p10, cr0, %1\n\t" /* flds s0, %1 */
+ "ldcl p10, cr0, %2\n\t" /* flds s1, %2 */
+ "cdp p10, 8, cr0, cr0, cr0, 1\n\t" /* fdivs s0, s0, s1 */
+ "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr) /* fmrx %0, fpscr */
+ : "m" (fp_min), "m" (fp_three)
+ : "s0", "s1");
+
+ /* Last: inexact. */
+ if (FE_INEXACT & excepts)
+ __asm__ __volatile__ (
+ "ldc p10, cr0, %1\n\t" /* flds s0, %1 */
+ "ldcl p10, cr0, %2\n\t" /* flds s1, %2 */
+ "cdp p10, 8, cr0, cr0, cr0, 1\n\t" /* fdivs s0, s0, s1 */
+ "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr) /* fmrx %0, fpscr */
+ : "m" (fp_two), "m" (fp_three)
+ : "s0", "s1");
+
+ /* Success. */
+ return 0;
+ }
+}
+libm_hidden_def (__feraiseexcept)
+weak_alias (__feraiseexcept, feraiseexcept)
+libm_hidden_weak (feraiseexcept)
diff --git a/src/system/libroot/posix/glibc/include/arch/arm/arm-features.h b/src/system/libroot/posix/glibc/include/arch/arm/arm-features.h
new file mode 100644
index 0000000000..69c4f9d604
--- /dev/null
+++ b/src/system/libroot/posix/glibc/include/arch/arm/arm-features.h
@@ -0,0 +1,59 @@
+/* Macros to test for CPU features on ARM. Generic ARM version.
+ Copyright (C) 2012-2018 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
+ . */
+
+#ifndef _ARM_ARM_FEATURES_H
+#define _ARM_ARM_FEATURES_H 1
+
+/* An OS-specific arm-features.h file should define ARM_HAVE_VFP to
+ an appropriate expression for testing at runtime whether the VFP
+ hardware is present. We'll then redefine it to a constant if we
+ know at compile time that we can assume VFP. */
+
+#ifndef __SOFTFP__
+/* The compiler is generating VFP instructions, so we're already
+ assuming the hardware exists. */
+# undef ARM_HAVE_VFP
+# define ARM_HAVE_VFP 1
+#endif
+
+/* An OS-specific arm-features.h file may define ARM_ASSUME_NO_IWMMXT
+ to indicate at compile time that iWMMXt hardware is never present
+ at runtime (or that we never care about its state) and so need not
+ be checked for. */
+
+/* A more-specific arm-features.h file may define ARM_ALWAYS_BX to indicate
+ that instructions using pc as a destination register must never be used,
+ so a "bx" (or "blx") instruction is always required. */
+
+/* The log2 of the minimum alignment required for an address that
+ is the target of a computed branch (i.e. a "bx" instruction).
+ A more-specific arm-features.h file may define this to set a more
+ stringent requirement.
+
+ Using this only makes sense for code in ARM mode (where instructions
+ always have a fixed size of four bytes), or for Thumb-mode code that is
+ specifically aligning all the related branch targets to match (since
+ Thumb instructions might be either two or four bytes). */
+#ifndef ARM_BX_ALIGN_LOG2
+# define ARM_BX_ALIGN_LOG2 2
+#endif
+
+/* An OS-specific arm-features.h file may define ARM_NO_INDEX_REGISTER to
+ indicate that the two-register addressing modes must never be used. */
+
+#endif /* arm-features.h */
diff --git a/src/system/libroot/posix/glibc/include/arch/arm/bits/fenv.h b/src/system/libroot/posix/glibc/include/arch/arm/bits/fenv.h
index 7bd242385f..d3bbbc0f06 100644
--- a/src/system/libroot/posix/glibc/include/arch/arm/bits/fenv.h
+++ b/src/system/libroot/posix/glibc/include/arch/arm/bits/fenv.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 2004-2018 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
@@ -12,9 +12,8 @@
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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library. If not, see
+ . */
#ifndef _FENV_H
# error "Never use directly; include instead."
@@ -23,36 +22,69 @@
/* Define bits representing exceptions in the FPU status word. */
enum
{
- FE_INVALID = 1,
-#define FE_INVALID FE_INVALID
- FE_DIVBYZERO = 2,
-#define FE_DIVBYZERO FE_DIVBYZERO
- FE_OVERFLOW = 4,
-#define FE_OVERFLOW FE_OVERFLOW
- FE_UNDERFLOW = 8,
-#define FE_UNDERFLOW FE_UNDERFLOW
+ FE_INVALID =
+#define FE_INVALID 1
+ FE_INVALID,
+ FE_DIVBYZERO =
+#define FE_DIVBYZERO 2
+ FE_DIVBYZERO,
+ FE_OVERFLOW =
+#define FE_OVERFLOW 4
+ FE_OVERFLOW,
+ FE_UNDERFLOW =
+#define FE_UNDERFLOW 8
+ FE_UNDERFLOW,
+ FE_INEXACT =
+#define FE_INEXACT 16
+ FE_INEXACT,
};
/* Amount to shift by to convert an exception to a mask bit. */
-#define FE_EXCEPT_SHIFT 16
+#define FE_EXCEPT_SHIFT 8
/* All supported exceptions. */
#define FE_ALL_EXCEPT \
- (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)
+ (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
-/* The ARM FPU basically only supports round-to-nearest. Other rounding
- modes exist, but you have to encode them in the actual instruction. */
+/* VFP supports all of the four defined rounding modes. */
+enum
+ {
+ FE_TONEAREST =
#define FE_TONEAREST 0
+ FE_TONEAREST,
+ FE_UPWARD =
+#define FE_UPWARD 0x400000
+ FE_UPWARD,
+ FE_DOWNWARD =
+#define FE_DOWNWARD 0x800000
+ FE_DOWNWARD,
+ FE_TOWARDZERO =
+#define FE_TOWARDZERO 0xc00000
+ FE_TOWARDZERO
+ };
/* Type representing exception flags. */
-typedef unsigned long int fexcept_t;
+typedef unsigned int fexcept_t;
/* Type representing floating-point environment. */
typedef struct
{
- unsigned long int __cw;
+ unsigned int __cw;
}
fenv_t;
/* If the default argument is used we use this value. */
-#define FE_DFL_ENV ((fenv_t *) -1l)
+#define FE_DFL_ENV ((const fenv_t *) -1l)
+
+#ifdef __USE_GNU
+/* Floating-point environment where none of the exceptions are masked. */
+# define FE_NOMASK_ENV ((const fenv_t *) -2)
+#endif
+
+#if 0 // __GLIBC_USE (IEC_60559_BFP_EXT)
+/* Type representing floating-point control modes. */
+typedef unsigned int femode_t;
+
+/* Default floating-point control modes. */
+# define FE_DFL_MODE ((const femode_t *) -1L)
+#endif
diff --git a/src/system/libroot/posix/glibc/include/arch/arm/fenv_private.h b/src/system/libroot/posix/glibc/include/arch/arm/fenv_private.h
new file mode 100644
index 0000000000..a60d676b0c
--- /dev/null
+++ b/src/system/libroot/posix/glibc/include/arch/arm/fenv_private.h
@@ -0,0 +1,251 @@
+/* Private floating point rounding and exceptions handling. ARM VFP version.
+ Copyright (C) 2014-2018 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
+ . */
+
+#ifndef FENV_PRIVATE_H
+#define FENV_PRIVATE_H 1
+
+#include
+#include
+
+# define __glibc_unlikely(x) __builtin_expect ((x), 0)
+
+static __always_inline void
+libc_feholdexcept_vfp (fenv_t *envp)
+{
+ fpu_control_t fpscr;
+
+ _FPU_GETCW (fpscr);
+ envp->__cw = fpscr;
+
+ /* Clear exception flags and set all exceptions to non-stop. */
+ fpscr &= ~_FPU_MASK_EXCEPT;
+ _FPU_SETCW (fpscr);
+}
+
+static __always_inline void
+libc_fesetround_vfp (int round)
+{
+ fpu_control_t fpscr;
+
+ _FPU_GETCW (fpscr);
+
+ /* Set new rounding mode if different. */
+ if (__glibc_unlikely ((fpscr & _FPU_MASK_RM) != round))
+ _FPU_SETCW ((fpscr & ~_FPU_MASK_RM) | round);
+}
+
+static __always_inline void
+libc_feholdexcept_setround_vfp (fenv_t *envp, int round)
+{
+ fpu_control_t fpscr;
+
+ _FPU_GETCW (fpscr);
+ envp->__cw = fpscr;
+
+ /* Clear exception flags, set all exceptions to non-stop,
+ and set new rounding mode. */
+ fpscr &= ~(_FPU_MASK_EXCEPT | _FPU_MASK_RM);
+ _FPU_SETCW (fpscr | round);
+}
+
+static __always_inline void
+libc_feholdsetround_vfp (fenv_t *envp, int round)
+{
+ fpu_control_t fpscr;
+
+ _FPU_GETCW (fpscr);
+ envp->__cw = fpscr;
+
+ /* Set new rounding mode if different. */
+ if (__glibc_unlikely ((fpscr & _FPU_MASK_RM) != round))
+ _FPU_SETCW ((fpscr & ~_FPU_MASK_RM) | round);
+}
+
+static __always_inline void
+libc_feresetround_vfp (fenv_t *envp)
+{
+ fpu_control_t fpscr, round;
+
+ _FPU_GETCW (fpscr);
+
+ /* Check whether rounding modes are different. */
+ round = (envp->__cw ^ fpscr) & _FPU_MASK_RM;
+
+ /* Restore the rounding mode if it was changed. */
+ if (__glibc_unlikely (round != 0))
+ _FPU_SETCW (fpscr ^ round);
+}
+
+static __always_inline int
+libc_fetestexcept_vfp (int ex)
+{
+ fpu_control_t fpscr;
+
+ _FPU_GETCW (fpscr);
+ return fpscr & ex & FE_ALL_EXCEPT;
+}
+
+static __always_inline void
+libc_fesetenv_vfp (const fenv_t *envp)
+{
+ fpu_control_t fpscr, new_fpscr;
+
+ _FPU_GETCW (fpscr);
+ new_fpscr = envp->__cw;
+
+ /* Write new FPSCR if different (ignoring NZCV flags). */
+ if (__glibc_unlikely (((fpscr ^ new_fpscr) & ~_FPU_MASK_NZCV) != 0))
+ _FPU_SETCW (new_fpscr);
+}
+
+static __always_inline int
+libc_feupdateenv_test_vfp (const fenv_t *envp, int ex)
+{
+ fpu_control_t fpscr, new_fpscr;
+ int excepts;
+
+ _FPU_GETCW (fpscr);
+
+ /* Merge current exception flags with the saved fenv. */
+ excepts = fpscr & FE_ALL_EXCEPT;
+ new_fpscr = envp->__cw | excepts;
+
+ /* Write new FPSCR if different (ignoring NZCV flags). */
+ if (__glibc_unlikely (((fpscr ^ new_fpscr) & ~_FPU_MASK_NZCV) != 0))
+ _FPU_SETCW (new_fpscr);
+
+ /* Raise the exceptions if enabled in the new FP state. */
+ if (__glibc_unlikely (excepts & (new_fpscr >> FE_EXCEPT_SHIFT)))
+ __feraiseexcept (excepts);
+
+ return excepts & ex;
+}
+
+static __always_inline void
+libc_feupdateenv_vfp (const fenv_t *envp)
+{
+ libc_feupdateenv_test_vfp (envp, 0);
+}
+
+static __always_inline void
+libc_feholdsetround_vfp_ctx (struct rm_ctx *ctx, int r)
+{
+ fpu_control_t fpscr, round;
+
+ _FPU_GETCW (fpscr);
+ ctx->updated_status = false;
+ ctx->env.__cw = fpscr;
+
+ /* Check whether rounding modes are different. */
+ round = (fpscr ^ r) & _FPU_MASK_RM;
+
+ /* Set the rounding mode if changed. */
+ if (__glibc_unlikely (round != 0))
+ {
+ ctx->updated_status = true;
+ _FPU_SETCW (fpscr ^ round);
+ }
+}
+
+static __always_inline void
+libc_feresetround_vfp_ctx (struct rm_ctx *ctx)
+{
+ /* Restore the rounding mode if updated. */
+ if (__glibc_unlikely (ctx->updated_status))
+ {
+ fpu_control_t fpscr;
+
+ _FPU_GETCW (fpscr);
+ fpscr = (fpscr & ~_FPU_MASK_RM) | (ctx->env.__cw & _FPU_MASK_RM);
+ _FPU_SETCW (fpscr);
+ }
+}
+
+static __always_inline void
+libc_fesetenv_vfp_ctx (struct rm_ctx *ctx)
+{
+ fpu_control_t fpscr, new_fpscr;
+
+ _FPU_GETCW (fpscr);
+ new_fpscr = ctx->env.__cw;
+
+ /* Write new FPSCR if different (ignoring NZCV flags). */
+ if (__glibc_unlikely (((fpscr ^ new_fpscr) & ~_FPU_MASK_NZCV) != 0))
+ _FPU_SETCW (new_fpscr);
+}
+
+#ifndef __SOFTFP__
+
+# define libc_feholdexcept libc_feholdexcept_vfp
+# define libc_feholdexceptf libc_feholdexcept_vfp
+# define libc_feholdexceptl libc_feholdexcept_vfp
+
+# define libc_fesetround libc_fesetround_vfp
+# define libc_fesetroundf libc_fesetround_vfp
+# define libc_fesetroundl libc_fesetround_vfp
+
+# define libc_feresetround libc_feresetround_vfp
+# define libc_feresetroundf libc_feresetround_vfp
+# define libc_feresetroundl libc_feresetround_vfp
+
+# define libc_feresetround_noex libc_fesetenv_vfp
+# define libc_feresetround_noexf libc_fesetenv_vfp
+# define libc_feresetround_noexl libc_fesetenv_vfp
+
+# define libc_feholdexcept_setround libc_feholdexcept_setround_vfp
+# define libc_feholdexcept_setroundf libc_feholdexcept_setround_vfp
+# define libc_feholdexcept_setroundl libc_feholdexcept_setround_vfp
+
+# define libc_feholdsetround libc_feholdsetround_vfp
+# define libc_feholdsetroundf libc_feholdsetround_vfp
+# define libc_feholdsetroundl libc_feholdsetround_vfp
+
+# define libc_fetestexcept libc_fetestexcept_vfp
+# define libc_fetestexceptf libc_fetestexcept_vfp
+# define libc_fetestexceptl libc_fetestexcept_vfp
+
+# define libc_fesetenv libc_fesetenv_vfp
+# define libc_fesetenvf libc_fesetenv_vfp
+# define libc_fesetenvl libc_fesetenv_vfp
+
+# define libc_feupdateenv libc_feupdateenv_vfp
+# define libc_feupdateenvf libc_feupdateenv_vfp
+# define libc_feupdateenvl libc_feupdateenv_vfp
+
+# define libc_feupdateenv_test libc_feupdateenv_test_vfp
+# define libc_feupdateenv_testf libc_feupdateenv_test_vfp
+# define libc_feupdateenv_testl libc_feupdateenv_test_vfp
+
+/* We have support for rounding mode context. */
+#define HAVE_RM_CTX 1
+
+# define libc_feholdsetround_ctx libc_feholdsetround_vfp_ctx
+# define libc_feresetround_ctx libc_feresetround_vfp_ctx
+# define libc_feresetround_noex_ctx libc_fesetenv_vfp_ctx
+
+# define libc_feholdsetroundf_ctx libc_feholdsetround_vfp_ctx
+# define libc_feresetroundf_ctx libc_feresetround_vfp_ctx
+# define libc_feresetround_noexf_ctx libc_fesetenv_vfp_ctx
+
+# define libc_feholdsetroundl_ctx libc_feholdsetround_vfp_ctx
+# define libc_feresetroundl_ctx libc_feresetround_vfp_ctx
+# define libc_feresetround_noexl_ctx libc_fesetenv_vfp_ctx
+
+#endif
+
+#endif /* FENV_PRIVATE_H */
diff --git a/src/system/libroot/posix/glibc/include/arch/arm/fpu_control.h b/src/system/libroot/posix/glibc/include/arch/arm/fpu_control.h
new file mode 100644
index 0000000000..6b1b176eae
--- /dev/null
+++ b/src/system/libroot/posix/glibc/include/arch/arm/fpu_control.h
@@ -0,0 +1,75 @@
+/* FPU control word definitions. ARM VFP version.
+ Copyright (C) 2004-2018 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
+ . */
+
+#ifndef _FPU_CONTROL_H
+#define _FPU_CONTROL_H
+
+#if !(defined(_LIBC) && !defined(_LIBC_TEST)) && defined(__SOFTFP__)
+
+#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)
+extern fpu_control_t __fpu_control;
+
+#else
+
+/* masking of interrupts */
+#define _FPU_MASK_IM 0x00000100 /* invalid operation */
+#define _FPU_MASK_ZM 0x00000200 /* divide by zero */
+#define _FPU_MASK_OM 0x00000400 /* overflow */
+#define _FPU_MASK_UM 0x00000800 /* underflow */
+#define _FPU_MASK_PM 0x00001000 /* inexact */
+
+#define _FPU_MASK_NZCV 0xf0000000 /* NZCV flags */
+#define _FPU_MASK_RM 0x00c00000 /* rounding mode */
+#define _FPU_MASK_EXCEPT 0x00001f1f /* all exception flags */
+
+/* Some bits in the FPSCR are not yet defined. They must be preserved when
+ modifying the contents. */
+#define _FPU_RESERVED 0x00086060
+#define _FPU_DEFAULT 0x00000000
+
+/* Default + exceptions enabled. */
+#define _FPU_IEEE (_FPU_DEFAULT | 0x00001f00)
+
+/* Type of the control word. */
+typedef unsigned int fpu_control_t;
+
+/* Macros for accessing the hardware control word. */
+#ifdef __SOFTFP__
+/* This is fmrx %0, fpscr. */
+# define _FPU_GETCW(cw) \
+ __asm__ __volatile__ ("mrc p10, 7, %0, cr1, cr0, 0" : "=r" (cw))
+/* This is fmxr fpscr, %0. */
+# define _FPU_SETCW(cw) \
+ __asm__ __volatile__ ("mcr p10, 7, %0, cr1, cr0, 0" : : "r" (cw))
+#else
+# define _FPU_GETCW(cw) \
+ __asm__ __volatile__ ("vmrs %0, fpscr" : "=r" (cw))
+# define _FPU_SETCW(cw) \
+ __asm__ __volatile__ ("vmsr fpscr, %0" : : "r" (cw))
+#endif
+
+/* Default control word set at startup. */
+extern fpu_control_t __fpu_control;
+
+#endif /* __SOFTFP__ */
+
+#endif /* _FPU_CONTROL_H */