]> gcc.gnu.org Git - gcc.git/commitdiff
extend.texi (Variable Attributes): Document vector_size.
authorAldy Hernandez <aldyh@redhat.com>
Fri, 7 Dec 2001 18:49:16 +0000 (18:49 +0000)
committerAldy Hernandez <aldyh@gcc.gnu.org>
Fri, 7 Dec 2001 18:49:16 +0000 (18:49 +0000)
2001-12-07  Aldy Hernandez  <aldyh@redhat.com>

* doc/extend.texi (Variable Attributes): Document vector_size.

        * attribs.c (c_common_attribute_table): Add vector_size.
(handle_vector_size_attribute): New.
        (vector_size_helper): New.
(decl_attributes): Relayout the decl after calculating attribs.

From-SVN: r47764

gcc/ChangeLog
gcc/attribs.c
gcc/doc/extend.texi

index 143aa204ab062bd9c2cec4a181f0c4a5362d3008..04b32b921404ca4fb106ba2f19fc63fa9d449ad1 100644 (file)
@@ -1,3 +1,12 @@
+2001-12-07  Aldy Hernandez  <aldyh@redhat.com>
+
+       * doc/extend.texi (Variable Attributes): Document vector_size.
+
+        * attribs.c (c_common_attribute_table): Add vector_size.
+       (handle_vector_size_attribute): New.
+        (vector_size_helper): New.
+       (decl_attributes): Relayout the decl after calculating attribs.
+
 2001-12-07  Joseph S. Myers  <jsm28@cam.ac.uk>
 
        * doc/gcc.texi: Don't include install-old.texi.  Adjust menu
index 9322c421106fe04ccf8839a1cc3e0056787b9eae..554591310d9a64f9b02cb51e6454959e1b4e87e7 100644 (file)
@@ -82,6 +82,9 @@ static tree handle_no_limit_stack_attribute PARAMS ((tree *, tree, tree, int,
                                                     bool *));
 static tree handle_pure_attribute      PARAMS ((tree *, tree, tree, int,
                                                 bool *));
+static tree handle_vector_size_attribute PARAMS ((tree *, tree, tree, int,
+                                                 bool *));
+static tree vector_size_helper PARAMS ((tree, tree));
 
 /* Table of machine-independent attributes common to all C-like languages.  */
 static const struct attribute_spec c_common_attribute_table[] =
@@ -135,6 +138,8 @@ static const struct attribute_spec c_common_attribute_table[] =
                              handle_no_limit_stack_attribute },
   { "pure",                   0, 0, true,  false, false,
                              handle_pure_attribute },
+  { "vector_size",           1, 1, false, true, false,
+                             handle_vector_size_attribute },
   { NULL,                     0, 0, false, false, false, NULL }
 };
 
@@ -363,6 +368,18 @@ decl_attributes (node, attributes, flags)
        returned_attrs = chainon ((*spec->handler) (anode, name, args,
                                                    flags, &no_add_attrs),
                                  returned_attrs);
+
+      /* Layout the decl in case anything changed.  */
+      if (spec->type_required && DECL_P (*node)
+         && TREE_CODE (*node) == VAR_DECL)
+       {
+         /* Force a recalculation of mode and size.  */
+         DECL_MODE (*node) = VOIDmode;
+         DECL_SIZE (*node) = 0;
+
+         layout_decl (*node, 0);
+       }
+
       if (!no_add_attrs)
        {
          tree old_attrs;
@@ -1119,6 +1136,128 @@ handle_pure_attribute (node, name, args, flags, no_add_attrs)
   return NULL_TREE;
 }
 
