From b0090d524a41163fcf8bbc16fdf36299b5f30d8c Mon Sep 17 00:00:00 2001 From: janis Date: Wed, 6 May 2009 16:59:53 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@147188 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 ++++ gcc/dfp.c | 84 ++++++++++++++++++++++++++------------ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.dg/dfp/pr39986.c | 31 ++++++++++++++ 4 files changed, 101 insertions(+), 26 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/dfp/pr39986.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7b3d41e9d1b..921d498ba39 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2009-05-06 Janis Johnson + + 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 * dwarf2out.c (new_reg_loc_descr): Don't ever create DW_OP_regX. diff --git a/gcc/dfp.c b/gcc/dfp.c index 875e8c409a0..5e1dbcc41eb 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 b4abbedc4f3..f639c581acd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-05-06 Janis Johnson + + PR middle-end/39986 + * gcc.dg/dfp/pr39986.c: New test. + 2009-05-06 Michael Matz * 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 00000000000..53bda3c824a --- /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" } } */ -- 2.11.0