Patchwork Non-TFmode targets broken with "[fortran,patch] Complete front-end support for __float128"

login
register
mail settings
Submitter Tobias Burnus
Date Aug. 28, 2010, 9:12 a.m.
Message ID <4C78D2F1.4000609@net-b.de>
Download mbox | patch
Permalink /patch/62901/
State New
Headers show

Comments

Tobias Burnus - Aug. 28, 2010, 9:12 a.m.
Andrew Pinski wrote:
>>> Breaking targets without TFmode, like cris-elf
> Here is a very untested patch which should improve the issue.  I say
> untested because I was writing this for Tobias just for sample code.

The following patch seems to work. However, it is only lightly tested 
(compiled on x86-64-linux and few test cases, neither bootstrapped nor 
regtested).

Tobias

Patch

Index: gcc/fortran/trans-types.c
===================================================================
--- gcc/fortran/trans-types.c	(Revision 163612)
+++ gcc/fortran/trans-types.c	(Arbeitskopie)
@@ -409,12 +409,12 @@  gfc_init_kinds (void)
 	continue;
 
       /* Only let float, double, long double and __float128 go through.
-	 Runtime support for others is not provided, so they would be
-	 useless.  TODO: TFmode support should be enabled once libgfortran
-	 support is done.  */
+	 runtime support for others is not provided, so they would be
+	 useless.  */
 	if (mode != TYPE_MODE (float_type_node)
 	  && (mode != TYPE_MODE (double_type_node))
-          && (mode != TYPE_MODE (long_double_type_node)))
+          && (mode != TYPE_MODE (long_double_type_node))
+	  && (float128_type_node && mode != TYPE_MODE (float128_type_node)))
 	continue;
 
       /* Let the kind equal the precision divided by 8, rounding up.  Again,
@@ -717,7 +717,8 @@  gfc_build_real_type (gfc_real_info *info
     info->c_double = 1;
   if (mode_precision == LONG_DOUBLE_TYPE_SIZE)
     info->c_long_double = 1;
-  if (mode_precision != LONG_DOUBLE_TYPE_SIZE && mode_precision == 128)
+  if (mode_precision != LONG_DOUBLE_TYPE_SIZE
+      && float128_type_node && TYPE_PRECISION (float128_type_node) == mode_precision)
     {
       info->c_float128 = 1;
       gfc_real16_is_float128 = true;
@@ -730,6 +731,9 @@  gfc_build_real_type (gfc_real_info *info
   if (TYPE_PRECISION (long_double_type_node) == mode_precision)
     return long_double_type_node;
 
+  if (float128_type_node && TYPE_PRECISION (float128_type_node) == mode_precision)
+    return float128_type_node;
+
   new_type = make_node (REAL_TYPE);
   TYPE_PRECISION (new_type) = mode_precision;
   layout_type (new_type);
@@ -749,6 +753,8 @@  gfc_build_complex_type (tree scalar_type
     return complex_double_type_node;
   if (scalar_type == long_double_type_node)
     return complex_long_double_type_node;
+  if (float128_type_node && scalar_type == float128_type_node)
+    return complex_float128_type_node;
 
   new_type = make_node (COMPLEX_TYPE);
   TREE_TYPE (new_type) = scalar_type;
@@ -846,17 +852,12 @@  gfc_init_types (void)
 		gfc_real_kinds[index].kind);
       PUSH_TYPE (name_buf, type);
 
-      if (gfc_real_kinds[index].c_float128)
-	float128_type_node = type;
-
       type = gfc_build_complex_type (type);
       gfc_complex_types[index] = type;
       snprintf (name_buf, sizeof(name_buf), "complex(kind=%d)",
 		gfc_real_kinds[index].kind);
       PUSH_TYPE (name_buf, type);
 
-      if (gfc_real_kinds[index].c_float128)
-	complex_float128_type_node = type;
     }
 
   for (index = 0; gfc_character_kinds[index].kind != 0; ++index)
@@ -2625,4 +2626,19 @@  gfc_get_array_descr_info (const_tree typ
   return true;
 }
 
+/* Registration of machine- or os-specific builtin types.  */
+void
+gfc_register_builtin_type (tree type,
+                           const char *name)
+{
+  /*  Record the __float128 type and the corresponding complex type too. */
+  if (strcmp (name, "__float128") == 0)
+    {
+      float128_type_node = type;
+      complex_float128_type_node = make_node (COMPLEX_TYPE);
+      TREE_TYPE (complex_float128_type_node) = type;
+      layout_type (complex_float128_type_node);
+    }
+}
+
 #include "gt-fortran-trans-types.h"
Index: gcc/fortran/trans-types.h
===================================================================
--- gcc/fortran/trans-types.h	(Revision 163612)
+++ gcc/fortran/trans-types.h	(Arbeitskopie)
@@ -101,4 +101,6 @@  tree gfc_get_dtype (tree);
 
 tree gfc_get_ppc_type (gfc_component *);
 
+void gfc_register_builtin_type (tree, const char *);
+
 #endif
Index: gcc/fortran/f95-lang.c
===================================================================
--- gcc/fortran/f95-lang.c	(Revision 163612)
+++ gcc/fortran/f95-lang.c	(Arbeitskopie)
@@ -125,6 +125,7 @@  static void gfc_init_ts (void);
 #undef LANG_HOOKS_OMP_FIRSTPRIVATIZE_TYPE_SIZES
 #undef LANG_HOOKS_BUILTIN_FUNCTION
 #undef LANG_HOOKS_GET_ARRAY_DESCR_INFO
+#undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
 
 /* Define lang hooks.  */
 #define LANG_HOOKS_NAME                 "GNU Fortran"
@@ -155,6 +156,7 @@  static void gfc_init_ts (void);
   gfc_omp_firstprivatize_type_sizes
 #define LANG_HOOKS_BUILTIN_FUNCTION          gfc_builtin_function
 #define LANG_HOOKS_GET_ARRAY_DESCR_INFO	     gfc_get_array_descr_info
+#define LANG_HOOKS_REGISTER_BUILTIN_TYPE     gfc_register_builtin_type
 
 struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;