Commit 5a5c6435 by Janis Johnson Committed by Janis Johnson

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
parent 96474f36
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> 2009-05-06 Jakub Jelinek <jakub@redhat.com>
* dwarf2out.c (new_reg_loc_descr): Don't ever create DW_OP_regX. * dwarf2out.c (new_reg_loc_descr): Don't ever create DW_OP_regX.
......
...@@ -133,6 +133,7 @@ encode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED, ...@@ -133,6 +133,7 @@ encode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
decNumber dn; decNumber dn;
decimal32 d32; decimal32 d32;
decContext set; decContext set;
int32_t image;
decContextDefault (&set, DEC_INIT_DECIMAL128); decContextDefault (&set, DEC_INIT_DECIMAL128);
set.traps = 0; set.traps = 0;
...@@ -140,7 +141,8 @@ encode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED, ...@@ -140,7 +141,8 @@ encode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
decimal_to_decnumber (r, &dn); decimal_to_decnumber (r, &dn);
decimal32FromNumber (&d32, &dn, &set); 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. */ /* Decode an IEEE 754 decimal32 type into a real. */
...@@ -152,11 +154,13 @@ decode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED, ...@@ -152,11 +154,13 @@ decode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
decNumber dn; decNumber dn;
decimal32 d32; decimal32 d32;
decContext set; decContext set;
int32_t image;
decContextDefault (&set, DEC_INIT_DECIMAL128); decContextDefault (&set, DEC_INIT_DECIMAL128);
set.traps = 0; set.traps = 0;
memcpy (&d32.bytes, &buf[0], sizeof (uint32_t)); image = buf[0];
memcpy (&d32.bytes, &image, sizeof (int32_t));
decimal32ToNumber (&d32, &dn); decimal32ToNumber (&d32, &dn);
decimal_from_decnumber (r, &dn, &set); decimal_from_decnumber (r, &dn, &set);
...@@ -171,6 +175,7 @@ encode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED, ...@@ -171,6 +175,7 @@ encode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
decNumber dn; decNumber dn;
decimal64 d64; decimal64 d64;
decContext set; decContext set;
int32_t image;
decContextDefault (&set, DEC_INIT_DECIMAL128); decContextDefault (&set, DEC_INIT_DECIMAL128);
set.traps = 0; set.traps = 0;
...@@ -180,13 +185,17 @@ encode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED, ...@@ -180,13 +185,17 @@ encode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN) if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
{ {
memcpy (&buf[0], &d64.bytes[0], sizeof (uint32_t)); memcpy (&image, &d64.bytes[0], sizeof (int32_t));
memcpy (&buf[1], &d64.bytes[4], sizeof (uint32_t)); buf[0] = image;
memcpy (&image, &d64.bytes[4], sizeof (int32_t));
buf[1] = image;
} }
else else
{ {
memcpy (&buf[0], &d64.bytes[4], sizeof (uint32_t)); memcpy (&image, &d64.bytes[4], sizeof (int32_t));
memcpy (&buf[1], &d64.bytes[0], sizeof (uint32_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, ...@@ -199,19 +208,24 @@ decode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
decNumber dn; decNumber dn;
decimal64 d64; decimal64 d64;
decContext set; decContext set;
int32_t image;
decContextDefault (&set, DEC_INIT_DECIMAL128); decContextDefault (&set, DEC_INIT_DECIMAL128);
set.traps = 0; set.traps = 0;
if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN) if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
{ {
memcpy (&d64.bytes[0], &buf[0], sizeof (uint32_t)); image = buf[0];
memcpy (&d64.bytes[4], &buf[1], sizeof (uint32_t)); memcpy (&d64.bytes[0], &image, sizeof (int32_t));
image = buf[1];
memcpy (&d64.bytes[4], &image, sizeof (int32_t));
} }
else else
{ {
memcpy (&d64.bytes[0], &buf[1], sizeof (uint32_t)); image = buf[1];
memcpy (&d64.bytes[4], &buf[0], sizeof (uint32_t)); memcpy (&d64.bytes[0], &image, sizeof (int32_t));
image = buf[0];
memcpy (&d64.bytes[4], &image, sizeof (int32_t));
} }
decimal64ToNumber (&d64, &dn); decimal64ToNumber (&d64, &dn);
...@@ -227,6 +241,7 @@ encode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED, ...@@ -227,6 +241,7 @@ encode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
decNumber dn; decNumber dn;
decContext set; decContext set;
decimal128 d128; decimal128 d128;
int32_t image;
decContextDefault (&set, DEC_INIT_DECIMAL128); decContextDefault (&set, DEC_INIT_DECIMAL128);
set.traps = 0; set.traps = 0;
...@@ -236,17 +251,25 @@ encode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED, ...@@ -236,17 +251,25 @@ encode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN) if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
{ {
memcpy (&buf[0], &d128.bytes[0], sizeof (uint32_t)); memcpy (&image, &d128.bytes[0], sizeof (int32_t));
memcpy (&buf[1], &d128.bytes[4], sizeof (uint32_t)); buf[0] = image;
memcpy (&buf[2], &d128.bytes[8], sizeof (uint32_t)); memcpy (&image, &d128.bytes[4], sizeof (int32_t));
memcpy (&buf[3], &d128.bytes[12], sizeof (uint32_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 else
{ {
memcpy (&buf[0], &d128.bytes[12], sizeof (uint32_t)); memcpy (&image, &d128.bytes[12], sizeof (int32_t));
memcpy (&buf[1], &d128.bytes[8], sizeof (uint32_t)); buf[0] = image;
memcpy (&buf[2], &d128.bytes[4], sizeof (uint32_t)); memcpy (&image, &d128.bytes[8], sizeof (int32_t));
memcpy (&buf[3], &d128.bytes[0], sizeof (uint32_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, ...@@ -259,23 +282,32 @@ decode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
decNumber dn; decNumber dn;
decimal128 d128; decimal128 d128;
decContext set; decContext set;
int32_t image;
decContextDefault (&set, DEC_INIT_DECIMAL128); decContextDefault (&set, DEC_INIT_DECIMAL128);
set.traps = 0; set.traps = 0;
if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN) if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
{ {
memcpy (&d128.bytes[0], &buf[0], sizeof (uint32_t)); image = buf[0];
memcpy (&d128.bytes[4], &buf[1], sizeof (uint32_t)); memcpy (&d128.bytes[0], &image, sizeof (int32_t));
memcpy (&d128.bytes[8], &buf[2], sizeof (uint32_t)); image = buf[1];
memcpy (&d128.bytes[12], &buf[3], sizeof (uint32_t)); 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 else
{ {
memcpy (&d128.bytes[0], &buf[3], sizeof (uint32_t)); image = buf[3];
memcpy (&d128.bytes[4], &buf[2], sizeof (uint32_t)); memcpy (&d128.bytes[0], &image, sizeof (int32_t));
memcpy (&d128.bytes[8], &buf[1], sizeof (uint32_t)); image = buf[2];
memcpy (&d128.bytes[12], &buf[0], sizeof (uint32_t)); 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); decimal128ToNumber (&d128, &dn);
......
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> 2009-05-06 Michael Matz <matz@suse.de>
* gfortran.dg/pr40021.f: New test. * gfortran.dg/pr40021.f: New test.
......
/* { 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" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment