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 for __float80 and __float128 mangling


This patch fixes ICEs mangling C++ functions taking __float80 (on
ia64-hpux) or __float128 (on x86/x86_64).

The only odd point is the mangling on ia64-hpux, where "long double"
is the same as __float128 and is mangled as "e", so __float80 gets the
mangling "u9__float80".  HP aCC mangles "long double" as "g", but it
is intended it will gain a switch to use the GCC mangling so though
the aCC mangling makes more sense it doesn't seem to make sense now to
change GCC to match aCC conditionally on a new ABI version.  (The ABI
specification document presumes that "long double" and __float80 are
the same type, hence the ambiguity.)

Bootstrapped with no regressions on ia64-hp-hpux11.23 and
x86_64-unknown-linux-gnu; I don't have access to ia64-linux to test
there.  OK to commit?

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
    jsm@polyomino.org.uk (personal mail)
    joseph@codesourcery.com (CodeSourcery mail)
    jsm28@gcc.gnu.org (Bugzilla assignments and CCs)

2005-06-19  Joseph S. Myers  <joseph@codesourcery.com>

	* config/i386/i386.c (TARGET_MANGLE_FUNDAMENTAL_TYPE): Define.
	(ix86_mangle_fundamental_type): New.
	* config/ia64/ia64.c (TARGET_MANGLE_FUNDAMENTAL_TYPE): Define.
	(ia64_mangle_fundamental_type): New.

testsuite:
2005-06-19  Joseph S. Myers  <joseph@codesourcery.com>

	* g++.dg/abi/mangle24.C, g++.dg/abi/mangle25.C: New tests.

diff -rupN GCC.orig/gcc/config/i386/i386.c GCC/gcc/config/i386/i386.c
--- GCC.orig/gcc/config/i386/i386.c	2005-06-16 19:34:22.000000000 +0000
+++ GCC/gcc/config/i386/i386.c	2005-06-19 01:20:15.000000000 +0000
@@ -905,6 +905,7 @@ static bool ix86_pass_by_reference (CUMU
 				    tree, bool);
 static void ix86_init_builtins (void);
 static rtx ix86_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
+static const char *ix86_mangle_fundamental_type (tree);
 
 /* This function is only used on Solaris.  */
 static void i386_solaris_elf_named_section (const char *, unsigned int, tree)
@@ -1077,6 +1078,9 @@ static void init_ext_80387_constants (vo
 #define TARGET_INSERT_ATTRIBUTES SUBTARGET_INSERT_ATTRIBUTES
 #endif
 
+#undef TARGET_MANGLE_FUNDAMENTAL_TYPE
+#define TARGET_MANGLE_FUNDAMENTAL_TYPE ix86_mangle_fundamental_type
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 
@@ -17513,4 +17517,22 @@ i386_solaris_elf_named_section (const ch
   default_elf_asm_named_section (name, flags, decl);
 }
 
+/* Return the mangling of TYPE if it is an extended fundamental type.  */
+
+static const char *
+ix86_mangle_fundamental_type (tree type)
+{
+  switch (TYPE_MODE (type))
+    {
+    case TFmode:
+      /* __float128 is "g".  */
+      return "g";
+    case XFmode:
+      /* "long double" or __float80 is "e".  */
+      return "e";
+    default:
+      return NULL;
+    }
+}
+
 #include "gt-i386.h"
diff -rupN GCC.orig/gcc/config/ia64/ia64.c GCC/gcc/config/ia64/ia64.c
--- GCC.orig/gcc/config/ia64/ia64.c	2005-06-18 11:50:33.000000000 +0000
+++ GCC/gcc/config/ia64/ia64.c	2005-06-19 01:17:01.000000000 +0000
@@ -262,6 +262,7 @@ static tree ia64_gimplify_va_arg (tree, 
 static bool ia64_scalar_mode_supported_p (enum machine_mode mode);
 static bool ia64_vector_mode_supported_p (enum machine_mode mode);
 static bool ia64_cannot_force_const_mem (rtx);
+static const char *ia64_mangle_fundamental_type (tree);
 
 /* Table of valid machine attributes.  */
 static const struct attribute_spec ia64_attribute_table[] =
@@ -429,6 +430,9 @@ static const struct attribute_spec ia64_
 #undef TARGET_CANNOT_FORCE_CONST_MEM
 #define TARGET_CANNOT_FORCE_CONST_MEM ia64_cannot_force_const_mem
 
+#undef TARGET_MANGLE_FUNDAMENTAL_TYPE
+#define TARGET_MANGLE_FUNDAMENTAL_TYPE ia64_mangle_fundamental_type
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 typedef enum
@@ -8628,4 +8632,21 @@ ia64_profile_hook (int labelno)
 		     label, Pmode);
 }
 