+/* Handle a "vector_size" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+static tree
+handle_vector_size_attribute (node, name, args, flags, no_add_attrs)
+     tree *node;
+     tree name;
+     tree args;
+     int flags ATTRIBUTE_UNUSED;
+     bool *no_add_attrs;
+{
+  unsigned int vecsize, nunits;
+  enum machine_mode mode, orig_mode, new_mode;
+  tree type = *node, new_type;
+
+  *no_add_attrs = true;
+
+  if (TREE_CODE (TREE_VALUE (args)) != INTEGER_CST)
+    {
+      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
+      return NULL_TREE;
+    }
+
+  /* Get the vector size (in bytes).  */
+  vecsize = TREE_INT_CST_LOW (TREE_VALUE (args));
+
+  /* We need to provide for vector pointers, vector arrays, and
+     functions returning vectors.  For example:
+
+       __attribute__((vector_size(16))) short *foo;
+
+     In this case, the mode is SI, but the type being modified is
+     HI, so we need to look further.  */
+
+  while (POINTER_TYPE_P (type)
+        || TREE_CODE (type) == FUNCTION_TYPE
+        || TREE_CODE (type) == ARRAY_TYPE)
+    type = TREE_TYPE (type);
+
+  /* Get the mode of the type being modified.  */
+  orig_mode = TYPE_MODE (type);
+
+  if (TREE_CODE (type) == RECORD_TYPE ||
+      (GET_MODE_CLASS (orig_mode) != MODE_FLOAT
+       && GET_MODE_CLASS (orig_mode) != MODE_INT))
+    {
+      error ("invalid vector type for attribute `%s'",
+            IDENTIFIER_POINTER (name));
+      return NULL_TREE;
+    }
+
+  /* Calculate how many units fit in the vector.  */
+  nunits = vecsize / TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
+
+  /* Find a suitably sized vector.  */
+  new_mode = VOIDmode;
+  for (mode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (orig_mode) == MODE_INT
+                                       ? MODE_VECTOR_INT
+                                       : MODE_VECTOR_FLOAT);
+       mode != VOIDmode;
+       mode = GET_MODE_WIDER_MODE (mode))
+    if (vecsize == GET_MODE_SIZE (mode)        && nunits == GET_MODE_NUNITS (mode))
+      {
+       new_mode = mode;
+       break;
+      }
+
+  if (new_mode == VOIDmode)
+    error ("no vector mode with the size and type specified could be found");
+  else
+    {
+      new_type = type_for_mode (new_mode, TREE_UNSIGNED (type));
+      if (!new_type)
+       error ("no vector mode with the size and type specified could be found");
+      else
+       /* Build back pointers if needed.  */
+       *node = vector_size_helper (*node, new_type);
+    }
+    
+  return NULL_TREE;
+}
+
+/* HACK.  GROSS.  This is absolutely disgusting.  I wish there was a
+   better way.
+
+   If we requested a pointer to a vector, build up the pointers that
+   we stripped off while looking for the inner type.  Similarly for
+   return values from functions.
+
+   The argument "type" is the top of the chain, and "bottom" is the
+   new type which we will point to.  */
+
+static tree
+vector_size_helper (type, bottom)
+     tree type, bottom;
+{
+  tree inner, outer;
+
+  if (POINTER_TYPE_P (type))
+    {
+      inner = vector_size_helper (TREE_TYPE (type), bottom);
+      outer = build_pointer_type (inner);
+    }
+  else if (TREE_CODE (type) == ARRAY_TYPE)
+    {
+      inner = vector_size_helper (TREE_TYPE (type), bottom);
+      outer = build_array_type (inner, TYPE_VALUES (type));
+    }
+  else if (TREE_CODE (type) == FUNCTION_TYPE)
+    {
+      inner = vector_size_helper (TREE_TYPE (type), bottom);
+      outer = build_function_type (inner, TYPE_VALUES (type));
+    }
+  else
+    return bottom;
+  
+  TREE_READONLY (outer) = TREE_READONLY (type);
+  TREE_THIS_VOLATILE (outer) = TREE_THIS_VOLATILE (type);
+
+  return outer;
+}
+
 /* Split SPECS_ATTRS, a list of declspecs and prefix attributes, into two
    lists.  SPECS_ATTRS may also be just a typespec (eg: RECORD_TYPE).
 
index a6853d8206e3e7c41d737ace2716db3c17b55b96..e75a8d600c9f708d3bfefa585f7ab95defdde24b 100644 (file)
@@ -2794,14 +2794,15 @@ section.
 
 The keyword @code{__attribute__} allows you to specify special
 attributes of variables or structure fields.  This keyword is followed
-by an attribute specification inside double parentheses.  Eight
+by an attribute specification inside double parentheses.  Nine
 attributes are currently defined for variables: @code{aligned},
 @code{mode}, @code{nocommon}, @code{packed}, @code{section},
-@code{transparent_union}, @code{unused}, and @code{weak}.  Some other
-attributes are defined for variables on particular target systems.  Other
-attributes are available for functions (@pxref{Function Attributes}) and
-for types (@pxref{Type Attributes}).  Other front ends might define more
-attributes (@pxref{C++ Extensions,,Extensions to the C++ Language}).
+@code{transparent_union}, @code{unused}, @code{vector_size}, and
+@code{weak}.  Some other attributes are defined for variables on
+particular target systems.  Other attributes are available for functions
+(@pxref{Function Attributes}) and for types (@pxref{Type Attributes}).
+Other front ends might define more attributes (@pxref{C++
+Extensions,,Extensions to the C++ Language}).
 
 You may also specify attributes with @samp{__} preceding and following
 each keyword.  This allows you to use them in header files without
@@ -3003,6 +3004,35 @@ This attribute, attached to a variable, means that the variable is meant
 to be possibly unused.  GCC will not produce a warning for this
 variable.
 
+@item vector_size (@var{bytes})
+This attribute specifies the vector size for the variable, measured in
+bytes.  For example, the declaration:
+
+@smallexample
+int foo __attribute__ ((vector_size (16)));
+@end smallexample
+
+@noindent
+causes the compiler to set the mode for @code{foo}, to be 16 bytes,
+divided into @code{int} sized units.  Assuming a 32-bit int (a vector of
+4 units of 4 bytes), the corresponding mode of @code{foo} will be V4SI@.
+
+This attribute is only applicable to integral and float scalars,
+although arrays, pointers, and function return values are allowed in
+conjunction with this construct.
+
+Aggregates with this attribute are invalid, even if they are of the same
+size as a corresponding scalar.  For example, the declaration:
+
+@smallexample
+struct S { int a; };
+struct S  __attribute__ ((vector_size (16))) foo;
+@end smallexample
+
+@noindent
+is invalid even if the size of the structure is the same as the size of
+the @code{int}.
+
 @item weak
 The @code{weak} attribute is described in @xref{Function Attributes}.
 
This page took 0.083073 seconds and 5 git commands to generate.