The x86_64 and i386 versions of scalbl return sNaN for some cases of
sNaN input and are missing "invalid" exceptions for other cases. This
results from overly complicated code that either returns a NaN input,
or discards both inputs when one is NaN and loads a NaN from memory.
This patch fixes this by simplifying the code to add the arguments
when either one is NaN.
Tested for x86_64 and x86.
[BZ #20296]
* sysdeps/i386/fpu/e_scalbl.S (__ieee754_scalbl): Add arguments
when either argument is a NaN.
* sysdeps/x86_64/fpu/e_scalbl.S (__ieee754_scalbl): Likewise.
* math/libm-test.inc (scalb_test_data): Add sNaN tests.
Various x86 / x86_64 versions of scalb / scalbf / scalbl produce
spurious "invalid" exceptions for (qNaN, -Inf) arguments, because this
is wrongly handled like (+/-Inf, -Inf) which *should* raise such an
exception. (In fact the NaN case of the code determining whether to
quietly return a zero or a NaN for second argument -Inf was
accidentally dead since the code had been made to return a NaN with
exception.) This patch fixes the code to do the proper test for an
infinity as distinct from a NaN.
(Since the existing code does nothing to distinguish qNaNs and sNaNs
here, this patch doesn't either. If in future we systematically
implement proper sNaN semantics following TS 18661-1:2014, there will
be lots of bugs to address - Thomas found lots of issues with his
patch <https://sourceware.org/ml/libc-ports/2013-04/msg00008.html> to
add SNaN tests (which never went in and would now require significant
reworking).)
Tested for x86_64 and x86. Committed.
[BZ #16783]
* sysdeps/i386/fpu/e_scalb.S (__ieee754_scalb): Do not handle
arguments (NaN, -Inf) the same as (+/-Inf, -Inf).
* sysdeps/i386/fpu/e_scalbf.S (__ieee754_scalbf): Likewise.
* sysdeps/i386/fpu/e_scalbl.S (__ieee754_scalbl): Likewise.
* sysdeps/x86_64/fpu/e_scalbl.S (__ieee754_scalbl): Likewise.
* math/libm-test.inc (scalb_test_data): Add more tests.
* sysdeps/unix/sysv/linux/x86_64/Makefile: New file.
* sysdeps/unix/sysv/linux/x86_64/Versions: New file.
* sysdeps/unix/sysv/linux/x86_64/bits/fcntl.h: New file.
* sysdeps/unix/sysv/linux/x86_64/bits/mman.h: New file.
* sysdeps/unix/sysv/linux/x86_64/bits/stat.h: New file.
* sysdeps/unix/sysv/linux/x86_64/bits/statfs.h: New file.
* sysdeps/unix/sysv/linux/x86_64/bits/time.h: New file.
* sysdeps/unix/sysv/linux/x86_64/bits/types.h: New file.
* sysdeps/unix/sysv/linux/x86_64/brk.c: New file.
* sysdeps/unix/sysv/linux/x86_64/clone.S: New file.
* sysdeps/unix/sysv/linux/x86_64/fstatfs64.c: New file.
* sysdeps/unix/sysv/linux/x86_64/ftruncate64.c: New file.
* sysdeps/unix/sysv/linux/x86_64/fxstat.c: New file.
* sysdeps/unix/sysv/linux/x86_64/fxstat64.c: New file.
* sysdeps/unix/sysv/linux/x86_64/getdents.c: New file.
* sysdeps/unix/sysv/linux/x86_64/getdents64.c: New file.
* sysdeps/unix/sysv/linux/x86_64/getrlimit64.c: New file.
* sysdeps/unix/sysv/linux/x86_64/gettimeofday.c: New file.
* sysdeps/unix/sysv/linux/x86_64/glob64.c: New file.
* sysdeps/unix/sysv/linux/x86_64/lxstat.c: New file.
* sysdeps/unix/sysv/linux/x86_64/lxstat64.c: New file.
* sysdeps/unix/sysv/linux/x86_64/mmap64.c: New file.
* sysdeps/unix/sysv/linux/x86_64/pread64.c: New file.
* sysdeps/unix/sysv/linux/x86_64/profil-counter.h: New file.
* sysdeps/unix/sysv/linux/x86_64/pwrite64.c: New file.
* sysdeps/unix/sysv/linux/x86_64/readdir.c: New file.
* sysdeps/unix/sysv/linux/x86_64/readdir64.c: New file.
* sysdeps/unix/sysv/linux/x86_64/readdir64_r.c: New file.
* sysdeps/unix/sysv/linux/x86_64/readdir_r.c: New file.
* sysdeps/unix/sysv/linux/x86_64/recv.c: New file.
* sysdeps/unix/sysv/linux/x86_64/register-dump.h: New file.
* sysdeps/unix/sysv/linux/x86_64/send.c: New file.
* sysdeps/unix/sysv/linux/x86_64/setrlimit64.c: New file.
* sysdeps/unix/sysv/linux/x86_64/sigaction.c: New file.
* sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h: New file.
* sysdeps/unix/sysv/linux/x86_64/sigpending.c: New file.
* sysdeps/unix/sysv/linux/x86_64/sigprocmask.c: New file.
* sysdeps/unix/sysv/linux/x86_64/sigsuspend.c: New file.
* sysdeps/unix/sysv/linux/x86_64/statfs64.c: New file.
* sysdeps/unix/sysv/linux/x86_64/sys/perm.h: New file.
* sysdeps/unix/sysv/linux/x86_64/sys/procfs.h: New file.
* sysdeps/unix/sysv/linux/x86_64/sys/reg.h: New file.
* sysdeps/unix/sysv/linux/x86_64/sys/ucontext.h: New file.
* sysdeps/unix/sysv/linux/x86_64/sys/user.h: New file.
* sysdeps/unix/sysv/linux/x86_64/syscall.S: New file.
* sysdeps/unix/sysv/linux/x86_64/syscalls.list: New file.
* sysdeps/unix/sysv/linux/x86_64/sysdep.S: New file.
* sysdeps/unix/sysv/linux/x86_64/sysdep.h: New file.
* sysdeps/unix/sysv/linux/x86_64/time.c: New file.
* sysdeps/unix/sysv/linux/x86_64/truncate64.c: New file.
* sysdeps/unix/sysv/linux/x86_64/umount.c: New file.
* sysdeps/unix/sysv/linux/x86_64/vfork.S: New file.
* sysdeps/unix/sysv/linux/x86_64/xstat.c: New file.
* sysdeps/unix/sysv/linux/x86_64/xstat64.c: New file.
* sysdeps/unix/x86_64/sysdep.S: New file.
* sysdeps/unix/x86_64/sysdep.h: New file.
* sysdeps/x86_64/Implies: New file.
* sysdeps/x86_64/Makefile: New file.
* sysdeps/x86_64/Versions: New file.
* sysdeps/x86_64/__longjmp.S: New file.
* sysdeps/x86_64/abort-instr.h: New file.
* sysdeps/x86_64/atomicity.h: New file.
* sysdeps/x86_64/bits/endian.h: New file.
* sysdeps/x86_64/bits/setjmp.h: New file.
* sysdeps/x86_64/bits/string.h: New file.
* sysdeps/x86_64/bp-asm.h: New file.
* sysdeps/x86_64/bsd-_setjmp.S: New file.
* sysdeps/x86_64/bsd-setjmp.S: New file.
* sysdeps/x86_64/dl-machine.h: New file.
* sysdeps/x86_64/elf/initfini.c: New file.
* sysdeps/x86_64/elf/start.S: New file.
* sysdeps/x86_64/ffs.c: New file.
* sysdeps/x86_64/ffsll.c: New file.
* sysdeps/x86_64/fpu/bits/fenv.h: New file.
* sysdeps/x86_64/fpu/bits/mathdef.h: New file.
* sysdeps/x86_64/fpu/e_acosl.c: New file.
* sysdeps/x86_64/fpu/e_atan2l.c: New file.
* sysdeps/x86_64/fpu/e_exp2l.S: New file.
* sysdeps/x86_64/fpu/e_expl.c: New file.
* sysdeps/x86_64/fpu/e_fmodl.S: New file.
* sysdeps/x86_64/fpu/e_log10l.S: New file.
* sysdeps/x86_64/fpu/e_log2l.S: New file.
* sysdeps/x86_64/fpu/e_logl.S: New file.
* sysdeps/x86_64/fpu/e_powl.S: New file.
* sysdeps/x86_64/fpu/e_rem_pio2l.c: New file.
* sysdeps/x86_64/fpu/e_scalbl.S: New file.
* sysdeps/x86_64/fpu/e_sqrtl.c: New file.
* sysdeps/x86_64/fpu/fclrexcpt.c: New file.
* sysdeps/x86_64/fpu/fedisblxcpt.c: New file.
* sysdeps/x86_64/fpu/feenablxcpt.c: New file.
* sysdeps/x86_64/fpu/fegetenv.c: New file.
* sysdeps/x86_64/fpu/fegetexcept.c: New file.
* sysdeps/x86_64/fpu/fegetround.c: New file.
* sysdeps/x86_64/fpu/feholdexcpt.c: New file.
* sysdeps/x86_64/fpu/fesetenv.c: New file.
* sysdeps/x86_64/fpu/fesetround.c: New file.
* sysdeps/x86_64/fpu/fgetexcptflg.c: New file.
* sysdeps/x86_64/fpu/fraiseexcpt.c: New file.
* sysdeps/x86_64/fpu/fsetexcptflg.c: New file.
* sysdeps/x86_64/fpu/ftestexcept.c: New file.
* sysdeps/x86_64/fpu/libm-test-ulps: New file.
* sysdeps/x86_64/fpu/math_ldbl.h: New file.
* sysdeps/x86_64/fpu/printf_fphex.c: New file.
* sysdeps/x86_64/fpu/s_atanl.c: New file.
* sysdeps/x86_64/fpu/s_cosl.S: New file.
* sysdeps/x86_64/fpu/s_expm1l.S: New file.
* sysdeps/x86_64/fpu/s_fpclassifyl.c: New file.
* sysdeps/x86_64/fpu/s_isinfl.c: New file.
* sysdeps/x86_64/fpu/s_isnanl.c: New file.
* sysdeps/x86_64/fpu/s_log1pl.S: New file.
* sysdeps/x86_64/fpu/s_logbl.c: New file.
* sysdeps/x86_64/fpu/s_nextafterl.c: New file.
* sysdeps/x86_64/fpu/s_nexttoward.c: New file.
* sysdeps/x86_64/fpu/s_nexttowardf.c: New file.
* sysdeps/x86_64/fpu/s_rintl.c: New file.
* sysdeps/x86_64/fpu/s_significandl.c: New file.
* sysdeps/x86_64/fpu/s_sincosl.S: New file.
* sysdeps/x86_64/fpu/s_sinl.S: New file.
* sysdeps/x86_64/fpu/s_tanl.S: New file.
* sysdeps/x86_64/gmp-mparam.h: New file.
* sysdeps/x86_64/hp-timing.c: New file.
* sysdeps/x86_64/hp-timing.h: New file.
* sysdeps/x86_64/htonl.S: New file.
* sysdeps/x86_64/memusage.h: New file.
* sysdeps/x86_64/setjmp.S: New file.
* sysdeps/x86_64/soft-fp/sfp-machine.h: New file.
* sysdeps/x86_64/stackinfo.h: New file.
* sysdeps/x86_64/sysdep.h: New file.
* sysdeps/unix/sysv/linux/x86_64/ldd-rewrite.sed: New file.