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>
* 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,
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);
......
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.
......
/* { 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