diff gcc/dfp.c @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents f6334be47118
children 84e7813d76e9
line wrap: on
line diff
--- a/gcc/dfp.c	Sun Aug 21 07:07:55 2011 +0900
+++ b/gcc/dfp.c	Fri Oct 27 22:46:09 2017 +0900
@@ -1,6 +1,5 @@
 /* Decimal floating point support.
-   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
-   Foundation, Inc.
+   Copyright (C) 2005-2017 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -23,17 +22,14 @@
 #include "coretypes.h"
 #include "tm.h"
 #include "tree.h"
-#include "tm_p.h"
 #include "dfp.h"
 
 /* The order of the following headers is important for making sure
    decNumber structure is large enough to hold decimal128 digits.  */
 
 #include "decimal128.h"
-#include "decimal128Local.h"
 #include "decimal64.h"
 #include "decimal32.h"
-#include "decNumber.h"
 
 #ifndef WORDS_BIGENDIAN
 #define WORDS_BIGENDIAN 0
@@ -110,7 +106,33 @@
         decNumberFromString (dn, "nan", &set);
       break;
     case rvc_normal:
-      gcc_assert (r->decimal);
+      if (!r->decimal)
+	{
+	  /* dconst{1,2,m1,half} are used in various places in
+	     the middle-end and optimizers, allow them here
+	     as an exception by converting them to decimal.  */
+	  if (memcmp (r, &dconst1, sizeof (*r)) == 0)
+	    {
+	      decNumberFromString (dn, "1", &set);
+	      break;
+	    }
+	  if (memcmp (r, &dconst2, sizeof (*r)) == 0)
+	    {
+	      decNumberFromString (dn, "2", &set);
+	      break;
+	    }
+	  if (memcmp (r, &dconstm1, sizeof (*r)) == 0)
+	    {
+	      decNumberFromString (dn, "-1", &set);
+	      break;
+	    }
+	  if (memcmp (r, &dconsthalf, sizeof (*r)) == 0)
+	    {
+	      decNumberFromString (dn, "0.5", &set);
+	      break;
+	    }
+	  gcc_unreachable ();
+	}
       decimal128ToNumber ((const decimal128 *) r->sig, dn);
       break;
     default:
@@ -317,13 +339,13 @@
 
 static void
 decimal_to_binary (REAL_VALUE_TYPE *to, const REAL_VALUE_TYPE *from,
-		   enum machine_mode mode)
+		   const real_format *fmt)
 {
   char string[256];
   const decimal128 *const d128 = (const decimal128 *) from->sig;
 
   decimal128ToString (d128, string);
-  real_from_string3 (to, string, mode);
+  real_from_string3 (to, string, fmt);
 }
 
 
@@ -433,15 +455,13 @@
    binary and decimal types.  */
 
 void
-decimal_real_convert (REAL_VALUE_TYPE *r, enum machine_mode mode,
+decimal_real_convert (REAL_VALUE_TYPE *r, const real_format *fmt,
 		      const REAL_VALUE_TYPE *a)
 {
-  const struct real_format *fmt = REAL_MODE_FORMAT (mode);
-
   if (a->decimal && fmt->b == 10)
     return;
   if (a->decimal)
-      decimal_to_binary (r, a, mode);
+      decimal_to_binary (r, a, fmt);
   else
       decimal_from_binary (r, a);
 }
@@ -579,11 +599,11 @@
   return real_to_integer (&to);
 }
 
-/* Likewise, but to an integer pair, HI+LOW.  */
+/* Likewise, but returns a wide_int with PRECISION.  *FAIL is set if the
+   value does not fit.  */
 
-void
-decimal_real_to_integer2 (HOST_WIDE_INT *plow, HOST_WIDE_INT *phigh,
-			  const REAL_VALUE_TYPE *r)
+wide_int
+decimal_real_to_integer (const REAL_VALUE_TYPE *r, bool *fail, int precision)
 {
   decContext set;
   decNumber dn, dn2, dn3;
@@ -603,7 +623,7 @@
      function.  */
   decNumberToString (&dn, string);
   real_from_string (&to, string);
-  real_to_integer2 (plow, phigh, &to);
+  return real_to_integer (&to, fail, precision);
 }
 
 /* Perform the decimal floating point operation described by CODE.
@@ -694,19 +714,19 @@
    If SIGN is nonzero, R is set to the most negative finite value.  */
 
 void
-decimal_real_maxval (REAL_VALUE_TYPE *r, int sign, enum machine_mode mode)
+decimal_real_maxval (REAL_VALUE_TYPE *r, int sign, machine_mode mode)
 {
   const char *max;
 
   switch (mode)
     {
-    case SDmode:
+    case E_SDmode:
       max = "9.999999E96";
       break;
-    case DDmode:
+    case E_DDmode:
       max = "9.999999999999999E384";
       break;
-    case TDmode:
+    case E_TDmode:
       max = "9.999999999999999999999999999999999E6144";
       break;
     default: