OSDN Git Service

* config/arc/arc.h (LIB_SPEC): Define.
[pf3gnuchains/gcc-fork.git] / gcc / dfp.c
index ab05751..5a18db9 100644 (file)
--- a/gcc/dfp.c
+++ b/gcc/dfp.c
@@ -1,11 +1,12 @@
 /* Decimal floating point support.
 /* Decimal floating point support.
-   Copyright (C) 2005 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+   Foundation, Inc.
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -14,17 +15,14 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
 #include "tree.h"
 
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
 #include "tree.h"
-#include "toplev.h"
-#include "real.h"
 #include "tm_p.h"
 #include "dfp.h"
 
 #include "tm_p.h"
 #include "dfp.h"
 
@@ -32,28 +30,14 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
    decNumber structure is large enough to hold decimal128 digits.  */
 
 #include "decimal128.h"
    decNumber structure is large enough to hold decimal128 digits.  */
 
 #include "decimal128.h"
+#include "decimal128Local.h"
 #include "decimal64.h"
 #include "decimal32.h"
 #include "decNumber.h"
 
 #include "decimal64.h"
 #include "decimal32.h"
 #include "decNumber.h"
 
-static unsigned long
-dfp_byte_swap (unsigned long in)
-{
-  unsigned long out;
-  unsigned char *p = (unsigned char *) &out;
-  union {
-    unsigned long i;
-    unsigned char b[4];
-  } u;
-
-  u.i = in;
-  p[0] = u.b[3];
-  p[1] = u.b[2];
-  p[2] = u.b[1];
-  p[3] = u.b[0];
-
-  return out;
-}
+#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
 
 /* Initialize R (a real with the decimal flag set) from DN.  Can
    utilize status passed in via CONTEXT, if a previous operation had
@@ -65,8 +49,6 @@ decimal_from_decnumber (REAL_VALUE_TYPE *r, decNumber *dn, decContext *context)
   memset (r, 0, sizeof (REAL_VALUE_TYPE));
 
   r->cl = rvc_normal;
   memset (r, 0, sizeof (REAL_VALUE_TYPE));
 
   r->cl = rvc_normal;
-  if (decNumberIsZero (dn))
-    r->cl = rvc_zero;
   if (decNumberIsNaN (dn))
     r->cl = rvc_nan;
   if (decNumberIsInfinite (dn))
   if (decNumberIsNaN (dn))
     r->cl = rvc_nan;
   if (decNumberIsInfinite (dn))
@@ -96,7 +78,7 @@ decimal_real_from_string (REAL_VALUE_TYPE *r, const char *s)
   decContextDefault (&set, DEC_INIT_DECIMAL128);
   set.traps = 0;
 
   decContextDefault (&set, DEC_INIT_DECIMAL128);
   set.traps = 0;
 
-  decNumberFromString (&dn, (char *) s, &set);
+  decNumberFromString (&dn, s, &set);
 
   /* It would be more efficient to store directly in decNumber format,
      but that is impractical from current data structure size.
 
   /* It would be more efficient to store directly in decNumber format,
      but that is impractical from current data structure size.
@@ -119,17 +101,17 @@ decimal_to_decnumber (const REAL_VALUE_TYPE *r, decNumber *dn)
       decNumberZero (dn);
       break;
     case rvc_inf:
       decNumberZero (dn);
       break;
     case rvc_inf:
-      decNumberFromString (dn, (char *)"Infinity", &set);
+      decNumberFromString (dn, "Infinity", &set);
       break;
     case rvc_nan:
       if (r->signalling)
       break;
     case rvc_nan:
       if (r->signalling)
-        decNumberFromString (dn, (char *)"snan", &set);
+        decNumberFromString (dn, "snan", &set);
       else
       else
-        decNumberFromString (dn, (char *)"nan", &set);
+        decNumberFromString (dn, "nan", &set);
       break;
     case rvc_normal:
       gcc_assert (r->decimal);
       break;
     case rvc_normal:
       gcc_assert (r->decimal);
-      decimal128ToNumber ((decimal128 *) r->sig, dn);
+      decimal128ToNumber ((const decimal128 *) r->sig, dn);
       break;
     default:
       gcc_unreachable ();
       break;
     default:
       gcc_unreachable ();
@@ -137,61 +119,61 @@ decimal_to_decnumber (const REAL_VALUE_TYPE *r, decNumber *dn)
 
   /* Fix up sign bit.  */
   if (r->sign != decNumberIsNegative (dn))
 
   /* Fix up sign bit.  */
   if (r->sign != decNumberIsNegative (dn))
