+2019-12-09 Joseph Myers <joseph@codesourcery.com>
+
+ PR middle-end/91226
+ * gcc.dg/dfp/bid-non-canonical-d128-1.c,
+ gcc.dg/dfp/bid-non-canonical-d128-2.c,
+ gcc.dg/dfp/bid-non-canonical-d128-3.c,
+ gcc.dg/dfp/bid-non-canonical-d128-4.c,
+ gcc.dg/dfp/bid-non-canonical-d32-1.c,
+ gcc.dg/dfp/bid-non-canonical-d32-2.c,
+ gcc.dg/dfp/bid-non-canonical-d64-1.c,
+ gcc.dg/dfp/bid-non-canonical-d64-2.c: New tests.
+
2019-12-09 Matthew Malcomson <matthew.malcomson@arm.com>
PR middle-end/92410
--- /dev/null
+/* Test non-canonical BID significands: _Decimal128. Bug 91226. */
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && lp64 } } } */
+/* { dg-options "-std=gnu2x -O2" } */
+
+extern void abort (void);
+extern void exit (int);
+
+union u
+{
+ _Decimal128 d128;
+ unsigned __int128 u128;
+};
+
+#define U128(hi, lo) (((unsigned __int128) lo) \
+ | (((unsigned __int128) hi) << 64))
+
+int
+main (void)
+{
+ unsigned __int128 i = U128 (0x3041ed09bead87c0ULL, 0x378d8e6400000001ULL);
+ union u x;
+ _Decimal128 d128;
+ x.u128 = i;
+ d128 = x.d128;
+ volatile double d = d128;
+ if (d == 0)
+ exit (0);
+ else
+ abort ();
+}
--- /dev/null
+/* Test non-canonical BID significands: _Decimal128, case where
+ combination field starts 11. Bug 91226. */
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && lp64 } } } */
+/* { dg-options "-std=gnu2x -O2" } */
+
+extern void abort (void);
+extern void exit (int);
+
+union u
+{
+ _Decimal128 d128;
+ unsigned __int128 u128;
+};
+
+#define U128(hi, lo) (((unsigned __int128) lo) \
+ | (((unsigned __int128) hi) << 64))
+
+int
+main (void)
+{
+ unsigned __int128 i = U128 (0x6e79000000000000ULL, 0x1ULL);
+ union u x;
+ _Decimal128 d128;
+ x.u128 = i;
+ d128 = x.d128;
+ volatile double d = d128;
+ if (d != 0)
+ abort ();
+ /* The above number should have quantum exponent 1234. */
+ _Decimal128 t1233 = 0.e1233DL, t1234 = 0.e1234DL, t1235 = 0.e1235DL;
+ _Decimal128 dx;
+ dx = d128 + t1233;
+ if (__builtin_memcmp (&dx, &t1233, 16) != 0)
+ abort ();
+ dx = d128 + t1234;
+ if (__builtin_memcmp (&dx, &t1234, 16) != 0)
+ abort ();
+ dx = d128 + t1235;
+ if (__builtin_memcmp (&dx, &t1234, 16) != 0)
+ abort ();
+ exit (0);
+}
--- /dev/null
+/* Test non-canonical BID significands: _Decimal128. Bug 91226. */
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && lp64 } } } */
+/* { dg-options "-std=gnu2x -O0" } */
+
+#include "bid-non-canonical-d128-1.c"
--- /dev/null
+/* Test non-canonical BID significands: _Decimal128, case where
+ combination field starts 11. Bug 91226. */
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && lp64 } } } */
+/* { dg-options "-std=gnu2x -O0" } */
+
+#include "bid-non-canonical-d128-2.c"
--- /dev/null
+/* Test non-canonical BID significands: _Decimal32. Bug 91226. */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-std=gnu2x -O2" } */
+
+extern void abort (void);
+extern void exit (int);
+
+union u
+{
+ _Decimal32 d32;
+ unsigned int u32;
+};
+
+int
+main (void)
+{
+ union u x;
+ _Decimal32 d32;
+ x.u32 = 0x6cb89681U;
+ d32 = x.d32;
+ volatile double d = d32;
+ if (d == 0)
+ exit (0);
+ else
+ abort ();
+}
--- /dev/null
+/* Test non-canonical BID significands: _Decimal32. Bug 91226. */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-std=gnu2x -O0" } */
+
+#include "bid-non-canonical-d32-1.c"
--- /dev/null
+/* Test non-canonical BID significands: _Decimal64. Bug 91226. */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-std=gnu2x -O2" } */
+
+extern void abort (void);
+extern void exit (int);
+
+union u
+{
+ _Decimal64 d64;
+ unsigned long long int u64;
+};
+
+int
+main (void)
+{
+ union u x;
+ _Decimal64 d64;
+ x.u64 = 0x6c7386f26fc10001ULL;
+ d64 = x.d64;
+ volatile double d = d64;
+ if (d == 0)
+ exit (0);
+ else
+ abort ();
+}
--- /dev/null
+/* Test non-canonical BID significands: _Decimal64. Bug 91226. */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-std=gnu2x -O0" } */
+
+#include "bid-non-canonical-d64-1.c"
+2019-12-09 Joseph Myers <joseph@codesourcery.com>
+
+ PR middle-end/91226
+ * bid/bid2dpd_dpd2bid.c (_bid_to_dpd64): Handle non-canonical
+ significands.
+ (_bid_to_dpd128): Likewise. Check for case where combination
+ field starts 1100, 1101 or 1110.
+
2019-01-01 Jakub Jelinek <jakub@redhat.com>
Update copyright years.
if ((comb & 0xc00) == 0xc00) { /* G0..G1 = 11 -> exp is G2..G11 */
exp = (comb) & 0x3ff;
bcoeff = (x & 0x0007ffffffffffffull) | 0x0020000000000000ull;
+ if (bcoeff >= 10000000000000000ull)
+ bcoeff = 0;
} else {
exp = (comb >> 2) & 0x3ff;
bcoeff = (x & 0x001fffffffffffffull);
if ((comb & 0x1e000) == 0x1e000) {
res = x;
} else { /* normal number */
- exp = ((x.w[1] & 0x7fff000000000000ull) >> 49) & 0x3fff;
- bcoeff.w[1] = (x.w[1] & 0x0001ffffffffffffull);
- bcoeff.w[0] = x.w[0];
+ if ((comb & 0x18000) == 0x18000) {
+ /* Noncanonical significand (prepending 8 or 9 to any 110-bit
+ trailing significand field produces a value above 10^34). */
+ exp = (comb & 0x7fff) >> 1;
+ bcoeff.w[1] = 0;
+ bcoeff.w[0] = 0;
+ } else {
+ exp = ((x.w[1] & 0x7fff000000000000ull) >> 49) & 0x3fff;
+ bcoeff.w[1] = (x.w[1] & 0x0001ffffffffffffull);
+ bcoeff.w[0] = x.w[0];
+ if (bcoeff.w[1] > 0x1ed09bead87c0ull
+ || (bcoeff.w[1] == 0x1ed09bead87c0ull
+ && bcoeff.w[0] >= 0x378d8e6400000000ull)) {
+ bcoeff.w[1] = 0;
+ bcoeff.w[0] = 0;
+ }
+ }
d1018 = reciprocals10_128[18];
__mul_128x128_high (BH, bcoeff, d1018);
amount = recip_scale[18];