glibc/math/test-tgmath-ret.c
Joseph Myers 55a38f8236 Add llogb, llogbf, llogbl.
TS 18661-1 defines llogb functions that are like ilogb except that
they return long int instead of int.  Corresponding FP_LLOGB* macros
are defined, whose values are required to have the obvious
correspondence to those of the FP_ILOGB* macros.

This patch implements these functions and macros for glibc.  llogb
uses the type-generic infrastructure, with an implementation similar
to the wrapper for ilogb but with additional conversion from FP_ILOGB*
to FP_LLOGB*; this approach avoids needing to modify or duplicate any
of the architecture-specific ilogb implementations.  Tests are also
based on those for ilogb.

Ideally the llogb functions would alias the ilogb ones when long is
32-bit, but such aliasing requires the associated header declarations
of the different-type alias to be hidden, typically by defining macros
before including the header (see e.g. how
sysdeps/ieee754/dbl-64/wordsize-64/s_llround.c defines lround to
__hidden_lround before including <math.h>).  The infrastructure for
type-generic function implementations does not support defining such
macros at present (since C code can't define a macro whose name is
determined by other macros).  So this patch leaves them as separate
functions (similar to e.g. scalbln and scalbn being separate in such a
case as well), but with the remapping of FP_ILOGB* to FP_LLOGB*
conditioned out in the case where it would be the identity map.

Tested for x86_64, x86, mips64 and powerpc.

	* math/bits/mathcalls.h [__GLIBC_USE (IEC_60559_BFP_EXT)] (llogb):
	New declaration.
	* math/tgmath.h [__GLIBC_USE (IEC_60559_BFP_EXT)] (llogb): New
	macro.
	* math/math.h [__GLIBC_USE (IEC_60559_BFP_EXT)] (__FP_LONG_MAX):
	New macro.
	[__GLIBC_USE (IEC_60559_BFP_EXT)] (FP_LLOGB0): Likewise.
	[__GLIBC_USE (IEC_60559_BFP_EXT)] (FP_LLOGBNAN): Likewise.
	* math/Versions (llogb): New libm symbol at version GLIBC_2.25.
	(llogbf): Likewise.
	(llogbl): Likewise.
	* math/Makefile (gen-libm-calls): Add w_llogbF.
	(tests): Add test-fp-llogb-constants.
	* math/w_llogb_template.c: New file.  Based on
	math/w_ilogb_template.c.
	* math/libm-test.inc (llogb_test_data): New array.
	(llogb_test): New function.
	(main): Call llogb_test.
	* math/test-fp-llogb-constants.c: New file.  Based on
	math/test-fp-ilogb-constants.c.
	* math/test-tgmath-ret.c (llogb): New CHECK_RET_CONST call.
	(do_test): Call check_return_llogb.
	* math/test-tgmath.c (NCALLS): Increase to 126.
	(F(compile_test)): Call llogb.
	(F(llogb)): New function.
	* manual/math.texi (Exponents and Logarithms): Document llogb,
	llogbf, llogbl, FP_LLOGB0 and FP_LLOGBNAN.
	* manual/libm-err-tab.pl (@all_functions): Add llogb.
	* sysdeps/ieee754/ldbl-opt/nldbl-llogb.c: New file.
	* sysdeps/ieee754/ldbl-opt/w_llogbl.c: Likewise.
	* sysdeps/ieee754/ldbl-opt/Makefile (libnldbl-calls): Add llogb.
	(CFLAGS-nldbl-llogb.c): New variable.
	* sysdeps/nacl/libm.abilist: Update.
	* sysdeps/unix/sysv/linux/aarch64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/alpha/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/arm/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/hppa/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/i386/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/ia64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/microblaze/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips32/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/nios2/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist:
	Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist:
	Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist:
	Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist:
	Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sh/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libm.abilist:
	Likewise.
	* sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libm.abilist:
	Likewise.
	* sysdeps/unix/sysv/linux/tile/tilepro/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist: Likewise.
2016-12-02 01:42:49 +00:00

87 lines
2.5 KiB
C

/* Test compilation of tgmath macros.
Copyright (C) 2003-2016 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Andreas Jaeger <aj@suse.de>, 2003.
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 <math.h>
#include <complex.h>
#include <tgmath.h>
#include <stdio.h>
static float fx;
static double dx;
static long double lx;
static int errors = 0;
static void
our_error (const char *c)
{
puts (c);
++errors;
}
/* First function where the return type is constant. */
#define CHECK_RET_CONST_TYPE(func, rettype, arg, name) \
if (sizeof (func (arg)) != sizeof (rettype)) \
our_error ("Return size of " #func " is wrong with " #name " argument");
#define CHECK_RET_CONST_FLOAT(func, rettype) \
CHECK_RET_CONST_TYPE (func, rettype, fx, float)
#define CHECK_RET_CONST_DOUBLE(func, rettype) \
CHECK_RET_CONST_TYPE (func, rettype, dx, double)
#ifdef NO_LONG_DOUBLE
# define CHECK_RET_CONST_LDOUBLE(func, rettype)
#else
# define CHECK_RET_CONST_LDOUBLE(func, rettype) \
CHECK_RET_CONST_TYPE (func, rettype, lx, long double)
#endif
#define CHECK_RET_CONST(func, rettype) \
static void \
check_return_ ##func (void) \
{ \
CHECK_RET_CONST_FLOAT (func, rettype) \
CHECK_RET_CONST_DOUBLE (func, rettype) \
CHECK_RET_CONST_LDOUBLE (func, rettype) \
}
CHECK_RET_CONST(ilogb, int)
CHECK_RET_CONST(llogb, long)
CHECK_RET_CONST(lrint, long)
CHECK_RET_CONST(lround, long)
CHECK_RET_CONST(llrint, long long)
CHECK_RET_CONST(llround, long long)
static int
do_test (void)
{
check_return_ilogb ();
check_return_llogb ();
check_return_lrint ();
check_return_lround ();
check_return_llrint ();
check_return_llround ();
printf ("%Zd\n", sizeof(carg (lx)));
return errors != 0;
}
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"