This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] have pretty printer include NaN representation


The pretty-printer formats NaNs simply as Nan, even though
there is much more to a NaN than than that.  At the very
least, one might like to know if the NaN is signaling or
quiet, negative or positive.  If it's not in a canonical
form, one might also be interested in the significand
and exponent parts.  The attached patch enhances
the pretty printer to include all these details in
its detailed output.

Tested by bootstrapping & regtesting on x86_64-linux.

Martin
gcc/ChangeLog:

	* print-tree.c (print_real_cst): New function.
	(print_node_brief): Call it.
	(print_node): Ditto.

Index: gcc/print-tree.c
===================================================================
--- gcc/print-tree.c	(revision 262312)
+++ gcc/print-tree.c	(working copy)
@@ -52,6 +52,71 @@ dump_addr (FILE *file, const char *prefix, const v
     fprintf (file, "%s" HOST_PTR_PRINTF, prefix, addr);
 }
 
+/* Print to FILE a NODE representing a REAL_CST constant, including
+   Infinity and NaN.  Be verbose when BFRIEF is false.  */
+
+static void
+print_real_cst (FILE *file, const_tree node, bool brief)
+{
+  if (TREE_OVERFLOW (node))
+    fprintf (file, " overflow");
+
+  REAL_VALUE_TYPE d = TREE_REAL_CST (node);
+  if (REAL_VALUE_ISINF (d))
+    fprintf (file,  REAL_VALUE_NEGATIVE (d) ? " -Inf" : " Inf");
+  else if (REAL_VALUE_ISNAN (d))
+    {
+      /* Print a NaN in the format [-][Q|S]NaN[(significand[exponent])]
+	 where significand is a hexadecimal string that starts with
+	 the 0x prefix followed by 0 if the number is not canonical
+	 and a non-zero digit if it is, and exponent is decimal.  */
+      unsigned start = 0;
+      const char *psig = (const char *) d.sig;
+      for (unsigned i = 0; i != sizeof d.sig; ++i)
+	if (psig[i])
+	  {
+	    start = i;
+	    break;
+	  }
+
+      fprintf (file, " %s%sNaN", d.sign ? "-" : "",
+	       d.signalling ? "S" : "Q");
+
+      if (brief)
+	return;
+
+      if (start)
+	fprintf (file, "(0x%s", d.canonical ? "" : "0");
+      else if (d.uexp)
+	fprintf (file, "(%s", d.canonical ? "" : "0");
+      else if (!d.canonical)
+	{
+	  fprintf (file, "(0)");
+	  return;
+	}
+
+      if (psig[start])
+	{
+	  for (unsigned i = start; i != sizeof d.sig; ++i)
+	    if (i == start)
+	      fprintf (file, "%x", psig[i]);
+	    else
+	      fprintf (file, "%02x", psig[i]);
+	}
+
+      if (d.uexp)
+	fprintf (file, "%se%u)", psig[start] ? "," : "", d.uexp);
+      else if (psig[start])
+	fputc (')', file);
+    }
+  else
+    {
+      char string[64];
+      real_to_decimal (string, &d, sizeof (string), 0, 1);
+      fprintf (file, " %s", string);
+    }
+}
+
 /* Print a node in brief fashion, with just the code, address and name.  */
 
 void
@@ -121,24 +186,7 @@ print_node_brief (FILE *file, const char *prefix,
       print_dec (wi::to_wide (node), file, TYPE_SIGN (TREE_TYPE (node)));
     }
   if (TREE_CODE (node) == REAL_CST)
-    {
-      REAL_VALUE_TYPE d;
-
-      if (TREE_OVERFLOW (node))
-	fprintf (file, " overflow");
-
-      d = TREE_REAL_CST (node);
-      if (REAL_VALUE_ISINF (d))
-	fprintf (file,  REAL_VALUE_NEGATIVE (d) ? " -Inf" : " Inf");
-      else if (REAL_VALUE_ISNAN (d))
-	fprintf (file, " Nan");
-      else
-	{
-	  char string[60];
-	  real_to_decimal (string, &d, sizeof (string), 0, 1);
-	  fprintf (file, " %s", string);
-	}
-    }
+    print_real_cst (file, node, true);
   if (TREE_CODE (node) == FIXED_CST)
     {
       FIXED_VALUE_TYPE f;
@@ -730,24 +778,7 @@ print_node (FILE *file, const char *prefix, tree n
 	  break;
 
 	case REAL_CST:
-	  {
-	    REAL_VALUE_TYPE d;
-
-	    if (TREE_OVERFLOW (node))
-	      fprintf (file, " overflow");
-
-	    d = TREE_REAL_CST (node);
-	    if (REAL_VALUE_ISINF (d))
-	      fprintf (file,  REAL_VALUE_NEGATIVE (d) ? " -Inf" : " Inf");
-	    else if (REAL_VALUE_ISNAN (d))
-	      fprintf (file, " Nan");
-	    else
-	      {
-		char string[64];
-		real_to_decimal (string, &d, sizeof (string), 0, 1);
-		fprintf (file, " %s", string);
-	      }
-	  }
+	  print_real_cst (file, node, false);
 	  break;
 
 	case FIXED_CST:

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]