aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel F. T. Gomes <gftg@linux.vnet.ibm.com>2017-05-29 10:49:42 -0300
committerGabriel F. T. Gomes <gftg@linux.vnet.ibm.com>2017-06-07 17:04:58 -0300
commitaab0f374e7c43f6baf88db271865feabb7bcc1b2 (patch)
tree4a83a72039818f7eea6942062462b2f9149e7d9d
parent32bf1d09dadee5b60df869ed3567a2b12c04e3fc (diff)
downloadglibc-aab0f374e7c43f6baf88db271865feabb7bcc1b2.zip
glibc-aab0f374e7c43f6baf88db271865feabb7bcc1b2.tar.gz
glibc-aab0f374e7c43f6baf88db271865feabb7bcc1b2.tar.bz2
Remove duplicated code from __printf_fp_l, __printf_fphex, and __printf_size
In __printf_fp_l, __printf_fphex, and __printf_size the blocks of code that are used to read a double or long double argument, check for special values and convert to multiprecision are similar. When adding float128 support to libc, more code would be duplicated to deal with the extra type. This patch moves the repetitive code to a macro which is now used by double and long double and will be used for float128 when support is added, thus avoiding more duplication. Tested for powerpc64le and s390x. * stdio-common/printf_fp.c (PRINTF_FP_FETCH): New macro. (__printf_fp_l): Use the new macro to avoid duplicating code. * stdio-common/printf_fphex.c (PRINTF_FPHEX_FETCH): New macro. (__printf_fphex): Use the new macro to avoid duplicating code. * stdio-common/printf_size.c (PRINTF_SIZE_FETCH): New macro. (__printf_size): Use the new macro to avoid duplicating code.
-rw-r--r--ChangeLog9
-rw-r--r--stdio-common/printf_fp.c130
-rw-r--r--stdio-common/printf_fphex.c110
-rw-r--r--stdio-common/printf_size.c75
4 files changed, 125 insertions, 199 deletions
diff --git a/ChangeLog b/ChangeLog
index 0b75c87..429fe41 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
2017-06-07 Gabriel F. T. Gomes <gftg@linux.vnet.ibm.com>
+ * stdio-common/printf_fp.c (PRINTF_FP_FETCH): New macro.
+ (__printf_fp_l): Use the new macro to avoid duplicating code.
+ * stdio-common/printf_fphex.c (PRINTF_FPHEX_FETCH): New macro.
+ (__printf_fphex): Use the new macro to avoid duplicating code.
+ * stdio-common/printf_size.c (PRINTF_SIZE_FETCH): New macro.
+ (__printf_size): Use the new macro to avoid duplicating code.
+
+2017-06-07 Gabriel F. T. Gomes <gftg@linux.vnet.ibm.com>
+
* include/gmp.h: Include bits/floatn.h
(__mpn_extract_float128): Declare when __HAVE_DISTINCT_FLOAT128 is 1.
* stdlib/gmp-impl.h: Also check if alloca is not defined before
diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c
index 7845d96..65ee9a7 100644
--- a/stdio-common/printf_fp.c
+++ b/stdio-common/printf_fp.c
@@ -327,94 +327,58 @@ __printf_fp_l (FILE *fp, locale_t loc,
else
grouping = NULL;
+#define PRINTF_FP_FETCH(FLOAT, VAR, SUFFIX, MANT_DIG) \
+ { \
+ (VAR) = *(const FLOAT *) args[0]; \
+ \
+ /* Check for special values: not a number or infinity. */ \
+ if (isnan (VAR)) \
+ { \
+ is_neg = signbit (VAR); \
+ if (isupper (info->spec)) \
+ { \
+ special = "NAN"; \
+ wspecial = L"NAN"; \
+ } \
+ else \
+ { \
+ special = "nan"; \
+ wspecial = L"nan"; \
+ } \
+ } \
+ else if (isinf (VAR)) \
+ { \
+ is_neg = signbit (VAR); \
+ if (isupper (info->spec)) \
+ { \
+ special = "INF"; \
+ wspecial = L"INF"; \
+ } \
+ else \
+ { \
+ special = "inf"; \
+ wspecial = L"inf"; \
+ } \
+ } \
+ else \
+ { \
+ p.fracsize = __mpn_extract_##SUFFIX \
+ (fp_input, \
+ (sizeof (fp_input) / sizeof (fp_input[0])), \
+ &p.exponent, &is_neg, VAR); \
+ to_shift = 1 + p.fracsize * BITS_PER_MP_LIMB - MANT_DIG; \
+ } \
+ }
+
/* Fetch the argument value. */
#ifndef __NO_LONG_DOUBLE_MATH
if (info->is_long_double && sizeof (long double) > sizeof (double))
- {
- fpnum.ldbl = *(const long double *) args[0];
-
- /* Check for special values: not a number or infinity. */
- if (isnan (fpnum.ldbl))
- {
- is_neg = signbit (fpnum.ldbl);
- if (isupper (info->spec))
- {
- special = "NAN";
- wspecial = L"NAN";
- }
- else
- {
- special = "nan";
- wspecial = L"nan";
- }
- }
- else if (isinf (fpnum.ldbl))
- {
- is_neg = signbit (fpnum.ldbl);
- if (isupper (info->spec))
- {
- special = "INF";
- wspecial = L"INF";
- }
- else
- {
- special = "inf";
- wspecial = L"inf";
- }
- }
- else
- {
- p.fracsize = __mpn_extract_long_double (fp_input,
- (sizeof (fp_input) /
- sizeof (fp_input[0])),
- &p.exponent, &is_neg,
- fpnum.ldbl);
- to_shift = 1 + p.fracsize * BITS_PER_MP_LIMB - LDBL_MANT_DIG;
- }
- }
+ PRINTF_FP_FETCH (long double, fpnum.ldbl, long_double, LDBL_MANT_DIG)
else
-#endif /* no long double */
- {
- fpnum.dbl = *(const double *) args[0];
+#endif
+ PRINTF_FP_FETCH (double, fpnum.dbl, double, DBL_MANT_DIG)
- /* Check for special values: not a number or infinity. */
- if (isnan (fpnum.dbl))
- {
- is_neg = signbit (fpnum.dbl);
- if (isupper (info->spec))
- {
- special = "NAN";
- wspecial = L"NAN";
- }
- else
- {
- special = "nan";
- wspecial = L"nan";
- }
- }
- else if (isinf (fpnum.dbl))
- {
- is_neg = signbit (fpnum.dbl);
- if (isupper (info->spec))
- {
- special = "INF";
- wspecial = L"INF";
- }
- else
- {
- special = "inf";
- wspecial = L"inf";
- }
- }
- else
- {
- p.fracsize = __mpn_extract_double (fp_input,
- (sizeof (fp_input)
- / sizeof (fp_input[0])),
- &p.exponent, &is_neg, fpnum.dbl);
- to_shift = 1 + p.fracsize * BITS_PER_MP_LIMB - DBL_MANT_DIG;
- }
- }
+#undef PRINTF_FP_FETCH
if (special)
{
diff --git a/stdio-common/printf_fphex.c b/stdio-common/printf_fphex.c
index b207e00..7b469c0 100644
--- a/stdio-common/printf_fphex.c
+++ b/stdio-common/printf_fphex.c
@@ -157,82 +157,52 @@ __printf_fphex (FILE *fp,
/* The decimal point character must never be zero. */
assert (*decimal != '\0' && decimalwc != L'\0');
+#define PRINTF_FPHEX_FETCH(FLOAT, VAR) \
+ { \
+ (VAR) = *(const FLOAT *) args[0]; \
+ \
+ /* Check for special values: not a number or infinity. */ \
+ if (isnan (VAR)) \
+ { \
+ if (isupper (info->spec)) \
+ { \
+ special = "NAN"; \
+ wspecial = L"NAN"; \
+ } \
+ else \
+ { \
+ special = "nan"; \
+ wspecial = L"nan"; \
+ } \
+ } \
+ else \
+ { \
+ if (isinf (VAR)) \
+ { \
+ if (isupper (info->spec)) \
+ { \
+ special = "INF"; \
+ wspecial = L"INF"; \
+ } \
+ else \
+ { \
+ special = "inf"; \
+ wspecial = L"inf"; \
+ } \
+ } \
+ } \
+ negative = signbit (VAR); \
+ }
/* Fetch the argument value. */
#ifndef __NO_LONG_DOUBLE_MATH
if (info->is_long_double && sizeof (long double) > sizeof (double))
- {
- fpnum.ldbl = *(const long double *) args[0];
-
- /* Check for special values: not a number or infinity. */
- if (isnan (fpnum.ldbl))
- {
- if (isupper (info->spec))
- {
- special = "NAN";
- wspecial = L"NAN";
- }
- else
- {
- special = "nan";
- wspecial = L"nan";
- }
- }
- else
- {
- if (isinf (fpnum.ldbl))
- {
- if (isupper (info->spec))
- {
- special = "INF";
- wspecial = L"INF";
- }
- else
- {
- special = "inf";
- wspecial = L"inf";
- }
- }
- }
- negative = signbit (fpnum.ldbl);
- }
+ PRINTF_FPHEX_FETCH (long double, fpnum.ldbl)
else
-#endif /* no long double */
- {
- fpnum.dbl.d = *(const double *) args[0];
+#endif
+ PRINTF_FPHEX_FETCH (double, fpnum.dbl.d)
- /* Check for special values: not a number or infinity. */
- if (isnan (fpnum.dbl.d))
- {
- if (isupper (info->spec))
- {
- special = "NAN";
- wspecial = L"NAN";
- }
- else
- {
- special = "nan";
- wspecial = L"nan";
- }
- }
- else
- {
- if (isinf (fpnum.dbl.d))
- {
- if (isupper (info->spec))
- {
- special = "INF";
- wspecial = L"INF";
- }
- else
- {
- special = "inf";
- wspecial = L"inf";
- }
- }
- }
- negative = signbit (fpnum.dbl.d);
- }
+#undef PRINTF_FPHEX_FETCH
if (special)
{
diff --git a/stdio-common/printf_size.c b/stdio-common/printf_size.c
index 9403aea..bc953dc 100644
--- a/stdio-common/printf_size.c
+++ b/stdio-common/printf_size.c
@@ -118,57 +118,40 @@ __printf_size (FILE *fp, const struct printf_info *info,
int done = 0;
int wide = info->wide;
+#define PRINTF_SIZE_FETCH(FLOAT, VAR) \
+ { \
+ (VAR) = *(const FLOAT *) args[0]; \
+ \
+ /* Check for special values: not a number or infinity. */ \
+ if (isnan (VAR)) \
+ { \
+ special = "nan"; \
+ wspecial = L"nan"; \
+ /* is_neg = 0; Already zero */ \
+ } \
+ else if (isinf (VAR)) \
+ { \
+ is_neg = signbit (VAR); \
+ special = "inf"; \
+ wspecial = L"inf"; \
+ } \
+ else \
+ while ((VAR) >= divisor && tag[1] != '\0') \
+ { \
+ (VAR) /= divisor; \
+ ++tag; \
+ } \
+ }
+
/* Fetch the argument value. */
#ifndef __NO_LONG_DOUBLE_MATH
if (info->is_long_double && sizeof (long double) > sizeof (double))
- {
- fpnum.ldbl = *(const long double *) args[0];
-
- /* Check for special values: not a number or infinity. */
- if (isnan (fpnum.ldbl))
- {
- special = "nan";
- wspecial = L"nan";
- // is_neg = 0; Already zero
- }
- else if (isinf (fpnum.ldbl))
- {
- is_neg = signbit (fpnum.ldbl);
- special = "inf";
- wspecial = L"inf";
- }
- else
- while (fpnum.ldbl >= divisor && tag[1] != '\0')
- {
- fpnum.ldbl /= divisor;
- ++tag;
- }
- }
+ PRINTF_SIZE_FETCH (long double, fpnum.ldbl)
else
-#endif /* no long double */
- {
- fpnum.dbl.d = *(const double *) args[0];
+#endif
+ PRINTF_SIZE_FETCH (double, fpnum.dbl.d)
- /* Check for special values: not a number or infinity. */
- if (isnan (fpnum.dbl.d))
- {
- special = "nan";
- wspecial = L"nan";
- // is_neg = 0; Already zero
- }
- else if (isinf (fpnum.dbl.d))
- {
- is_neg = signbit (fpnum.dbl.d);
- special = "inf";
- wspecial = L"inf";
- }
- else
- while (fpnum.dbl.d >= divisor && tag[1] != '\0')
- {
- fpnum.dbl.d /= divisor;
- ++tag;
- }
- }
+#undef PRINTF_SIZE_FETCH
if (special)
{