-    decNumberNegate (dn);
+    dn->bits ^= DECNEG;
 }
 
 }
 
-/* Encode a real into an IEEE 754R decimal32 type.  */
+/* Encode a real into an IEEE 754 decimal32 type.  */
 
 
-void 
+void
 encode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
                  long *buf, const REAL_VALUE_TYPE *r)
 {
   decNumber dn;
   decimal32 d32;
   decContext set;
 encode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
                  long *buf, const REAL_VALUE_TYPE *r)
 {
   decNumber dn;
   decimal32 d32;
   decContext set;
+  int32_t image;
 
   decContextDefault (&set, DEC_INIT_DECIMAL128);
   set.traps = 0;
 
 
   decContextDefault (&set, DEC_INIT_DECIMAL128);
   set.traps = 0;
 
-  decimal_to_decnumber (r, &dn); 
+  decimal_to_decnumber (r, &dn);
   decimal32FromNumber (&d32, &dn, &set);
 
   decimal32FromNumber (&d32, &dn, &set);
 
-  if (FLOAT_WORDS_BIG_ENDIAN)
-    buf[0] = *(uint32_t *) d32.bytes;
-  else
-    buf[0] = dfp_byte_swap (*(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,
-                      REAL_VALUE_TYPE *r, const long *buf)
+void
+decode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
+                 REAL_VALUE_TYPE *r, const long *buf)
 {
   decNumber dn;
   decimal32 d32;
   decContext set;
 {
   decNumber dn;
   decimal32 d32;
   decContext set;
+  int32_t image;
 
   decContextDefault (&set, DEC_INIT_DECIMAL128);
   set.traps = 0;
 
 
   decContextDefault (&set, DEC_INIT_DECIMAL128);
   set.traps = 0;
 
-  if (FLOAT_WORDS_BIG_ENDIAN)
-    *((uint32_t *) d32.bytes) = (uint32_t) buf[0];
-  else
-    *((uint32_t *) d32.bytes) = dfp_byte_swap ((uint32_t) buf[0]);
+  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);
 }
 
 }
 
