OSDN Git Service

PR middle-end/39986
authorjanis <janis@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 6 May 2009 16:59:53 +0000 (16:59 +0000)
committerjanis <janis@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 6 May 2009 16:59:53 +0000 (16:59 +0000)
* 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
gcc/dfp.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/dfp/pr39986.c [new file with mode: 0644]

index 7b3d41e..921d498 100644 (file)
@@ -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.
index 875e8c4..5e1dbcc 100644 (file)
--- 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);
index b4abbed..f639c58 100644 (file)
@@ -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 (file)
index 0000000..53bda3c
--- /dev/null
@@ -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" } } */