From 1b6adf888de14675bc3207578dcb7132ed5f8ecc Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Sat, 17 Aug 2013 18:21:58 +0930 Subject: PowerPC floating point little-endian [1 of 15] http://sourceware.org/ml/libc-alpha/2013-08/msg00081.html This is the first of a series of patches to ban ieee854_long_double and the ieee854_long_double macros when using IBM long double. union ieee854_long_double just isn't correct for IBM long double, especially when little-endian, and pretending it is OK has allowed a number of bugs to remain undetected in sysdeps/ieee754/ldbl-128ibm/. This changes the few places in generic code that use it. * stdio-common/printf_size.c (__printf_size): Don't use union ieee854_long_double in fpnum union. * stdio-common/printf_fphex.c (__printf_fphex): Likewise. Use signbit macro to retrieve sign from long double. * stdio-common/printf_fp.c (___printf_fp): Use signbit macro to retrieve sign from long double. * sysdeps/ieee754/ldbl-128ibm/printf_fphex.c: Adjust for fpnum change. * sysdeps/ieee754/ldbl-128/printf_fphex.c: Likewise. * sysdeps/ieee754/ldbl-96/printf_fphex.c: Likewise. * sysdeps/x86_64/fpu/printf_fphex.c: Likewise. * math/test-misc.c (main): Don't use union ieee854_long_double. ports/ * sysdeps/ia64/fpu/printf_fphex.c: Adjust for fpnum change. --- math/test-misc.c | 289 +++++++++++++++---------------------------------------- 1 file changed, 75 insertions(+), 214 deletions(-) (limited to 'math') diff --git a/math/test-misc.c b/math/test-misc.c index 27d673b823..f5276ebff9 100644 --- a/math/test-misc.c +++ b/math/test-misc.c @@ -722,300 +722,161 @@ main (void) #ifndef NO_LONG_DOUBLE { - union ieee854_long_double v1; - union ieee854_long_double v2; - long double ld; + long double v1, v2; - v1.d = ld = LDBL_MIN; - if (fpclassify (ld) != FP_NORMAL) + v1 = LDBL_MIN; + if (fpclassify (v1) != FP_NORMAL) { - printf ("fpclassify (LDBL_MIN) failed: %d\n", fpclassify (ld)); + printf ("fpclassify (LDBL_MIN) failed: %d (%La)\n", + fpclassify (v1), v1); result = 1; } - ld = nextafterl (ld, LDBL_MIN / 2.0); - if (fpclassify (ld) != FP_SUBNORMAL) + v2 = nextafterl (v1, LDBL_MIN / 2.0); + if (fpclassify (v2) != FP_SUBNORMAL) { printf ("fpclassify (LDBL_MIN-epsilon) failed: %d (%La)\n", - fpclassify (ld), ld); + fpclassify (v2), v2); result = 1; } - v2.d = ld = nextafterl (ld, LDBL_MIN); - if (fpclassify (ld) != FP_NORMAL) + v2 = nextafterl (v2, LDBL_MIN); + if (fpclassify (v2) != FP_NORMAL) { printf ("fpclassify (LDBL_MIN-epsilon+epsilon) failed: %d (%La)\n", - fpclassify (ld), ld); + fpclassify (v2), v2); result = 1; } - if (v1.ieee.mantissa0 != v2.ieee.mantissa0) + if (v1 != v2) { - printf ("LDBL_MIN: mantissa0 differs: %8x vs %8x\n", - v1.ieee.mantissa0, v2.ieee.mantissa0); - result = 1; - } - if (v1.ieee.mantissa1 != v2.ieee.mantissa1) - { - printf ("LDBL_MIN: mantissa1 differs: %8x vs %8x\n", - v1.ieee.mantissa1, v2.ieee.mantissa1); - result = 1; - } - if (v1.ieee.exponent != v2.ieee.exponent) - { - printf ("LDBL_MIN: exponent differs: %4x vs %4x\n", - v1.ieee.exponent, v2.ieee.exponent); - result = 1; - } - if (v1.ieee.negative != v2.ieee.negative) - { - printf ("LDBL_MIN: negative differs: %d vs %d\n", - v1.ieee.negative, v2.ieee.negative); + printf ("LDBL_MIN-epsilon+epsilon != LDBL_MIN: %La vs %La\n", v2, v1); result = 1; } - v1.d = ld = -LDBL_MIN; - if (fpclassify (ld) != FP_NORMAL) + v1 = -LDBL_MIN; + if (fpclassify (v1) != FP_NORMAL) { - printf ("fpclassify (-LDBL_MIN) failed: %d\n", fpclassify (ld)); + printf ("fpclassify (-LDBL_MIN) failed: %d (%La)\n", + fpclassify (v1), v1); result = 1; } - ld = nextafterl (ld, -LDBL_MIN / 2.0); - if (fpclassify (ld) != FP_SUBNORMAL) + v2 = nextafterl (v1, -LDBL_MIN / 2.0); + if (fpclassify (v2) != FP_SUBNORMAL) { printf ("fpclassify (-LDBL_MIN-epsilon) failed: %d (%La)\n", - fpclassify (ld), ld); + fpclassify (v2), v2); result = 1; } - v2.d = ld = nextafterl (ld, -LDBL_MIN); - if (fpclassify (ld) != FP_NORMAL) + v2 = nextafterl (v2, -LDBL_MIN); + if (fpclassify (v2) != FP_NORMAL) { printf ("fpclassify (-LDBL_MIN-epsilon+epsilon) failed: %d (%La)\n", - fpclassify (ld), ld); + fpclassify (v2), v2); result = 1; } - if (v1.ieee.mantissa0 != v2.ieee.mantissa0) - { - printf ("-LDBL_MIN: mantissa0 differs: %8x vs %8x\n", - v1.ieee.mantissa0, v2.ieee.mantissa0); - result = 1; - } - if (v1.ieee.mantissa1 != v2.ieee.mantissa1) - { - printf ("-LDBL_MIN: mantissa1 differs: %8x vs %8x\n", - v1.ieee.mantissa1, v2.ieee.mantissa1); - result = 1; - } - if (v1.ieee.exponent != v2.ieee.exponent) + if (v1 != v2) { - printf ("-LDBL_MIN: exponent differs: %4x vs %4x\n", - v1.ieee.exponent, v2.ieee.exponent); - result = 1; - } - if (v1.ieee.negative != v2.ieee.negative) - { - printf ("-LDBL_MIN: negative differs: %d vs %d\n", - v1.ieee.negative, v2.ieee.negative); + printf ("-LDBL_MIN-epsilon+epsilon != -LDBL_MIN: %La vs %La\n", v2, v1); result = 1; } - ld = LDBL_MAX; - if (fpclassify (ld) != FP_NORMAL) + v1 = LDBL_MAX; + if (fpclassify (v1) != FP_NORMAL) { - printf ("fpclassify (LDBL_MAX) failed: %d\n", fpclassify (ld)); + printf ("fpclassify (LDBL_MAX) failed: %d (%La)\n", + fpclassify (v1), v1); result = 1; } - ld = nextafterl (ld, INFINITY); - if (fpclassify (ld) != FP_INFINITE) + v2 = nextafterl (v1, INFINITY); + if (fpclassify (v2) != FP_INFINITE) { - printf ("fpclassify (LDBL_MAX+epsilon) failed: %d\n", fpclassify (ld)); + printf ("fpclassify (LDBL_MAX+epsilon) failed: %d (%La)\n", + fpclassify (v2), v2); result = 1; } - ld = -LDBL_MAX; - if (fpclassify (ld) != FP_NORMAL) + v1 = -LDBL_MAX; + if (fpclassify (v1) != FP_NORMAL) { - printf ("fpclassify (-LDBL_MAX) failed: %d\n", fpclassify (ld)); + printf ("fpclassify (-LDBL_MAX) failed: %d (%La)\n", + fpclassify (v1), v1); result = 1; } - ld = nextafterl (ld, -INFINITY); - if (fpclassify (ld) != FP_INFINITE) + v2 = nextafterl (v1, -INFINITY); + if (fpclassify (v2) != FP_INFINITE) { - printf ("fpclassify (-LDBL_MAX-epsilon) failed: %d\n", - fpclassify (ld)); + printf ("fpclassify (-LDBL_MAX-epsilon) failed: %d (%La)\n", + fpclassify (v2), v2); result = 1; } - v1.d = ld = 0.0625; - ld = nextafterl (ld, 0.0); - v2.d = ld = nextafterl (ld, 1.0); + v1 = 0.0625; + v2 = nextafterl (v1, 0.0); + v2 = nextafterl (v2, 1.0); - if (v1.ieee.mantissa0 != v2.ieee.mantissa0) - { - printf ("0.0625L down: mantissa0 differs: %8x vs %8x\n", - v1.ieee.mantissa0, v2.ieee.mantissa0); - result = 1; - } - if (v1.ieee.mantissa1 != v2.ieee.mantissa1) - { - printf ("0.0625L down: mantissa1 differs: %8x vs %8x\n", - v1.ieee.mantissa1, v2.ieee.mantissa1); - result = 1; - } - if (v1.ieee.exponent != v2.ieee.exponent) - { - printf ("0.0625L down: exponent differs: %4x vs %4x\n", - v1.ieee.exponent, v2.ieee.exponent); - result = 1; - } - if (v1.ieee.negative != v2.ieee.negative) + if (v1 != v2) { - printf ("0.0625L down: negative differs: %d vs %d\n", - v1.ieee.negative, v2.ieee.negative); + printf ("0.0625L-epsilon+epsilon != 0.0625L: %La vs %La\n", v2, v1); result = 1; } - v1.d = ld = 0.0625; - ld = nextafterl (ld, 1.0); - v2.d = ld = nextafterl (ld, 0.0); + v1 = 0.0625; + v2 = nextafterl (v1, 1.0); + v2 = nextafterl (v2, 0.0); - if (v1.ieee.mantissa0 != v2.ieee.mantissa0) - { - printf ("0.0625L up: mantissa0 differs: %8x vs %8x\n", - v1.ieee.mantissa0, v2.ieee.mantissa0); - result = 1; - } - if (v1.ieee.mantissa1 != v2.ieee.mantissa1) - { - printf ("0.0625L up: mantissa1 differs: %8x vs %8x\n", - v1.ieee.mantissa1, v2.ieee.mantissa1); - result = 1; - } - if (v1.ieee.exponent != v2.ieee.exponent) - { - printf ("0.0625L up: exponent differs: %4x vs %4x\n", - v1.ieee.exponent, v2.ieee.exponent); - result = 1; - } - if (v1.ieee.negative != v2.ieee.negative) + if (v1 != v2) { - printf ("0.0625L up: negative differs: %d vs %d\n", - v1.ieee.negative, v2.ieee.negative); + printf ("0.0625L+epsilon-epsilon != 0.0625L: %La vs %La\n", v2, v1); result = 1; } - v1.d = ld = -0.0625; - ld = nextafterl (ld, 0.0); - v2.d = ld = nextafterl (ld, -1.0); + v1 = -0.0625; + v2 = nextafterl (v1, 0.0); + v2 = nextafterl (v2, -1.0); - if (v1.ieee.mantissa0 != v2.ieee.mantissa0) + if (v1 != v2) { - printf ("-0.0625L up: mantissa0 differs: %8x vs %8x\n", - v1.ieee.mantissa0, v2.ieee.mantissa0); - result = 1; - } - if (v1.ieee.mantissa1 != v2.ieee.mantissa1) - { - printf ("-0.0625L up: mantissa1 differs: %8x vs %8x\n", - v1.ieee.mantissa1, v2.ieee.mantissa1); - result = 1; - } - if (v1.ieee.exponent != v2.ieee.exponent) - { - printf ("-0.0625L up: exponent differs: %4x vs %4x\n", - v1.ieee.exponent, v2.ieee.exponent); - result = 1; - } - if (v1.ieee.negative != v2.ieee.negative) - { - printf ("-0.0625L up: negative differs: %d vs %d\n", - v1.ieee.negative, v2.ieee.negative); + printf ("-0.0625L+epsilon-epsilon != -0.0625L: %La vs %La\n", v2, v1); result = 1; } - v1.d = ld = -0.0625; - ld = nextafterl (ld, -1.0); - v2.d = ld = nextafterl (ld, 0.0); + v1 = -0.0625; + v2 = nextafterl (v1, -1.0); + v2 = nextafterl (v2, 0.0); - if (v1.ieee.mantissa0 != v2.ieee.mantissa0) - { - printf ("-0.0625L down: mantissa0 differs: %8x vs %8x\n", - v1.ieee.mantissa0, v2.ieee.mantissa0); - result = 1; - } - if (v1.ieee.mantissa1 != v2.ieee.mantissa1) - { - printf ("-0.0625L down: mantissa1 differs: %8x vs %8x\n", - v1.ieee.mantissa1, v2.ieee.mantissa1); - result = 1; - } - if (v1.ieee.exponent != v2.ieee.exponent) + if (v1 != v2) { - printf ("-0.0625L down: exponent differs: %4x vs %4x\n", - v1.ieee.exponent, v2.ieee.exponent); - result = 1; - } - if (v1.ieee.negative != v2.ieee.negative) - { - printf ("-0.0625L down: negative differs: %d vs %d\n", - v1.ieee.negative, v2.ieee.negative); + printf ("-0.0625L-epsilon+epsilon != -0.0625L: %La vs %La\n", v2, v1); result = 1; } - v1.d = ld = 0.0; - ld = nextafterl (ld, 1.0); - v2.d = nextafterl (ld, -1.0); + v1 = 0.0; + v2 = nextafterl (v1, 1.0); + v2 = nextafterl (v2, -1.0); - if (v1.ieee.mantissa0 != v2.ieee.mantissa0) - { - printf ("0.0L up: mantissa0 differs: %8x vs %8x\n", - v1.ieee.mantissa0, v2.ieee.mantissa0); - result = 1; - } - if (v1.ieee.mantissa1 != v2.ieee.mantissa1) - { - printf ("0.0L up: mantissa1 differs: %8x vs %8x\n", - v1.ieee.mantissa1, v2.ieee.mantissa1); - result = 1; - } - if (v1.ieee.exponent != v2.ieee.exponent) + if (v1 != v2) { - printf ("0.0L up: exponent differs: %4x vs %4x\n", - v1.ieee.exponent, v2.ieee.exponent); + printf ("0.0+epsilon-epsilon != 0.0L: %La vs %La\n", v2, v1); result = 1; } - if (0 != v2.ieee.negative) + if (signbit (v2)) { - printf ("0.0L up: negative differs: 0 vs %d\n", - v2.ieee.negative); + printf ("0.0+epsilon-epsilon is negative\n"); result = 1; } - v1.d = ld = 0.0; - ld = nextafterl (ld, -1.0); - v2.d = nextafterl (ld, 1.0); + v1 = 0.0; + v2 = nextafterl (v1, -1.0); + v2 = nextafterl (v2, 1.0); - if (v1.ieee.mantissa0 != v2.ieee.mantissa0) - { - printf ("0.0L down: mantissa0 differs: %8x vs %8x\n", - v1.ieee.mantissa0, v2.ieee.mantissa0); - result = 1; - } - if (v1.ieee.mantissa1 != v2.ieee.mantissa1) + if (v1 != v2) { - printf ("0.0L down: mantissa1 differs: %8x vs %8x\n", - v1.ieee.mantissa1, v2.ieee.mantissa1); - result = 1; - } - if (v1.ieee.exponent != v2.ieee.exponent) - { - printf ("0.0L down: exponent differs: %4x vs %4x\n", - v1.ieee.exponent, v2.ieee.exponent); + printf ("0.0-epsilon+epsilon != 0.0L: %La vs %La\n", v2, v1); result = 1; } - if (1 != v2.ieee.negative) + if (!signbit (v2)) { - printf ("0.0L down: negative differs: 1 vs %d\n", - v2.ieee.negative); + printf ("0.0-epsilon+epsilon is positive\n"); result = 1; } -- cgit 1.4.1