target-def.h (TARGET_SCALAR_MODE_SUPPORTED_P): New.
authorRichard Henderson <rth@redhat.com>
Thu, 26 Aug 2004 00:24:37 +0000 (17:24 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 26 Aug 2004 00:24:37 +0000 (17:24 -0700)
        * target-def.h (TARGET_SCALAR_MODE_SUPPORTED_P): New.
        * target.h (struct gcc_target): Add scalar_mode_supported_p.
        * targhooks.c (default_scalar_mode_supported_p): New.
        * targhooks.h (default_scalar_mode_supported_p): Declare.
        * doc/tm.texi (TARGET_SCALAR_MODE_SUPPORTED_P): Document.

        * c-common.c (handle_mode_attribute): Query scalar_mode_supported_p
        before attempting to create types.  Tidy.
        * expr.c (vector_mode_valid_p): Use scalar_mode_supported_p.

        * config/alpha/alpha.c (alpha_scalar_mode_supported_p): New.
        (TARGET_SCALAR_MODE_SUPPORTED_P): New.

From-SVN: r86593

gcc/ChangeLog
gcc/c-common.c
gcc/config/alpha/alpha.c
gcc/doc/tm.texi
gcc/expr.c
gcc/target-def.h
gcc/target.h
gcc/targhooks.c
gcc/targhooks.h

index 36363d1148eed33b5020dad08329c94332eb304e..43d00b5fd3913b205913ebd5f1bcffbed256e5ab 100644 (file)
@@ -1,3 +1,18 @@
+2004-08-25  Richard Henderson  <rth@redhat.com>
+
+       * target-def.h (TARGET_SCALAR_MODE_SUPPORTED_P): New.
+       * target.h (struct gcc_target): Add scalar_mode_supported_p.
+       * targhooks.c (default_scalar_mode_supported_p): New.
+       * targhooks.h (default_scalar_mode_supported_p): Declare.
+       * doc/tm.texi (TARGET_SCALAR_MODE_SUPPORTED_P): Document.
+
+       * c-common.c (handle_mode_attribute): Query scalar_mode_supported_p
+       before attempting to create types.  Tidy.
+       * expr.c (vector_mode_valid_p): Use scalar_mode_supported_p.
+
+       * config/alpha/alpha.c (alpha_scalar_mode_supported_p): New.
+       (TARGET_SCALAR_MODE_SUPPORTED_P): New.
+
 2004-08-25  Richard Henderson  <rth@redhat.com>
 
        * config/i386/freebsd.h (SUBTARGET_OVERRIDE_OPTIONS): Don't
index 62d2231587f2bee8a90cc0807738b65864a89af1..7e691660ac463d3895d130ca1810529dd450874f 100644 (file)
@@ -4267,7 +4267,7 @@ handle_mode_attribute (tree *node, tree name, tree args,
       int len = strlen (p);
       enum machine_mode mode = VOIDmode;
       tree typefm;
-      tree ptr_type;
+      bool valid_mode;
 
       if (len > 4 && p[0] == '_' && p[1] == '_'
          && p[len - 1] == '_' && p[len - 2] == '_')
@@ -4294,51 +4294,67 @@ handle_mode_attribute (tree *node, tree name, tree args,
 
       if (mode == VOIDmode)
        {
-         error ("unknown machine mode `%s'", p);
+         error ("unknown machine mode %<%s%>", p);
          return NULL_TREE;
        }
 
-      if (VECTOR_MODE_P (mode))
+      valid_mode = false;
+      switch (GET_MODE_CLASS (mode))
        {
+       case MODE_INT:
+       case MODE_PARTIAL_INT:
+       case MODE_FLOAT:
+         valid_mode = targetm.scalar_mode_supported_p (mode);
+         break;
+
+       case MODE_COMPLEX_INT:
+       case MODE_COMPLEX_FLOAT:
+         valid_mode = targetm.scalar_mode_supported_p (GET_MODE_INNER (mode));
+         break;
+
+       case MODE_VECTOR_INT:
+       case MODE_VECTOR_FLOAT:
          warning ("specifying vector types with __attribute__ ((mode)) "
                   "is deprecated");
          warning ("use __attribute__ ((vector_size)) instead");
-       }
+         valid_mode = vector_mode_valid_p (mode);
+         break;
 
-      typefm = lang_hooks.types.type_for_mode (mode, TYPE_UNSIGNED (type));
-      if (typefm == NULL_TREE)
-       error ("no data type for mode `%s'", p);
+       default:
+         break;
+       }
+      if (!valid_mode)
+       {
+         error ("unable to emulate %<%s%>", p);
+         return NULL_TREE;
+       }
 
-      else if ((TREE_CODE (type) == POINTER_TYPE
-               || TREE_CODE (type) == REFERENCE_TYPE)
-              && !targetm.valid_pointer_mode (mode))
-       error ("invalid pointer mode `%s'", p);
-      else
+      if (POINTER_TYPE_P (type))
        {
-         /* If this is a vector, make sure we either have hardware
-            support, or we can emulate it.  */
-         if (VECTOR_MODE_P (mode) && !vector_mode_valid_p (mode))
+         tree (*fn)(tree, enum machine_mode, bool);
+
+         if (!targetm.valid_pointer_mode (mode))
            {
-             error ("unable to emulate '%s'", GET_MODE_NAME (mode));
+             error ("invalid pointer mode %<%s%>", p);
              return NULL_TREE;
            }
 
-         if (TREE_CODE (type) == POINTER_TYPE)
-           {
-             ptr_type = build_pointer_type_for_mode (TREE_TYPE (type),
-                                                     mode, false);
-             *node = ptr_type;
-           }
-         else if (TREE_CODE (type) == REFERENCE_TYPE)
-           {
-             ptr_type = build_reference_type_for_mode (TREE_TYPE (type),
-                                                       mode, false);
-             *node = ptr_type;
-           }
+          if (TREE_CODE (type) == POINTER_TYPE)
+           fn = build_pointer_type_for_mode;
          else
-           *node = typefm;
-         /* No need to layout the type here.  The caller should do this.  */
+           fn = build_reference_type_for_mode;
+         typefm = fn (TREE_TYPE (type), mode, false);
        }
+      else
+        typefm = lang_hooks.types.type_for_mode (mode, TYPE_UNSIGNED (type));
+      if (typefm == NULL_TREE)
+       {
+         error ("no data type for mode %<%s%>", p);
+         return NULL_TREE;
+       }
+      *node = typefm;
+
+      /* No need to layout the type here.  The caller should do this.  */
     }
 
   return NULL_TREE;
index c623e009fb102cde4c3991326cdee8280ba519a1..c6d93446a840acad106a2bf8c14a502a09b6fe98 100644 (file)
@@ -670,14 +670,45 @@ alpha_extra_constraint (rtx value, int c)
     }
 }
 
