[Bug c++/8861] [3.3/3.4 regression] [ABI] mangling floating point literal in template arg expression

zack@codesourcery.com gcc-bugzilla@gcc.gnu.org
Sun Jun 8 18:13:00 GMT 2003


PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=8861



------- Additional Comments From zack@codesourcery.com  2003-06-08 18:13 -------
Subject: Re:  PATCH: mangling floating point literal in
 template arg expression


And here's the patch that was supposed to be attached to that message.

>         PR c++/8861
>         * mangle.c (write_template_arg_literal): Correct the mangling
>         of floating-point literals.

===================================================================
Index: mangle.c
--- mangle.c	3 Apr 2003 03:45:48 -0000	1.68
+++ mangle.c	8 Jun 2003 18:12:41 -0000
@@ -2024,11 +2024,12 @@ write_expression (expr)
      "Literal arguments, e.g. "A<42L>", are encoded with their type
      and value. Negative integer values are preceded with "n"; for
      example, "A<-42L>" becomes "1AILln42EE". The bool value false is
-     encoded as 0, true as 1. If floating-point arguments are accepted
-     as an extension, their values should be encoded using a
-     fixed-length lowercase hexadecimal string corresponding to the
-     internal representation (IEEE on IA-64), high-order bytes first,
-     without leading zeroes. For example: "Lfbff000000E" is -1.0f."  */
+     encoded as 0, true as 1.
+
+     Floating-point literals are encoded using a fixed-length lowercase
+     hexadecimal string corresponding to the internal representation
+     (IEEE on Itanium), high-order bytes first, without leading
+     zeroes. For example: "Lf bf800000 E" is -1.0f on Itanium."  */
 
 static void
 write_template_arg_literal (value)
@@ -2056,22 +2057,30 @@ write_template_arg_literal (value)
     }
   else if (TREE_CODE (value) == REAL_CST)
     {
-#ifdef CROSS_COMPILE
-      static int explained;
+      long target_real[4];  /* largest supported float */
+      char buffer[9];  /* eight hex digits in a 32-bit number */
+      int i;
+      int words = GET_MODE_BITSIZE (TYPE_MODE (type)) / 32;
 
-      if (!explained) 
-	{
-	  sorry ("real-valued template parameters when cross-compiling");
-	  explained = 1;
-	}
-#else
-      size_t i;
-      for (i = 0; i < sizeof (TREE_REAL_CST (value)); ++i)
-	write_number (((unsigned char *) 
-		       &TREE_REAL_CST (value))[i], 
-		      /*unsigned_p=*/1,
-		      16);
-#endif
+      real_to_target (target_real, &TREE_REAL_CST (value),
+		      TYPE_MODE (type));
+
+      /* The value in target_real is in the target word order, so we
+	 must write it out backward if that happens to be little-
+	 endian.  write_number cannot be used, it will produce
+	 uppercase.  */
+      if (FLOAT_WORDS_BIG_ENDIAN)
+	for (i = 0; i < words; i++)
+	  {
+	    sprintf (buffer, "%08lx", target_real[i]);
+	    write_chars (buffer, 8);
+	  }
+      else
+	for (i = words-1; i >= 0; i--)
+	  {
+	    sprintf (buffer, "%08lx", target_real[i]);
+	    write_chars (buffer, 8);
+	  }
     }
   else
     abort ();



More information about the Gcc-bugs mailing list