+/* Return the mangling of TYPE if it is an extended fundamental type.  */
+
+static const char *
+ia64_mangle_fundamental_type (tree type)
+{
+  /* On HP-UX, "long double" is mangled as "e" so __float128 is
+     mangled as "e".  */
+  if (!TARGET_HPUX && TYPE_MODE (type) == TFmode)
+    return "g";
+  /* On HP-UX, "e" is not available as a mangling of __float80 so use
+     an extended mangling.  Elsewhere, "e" is available since long
+     double is 80 bits.  */
+  if (TYPE_MODE (type) == XFmode)
+    return TARGET_HPUX ? "u9__float80" : "e";
+  return NULL;
+}
+
 #include "gt-ia64.h"
diff -rupN GCC.orig/gcc/testsuite/g++.dg/abi/mangle24.C GCC/gcc/testsuite/g++.dg/abi/mangle24.C
--- GCC.orig/gcc/testsuite/g++.dg/abi/mangle24.C	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/g++.dg/abi/mangle24.C	2005-06-19 12:37:43.000000000 +0000
@@ -0,0 +1,12 @@
+// Test mangling of __float80.
+// The C++ ABI document says __float80 is mangled as "e".  It
+// also says that "long double" is mangled as "e", so these conflict on
+// ia64-hpux where "long double" is "e" and __float80 is "u9__float80".
+// Origin: Joseph Myers <joseph@codesourcery.com>
+// { dg-do compile { target i?86-*-* x86_64-*-* ia64-*-* } } */
+// { dg-options "" } */
+// { dg-final { scan-assembler "_Z1fe" { target i?86-*-* x86_64-*-* } } } */
+// { dg-final { scan-assembler "_Z1fe" { target { ia64-*-* && { ! "ia64-*-hpux*" } } } } } */
+// { dg-final { scan-assembler "_Z1fu9__float80" { target ia64-*-hpux* } } } */
+
+int f(__float80 x) { return 0; }
diff -rupN GCC.orig/gcc/testsuite/g++.dg/abi/mangle25.C GCC/gcc/testsuite/g++.dg/abi/mangle25.C
--- GCC.orig/gcc/testsuite/g++.dg/abi/mangle25.C	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/g++.dg/abi/mangle25.C	2005-06-19 12:37:55.000000000 +0000
@@ -0,0 +1,13 @@
+// Test mangling of __float128.
+// The C++ ABI document says __float128 is mangled as "g".  It
+// also says that "long double" is mangled as "e", so these conflict on
+// ia64-hpux where "long double" is "e" and __float128 is synonymous with
+// "long double".
+// Origin: Joseph Myers <joseph@codesourcery.com>
+// { dg-do compile { target i?86-*-* x86_64-*-* ia64-*-* } } */
+// { dg-options "" } */
+// { dg-final { scan-assembler "_Z1fg" { target i?86-*-* x86_64-*-* } } } */
+// { dg-final { scan-assembler "_Z1fg" { target { ia64-*-* && { ! "ia64-*-hpux*" } } } } } */
+// { dg-final { scan-assembler "_Z1fe" { target ia64-*-hpux* } } } */
+
+int f(__float128 x) { return 0; }


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