OSDN Git Service

PR c++/39866
[pf3gnuchains/gcc-fork.git] / gcc / dfp.c
index 2526ef6..5e1dbcc 100644 (file)
--- a/gcc/dfp.c
+++ b/gcc/dfp.c
@@ -1,5 +1,6 @@
 /* Decimal floating point support.
-   Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software
+   Foundation, Inc.
 
 This file is part of GCC.
 
@@ -36,6 +37,10 @@ along with GCC; see the file COPYING3.  If not see
 #include "decimal32.h"
 #include "decNumber.h"
 
+#ifndef WORDS_BIGENDIAN
+#define WORDS_BIGENDIAN 0
+#endif
+
 /* Initialize R (a real with the decimal flag set) from DN.  Can
    utilize status passed in via CONTEXT, if a previous operation had
    interesting status.  */
@@ -119,7 +124,7 @@ decimal_to_decnumber (const REAL_VALUE_TYPE *r, decNumber *dn)
     dn->bits ^= DECNEG;
 }
 
-/* Encode a real into an IEEE 754R decimal32 type.  */
+/* Encode a real into an IEEE 754 decimal32 type.  */
 
 void
 encode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
@@ -128,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;
@@ -135,10 +141,11 @@ encode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
   decimal_to_decnumber (r, &dn); 
   decimal32FromNumber (&d32, &dn, &set);
 
-  buf[0] = *(uint32_t *) d32.bytes;
+  memcpy (&image, d32.bytes, sizeof (int32_t));
+  buf[0] = image;
 }
 
-/* Decode an IEEE 754R decimal32 type into a real.  */
+/* Decode an IEEE 754 decimal32 type into a real.  */
 
 void
 decode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
@@ -147,17 +154,19 @@ 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;
 
-  *((uint32_t *) d32.bytes) = (uint32_t) buf[0];
+  image = buf[0];
+  memcpy (&d32.bytes, &image, sizeof (int32_t));
 
   decimal32ToNumber (&d32, &dn);
   decimal_from_decnumber (r, &dn, &set); 
 }
 
-/* Encode a real into an IEEE 754R decimal64 type.  */
+/* Encode a real into an IEEE 754 decimal64 type.  */
 
 void
 encode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
@@ -166,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;
@@ -173,11 +183,23 @@ encode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
   decimal_to_decnumber (r, &dn);
   decimal64FromNumber (&d64, &dn, &set);
 
-  buf[0] = *(uint32_t *) &d64.bytes[0];
-  buf[1] = *(uint32_t *) &d64.bytes[4];
+  if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
+    {
+      memcpy (&image, &d64.bytes[0], sizeof (int32_t));
+      buf[0] = image;
+      memcpy (&image, &d64.bytes[4], sizeof (int32_t));
+      buf[1] = image;
+    }
+  else
+    {
+      memcpy (&image, &d64.bytes[4], sizeof (int32_t));
+      buf[0] = image;
+      memcpy (&image, &d64.bytes[0], sizeof (int32_t));
+      buf[1] = image;
+    }
 }
 
-/* Decode an IEEE 754R decimal64 type into a real.  */
+/* Decode an IEEE 754 decimal64 type into a real.  */
 
 void
 decode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
@@ -186,18 +208,31 @@ 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;
 
-  *((uint32_t *) &d64.bytes[0]) = (uint32_t) buf[0];
-  *((uint32_t *) &d64.bytes[4]) = (uint32_t) buf[1];
+  if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
+    {
+      image = buf[0];
+      memcpy (&d64.bytes[0], &image, sizeof (int32_t));
+      image = buf[1];
+      memcpy (&d64.bytes[4], &image, sizeof (int32_t));
+    }
+  else
+    {
+      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);
   decimal_from_decnumber (r, &dn, &set); 
 }
 
-/* Encode a real into an IEEE 754R decimal128 type.  */
+/* Encode a real into an IEEE 754 decimal128 type.  */
 
 void
 encode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
@@ -206,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;
@@ -213,13 +249,31 @@ encode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
   decimal_to_decnumber (r, &dn);
   decimal128FromNumber (&d128, &dn, &set);
 
-  buf[0] = *(uint32_t *) &d128.bytes[0];
-  buf[1] = *(uint32_t *) &d128.bytes[4];
-  buf[2] = *(uint32_t *) &d128.bytes[8];
-  buf[3] = *(uint32_t *) &d128.bytes[12];
+  if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
+    {
+      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 (&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;
+    }
 }
 
-/* Decode an IEEE 754R decimal128 type into a real.  */
+/* Decode an IEEE 754 decimal128 type into a real.  */
 
 void
 decode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
@@ -228,14 +282,33 @@ 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;
 
-  *((uint32_t *) &d128.bytes[0])  = (uint32_t) buf[0];
-  *((uint32_t *) &d128.bytes[4])  = (uint32_t) buf[1];
-  *((uint32_t *) &d128.bytes[8])  = (uint32_t) buf[2];
-  *((uint32_t *) &d128.bytes[12]) = (uint32_t) buf[3];
+  if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
+    {
+      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
+    {
+      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);
   decimal_from_decnumber (r, &dn, &set); 
@@ -528,7 +601,7 @@ decimal_real_to_integer2 (HOST_WIDE_INT *plow, HOST_WIDE_INT *phigh,
   decNumberZero (&dn3);
   decNumberRescale (&dn, &dn2, &dn3, &set);
 
-  /* Conver to REAL_VALUE_TYPE and call appropriate conversion
+  /* Convert to REAL_VALUE_TYPE and call appropriate conversion
      function.  */
   decNumberToString (&dn, string);
   real_from_string (&to, string);