mirror of
https://sourceware.org/git/glibc.git
synced 2025-01-11 11:50:06 +00:00
powerpc: Refactor powerpc32 lround/lroundf/llround/llroundf
This patches consolidates all the powerpc llround{f} implementations on the generic sysdeps/powerpc/powerpc32/fpu/s_llround{f}. Checked on powerpc-linux-gnu (built without --with-cpu, with --with-cpu=power4 and with --with-cpu=power5+ and --disable-multi-arch), powerpc64-linux-gnu (built without --with-cp and with --with-cpu=power5+ and --disable-multi-arch). * sysdeps/powerpc/powerpc32/fpu/Makefile [$(subdir) == math] (CFLAGS-s_lround.c): New rule. * sysdeps/powerpc/powerpc32/fpu/s_llround.c (__llround): Add power5+ and fctidz optimization. * sysdeps/powerpc/powerpc32/fpu/s_lround.S: Remove file. * sysdeps/powerpc/powerpc32/fpu/s_lround.c: New file. * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/Makefile (CFLAGS-s_llround-power6.c, CFLAGS-s_llround-power5+.c, CFLAGS-s_llround-ppc32.c, CFLAGS-s_lround-ppc32.c, CFLAGS-s_lround-power5+.c): New rule. * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_llround-power5+.c: New file. * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_llround-power6.c: Likewise. * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_llround-ppc32.c: Likewise. * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_lround-power5+.c: Likewise. * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_lround-ppc32.c: Likewise. * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_llround-power5+.S: Remove file. * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_llround-power6.S: Likewise. * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_llround-ppc32.S: Likewise. * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_lround-power5+.S: Likewise. * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_lround-ppc32.S: Likewise. * sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S: Likewise. * sysdeps/powerpc/powerpc32/power4/fpu/s_llroundf.S: Likewise. * sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S: Likewise. * sysdeps/powerpc/powerpc32/power5+/fpu/s_llroundf.S: Likewise. * sysdeps/powerpc/powerpc32/power5+/fpu/s_lround.S: Likewise. * sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S: Likewise. * sysdeps/powerpc/powerpc32/power6/fpu/s_llroundf.S: Likewise. Reviewed-by: Gabriel F. T. Gomes <gabriel@inconstante.eti.br>
This commit is contained in:
parent
a63b96fbdd
commit
9d5d214e86
40
ChangeLog
40
ChangeLog
@ -1,3 +1,43 @@
|
||||
2019-06-26 Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
* sysdeps/powerpc/powerpc32/fpu/Makefile
|
||||
[$(subdir) == math] (CFLAGS-s_lround.c): New rule.
|
||||
* sysdeps/powerpc/powerpc32/fpu/s_llround.c (__llround): Add power5+
|
||||
and fctidz optimization.
|
||||
* sysdeps/powerpc/powerpc32/fpu/s_lround.S: Remove file.
|
||||
* sysdeps/powerpc/powerpc32/fpu/s_lround.c: New file.
|
||||
* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/Makefile
|
||||
(CFLAGS-s_llround-power6.c, CFLAGS-s_llround-power5+.c,
|
||||
CFLAGS-s_llround-ppc32.c, CFLAGS-s_lround-ppc32.c,
|
||||
CFLAGS-s_lround-power5+.c): New rule.
|
||||
* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_llround-power5+.c:
|
||||
New file.
|
||||
* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_llround-power6.c:
|
||||
Likewise.
|
||||
* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_llround-ppc32.c:
|
||||
Likewise.
|
||||
* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_lround-power5+.c:
|
||||
Likewise.
|
||||
* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_lround-ppc32.c:
|
||||
Likewise.
|
||||
* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_llround-power5+.S:
|
||||
Remove file.
|
||||
* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_llround-power6.S:
|
||||
Likewise.
|
||||
* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_llround-ppc32.S:
|
||||
Likewise.
|
||||
* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_lround-power5+.S:
|
||||
Likewise.
|
||||
* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_lround-ppc32.S:
|
||||
Likewise.
|
||||
* sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc32/power4/fpu/s_llroundf.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc32/power5+/fpu/s_llroundf.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc32/power5+/fpu/s_lround.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S: Likewise.
|
||||
* sysdeps/powerpc/powerpc32/power6/fpu/s_llroundf.S: Likewise.
|
||||
|
||||
2019-06-26 Vincent Chen <vincentc@andestech.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/syscall-names.list: Add nds32
|
||||
|
@ -2,6 +2,7 @@ ifeq ($(subdir),math)
|
||||
# lrint is aliased to lrintf, so suppress compiler builtins to
|
||||
# avoid mismatched signatures.
|
||||
CFLAGS-s_lrint.c += -fno-builtin-lrintf
|
||||
CFLAGS-s_lround.c += -fno-builtin-lroundf
|
||||
endif
|
||||
|
||||
ifeq ($(subdir),misc)
|
||||
|
@ -18,10 +18,10 @@
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <math_ldbl_opt.h>
|
||||
#include <math_private.h>
|
||||
#include <stdint.h>
|
||||
#include <libm-alias-double.h>
|
||||
#include <math-barriers.h>
|
||||
|
||||
/* Round to the nearest integer, with values exactly on a 0.5 boundary
|
||||
rounded away from zero, regardless of the current rounding mode.
|
||||
@ -31,9 +31,53 @@
|
||||
long long int
|
||||
__llround (double x)
|
||||
{
|
||||
#ifdef _ARCH_PWR5X
|
||||
x = round (x);
|
||||
/* The barrier prevents compiler from optimizing it to llround when
|
||||
compiled with -fno-math-errno */
|
||||
math_opt_barrier (x);
|
||||
return x;
|
||||
#else
|
||||
long long xr;
|
||||
if (HAVE_PPC_FCTIDZ)
|
||||
xr = (long long) x;
|
||||
{
|
||||
/* 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).".
|
||||
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.
|
||||
|
||||
It is necessary to detect when x is (+-)0x1.fffffffffffffp-2
|
||||
because adding +-0.5 in this case will cause an erroneous shift,
|
||||
carry and round. We simply return 0 if 0.5 > x > -0.5. Likewise
|
||||
if x is and odd number between +-(2^52 and 2^53-1) a shift and
|
||||
carry will erroneously round if biased with +-0.5. Therefore if x
|
||||
is greater/less than +-2^52 we don't need to bias the number with
|
||||
+-0.5. */
|
||||
double ax = fabs (x);
|
||||
|
||||
if (ax < 0.5)
|
||||
return 0;
|
||||
|
||||
if (ax < 0x1p+52)
|
||||
{
|
||||
/* Test whether an integer to avoid spurious "inexact". */
|
||||
double t = ax + 0x1p+52;
|
||||
t = t - 0x1p+52;
|
||||
if (ax != t)
|
||||
{
|
||||
ax = ax + 0.5;
|
||||
if (x < 0.0)
|
||||
ax = -fabs (ax);
|
||||
x = ax;
|
||||
}
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Avoid incorrect exceptions from libgcc conversions (as of GCC
|
||||
@ -80,5 +124,8 @@ __llround (double x)
|
||||
xr -= (long long) ((unsigned long long) xr - 1) < 0;
|
||||
}
|
||||
return xr;
|
||||
#endif
|
||||
}
|
||||
#ifndef __llround
|
||||
libm_alias_double (__llround, llround)
|
||||
#endif
|
||||
|
@ -1,123 +0,0 @@
|
||||
/* lround function. PowerPC32 version.
|
||||
Copyright (C) 2004-2019 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 <sysdep.h>
|
||||
#include <math_ldbl_opt.h>
|
||||
#include <libm-alias-float.h>
|
||||
#include <libm-alias-double.h>
|
||||
|
||||
.section .rodata.cst4,"aM",@progbits,4
|
||||
.align 2
|
||||
.LC0: /* 0.5 */
|
||||
.long 0x3f000000
|
||||
.LC1: /* 2^52. */
|
||||
.long 0x59800000
|
||||
.section .rodata.cst8,"aM",@progbits,8
|
||||
.align 3
|
||||
.LC2: /* 0x7fffffff.8p0. */
|
||||
.long 0x41dfffff
|
||||
.long 0xffe00000
|
||||
.LC3: /* -0x80000000.8p0. */
|
||||
.long 0xc1e00000
|
||||
.long 0x00100000
|
||||
.section ".text"
|
||||
|
||||
/* long [r3] lround (float x [fp1])
|
||||
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).".
|
||||
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. It is necessary to detect when x is
|
||||
(+-)0x1.fffffffffffffp-2 because adding +-0.5 in this case will
|
||||
cause an erroneous shift, carry and round. We simply return 0 if
|
||||
0.5 > x > -0.5. */
|
||||
|
||||
ENTRY (__lround)
|
||||
stwu r1,-16(r1)
|
||||
cfi_adjust_cfa_offset (16)
|
||||
#ifdef SHARED
|
||||
mflr r11
|
||||
cfi_register(lr,r11)
|
||||
SETUP_GOT_ACCESS(r9,got_label)
|
||||
addis r10,r9,.LC0-got_label@ha
|
||||
lfs fp10,.LC0-got_label@l(r10)
|
||||
addis r10,r9,.LC1-got_label@ha
|
||||
lfs fp11,.LC1-got_label@l(r10)
|
||||
addis r10,r9,.LC2-got_label@ha
|
||||
lfd fp9,.LC2-got_label@l(r10)
|
||||
addis r10,r9,.LC3-got_label@ha
|
||||
lfd fp8,.LC3-got_label@l(r10)
|
||||
mtlr r11
|
||||
cfi_same_value (lr)
|
||||
#else
|
||||
lis r9,.LC0@ha
|
||||
lfs fp10,.LC0@l(r9)
|
||||
lis r9,.LC1@ha
|
||||
lfs fp11,.LC1@l(r9)
|
||||
lis r9,.LC2@ha
|
||||
lfd fp9,.LC2@l(r9)
|
||||
lis r9,.LC3@ha
|
||||
lfd fp8,.LC3@l(r9)
|
||||
#endif
|
||||
fabs fp2, fp1 /* Get the absolute value of x. */
|
||||
fsub fp12,fp10,fp10 /* Compute 0.0. */
|
||||
fcmpu cr6, fp2, fp10 /* if |x| < 0.5 */
|
||||
fcmpu cr5, fp1, fp9 /* if x >= 0x7fffffff.8p0 */
|
||||
fcmpu cr1, fp1, fp8 /* if x <= -0x80000000.8p0 */
|
||||
fcmpu cr7, fp1, fp12 /* x is negative? x < 0.0 */
|
||||
blt- cr6,.Lretzero
|
||||
bge- cr5,.Loflow
|
||||
ble- cr1,.Loflow
|
||||
/* Test whether an integer to avoid spurious "inexact". */
|
||||
fadd fp3,fp2,fp11
|
||||
fsub fp3,fp3,fp11
|
||||
fcmpu cr5, fp2, fp3
|
||||
beq cr5,.Lnobias
|
||||
fadd fp3,fp2,fp10 /* |x|+=0.5 bias to prepare to round. */
|
||||
bge cr7,.Lconvert /* x is positive so don't negate x. */
|
||||
fnabs fp3,fp3 /* -(|x|+=0.5) */
|
||||
.Lconvert:
|
||||
fctiwz fp4,fp3 /* Convert to Integer word lround toward 0. */
|
||||
stfd fp4,8(r1)
|
||||
nop /* Ensure the following load is in a different dispatch */
|
||||
nop /* group to avoid pipe stall on POWER4&5. */
|
||||
nop
|
||||
lwz r3,8+LOWORD(r1) /* Load return as integer. */
|
||||
.Lout:
|
||||
addi r1,r1,16
|
||||
blr
|
||||
.Lretzero: /* when 0.5 > x > -0.5 */
|
||||
li r3,0 /* return 0. */
|
||||
b .Lout
|
||||
.Lnobias:
|
||||
fmr fp3,fp1
|
||||
b .Lconvert
|
||||
.Loflow:
|
||||
fmr fp3,fp11
|
||||
bge cr7,.Lconvert
|
||||
fnabs fp3,fp3
|
||||
b .Lconvert
|
||||
END (__lround)
|
||||
|
||||
libm_alias_double (__lround, lround)
|
||||
|
||||
strong_alias (__lround, __lroundf)
|
||||
libm_alias_float (__lround, lround)
|
77
sysdeps/powerpc/powerpc32/fpu/s_lround.c
Normal file
77
sysdeps/powerpc/powerpc32/fpu/s_lround.c
Normal file
@ -0,0 +1,77 @@
|
||||
/* lround function. PowerPC32 version.
|
||||
Copyright (C) 2004-2019 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/>. */
|
||||
|
||||
#define lroundf __redirect_lroundf
|
||||
#define __lroundf __redirect___lroundf
|
||||
#include <math.h>
|
||||
#undef lroundf
|
||||
#undef __lroundf
|
||||
#include <libm-alias-float.h>
|
||||
#include <libm-alias-double.h>
|
||||
|
||||
long int
|
||||
__lround (double x)
|
||||
{
|
||||
#ifdef _ARCH_PWR5X
|
||||
x = round (x);
|
||||
#else
|
||||
/* 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).".
|
||||
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. it is necessary to detect when x is
|
||||
(+-)0x1.fffffffffffffp-2 because adding +-0.5 in this case will
|
||||
cause an erroneous shift, carry and round. we simply return 0 if
|
||||
0.5 > x > -0.5. */
|
||||
|
||||
double ax = fabs (x);
|
||||
|
||||
if (ax < 0.5)
|
||||
return 0;
|
||||
|
||||
if (x >= 0x7fffffff.8p0 || x <= -0x80000000.8p0)
|
||||
x = (x < 0.0) ? -0x1p+52 : 0x1p+52;
|
||||
else
|
||||
{
|
||||
/* Test whether an integer to avoid spurious "inexact". */
|
||||
double t = ax + 0x1p+52;
|
||||
t = t - 0x1p+52;
|
||||
if (ax != t)
|
||||
{
|
||||
ax = ax + 0.5;
|
||||
if (x < 0.0)
|
||||
ax = -fabs (ax);
|
||||
x = ax;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Force evaluation of values larger than long int, so invalid
|
||||
exceptions are raise. */
|
||||
long long int ret;
|
||||
asm ("fctiwz %0, %1" : "=d" (ret) : "d" (x));
|
||||
return ret;
|
||||
}
|
||||
#ifndef __lround
|
||||
libm_alias_double (__lround, lround)
|
||||
|
||||
strong_alias (__lround, __lroundf)
|
||||
libm_alias_float (__lround, lround)
|
||||
#endif
|
@ -23,6 +23,11 @@ CFLAGS-s_llrintf-ppc32.c += -mcpu=power4
|
||||
CFLAGS-s_llrint-power6.c += -mcpu=power6
|
||||
CFLAGS-s_llrint-ppc32.c += -mcpu=power4
|
||||
CFLAGS-s_lrint-ppc32.c += -mcpu=power4
|
||||
CFLAGS-s_llround-power6.c += -mcpu=power6
|
||||
CFLAGS-s_llround-power5+.c += -mcpu=power5+
|
||||
CFLAGS-s_llround-ppc32.c += -mcpu=power4
|
||||
CFLAGS-s_lround-ppc32.c += -mcpu=power4
|
||||
CFLAGS-s_lround-power5+.c += -mcpu=power5+
|
||||
CFLAGS-s_ceil-power5+.c = -mcpu=power5+
|
||||
CFLAGS-s_ceilf-power5+.c = -mcpu=power5+
|
||||
CFLAGS-s_modf-power5+.c = -mcpu=power5+
|
||||
|
@ -1,31 +0,0 @@
|
||||
/* lround function. PowerPC32/POWER5+ version.
|
||||
Copyright (C) 2013-2019 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 <sysdep.h>
|
||||
#include <math_ldbl_opt.h>
|
||||
|
||||
#undef weak_alias
|
||||
#define weak_alias(a,b)
|
||||
#undef strong_alias
|
||||
#define strong_alias(a,b)
|
||||
#undef compat_symbol
|
||||
#define compat_symbol(a,b,c,d)
|
||||
|
||||
#define __llround __llround_power5plus
|
||||
|
||||
#include <sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S>
|
@ -0,0 +1,2 @@
|
||||
#define __llround __llround_power5plus
|
||||
#include <sysdeps/powerpc/powerpc32/fpu/s_llround.c>
|
@ -1,31 +0,0 @@
|
||||
/* lround function. PowerPC32/POWER6 version.
|
||||
Copyright (C) 2013-2019 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 <sysdep.h>
|
||||
#include <math_ldbl_opt.h>
|
||||
|
||||
#undef weak_alias
|
||||
#define weak_alias(a,b)
|
||||
#undef strong_alias
|
||||
#define strong_alias(a,b)
|
||||
#undef compat_symbol
|
||||
#define compat_symbol(a,b,c,d)
|
||||
|
||||
#define __llround __llround_power6
|
||||
|
||||
#include <sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S>
|
@ -0,0 +1,2 @@
|
||||
#define __llround __llround_power6
|
||||
#include <sysdeps/powerpc/powerpc32/fpu/s_llround.c>
|
@ -1,31 +0,0 @@
|
||||
/* llround function. PowerPC32 default version.
|
||||
Copyright (C) 2013-2019 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 <sysdep.h>
|
||||
#include <math_ldbl_opt.h>
|
||||
|
||||
#undef weak_alias
|
||||
#define weak_alias(a,b)
|
||||
#undef strong_alias
|
||||
#define strong_alias(a,b)
|
||||
#undef compat_symbol
|
||||
#define compat_symbol(a,b,c,d)
|
||||
|
||||
#define __llround __llround_ppc32
|
||||
|
||||
#include <sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S>
|
@ -0,0 +1,2 @@
|
||||
#define __llround __llround_ppc32
|
||||
#include <sysdeps/powerpc/powerpc32/fpu/s_llround.c>
|
@ -1,33 +0,0 @@
|
||||
/* lround function. POWER5+, PowerPC32 version.
|
||||
Copyright (C) 2013-2019 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 <sysdep.h>
|
||||
#include <math_ldbl_opt.h>
|
||||
|
||||
#undef hidden_def
|
||||
#define hidden_def(name)
|
||||
#undef weak_alias
|
||||
#define weak_alias(name, alias)
|
||||
#undef strong_alias
|
||||
#define strong_alias(name, alias)
|
||||
#undef compat_symbol
|
||||
#define compat_symbol(lib, name, alias, ver)
|
||||
|
||||
#define __lround __lround_power5plus
|
||||
|
||||
#include <sysdeps/powerpc/powerpc32/power5+/fpu/s_lround.S>
|
@ -0,0 +1,2 @@
|
||||
#define __lround __lround_power5plus
|
||||
#include <sysdeps/powerpc/powerpc32/fpu/s_lround.c>
|
@ -1,31 +0,0 @@
|
||||
/* lround function. PowerPC32 default version.
|
||||
Copyright (C) 2013-2019 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 <sysdep.h>
|
||||
#include <math_ldbl_opt.h>
|
||||
|
||||
#undef weak_alias
|
||||
#define weak_alias(a,b)
|
||||
#undef strong_alias
|
||||
#define strong_alias(a,b)
|
||||
#undef compat_symbol
|
||||
#define compat_symbol(a,b,c,d)
|
||||
|
||||
#define __lround __lround_ppc32
|
||||
|
||||
#include <sysdeps/powerpc/powerpc32/fpu/s_lround.S>
|
@ -0,0 +1,2 @@
|
||||
#define __lround __lround_ppc32
|
||||
#include <sysdeps/powerpc/powerpc32/fpu/s_lround.c>
|
@ -1,105 +0,0 @@
|
||||
/* llround function. PowerPC32 on PowerPC64 version.
|
||||
Copyright (C) 2004-2019 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 <sysdep.h>
|
||||
#include <math_ldbl_opt.h>
|
||||
#include <libm-alias-float.h>
|
||||
#include <libm-alias-double.h>
|
||||
|
||||
.section .rodata.cst8,"aM",@progbits,8
|
||||
.align 3
|
||||
.LC0: .long (52+127)<<23 /* 0x1p+52 */
|
||||
.long (-1+127)<<23 /* 0.5 */
|
||||
|
||||
.section ".text"
|
||||
|
||||
/* long [r3] lround (float x [fp1])
|
||||
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).".
|
||||
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.
|
||||
|
||||
It is necessary to detect when x is (+-)0x1.fffffffffffffp-2
|
||||
because adding +-0.5 in this case will cause an erroneous shift,
|
||||
carry and round. We simply return 0 if 0.5 > x > -0.5. Likewise
|
||||
if x is and odd number between +-(2^52 and 2^53-1) a shift and
|
||||
carry will erroneously round if biased with +-0.5. Therefore if x
|
||||
is greater/less than +-2^52 we don't need to bias the number with
|
||||
+-0.5. */
|
||||
|
||||
ENTRY (__llround)
|
||||
stwu r1,-16(r1)
|
||||
cfi_adjust_cfa_offset (16)
|
||||
#ifdef SHARED
|
||||
mflr r11
|
||||
cfi_register(lr,r11)
|
||||
SETUP_GOT_ACCESS(r9,got_label)
|
||||
addis r9,r9,.LC0-got_label@ha
|
||||
addi r9,r9,.LC0-got_label@l
|
||||
mtlr r11
|
||||
cfi_same_value (lr)
|
||||
lfs fp9,0(r9)
|
||||
lfs fp10,4(r9)
|
||||
#else
|
||||
lis r9,.LC0@ha
|
||||
lfs fp9,.LC0@l(r9) /* Load 2^52 into fpr9. */
|
||||
lfs fp10,.LC0@l+4(r9) /* Load 0.5 into fpr10. */
|
||||
#endif
|
||||
fabs fp2,fp1 /* Get the absolute value of x. */
|
||||
fsub fp12,fp10,fp10 /* Compute 0.0 into fpr12. */
|
||||
fcmpu cr6,fp2,fp10 /* if |x| < 0.5 */
|
||||
fcmpu cr7,fp2,fp9 /* if |x| >= 2^52 */
|
||||
fcmpu cr1,fp1,fp12 /* x is negative? x < 0.0 */
|
||||
blt- cr6,.Lretzero /* 0.5 > x < -0.5 so just return 0. */
|
||||
bge- cr7,.Lnobias /* 2^52 > x < -2^52 just convert with no bias. */
|
||||
/* Test whether an integer to avoid spurious "inexact". */
|
||||
fadd fp3,fp2,fp9
|
||||
fsub fp3,fp3,fp9
|
||||
fcmpu cr5,fp2,fp3
|
||||
beq cr5,.Lnobias
|
||||
fadd fp3,fp2,fp10 /* |x|+=0.5 bias to prepare to round. */
|
||||
bge cr1,.Lconvert /* x is positive so don't negate x. */
|
||||
fnabs fp3,fp3 /* -(|x|+=0.5) */
|
||||
.Lconvert:
|
||||
fctidz fp4,fp3 /* Convert to Integer double word round toward 0. */
|
||||
stfd fp4,8(r1)
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
lwz r3,8+HIWORD(r1) /* Load return as integer. */
|
||||
lwz r4,8+LOWORD(r1)
|
||||
.Lout:
|
||||
addi r1,r1,16
|
||||
blr
|
||||
.Lretzero: /* 0.5 > x > -0.5 */
|
||||
li r3,0 /* return 0. */
|
||||
li r4,0
|
||||
b .Lout
|
||||
.Lnobias:
|
||||
fmr fp3,fp1
|
||||
b .Lconvert
|
||||
END (__llround)
|
||||
|
||||
libm_alias_double (__llround, llround)
|
||||
|
||||
strong_alias (__llround, __llroundf)
|
||||
libm_alias_float (__llround, llround)
|
@ -1 +0,0 @@
|
||||
/* __llroundf is in s_llround.S */
|
@ -1,53 +0,0 @@
|
||||
/* lround function. POWER5+, PowerPC32 version.
|
||||
Copyright (C) 2006-2019 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 <sysdep.h>
|
||||
#include <math_ldbl_opt.h>
|
||||
#include <libm-alias-float.h>
|
||||
#include <libm-alias-double.h>
|
||||
|
||||
/* long [r3] llround (float x [fp1])
|
||||
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).".
|
||||
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)
|
||||
stwu r1,-16(r1)
|
||||
cfi_adjust_cfa_offset (16)
|
||||
frin fp2,fp1
|
||||
fctidz fp3,fp2 /* Convert To Integer Word lround toward 0. */
|
||||
stfd fp3,8(r1)
|
||||
nop /* Ensure the following load is in a different dispatch */
|
||||
nop /* group to avoid pipe stall on POWER4&5. */
|
||||
nop
|
||||
lwz r3,8+HIWORD(r1)
|
||||
lwz r4,8+LOWORD(r1)
|
||||
addi r1,r1,16
|
||||
blr
|
||||
END (__llround)
|
||||
|
||||
libm_alias_double (__llround, llround)
|
||||
|
||||
strong_alias (__llround, __llroundf)
|
||||
libm_alias_float (__llround, llround)
|
@ -1 +0,0 @@
|
||||
/* __llroundf is in s_llround.S */
|
@ -1,51 +0,0 @@
|
||||
/* lround function. POWER5+, PowerPC32 version.
|
||||
Copyright (C) 2006-2019 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 <sysdep.h>
|
||||
#include <math_ldbl_opt.h>
|
||||
#include <libm-alias-float.h>
|
||||
#include <libm-alias-double.h>
|
||||
|
||||
/* long [r3] lround (float x [fp1])
|
||||
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).".
|
||||
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 (__lround)
|
||||
stwu r1,-16(r1)
|
||||
cfi_adjust_cfa_offset (16)
|
||||
frin fp2,fp1
|
||||
fctiwz fp3,fp2 /* Convert To Integer Word lround toward 0. */
|
||||
stfd fp3,8(r1)
|
||||
nop /* Ensure the following load is in a different dispatch */
|
||||
nop /* group to avoid pipe stall on POWER4&5. */
|
||||
nop
|
||||
lwz r3,8+LOWORD(r1)
|
||||
addi r1,r1,16
|
||||
blr
|
||||
END (__lround)
|
||||
|
||||
libm_alias_double (__lround, lround)
|
||||
|
||||
strong_alias (__lround, __lroundf)
|
||||
libm_alias_float (__lround, lround)
|
@ -1,53 +0,0 @@
|
||||
/* lround function. POWER5+, PowerPC32 version.
|
||||
Copyright (C) 2006-2019 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 <sysdep.h>
|
||||
#include <math_ldbl_opt.h>
|
||||
#include <libm-alias-float.h>
|
||||
#include <libm-alias-double.h>
|
||||
|
||||
/* long [r3] llround (float x [fp1])
|
||||
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).".
|
||||
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)
|
||||
stwu r1,-16(r1)
|
||||
cfi_adjust_cfa_offset (16)
|
||||
frin fp2,fp1
|
||||
fctidz fp3,fp2 /* Convert To Integer Word lround toward 0. */
|
||||
stfd fp3,8(r1)
|
||||
/* Insure the following load is in a different dispatch group by
|
||||
inserting "group ending nop". */
|
||||
ori r1,r1,0
|
||||
lwz r3,8+HIWORD(r1)
|
||||
lwz r4,8+LOWORD(r1)
|
||||
addi r1,r1,16
|
||||
blr
|
||||
END (__llround)
|
||||
|
||||
libm_alias_double (__llround, llround)
|
||||
|
||||
strong_alias (__llround, __llroundf)
|
||||
libm_alias_float (__llround, llround)
|
@ -1 +0,0 @@
|
||||
/* __llroundf is in s_llround.S */
|
Loading…
Reference in New Issue
Block a user