-/* Implements target hook vector_mode_supported_p.  */
+/* The scalar modes supported differs from the default check-what-c-supports
+   version in that sometimes TFmode is available even when long double
+   indicates only DFmode.  On unicosmk, we have the situation that HImode
+   doesn't map to any C type, but of course we still support that.  */
+
+static bool
+alpha_scalar_mode_supported_p (enum machine_mode mode)
+{
+  switch (mode)
+    {
+    case QImode:
+    case HImode:
+    case SImode:
+    case DImode:
+    case TImode: /* via optabs.c */
+      return true;
+
+    case SFmode:
+    case DFmode:
+      return true;
+
+    case TFmode:
+      return TARGET_HAS_XFLOATING_LIBS;
+
+    default:
+      return false;
+    }
+}
+
+/* Alpha implements a couple of integer vector mode operations when
+   TARGET_MAX is enabled.  */
+
 static bool
 alpha_vector_mode_supported_p (enum machine_mode mode)
 {
   if (TARGET_MAX
-      && ((mode == V8QImode)
-         || (mode == V4HImode)
-         || (mode == V2SImode)))
+      && (mode == V8QImode
+         || mode == V4HImode
+         || mode == V2SImode))
     return true;
 
   return false;
@@ -9362,6 +9393,9 @@ alpha_init_libfuncs (void)
 #define TARGET_SPLIT_COMPLEX_ARG alpha_split_complex_arg
 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
 #define TARGET_GIMPLIFY_VA_ARG_EXPR alpha_gimplify_va_arg
+
+#undef TARGET_SCALAR_MODE_SUPPORTED_P
+#define TARGET_SCALAR_MODE_SUPPORTED_P alpha_scalar_mode_supported_p
 #undef TARGET_VECTOR_MODE_SUPPORTED_P
 #define TARGET_VECTOR_MODE_SUPPORTED_P alpha_vector_mode_supported_p
 
index 7240d19e83784a473bf7d81d26011257961f66b3..b15cb53dec67e896eaafb5aea211209f5b86c8b4 100644 (file)
@@ -3878,6 +3878,18 @@ arguments to @code{va_arg}; the latter two are as in
 @code{gimplify.c:gimplify_expr}.
 @end deftypefn
 
+@deftypefn {Target Hook} bool TARGET_SCALAR_MODE_SUPPORTED_P (enum machine_mode @var{mode})
+Define this to return nonzero if the port is prepared to handle
+insns involving scalar mode @var{mode}.  For a scalar mode to be
+considered supported, all the basic arithmetic and comparisons
+must work.
+
+The default version of this hook returns true for any mode
+required to handle the basic C types (as defined by the port).
+Included here are the double-word arithmetic supported by the
+code in @file{optabs.c}.
+@end deftypefn
+
 @deftypefn {Target Hook} bool TARGET_VECTOR_MODE_SUPPORTED_P (enum machine_mode @var{mode})
 Define this to return nonzero if the port is prepared to handle
 insns involving vector mode @var{mode}.  At the very least, it