-/* Encode a real into an IEEE 754R decimal64 type.  */
+/* Encode a real into an IEEE 754 decimal64 type.  */
 
 
-void 
+void
 encode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
                  long *buf, const REAL_VALUE_TYPE *r)
 {
   decNumber dn;
   decimal64 d64;
   decContext set;
 encode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
                  long *buf, const REAL_VALUE_TYPE *r)
 {
   decNumber dn;
   decimal64 d64;
   decContext set;
+  int32_t image;
 
   decContextDefault (&set, DEC_INIT_DECIMAL128);
   set.traps = 0;
 
   decContextDefault (&set, DEC_INIT_DECIMAL128);
   set.traps = 0;
@@ -199,55 +181,65 @@ encode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
   decimal_to_decnumber (r, &dn);
   decimal64FromNumber (&d64, &dn, &set);
 
   decimal_to_decnumber (r, &dn);
   decimal64FromNumber (&d64, &dn, &set);
 
-  if (FLOAT_WORDS_BIG_ENDIAN)
+  if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
     {
     {
-      buf[0] = *(uint32_t *) &d64.bytes[0];
-      buf[1] = *(uint32_t *) &d64.bytes[4];
+      memcpy (&image, &d64.bytes[0], sizeof (int32_t));
+      buf[0] = image;
+      memcpy (&image, &d64.bytes[4], sizeof (int32_t));
+      buf[1] = image;
     }
   else
     {
     }
   else
     {
-      buf[1] = dfp_byte_swap (*(uint32_t *) &d64.bytes[0]);
-      buf[0] = dfp_byte_swap (*(uint32_t *) &d64.bytes[4]);
+      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 
+void
 decode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
                  REAL_VALUE_TYPE *r, const long *buf)
 decode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
                  REAL_VALUE_TYPE *r, const long *buf)
-{ 
+{
   decNumber dn;
   decimal64 d64;
   decContext set;
   decNumber dn;
   decimal64 d64;
   decContext set;
+  int32_t image;
 
   decContextDefault (&set, DEC_INIT_DECIMAL128);
   set.traps = 0;
 
 
   decContextDefault (&set, DEC_INIT_DECIMAL128);
   set.traps = 0;
 
-  if (FLOAT_WORDS_BIG_ENDIAN)
+  if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
     {
     {
-      *((uint32_t *) &d64.bytes[0]) = (uint32_t) buf[0];
-      *((uint32_t *) &d64.bytes[4]) = (uint32_t) buf[1];
+      image = buf[0];
+      memcpy (&d64.bytes[0], &image, sizeof (int32_t));
+      image = buf[1];
+      memcpy (&d64.bytes[4], &image, sizeof (int32_t));
     }
   else
     {
     }
   else
     {
-      *((uint32_t *) &d64.bytes[0]) = dfp_byte_swap ((uint32_t) buf[1]);
-      *((uint32_t *) &d64.bytes[4]) = dfp_byte_swap ((uint32_t) buf[0]); 
+      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);
     }
 
   decimal64ToNumber (&d64, &dn);
-  decimal_from_decnumber (r, &dn, &set); 
+  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 
+void
 encode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
                   long *buf, const REAL_VALUE_TYPE *r)
 {
   decNumber dn;
   decContext set;
   decimal128 d128;
 encode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
                   long *buf, const REAL_VALUE_TYPE *r)
 {
   decNumber dn;
   decContext set;
   decimal128 d128;
+  int32_t image;
 
   decContextDefault (&set, DEC_INIT_DECIMAL128);
   set.traps = 0;
 
   decContextDefault (&set, DEC_INIT_DECIMAL128);
   set.traps = 0;
@@ -255,52 +247,69 @@ encode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
   decimal_to_decnumber (r, &dn);
   decimal128FromNumber (&d128, &dn, &set);
 
   decimal_to_decnumber (r, &dn);
   decimal128FromNumber (&d128, &dn, &set);
 
-  if (FLOAT_WORDS_BIG_ENDIAN)
+  if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
     {
     {
-      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];
+      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
     {
     }
   else
     {
-      buf[0] = dfp_byte_swap (*(uint32_t *) &d128.bytes[12]);
-      buf[1] = dfp_byte_swap (*(uint32_t *) &d128.bytes[8]);
-      buf[2] = dfp_byte_swap (*(uint32_t *) &d128.bytes[4]);
-      buf[3] = dfp_byte_swap (*(uint32_t *) &d128.bytes[0]);
+      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 
+void
 decode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
                   REAL_VALUE_TYPE *r, const long *buf)
 {
   decNumber dn;
   decimal128 d128;
   decContext set;
 decode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
                   REAL_VALUE_TYPE *r, const long *buf)
 {
   decNumber dn;
   decimal128 d128;
   decContext set;
+  int32_t image;
 
   decContextDefault (&set, DEC_INIT_DECIMAL128);
   set.traps = 0;
 
 
   decContextDefault (&set, DEC_INIT_DECIMAL128);
   set.traps = 0;
 
-  if (FLOAT_WORDS_BIG_ENDIAN)
+  if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
     {
     {
-      *((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];
+      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
     {
     }
   else
     {
-      *((uint32_t *) &d128.bytes[0])  = dfp_byte_swap ((uint32_t) buf[3]);
-      *((uint32_t *) &d128.bytes[4])  = dfp_byte_swap ((uint32_t) buf[2]);
-      *((uint32_t *) &d128.bytes[8])  = dfp_byte_swap ((uint32_t) buf[1]);
-      *((uint32_t *) &d128.bytes[12]) = dfp_byte_swap ((uint32_t) buf[0]);
+      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);
     }
 
   decimal128ToNumber (&d128, &dn);
-  decimal_from_decnumber (r, &dn, &set); 
+  decimal_from_decnumber (r, &dn, &set);
 }
 
 /* Helper function to convert from a binary real internal
 }
 
 /* Helper function to convert from a binary real internal
@@ -311,8 +320,7 @@ decimal_to_binary (REAL_VALUE_TYPE *to, const REAL_VALUE_TYPE *from,
                   enum machine_mode mode)
 {
   char string[256];
                   enum machine_mode mode)
 {
   char string[256];
-  decimal128 *d128;
-  d128 = (decimal128 *) from->sig;
+  const decimal128 *const d128 = (const decimal128 *) from->sig;
 
   decimal128ToString (d128, string);
   real_from_string3 (to, string, mode);
 
   decimal128ToString (d128, string);
   real_from_string3 (to, string, mode);
@@ -333,7 +341,7 @@ decimal_from_binary (REAL_VALUE_TYPE *to, const REAL_VALUE_TYPE *from)
 }
 
 /* Helper function to real.c:do_compare() to handle decimal internal
 }
 
 /* Helper function to real.c:do_compare() to handle decimal internal
-   represenation including when one of the operands is still in the
+   representation including when one of the operands is still in the
    binary internal representation.  */
 
 int
    binary internal representation.  */
 
 int
@@ -355,12 +363,12 @@ decimal_do_compare (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b,
       decimal_from_binary (&b1, b);
       b = &b1;
     }
       decimal_from_binary (&b1, b);
       b = &b1;
     }
-    
+
   /* Convert into decNumber form for comparison operation.  */
   decContextDefault (&set, DEC_INIT_DECIMAL128);
   /* Convert into decNumber form for comparison operation.  */
   decContextDefault (&set, DEC_INIT_DECIMAL128);
-  set.traps = 0;  
-  decimal128ToNumber ((decimal128 *) a->sig, &dn2);
-  decimal128ToNumber ((decimal128 *) b->sig, &dn3);
+  set.traps = 0;
+  decimal128ToNumber ((const decimal128 *) a->sig, &dn2);
+  decimal128ToNumber ((const decimal128 *) b->sig, &dn3);
 
   /* Finally, do the comparison.  */
   decNumberCompare (&dn, &dn2, &dn3, &set);
 
   /* Finally, do the comparison.  */
   decNumberCompare (&dn, &dn2, &dn3, &set);
@@ -372,7 +380,7 @@ decimal_do_compare (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b,
     return 0;
   else if (decNumberIsNegative (&dn))
     return -1;
     return 0;
   else if (decNumberIsNegative (&dn))
     return -1;
-  else 
+  else
     return 1;
 }
 
     return 1;
 }
 
@@ -425,7 +433,7 @@ decimal_round_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r)
    binary and decimal types.  */
 
 void
    binary and decimal types.  */
 
 void
-decimal_real_convert (REAL_VALUE_TYPE *r, enum machine_mode mode, 
+decimal_real_convert (REAL_VALUE_TYPE *r, enum machine_mode mode,
                      const REAL_VALUE_TYPE *a)
 {
   const struct real_format *fmt = REAL_MODE_FORMAT (mode);
                      const REAL_VALUE_TYPE *a)
 {
   const struct real_format *fmt = REAL_MODE_FORMAT (mode);
@@ -444,12 +452,13 @@ decimal_real_convert (REAL_VALUE_TYPE *r, enum machine_mode mode,
    CROP_TRAILING_ZEROS, strip trailing zeros.  Currently, not honoring
    DIGITS or CROP_TRAILING_ZEROS.  */
 
    CROP_TRAILING_ZEROS, strip trailing zeros.  Currently, not honoring
    DIGITS or CROP_TRAILING_ZEROS.  */
 
-void decimal_real_to_decimal (char *str, const REAL_VALUE_TYPE *r_orig,
-                             size_t buf_size,
-                             size_t digits ATTRIBUTE_UNUSED,
-                             int crop_trailing_zeros ATTRIBUTE_UNUSED)
+void
+decimal_real_to_decimal (char *str, const REAL_VALUE_TYPE *r_orig,
+                        size_t buf_size,
+                        size_t digits ATTRIBUTE_UNUSED,
+                        int crop_trailing_zeros ATTRIBUTE_UNUSED)
 {
 {
-  decimal128 *d128 = (decimal128*) r_orig->sig;
+  const decimal128 *const d128 = (const decimal128*) r_orig->sig;
 
   /* decimal128ToString requires space for at least 24 characters;
      Require two more for suffix.  */
 
   /* decimal128ToString requires space for at least 24 characters;
      Require two more for suffix.  */
@@ -473,7 +482,7 @@ decimal_do_add (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0,
 
   if (subtract_p)
     decNumberSubtract (&dn, &dn2, &dn3, &set);
 
   if (subtract_p)
     decNumberSubtract (&dn, &dn2, &dn3, &set);
-  else 
+  else
     decNumberAdd (&dn, &dn2, &dn3, &set);
 
   decimal_from_decnumber (r, &dn, &set);
     decNumberAdd (&dn, &dn2, &dn3, &set);
 
   decimal_from_decnumber (r, &dn, &set);
@@ -538,7 +547,7 @@ decimal_do_fix_trunc (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a)
   decContextDefault (&set, DEC_INIT_DECIMAL128);
   set.traps = 0;
   set.round = DEC_ROUND_DOWN;
   decContextDefault (&set, DEC_INIT_DECIMAL128);
   set.traps = 0;
   set.round = DEC_ROUND_DOWN;
-  decimal128ToNumber ((decimal128 *) a->sig, &dn2);
+  decimal128ToNumber ((const decimal128 *) a->sig, &dn2);
 
   decNumberToIntegralValue (&dn, &dn2, &set);
   decimal_from_decnumber (r, &dn, &set);
 
   decNumberToIntegralValue (&dn, &dn2, &set);
   decimal_from_decnumber (r, &dn, &set);
@@ -557,7 +566,7 @@ decimal_real_to_integer (const REAL_VALUE_TYPE *r)
   decContextDefault (&set, DEC_INIT_DECIMAL128);
   set.traps = 0;
   set.round = DEC_ROUND_DOWN;
   decContextDefault (&set, DEC_INIT_DECIMAL128);
   set.traps = 0;
   set.round = DEC_ROUND_DOWN;
-  decimal128ToNumber ((decimal128 *) r->sig, &dn);
+  decimal128ToNumber ((const decimal128 *) r->sig, &dn);
 
   decNumberToIntegralValue (&dn2, &dn, &set);
   decNumberZero (&dn3);
 
   decNumberToIntegralValue (&dn2, &dn, &set);
   decNumberZero (&dn3);
@@ -584,62 +593,55 @@ decimal_real_to_integer2 (HOST_WIDE_INT *plow, HOST_WIDE_INT *phigh,
   decContextDefault (&set, DEC_INIT_DECIMAL128);
   set.traps = 0;
   set.round = DEC_ROUND_DOWN;
   decContextDefault (&set, DEC_INIT_DECIMAL128);
   set.traps = 0;
   set.round = DEC_ROUND_DOWN;
-  decimal128ToNumber ((decimal128 *) r->sig, &dn);
+  decimal128ToNumber ((const decimal128 *) r->sig, &dn);
 
   decNumberToIntegralValue (&dn2, &dn, &set);
   decNumberZero (&dn3);
   decNumberRescale (&dn, &dn2, &dn3, &set);
 
 
   decNumberToIntegralValue (&dn2, &dn, &set);
   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);
   real_to_integer2 (plow, phigh, &to);
 }
 
      function.  */
   decNumberToString (&dn, string);
   real_from_string (&to, string);
   real_to_integer2 (plow, phigh, &to);
 }
 
-/* Perform the decimal floating point operation described by COODE.
-   For a unary operation, leave OP1 NULL.  This function returns true
-   if the result may be inexact due to loss of precision.  */
+/* Perform the decimal floating point operation described by CODE.
+   For a unary operation, OP1 will be NULL.  This function returns
+   true if the result may be inexact due to loss of precision.  */
 
 bool
 
 bool
-decimal_real_arithmetic (REAL_VALUE_TYPE *r, int icode,
+decimal_real_arithmetic (REAL_VALUE_TYPE *r, enum tree_code code,
                         const REAL_VALUE_TYPE *op0,
                         const REAL_VALUE_TYPE *op1)
 {
                         const REAL_VALUE_TYPE *op0,
                         const REAL_VALUE_TYPE *op1)
 {
-  enum tree_code code = icode;
-  REAL_VALUE_TYPE a1;
-  REAL_VALUE_TYPE b1;
+  REAL_VALUE_TYPE a, b;
 
 
-  /* If either op is not a decimal, create a temporary decimal
-     versions.  */
+  /* If either operand is non-decimal, create temporaries.  */
   if (!op0->decimal)
     {
   if (!op0->decimal)
     {
-      decimal_from_binary (&a1, op0);
-      op0 = &a1;
+      decimal_from_binary (&a, op0);
+      op0 = &a;
     }
   if (op1 && !op1->decimal)
     {
     }
   if (op1 && !op1->decimal)
     {
-      decimal_from_binary (&b1, op1);
-      op1 = &b1;
+      decimal_from_binary (&b, op1);
+      op1 = &b;
     }
 
   switch (code)
     {
     case PLUS_EXPR:
     }
 
   switch (code)
     {
     case PLUS_EXPR:
-      (void) decimal_do_add (r, op0, op1, 0);
-      break;
+      return decimal_do_add (r, op0, op1, 0);
 
     case MINUS_EXPR:
 
     case MINUS_EXPR:
-      (void) decimal_do_add (r, op0, op1, 1);
-      break;
+      return decimal_do_add (r, op0, op1, 1);
 
     case MULT_EXPR:
 
     case MULT_EXPR:
-      (void) decimal_do_multiply (r, op0, op1);
-      break;
+      return decimal_do_multiply (r, op0, op1);
 
     case RDIV_EXPR:
 
     case RDIV_EXPR:
-      (void) decimal_do_divide (r, op0, op1);
-      break;
+      return decimal_do_divide (r, op0, op1);
 
     case MIN_EXPR:
       if (op1->cl == rvc_nan)
 
     case MIN_EXPR:
       if (op1->cl == rvc_nan)
@@ -648,7 +650,7 @@ decimal_real_arithmetic (REAL_VALUE_TYPE *r, int icode,
         *r = *op0;
       else
         *r = *op1;
         *r = *op0;
       else
         *r = *op1;
-      break;
+      return false;
 
     case MAX_EXPR:
       if (op1->cl == rvc_nan)
 
     case MAX_EXPR:
       if (op1->cl == rvc_nan)
@@ -657,43 +659,35 @@ decimal_real_arithmetic (REAL_VALUE_TYPE *r, int icode,
         *r = *op1;
       else
         *r = *op0;
         *r = *op1;
       else
         *r = *op0;
-      break;
+      return false;
 
     case NEGATE_EXPR:
       {
 
     case NEGATE_EXPR:
       {
-       decimal128 *d128;
        *r = *op0;
        *r = *op0;
-       d128 = (decimal128 *) r->sig;
-       /* Flip high bit.  */
-       d128->bytes[0] ^= 1 << 7;
+       /* Flip sign bit.  */
+       decimal128FlipSign ((decimal128 *) r->sig);
        /* Keep sign field in sync.  */
        r->sign ^= 1;
       }
        /* Keep sign field in sync.  */
        r->sign ^= 1;
       }
-      break;
+      return false;
 
     case ABS_EXPR:
       {
 
     case ABS_EXPR:
       {
-        decimal128 *d128;
         *r = *op0;
         *r = *op0;
-        d128 = (decimal128 *) r->sig;
-       /* Clear high bit.  */
-        d128->bytes[0] &= 0x7f;
+       /* Clear sign bit.  */
+       decimal128ClearSign ((decimal128 *) r->sig);
        /* Keep sign field in sync.  */
        r->sign = 0;
       }
        /* Keep sign field in sync.  */
        r->sign = 0;
       }
-      break;
+      return false;
 
     case FIX_TRUNC_EXPR:
       decimal_do_fix_trunc (r, op0);
 
     case FIX_TRUNC_EXPR:
       decimal_do_fix_trunc (r, op0);
-      break;
+      return false;
 
     default:
       gcc_unreachable ();
     }
 
     default:
       gcc_unreachable ();
     }
-
-  /* FIXME: Indicate all operations as inexact for now due to unknown
-     working precision.  */
-  return true;
 }
 
 /* Fills R with the largest finite value representable in mode MODE.
 }
 
 /* Fills R with the largest finite value representable in mode MODE.
@@ -701,19 +695,19 @@ decimal_real_arithmetic (REAL_VALUE_TYPE *r, int icode,
 
 void
 decimal_real_maxval (REAL_VALUE_TYPE *r, int sign, enum machine_mode mode)
 
 void
 decimal_real_maxval (REAL_VALUE_TYPE *r, int sign, enum machine_mode mode)
-{ 
-  char *max;
+{
+  const char *max;
 
   switch (mode)
     {
     case SDmode:
 
   switch (mode)
     {
     case SDmode:
-      max = (char *) "9.999999E96";
+      max = "9.999999E96";
       break;
     case DDmode:
       break;
     case DDmode:
-      max = (char *) "9.999999999999999E384";
+      max = "9.999999999999999E384";
       break;
     case TDmode:
       break;
     case TDmode:
-      max = (char *) "9.999999999999999999999999999999999E6144";
+      max = "9.999999999999999999999999999999999E6144";
       break;
     default:
       gcc_unreachable ();
       break;
     default:
       gcc_unreachable ();
@@ -721,5 +715,5 @@ decimal_real_maxval (REAL_VALUE_TYPE *r, int sign, enum machine_mode mode)
 
   decimal_real_from_string (r, max);
   if (sign)
 
   decimal_real_from_string (r, max);
   if (sign)
-    r->sig[0] |= 0x80000000;
+    decimal128SetSign ((decimal128 *) r->sig, 1);
 }
 }