mirror of
git://sourceware.org/git/glibc.git
synced 2026-09-08 23:58:31 +08:00
stdio-common: Skip the a and A conversions for the IBM extended format
The reference implementation renders the a and A conversions by splitting the value into a significand of the width the type has and a power of two. That presumes the type is a single binary floating-point format. The IBM extended format is a pair of doubles instead, whose combined significand has no fixed width and whose subnormals are those of the low double rather than of the type, so what glibc produces for it does not follow from PREC and MINEXP: LDBL_MAX comes out as 0x1.fffffffffffff7ffffffffffff8p+1023 with twenty-eight fractional digits where the value has at most twenty-six worth of significand, and LDBL_TRUE_MIN as 0x0.0000000000001p-1022, which is the smallest subnormal double and nowhere near LDBL_MIN_EXP. The remaining conversions are unaffected, as they work from the value rather than from a decomposition of it, and were verified to be. Add an UNSUPPORTED_CONVS definition to the skeleton for conversions that cannot be modeled for the type at hand, and set it to the a and A pair where long double has that format, the generator then producing no records and an unsupported status which the long double wrapper reports. Tested on x86_64-linux-gnu and powerpc64le-linux-gnu, where all 672 results pass, and with the long double conversions forced to the IBM extended format, where the a and A ones report unsupported and the rest continue to pass. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
This commit is contained in:
committed by
Adhemerval Zanella
parent
71e40f25cf
commit
548997eb13
@@ -26,13 +26,22 @@ test_program_prefix=$1; shift
|
||||
|
||||
status=0
|
||||
|
||||
echo Verifying $format
|
||||
rc=0
|
||||
(set -o pipefail
|
||||
${test_program_prefix} \
|
||||
${common_objpfx}stdio-common/tst-printf-format-${xprintf}-ldouble $format |
|
||||
${PYTHON:-python3} tst-printf-format.py 2>&1 |
|
||||
head -n 1 |
|
||||
sed "s/^/Conversion $format output error, first line:\n/") 2>&1 ||
|
||||
status=1
|
||||
rc=$?
|
||||
|
||||
# The generator produces no records and reports an unsupported status for
|
||||
# a conversion the verification cannot model for the long double format in
|
||||
# use; see UNSUPPORTED_CONVS in tst-printf-format-skeleton-ldouble.c.
|
||||
case $rc in
|
||||
0) echo Verifying $format ;;
|
||||
77) echo Unsupported $format; status=77 ;;
|
||||
*) echo Verifying $format; status=1 ;;
|
||||
esac
|
||||
|
||||
exit $status
|
||||
|
||||
@@ -28,6 +28,15 @@
|
||||
#define REF_VAL(v) (v)
|
||||
#define PREC LDBL_MANT_DIG
|
||||
#define MINEXP LDBL_MIN_EXP
|
||||
#if LDBL_MANT_DIG == 106
|
||||
/* The IBM extended format is a pair of doubles rather than a significand
|
||||
of a single fixed width, so what the a and A conversions produce for it
|
||||
does not follow from PREC and MINEXP the way the verification assumes.
|
||||
Leave them out where the type has that format; the one target concerned
|
||||
builds everything with the IEEE format instead, so this only comes up
|
||||
where that has been turned off. */
|
||||
# define UNSUPPORTED_CONVS "aA"
|
||||
#endif
|
||||
typedef long double type_t;
|
||||
static const type_t vals[] =
|
||||
{ -HUGE_VAL, -LDBL_MAX, -LDBL_MIN, -0.0, -NAN, NAN, 0, LDBL_TRUE_MIN,
|
||||
|
||||
@@ -41,6 +41,10 @@
|
||||
MINEXP [optional] Minimum exponent integer constant. Set to the
|
||||
*_MIN_EXP value for the argument type handled, so that
|
||||
subnormal values can be told apart from normal ones.
|
||||
UNSUPPORTED_CONVS
|
||||
[optional] String of conversions the verification cannot
|
||||
model for the argument type handled. Asking for one of
|
||||
these produces no records and an unsupported status.
|
||||
|
||||
Typedefs:
|
||||
type_t Variadic function argument type. Define to the promoted
|
||||
@@ -67,6 +71,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <support/test-driver.h>
|
||||
|
||||
/* Set to nonzero to select all possible tuples with repetitions of 1..n
|
||||
elements from the set of flags as defined in FLAGS array below; n is
|
||||
@@ -87,6 +92,11 @@
|
||||
#ifndef MINEXP
|
||||
# define MINEXP 0
|
||||
#endif
|
||||
/* Set to the conversions that cannot be verified for the type handled;
|
||||
empty where they all can be, which is the usual case. */
|
||||
#ifndef UNSUPPORTED_CONVS
|
||||
# define UNSUPPORTED_CONVS ""
|
||||
#endif
|
||||
|
||||
/* The list of conversions permitted for the '#' flag, the '0' flag,
|
||||
and precision respectively. */
|
||||
@@ -333,6 +343,10 @@ do_test (int argc, char *argv[])
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
c = *argv[1];
|
||||
if (strchr (UNSUPPORTED_CONVS, c) != NULL)
|
||||
return EXIT_UNSUPPORTED;
|
||||
|
||||
mtrace ();
|
||||
|
||||
if (PREC != 0 && printf ("prec:%i\n", PREC) < 0)
|
||||
@@ -347,7 +361,6 @@ do_test (int argc, char *argv[])
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
c = *argv[1];
|
||||
for (v = 0; v < array_length (vals); v++)
|
||||
{
|
||||
if (printf ("val:%" REF_FMT "\n", REF_VAL (vals[v])) < 0)
|
||||
|
||||
Reference in New Issue
Block a user