aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJanis Johnson <janis187@us.ibm.com>2009-05-06 16:59:53 +0000
committerJanis Johnson <janis@gcc.gnu.org>2009-05-06 16:59:53 +0000
commit5a5c6435c6f0576d08efc6d105ef15e6a5a571a0 (patch)
tree928ac88253beb44b86c88a28f7a5efaf4bc5f574 /gcc
parent96474f366fef95a6645cb06e5b2d30a6fce77783 (diff)
downloadgcc-5a5c6435c6f0576d08efc6d105ef15e6a5a571a0.zip
gcc-5a5c6435c6f0576d08efc6d105ef15e6a5a571a0.tar.gz
gcc-5a5c6435c6f0576d08efc6d105ef15e6a5a571a0.tar.bz2
re PR middle-end/39986 (decimal float constant is incorrect when cc1 is a 64-bit binary)
PR middle-end/39986 * dfp.c (encode_decimal32, decode_decimal32, encode_decimal64, decode_decimal64, encode_decimal128, decode_decimal128): Avoid 32-bit memcpy into long. * gcc.dg/dfp/pr39986.c: New test. From-SVN: r147188
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/dfp.c84
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/dfp/pr39986.c31
4 files changed, 101 insertions, 26 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7b3d41e..921d498 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2009-05-06 Janis Johnson <janis187@us.ibm.com>
+
+ PR middle-end/39986
+ * dfp.c (encode_decimal32, decode_decimal32, encode_decimal64,
+ decode_decimal64, encode_decimal128, decode_decimal128): Avoid
+ 32-bit memcpy into long.
+
2009-05-06 Jakub Jelinek <jakub@redhat.com>
* dwarf2out.c (new_reg_loc_descr): Don't ever create DW_OP_regX.
diff --git a/gcc/dfp.c b/gcc/dfp.c
index 875e8c4..5e1dbcc 100644
--- a/gcc/dfp.c
+++ b/gcc/dfp.c
@@ -133,6 +133,7 @@ encode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
decNumber dn;
decimal32 d32;
decContext set;
+ int32_t image;
decContextDefault (&set, DEC_INIT_DECIMAL128);
set.traps = 0;
@@ -140,7 +141,8 @@ encode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
decimal_to_decnumber (r, &dn);
decimal32FromNumber (&d32, &dn, &set);
- memcpy (&buf[0], d32.bytes, sizeof (uint32_t));
+ memcpy (&image, d32.bytes, sizeof (int32_t));
+ buf[0] = image;
}
/* Decode an IEEE 754 decimal32 type into a real. */
@@ -152,11 +154,13 @@ decode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
decNumber dn;
decimal32 d32;
decContext set;
+ int32_t image;
decContextDefault (&set, DEC_INIT_DECIMAL128);
set.traps = 0;
- memcpy (&d32.bytes, &buf[0], sizeof (uint32_t));
+ image = buf[0];
+ memcpy (&d32.bytes, &image, sizeof (int32_t));
decimal32ToNumber (&d32, &dn);
decimal_from_decnumber (r, &dn, &set);
@@ -171,6 +175,7 @@ encode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
decNumber dn;
decimal64 d64;
decContext set;
+ int32_t image;
decContextDefault (&set, DEC_INIT_DECIMAL128);
set.traps = 0;
@@ -180,13 +185,17 @@ encode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
{
- memcpy (&buf[0], &d64.bytes[0], sizeof (uint32_t));
- memcpy (&buf[1], &d64.bytes[4], sizeof (uint32_t));
+ memcpy (&image, &d64.bytes[0], sizeof (int32_t));
+ buf[0] = image;
+ memcpy (&image, &d64.bytes[4], sizeof (int32_t));
+ buf[1] = image;
}
else
{
- memcpy (&buf[0], &d64.bytes[4], sizeof (uint32_t));
- memcpy (&buf[1], &d64.bytes[0], sizeof (uint32_t));
+ memcpy (&image, &d64.bytes[4], sizeof (int32_t));
+ buf[0] = image;
+ memcpy (&image, &d64.bytes[0], sizeof (int32_t));
+ buf[1] = image;
}
}
@@ -199,19 +208,24 @@ decode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
decNumber dn;
decimal64 d64;
decContext set;
+ int32_t image;
decContextDefault (&set, DEC_INIT_DECIMAL128);
set.traps = 0;
if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
{
- memcpy (&d64.bytes[0], &buf[0], sizeof (uint32_t));
- memcpy (&d64.bytes[4], &buf[1], sizeof (uint32_t));
+ image = buf[0];
+ memcpy (&d64.bytes[0], &image, sizeof (int32_t));
+ image = buf[1];
+ memcpy (&d64.bytes[4], &image, sizeof (int32_t));
}
else
{
- memcpy (&d64.bytes[0], &buf[1], sizeof (uint32_t));
- memcpy (&d64.bytes[4], &buf[0], sizeof (uint32_t));
+ image = buf[1];
+ memcpy (&d64.bytes[0], &image, sizeof (int32_t));
+ image = buf[0];
+ memcpy (&d64.bytes[4], &image, sizeof (int32_t));
}
decimal64ToNumber (&d64, &dn);
@@ -227,6 +241,7 @@ encode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
decNumber dn;
decContext set;
decimal128 d128;
+ int32_t image;
decContextDefault (&set, DEC_INIT_DECIMAL128);
set.traps = 0;
@@ -236,17 +251,25 @@ encode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
{
- memcpy (&buf[0], &d128.bytes[0], sizeof (uint32_t));
- memcpy (&buf[1], &d128.bytes[4], sizeof (uint32_t));
- memcpy (&buf[2], &d128.bytes[8], sizeof (uint32_t));
- memcpy (&buf[3], &d128.bytes[12], sizeof (uint32_t));
+ memcpy (&image, &d128.bytes[0], sizeof (int32_t));
+ buf[0] = image;
+ memcpy (&image, &d128.bytes[4], sizeof (int32_t));
+ buf[1] = image;
+ memcpy (&image, &d128.bytes[8], sizeof (int32_t));
+ buf[2] = image;
+ memcpy (&image, &d128.bytes[12], sizeof (int32_t));
+ buf[3] = image;
}
else
{
- memcpy (&buf[0], &d128.bytes[12], sizeof (uint32_t));
- memcpy (&buf[1], &d128.bytes[8], sizeof (uint32_t));
- memcpy (&buf[2], &d128.bytes[4], sizeof (uint32_t));
- memcpy (&buf[3], &d128.bytes[0], sizeof (uint32_t));
+ memcpy (&image, &d128.bytes[12], sizeof (int32_t));
+ buf[0] = image;
+ memcpy (&image, &d128.bytes[8], sizeof (int32_t));
+ buf[1] = image;
+ memcpy (&image, &d128.bytes[4], sizeof (int32_t));
+ buf[2] = image;
+ memcpy (&image, &d128.bytes[0], sizeof (int32_t));
+ buf[3] = image;
}
}
@@ -259,23 +282,32 @@ decode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
decNumber dn;
decimal128 d128;
decContext set;
+ int32_t image;
decContextDefault (&set, DEC_INIT_DECIMAL128);
set.traps = 0;
if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
{
- memcpy (&d128.bytes[0], &buf[0], sizeof (uint32_t));
- memcpy (&d128.bytes[4], &buf[1], sizeof (uint32_t));
- memcpy (&d128.bytes[8], &buf[2], sizeof (uint32_t));
- memcpy (&d128.bytes[12], &buf[3], sizeof (uint32_t));
+ image = buf[0];
+ memcpy (&d128.bytes[0], &image, sizeof (int32_t));
+ image = buf[1];
+ memcpy (&d128.bytes[4], &image, sizeof (int32_t));
+ image = buf[2];
+ memcpy (&d128.bytes[8], &image, sizeof (int32_t));
+ image = buf[3];
+ memcpy (&d128.bytes[12], &image, sizeof (int32_t));
}
else
{
- memcpy (&d128.bytes[0], &buf[3], sizeof (uint32_t));
- memcpy (&d128.bytes[4], &buf[2], sizeof (uint32_t));
- memcpy (&d128.bytes[8], &buf[1], sizeof (uint32_t));
- memcpy (&d128.bytes[12], &buf[0], sizeof (uint32_t));
+ image = buf[3];
+ memcpy (&d128.bytes[0], &image, sizeof (int32_t));
+ image = buf[2];
+ memcpy (&d128.bytes[4], &image, sizeof (int32_t));
+ image = buf[1];
+ memcpy (&d128.bytes[8], &image, sizeof (int32_t));
+ image = buf[0];
+ memcpy (&d128.bytes[12], &image, sizeof (int32_t));
}
decimal128ToNumber (&d128, &dn);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b4abbed..f639c58 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2009-05-06 Janis Johnson <janis187@us.ibm.com>
+
+ PR middle-end/39986
+ * gcc.dg/dfp/pr39986.c: New test.
+
2009-05-06 Michael Matz <matz@suse.de>
* gfortran.dg/pr40021.f: New test.
diff --git a/gcc/testsuite/gcc.dg/dfp/pr39986.c b/gcc/testsuite/gcc.dg/dfp/pr39986.c
new file mode 100644
index 0000000..53bda3c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/pr39986.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99" } */
+
+/* Check that the compiler generates the correct decimal float constants. */
+
+_Decimal32 a = 100.223df;
+_Decimal32 b = -2.3df;
+_Decimal64 c = 3.4e-4dd;
+_Decimal64 d = -4.500dd;
+_Decimal128 e = 5678901234567.89e+200dl;
+_Decimal128 f = -678901.234e-6dl;
+
+/* The first value is DPD, the second is BID. The order differs depending
+ on whether the target is big-endian or little-endian. */
+
+/* { dg-final { scan-assembler ".long\t(572653859|822183807)\n" } } */
+
+/* { dg-final { scan-assembler ".long\t(-1572863965|-1308622825)\n" } } */
+
+/* { dg-final { scan-assembler ".long\t(52|34)\n" } } */
+/* { dg-final { scan-assembler ".long\t(572784640|824180736)\n" } } */
+
+/* { dg-final { scan-assembler ".long\t(4736|4500)\n" } } */
+/* { dg-final { scan-assembler ".long\t(-1574174720|-1319108608)\n" } } */
+
+/* { dg-final { scan-assembler ".long\t(-1975952433|957645077)\n" } } */
+/* { dg-final { scan-assembler ".long\t(190215|132222)\n" } } */
+/* { dg-final { scan-assembler ".long\t(574193664|835452928)\n" } } */
+
+/* { dg-final { scan-assembler ".long\t(931280180|678901234)\n" } } */
+/* { dg-final { scan-assembler ".long\t(-1576681472|-1339162624)\n" } } */