diff options
author | Adhemerval Zanella <azanella@linux.vnet.ibm.com> | 2013-04-09 14:23:36 -0500 |
---|---|---|
committer | Adhemerval Zanella <azanella@linux.vnet.ibm.com> | 2013-04-12 07:23:27 -0500 |
commit | 42747c841a2a4c6c269f59c6c7d688a82a64a4b4 (patch) | |
tree | 830408267e8b887775402133aeb28d71308a5399 | |
parent | 4fc34c6e2f2abb08d56ebb7ce4860e1d337e0e84 (diff) | |
download | glibc-42747c841a2a4c6c269f59c6c7d688a82a64a4b4.zip glibc-42747c841a2a4c6c269f59c6c7d688a82a64a4b4.tar.gz glibc-42747c841a2a4c6c269f59c6c7d688a82a64a4b4.tar.bz2 |
PowerPC: llround/llroundf multilib for PowerPC32
13 files changed, 89 insertions, 61 deletions
diff --git a/sysdeps/powerpc/powerpc32/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc32/fpu/multiarch/Makefile index 4c63e5d..b877357 100644 --- a/sysdeps/powerpc/powerpc32/fpu/multiarch/Makefile +++ b/sysdeps/powerpc/powerpc32/fpu/multiarch/Makefile @@ -1,4 +1,8 @@ ifeq ($(subdir),math) libm-sysdep_routines += s_llrintf-power6 s_llrintf-power4 s_llrintf-c \ - s_llrint-power6 s_llrint-power4 s_llrint-c + s_llrint-power6 s_llrint-power4 s_llrint-c \ + s_llround-power6 s_llround-power5+ s_llround-power4 \ + s_llround-c + +CFLAGS-s_llround.c = -fno-builtin-llroundf endif diff --git a/sysdeps/powerpc/powerpc32/fpu/multiarch/s_llround-c.c b/sysdeps/powerpc/powerpc32/fpu/multiarch/s_llround-c.c new file mode 100644 index 0000000..a3acf44 --- /dev/null +++ b/sysdeps/powerpc/powerpc32/fpu/multiarch/s_llround-c.c @@ -0,0 +1,3 @@ +#undef __llround +#define __llround __llround_ppc32 +#include <sysdeps/powerpc/fpu/s_llround.c> diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S b/sysdeps/powerpc/powerpc32/fpu/multiarch/s_llround-power4.S index 07beb0a..d99a7e2 100644 --- a/sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S +++ b/sysdeps/powerpc/powerpc32/fpu/multiarch/s_llround-power4.S @@ -29,11 +29,11 @@ .section ".text" /* long [r3] lround (float x [fp1]) - IEEE 1003.1 lround function. IEEE specifies "round to the nearest + IEEE 1003.1 lround function. IEEE specifies "round to the nearest integer value, rounding halfway cases away from zero, regardless of the current rounding mode." However PowerPC Architecture defines - "round to Nearest" as "Choose the best approximation. In case of a - tie, choose the one that is even (least significant bit o).". + "round to Nearest" as "Choose the best approximation. In case of a + tie, choose the one that is even (least significant bit o).". So we can't use the PowerPC "round to Nearest" mode. Instead we set "round toward Zero" mode and round by adding +-0.5 before rounding to the integer value. @@ -46,7 +46,8 @@ is greater/less than +-2^52 we don't need to bias the number with +-0.5. */ -ENTRY (__llround) + .machine power4 +ENTRY (__llround_power4) stwu r1,-16(r1) cfi_adjust_cfa_offset (16) #ifdef SHARED @@ -92,17 +93,4 @@ ENTRY (__llround) .Lnobias: fmr fp3,fp1 b .Lconvert - END (__llround) - -weak_alias (__llround, llround) - -strong_alias (__llround, __llroundf) -weak_alias (__llround, llroundf) - -#ifdef NO_LONG_DOUBLE -weak_alias (__llround, llroundl) -strong_alias (__llround, __llroundl) -#endif -#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) -compat_symbol (libm, __llround, llroundl, GLIBC_2_1) -#endif +END (__llround_power4) diff --git a/sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S b/sysdeps/powerpc/powerpc32/fpu/multiarch/s_llround-power5+.S index 558bd2a..6c45ed2 100644 --- a/sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S +++ b/sysdeps/powerpc/powerpc32/fpu/multiarch/s_llround-power5+.S @@ -18,19 +18,19 @@ #include <sysdep.h> #include <math_ldbl_opt.h> - + /* long [r3] llround (float x [fp1]) - IEEE 1003.1 lround function. IEEE specifies "round to the nearest + IEEE 1003.1 lround function. IEEE specifies "round to the nearest integer value, rounding halfway cases away from zero, regardless of the current rounding mode." However PowerPC Architecture defines - "round to Nearest" as "Choose the best approximation. In case of a - tie, choose the one that is even (least significant bit o).". + "round to Nearest" as "Choose the best approximation. In case of a + tie, choose the one that is even (least significant bit o).". So we pre-round using the V2.02 Floating Round to Integer Nearest instruction before we use the Floating Convert to Integer Word with round to zero instruction. */ .machine "power5" -ENTRY (__llround) +ENTRY (__llround_power5) stwu r1,-16(r1) cfi_adjust_cfa_offset (16) frin fp2,fp1 @@ -43,17 +43,4 @@ ENTRY (__llround) lwz r3,8(r1) addi r1,r1,16 blr - END (__llround) - -weak_alias (__llround, llround) - -strong_alias (__llround, __llroundf) -weak_alias (__llround, llroundf) - -#ifdef NO_LONG_DOUBLE -weak_alias (__llround, llroundl) -strong_alias (__llround, __llroundl) -#endif -#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) -compat_symbol (libm, __llround, llroundl, GLIBC_2_1) -#endif +END (__llround_power5) diff --git a/sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S b/sysdeps/powerpc/powerpc32/fpu/multiarch/s_llround-power6.S index bfc5efb..da3fc14 100644 --- a/sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S +++ b/sysdeps/powerpc/powerpc32/fpu/multiarch/s_llround-power6.S @@ -18,19 +18,19 @@ #include <sysdep.h> #include <math_ldbl_opt.h> - + /* long [r3] llround (float x [fp1]) - IEEE 1003.1 lround function. IEEE specifies "round to the nearest + IEEE 1003.1 lround function. IEEE specifies "round to the nearest integer value, rounding halfway cases away from zero, regardless of the current rounding mode." However PowerPC Architecture defines - "round to Nearest" as "Choose the best approximation. In case of a - tie, choose the one that is even (least significant bit o).". + "round to Nearest" as "Choose the best approximation. In case of a + tie, choose the one that is even (least significant bit o).". So we pre-round using the V2.02 Floating Round to Integer Nearest instruction before we use the Floating Convert to Integer Word with round to zero instruction. */ - .machine "power5" -ENTRY (__llround) + .machine "power6" +ENTRY (__llround_power6) stwu r1,-16(r1) cfi_adjust_cfa_offset (16) frin fp2,fp1 @@ -43,17 +43,4 @@ ENTRY (__llround) lwz r3,8(r1) addi r1,r1,16 blr - END (__llround) - -weak_alias (__llround, llround) - -strong_alias (__llround, __llroundf) -weak_alias (__llround, llroundf) - -#ifdef NO_LONG_DOUBLE -weak_alias (__llround, llroundl) -strong_alias (__llround, __llroundl) -#endif -#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) -compat_symbol (libm, __llround, llroundl, GLIBC_2_1) -#endif +END (__llround_power6) diff --git a/sysdeps/powerpc/powerpc32/fpu/multiarch/s_llround.c b/sysdeps/powerpc/powerpc32/fpu/multiarch/s_llround.c new file mode 100644 index 0000000..6d23aab --- /dev/null +++ b/sysdeps/powerpc/powerpc32/fpu/multiarch/s_llround.c @@ -0,0 +1,58 @@ +/* Multiple versions of s_llround. + Copyright (C) 2013 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/>. */ + +/* Redefine llroundf/__llroundf so that compiler won't complain abouti + the type mismatch with the IFUNC selector in strong_alias/weak_alias + below. */ +#undef llroundf +#define llroundf __redirect_llroundf +#undef __llroundf +#define __llroundf __redirec___llroundf +#include <math.h> +#undef llroundf +#undef __llroundf +#include <math_ldbl_opt.h> +#include <shlib-compat.h> +#include "init-arch.h" + +extern __typeof (__llround) __llround_ppc32 attribute_hidden; +extern __typeof (__llround) __llround_power4 attribute_hidden; +extern __typeof (__llround) __llround_power5 attribute_hidden; +extern __typeof (__llround) __llround_power6 attribute_hidden; + +libc_ifunc (__llround, + (hwcap & PPC_FEATURE_ARCH_2_05) + ? __llround_power6 : + (hwcap & PPC_FEATURE_POWER5_PLUS) + ? __llround_power5 : + (hwcap & PPC_FEATURE_POWER4) + ? __llround_power4 + : __llround_ppc32); + +weak_alias (__llround, llround) + +strong_alias (__llround, __llroundf) +weak_alias (__llround, llroundf) + +#ifdef NO_LONG_DOUBLE +strong_alias (__llround, __llroundl) +weak_alias (__llround, llroundl) +#endif +#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) +compat_symbol (libm, __llround, llroundl, GLIBC_2_1); +#endif diff --git a/sysdeps/powerpc/powerpc32/fpu/multiarch/s_llroundf-power4.S b/sysdeps/powerpc/powerpc32/fpu/multiarch/s_llroundf-power4.S new file mode 100644 index 0000000..9967130 --- /dev/null +++ b/sysdeps/powerpc/powerpc32/fpu/multiarch/s_llroundf-power4.S @@ -0,0 +1 @@ +/* __llroundf_power4 is in s_llround-power4.S */ diff --git a/sysdeps/powerpc/powerpc32/fpu/multiarch/s_llroundf-power5+.S b/sysdeps/powerpc/powerpc32/fpu/multiarch/s_llroundf-power5+.S new file mode 100644 index 0000000..51d760c --- /dev/null +++ b/sysdeps/powerpc/powerpc32/fpu/multiarch/s_llroundf-power5+.S @@ -0,0 +1 @@ +/* __llroundf_power5+ is in s_llround-power5+.S */ diff --git a/sysdeps/powerpc/powerpc32/fpu/multiarch/s_llroundf-power6.S b/sysdeps/powerpc/powerpc32/fpu/multiarch/s_llroundf-power6.S new file mode 100644 index 0000000..adc0699 --- /dev/null +++ b/sysdeps/powerpc/powerpc32/fpu/multiarch/s_llroundf-power6.S @@ -0,0 +1 @@ +/* __llroundf_power6 is in s_llround-power6.S */ diff --git a/sysdeps/powerpc/powerpc32/fpu/multiarch/s_llroundf.c b/sysdeps/powerpc/powerpc32/fpu/multiarch/s_llroundf.c new file mode 100644 index 0000000..3ca6e17 --- /dev/null +++ b/sysdeps/powerpc/powerpc32/fpu/multiarch/s_llroundf.c @@ -0,0 +1 @@ +/* s__llroundf.c is implemented at s_llround.c */ diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/s_llroundf.S b/sysdeps/powerpc/powerpc32/power4/fpu/s_llroundf.S deleted file mode 100644 index 72d6181..0000000 --- a/sysdeps/powerpc/powerpc32/power4/fpu/s_llroundf.S +++ /dev/null @@ -1 +0,0 @@ -/* __llroundf is in s_llround.S */ diff --git a/sysdeps/powerpc/powerpc32/power5+/fpu/s_llroundf.S b/sysdeps/powerpc/powerpc32/power5+/fpu/s_llroundf.S deleted file mode 100644 index 030d2fd..0000000 --- a/sysdeps/powerpc/powerpc32/power5+/fpu/s_llroundf.S +++ /dev/null @@ -1 +0,0 @@ -/* __llroundf is in s_llround.S */ diff --git a/sysdeps/powerpc/powerpc32/power6/fpu/s_llroundf.S b/sysdeps/powerpc/powerpc32/power6/fpu/s_llroundf.S deleted file mode 100644 index 030d2fd..0000000 --- a/sysdeps/powerpc/powerpc32/power6/fpu/s_llroundf.S +++ /dev/null @@ -1 +0,0 @@ -/* __llroundf is in s_llround.S */ |