From 583b66bf18e66247b0c699cc0377fe7bb265f729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Fri, 8 Jun 2007 18:33:02 +0000 Subject: [PATCH] added trunc, truncf (and truncl on x86) from glibc should help on bug #1260 git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21350 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../posix/glibc/arch/generic/s_trunc.c | 61 +++++++++++++++++++ .../posix/glibc/arch/generic/s_truncf.c | 52 ++++++++++++++++ .../libroot/posix/glibc/arch/ppc/Jamfile | 1 + .../libroot/posix/glibc/arch/x86/Jamfile | 1 + .../libroot/posix/glibc/arch/x86/s_trunc.S | 36 +++++++++++ .../libroot/posix/glibc/arch/x86/s_truncf.S | 36 +++++++++++ .../libroot/posix/glibc/arch/x86/s_truncl.S | 36 +++++++++++ 7 files changed, 223 insertions(+) create mode 100644 src/system/libroot/posix/glibc/arch/generic/s_trunc.c create mode 100644 src/system/libroot/posix/glibc/arch/generic/s_truncf.c create mode 100644 src/system/libroot/posix/glibc/arch/x86/s_trunc.S create mode 100644 src/system/libroot/posix/glibc/arch/x86/s_truncf.S create mode 100644 src/system/libroot/posix/glibc/arch/x86/s_truncl.S diff --git a/src/system/libroot/posix/glibc/arch/generic/s_trunc.c b/src/system/libroot/posix/glibc/arch/generic/s_trunc.c new file mode 100644 index 0000000000..9ce7a40093 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/s_trunc.c @@ -0,0 +1,61 @@ +/* Truncate argument to nearest integral value not larger than the argument. + Copyright (C) 1997, 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +#include "math_private.h" + + +double +__trunc (double x) +{ + int32_t i0, j0; + u_int32_t i1; + int sx; + + EXTRACT_WORDS (i0, i1, x); + sx = i0 & 0x80000000; + j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; + if (j0 < 20) + { + if (j0 < 0) + /* The magnitude of the number is < 1 so the result is +-0. */ + INSERT_WORDS (x, sx, 0); + else + INSERT_WORDS (x, sx | (i0 & ~(0x000fffff >> j0)), 0); + } + else if (j0 > 51) + { + if (j0 == 0x400) + /* x is inf or NaN. */ + return x + x; + } + else + { + INSERT_WORDS (x, i0, i1 & ~(0xffffffffu >> (j0 - 20))); + } + + return x; +} +weak_alias (__trunc, trunc) +#ifdef NO_LONG_DOUBLE +strong_alias (__trunc, __truncl) +weak_alias (__trunc, truncl) +#endif diff --git a/src/system/libroot/posix/glibc/arch/generic/s_truncf.c b/src/system/libroot/posix/glibc/arch/generic/s_truncf.c new file mode 100644 index 0000000000..136f77a563 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/s_truncf.c @@ -0,0 +1,52 @@ +/* Truncate argument to nearest integral value not larger than the argument. + Copyright (C) 1997, 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +#include "math_private.h" + + +float +__truncf (float x) +{ + int32_t i0, j0; + int sx; + + GET_FLOAT_WORD (i0, x); + sx = i0 & 0x80000000; + j0 = ((i0 >> 23) & 0xff) - 0x7f; + if (j0 < 23) + { + if (j0 < 0) + /* The magnitude of the number is < 1 so the result is +-0. */ + SET_FLOAT_WORD (x, sx); + else + SET_FLOAT_WORD (x, sx | (i0 & ~(0x007fffff >> j0))); + } + else + { + if (j0 == 0x80) + /* x is inf or NaN. */ + return x + x; + } + + return x; +} +weak_alias (__truncf, truncf) diff --git a/src/system/libroot/posix/glibc/arch/ppc/Jamfile b/src/system/libroot/posix/glibc/arch/ppc/Jamfile index e9b1c330eb..13fcdebb6e 100644 --- a/src/system/libroot/posix/glibc/arch/ppc/Jamfile +++ b/src/system/libroot/posix/glibc/arch/ppc/Jamfile @@ -88,6 +88,7 @@ local genericSources = 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 diff --git a/src/system/libroot/posix/glibc/arch/x86/Jamfile b/src/system/libroot/posix/glibc/arch/x86/Jamfile index e265d80ce9..99bca10bd5 100644 --- a/src/system/libroot/posix/glibc/arch/x86/Jamfile +++ b/src/system/libroot/posix/glibc/arch/x86/Jamfile @@ -157,6 +157,7 @@ MergeObject posix_gnu_arch_$(TARGET_ARCH)_s.o : s_sin.S s_sinf.S s_sinl.S s_sincos.S s_sincosf.S s_sincosl.S s_tan.S s_tanf.S s_tanl.S + s_trunc.S s_truncf.S s_truncl.S ; MergeObject posix_gnu_arch_$(TARGET_ARCH)_generic.o : diff --git a/src/system/libroot/posix/glibc/arch/x86/s_trunc.S b/src/system/libroot/posix/glibc/arch/x86/s_trunc.S new file mode 100644 index 0000000000..5e6c3b4a99 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86/s_trunc.S @@ -0,0 +1,36 @@ +/* Truncate double value. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +ENTRY(__trunc) + fldl 4(%esp) + subl $8, %esp + fstcw 4(%esp) + movl $0xc00, %edx + orl 4(%esp), %edx + movl %edx, (%esp) + fldcw (%esp) + frndint + fldcw 4(%esp) + addl $8, %esp + ret +END(__trunc) +weak_alias (__trunc, trunc) diff --git a/src/system/libroot/posix/glibc/arch/x86/s_truncf.S b/src/system/libroot/posix/glibc/arch/x86/s_truncf.S new file mode 100644 index 0000000000..bbe2823680 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86/s_truncf.S @@ -0,0 +1,36 @@ +/* Truncate float value. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +ENTRY(__truncf) + flds 4(%esp) + subl $8, %esp + fstcw 4(%esp) + movl $0xc00, %edx + orl 4(%esp), %edx + movl %edx, (%esp) + fldcw (%esp) + frndint + fldcw 4(%esp) + addl $8, %esp + ret +END(__truncf) +weak_alias (__truncf, truncf) diff --git a/src/system/libroot/posix/glibc/arch/x86/s_truncl.S b/src/system/libroot/posix/glibc/arch/x86/s_truncl.S new file mode 100644 index 0000000000..4ff1f6f413 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86/s_truncl.S @@ -0,0 +1,36 @@ +/* Truncate long double value. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +ENTRY(__truncl) + fldt 4(%esp) + subl $8, %esp + fstcw 4(%esp) + movl $0xc00, %edx + orl 4(%esp), %edx + movl %edx, (%esp) + fldcw (%esp) + frndint + fldcw 4(%esp) + addl $8, %esp + ret +END(__truncl) +weak_alias (__truncl, truncl)