index b98986447f45cd9fc04944cbd2abd59af874784a..6811abedd803a71e6d16d875a7b650cb2850eaf4 100644 (file)
@@ -8799,7 +8799,7 @@ vector_mode_valid_p (enum machine_mode mode)
 
   /* If we have support for the inner mode, we can safely emulate it.
      We may not have V2DI, but me can emulate with a pair of DIs.  */
-  return mov_optab->handlers[innermode].insn_code != CODE_FOR_nothing;
+  return targetm.scalar_mode_supported_p (innermode);
 }
 
 /* Return a CONST_VECTOR rtx for a VECTOR_CST tree.  */
index 4d8fea0c8dd8dece3e77c6b3e8479cb2653297e4..156ebef7c7bcede756f1c382a732913344c277ed 100644 (file)
@@ -305,6 +305,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 #define TARGET_VALID_POINTER_MODE default_valid_pointer_mode
 #endif
 
+#ifndef TARGET_SCALAR_MODE_SUPPORTED_P
+#define TARGET_SCALAR_MODE_SUPPORTED_P default_scalar_mode_supported_p
+#endif
+
 #ifndef TARGET_VECTOR_MODE_SUPPORTED_P
 #define TARGET_VECTOR_MODE_SUPPORTED_P hook_bool_mode_false
 #endif
@@ -475,6 +479,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   TARGET_ENCODE_SECTION_INFO,                  \
   TARGET_STRIP_NAME_ENCODING,                  \
   TARGET_VALID_POINTER_MODE,                    \
+  TARGET_SCALAR_MODE_SUPPORTED_P,              \
   TARGET_VECTOR_MODE_SUPPORTED_P,               \
   TARGET_VECTOR_OPAQUE_P,                      \
   TARGET_RTX_COSTS,                            \
index 2c3798eaa5df70c9ab7f094aed24dce2d717030f..27e4086129e86661aa1e6e5ec7ab4c9e41654f19 100644 (file)
@@ -381,7 +381,14 @@ struct gcc_target
   /* True if MODE is valid for a pointer in __attribute__((mode("MODE"))).  */
   bool (* valid_pointer_mode) (enum machine_mode mode);
 
-  /* True if MODE is valid for a vector.  */
+  /* True if MODE is valid for the target.  By "valid", we mean able to
+     be manipulated in non-trivial ways.  In particular, this means all
+     the arithmetic is supported.  */
+  bool (* scalar_mode_supported_p) (enum machine_mode mode);
+
+  /* Similarly for vector modes.  "Supported" here is less strict.  At
+     least some operations are supported; need to check optabs or builtins
+     for further details.  */
   bool (* vector_mode_supported_p) (enum machine_mode mode);
 
   /* True if a vector is opaque.  */
index 00d7e8444d7fac2d6428d613cbd8fea1e9e4fa1f..6aa2e07117bda7dd563d340a984b31f67c620fa6 100644 (file)
@@ -62,6 +62,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "tm_p.h"
 #include "target-def.h"
 
+
 void
 default_external_libcall (rtx fun ATTRIBUTE_UNUSED)
 {
@@ -207,3 +208,49 @@ default_unwind_emit (FILE * stream ATTRIBUTE_UNUSED,
   /* Should never happen.  */
   abort ();
 }
+
+/* True if MODE is valid for the target.  By "valid", we mean able to
+   be manipulated in non-trivial ways.  In particular, this means all
+   the arithmetic is supported.
+
+   By default we guess this means that any C type is supported.  If
+   we can't map the mode back to a type that would be available in C,
+   then reject it.  Special case, here, is the double-word arithmetic
+   supported by optabs.c.  */
+
+bool
+default_scalar_mode_supported_p (enum machine_mode mode)
+{
+  int precision = GET_MODE_PRECISION (mode);
+
+  switch (GET_MODE_CLASS (mode))
+    {
+    case MODE_PARTIAL_INT:
+    case MODE_INT:
+      if (precision == CHAR_TYPE_SIZE)
+       return true;
+      if (precision == SHORT_TYPE_SIZE)
+       return true;
+      if (precision == INT_TYPE_SIZE)
+       return true;
+      if (precision == LONG_TYPE_SIZE)
+       return true;
+      if (precision == LONG_LONG_TYPE_SIZE)
+       return true;
+      if (precision == 2 * BITS_PER_WORD)
+       return true;
+      return false;
+
+    case MODE_FLOAT:
+      if (precision == FLOAT_TYPE_SIZE)
+       return true;
+      if (precision == DOUBLE_TYPE_SIZE)
+       return true;
+      if (precision == LONG_DOUBLE_TYPE_SIZE)
+       return true;
+      return false;
+
+    default:
+      abort ();
+    }
+}
index 077175eda9df6429f09dd252932542cf28697e8d..b91e51dec847e026531803a2428cf6b7cef04b16 100644 (file)
@@ -43,3 +43,5 @@ extern bool hook_pass_by_reference_must_pass_in_stack
   (CUMULATIVE_ARGS *, enum machine_mode mode, tree, bool);
 
 extern void default_unwind_emit (FILE *, rtx);
+
+extern bool default_scalar_mode_supported_p (enum machine_mode);