glibc/sysdeps/i386/fpu/e_scalb.S
Wilco Dijkstra 220622dde5 Add libm_alias_finite for _finite symbols
This patch adds a new macro, libm_alias_finite, to define all _finite
symbol.  It sets all _finite symbol as compat symbol based on its first
version (obtained from the definition at built generated first-versions.h).

The <fn>f128_finite symbols were introduced in GLIBC 2.26 and so need
special treatment in code that is shared between long double and float128.
It is done by adding a list, similar to internal symbol redifinition,
on sysdeps/ieee754/float128/float128_private.h.

Alpha also needs some tricky changes to ensure we still emit 2 compat
symbols for sqrt(f).

Passes buildmanyglibc.

Co-authored-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
2020-01-03 10:02:04 -03:00

102 lines
1.6 KiB
ArmAsm

/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Correct handling of y==-inf <drepper@gnu>
*/
#include <machine/asm.h>
#include <i386-math-asm.h>
#include <libm-alias-finite.h>
.section .rodata
.align ALIGNARG(4)
.type zero_nan,@object
zero_nan:
.double 0.0
nan: .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
.byte 0, 0, 0, 0, 0, 0, 0, 0x80
.byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
ASM_SIZE_DIRECTIVE(zero_nan)
#ifdef PIC
# define MO(op) op##@GOTOFF(%ecx)
# define MOX(op,x,f) op##@GOTOFF(%ecx,x,f)
#else
# define MO(op) op
# define MOX(op,x,f) op(,x,f)
#endif
.text
ENTRY(__ieee754_scalb)
fldl 12(%esp)
fxam
fnstsw
fldl 4(%esp)
andl $0x4700, %eax
cmpl $0x0700, %eax
je 1f
andl $0x4500, %eax
cmpl $0x0100, %eax
je 2f
fxam
fnstsw
andl $0x4500, %eax
cmpl $0x0100, %eax
je 3f
fld %st(1)
frndint
fcomp %st(2)
fnstsw
sahf
jne 4f
fscale
fstp %st(1)
DBL_NARROW_EVAL
ret
/* y is -inf */
1: fxam
#ifdef PIC
LOAD_PIC_REG (cx)
#endif
fnstsw
movl 8(%esp), %edx
shrl $5, %eax
fstp %st
fstp %st
andl $0x80000000, %edx
andl $0x0228, %eax
cmpl $0x0028, %eax
je 4f
andl $8, %eax
shrl $27, %edx
addl %edx, %eax
fldl MOX(zero_nan, %eax, 1)
ret
/* The result is NaN, but we must not raise an exception.
So use a variable. */
2: fstp %st
fstp %st
#ifdef PIC
LOAD_PIC_REG (cx)
#endif
fldl MO(nan)
ret
/* The first parameter is a NaN. Return it. */
3: fstp %st(1)
ret
/* Return NaN and raise the invalid exception. */
4: fstp %st
fstp %st
fldz
fdiv %st
ret
END(__ieee754_scalb)
libm_alias_finite (__ieee754_scalb, __scalb)