rx.c (add_vector_labels): New.
authorDJ Delorie <dj@redhat.com>
Wed, 28 May 2014 00:37:00 +0000 (20:37 -0400)
committerDJ Delorie <dj@gcc.gnu.org>
Wed, 28 May 2014 00:37:00 +0000 (20:37 -0400)
* config/rx/rx.c (add_vector_labels): New.
(rx_output_function_prologue): Call it.
(rx_handle_func_attribute): Don't require empty arguments.
(rx_handle_vector_attribute): New.
(rx_attribute_table): Add "vector" attribute.
* doc/extend.texi (interrupt, vector): Document new/changed
RX-specific attributes.

* config/rx/rx.c (rx_adjust_insn_length): Skip for non-insns.

From-SVN: r210995

gcc/ChangeLog
gcc/config/rx/rx.c
gcc/doc/extend.texi

index 8898e8de95f410feea64a591f04ac9a8b92da6da..fd26409c0a874a2c31fea4cd8eb10ee0d7972181 100644 (file)
@@ -1,3 +1,15 @@
+2014-05-27  DJ Delorie  <dj@redhat.com>
+
+       * config/rx/rx.c (add_vector_labels): New.
+       (rx_output_function_prologue): Call it.
+       (rx_handle_func_attribute): Don't require empty arguments.
+       (rx_handle_vector_attribute): New.
+       (rx_attribute_table): Add "vector" attribute.
+       * doc/extend.texi (interrupt, vector): Document new/changed
+       RX-specific attributes.
+
+       * config/rx/rx.c (rx_adjust_insn_length): Skip for non-insns.
+
 2014-05-27  Eric Botcazou  <ebotcazou@adacore.com>
 
        * double-int.c (div_and_round_double) <ROUND_DIV_EXPR>: Use the proper
index 4242c1a97172a46d41f7bd640e3e250d7e590604..c81b2d4a410f9bc432c332e37c9c71d3360c0c6a 100644 (file)
@@ -1809,10 +1809,69 @@ rx_expand_prologue (void)
     }
 }
 
+static void
+add_vector_labels (FILE *file, const char *aname)
+{
+  tree vec_attr;
+  tree val_attr;
+  const char *vname = "vect";
+  const char *s;
+  int vnum;
+
+  /* This node is for the vector/interrupt tag itself */
+  vec_attr = lookup_attribute (aname, DECL_ATTRIBUTES (current_function_decl));
+  if (!vec_attr)
+    return;
+
+  /* Now point it at the first argument */
+  vec_attr = TREE_VALUE (vec_attr);
+
+  /* Iterate through the arguments.  */
+  while (vec_attr)
+    {
+      val_attr = TREE_VALUE (vec_attr);
+      switch (TREE_CODE (val_attr))
+       {
+       case STRING_CST:
+         s = TREE_STRING_POINTER (val_attr);
+         goto string_id_common;
+
+       case IDENTIFIER_NODE:
+         s = IDENTIFIER_POINTER (val_attr);
+
+       string_id_common:
+         if (strcmp (s, "$default") == 0)
+           {
+             fprintf (file, "\t.global\t$tableentry$default$%s\n", vname);
+             fprintf (file, "$tableentry$default$%s:\n", vname);
+           }
+         else
+           vname = s;
+         break;
+
+       case INTEGER_CST:
+         vnum = TREE_INT_CST_LOW (val_attr);
+
+         fprintf (file, "\t.global\t$tableentry$%d$%s\n", vnum, vname);
+         fprintf (file, "$tableentry$%d$%s:\n", vnum, vname);
+         break;
+
+       default:
+         ;
+       }
+
+      vec_attr = TREE_CHAIN (vec_attr);
+    }
+
+}
+
 static void
 rx_output_function_prologue (FILE * file,
                             HOST_WIDE_INT frame_size ATTRIBUTE_UNUSED)
 {
+  add_vector_labels (file, "interrupt");
+  add_vector_labels (file, "vector");
+
   if (is_fast_interrupt_func (NULL_TREE))
     asm_fprintf (file, "\t; Note: Fast Interrupt Handler\n");
 
@@ -2602,7 +2661,6 @@ rx_handle_func_attribute (tree * node,
                          bool * no_add_attrs)
 {
   gcc_assert (DECL_P (* node));
-  gcc_assert (args == NULL_TREE);
 
   if (TREE_CODE (* node) != FUNCTION_DECL)
     {
@@ -2618,6 +2676,28 @@ rx_handle_func_attribute (tree * node,
   return NULL_TREE;
 }
 
+/* Check "vector" attribute.  */
+
+static tree
+rx_handle_vector_attribute (tree * node,
+                           tree   name,
+                           tree   args,
+                           int    flags ATTRIBUTE_UNUSED,
+                           bool * no_add_attrs)
+{
+  gcc_assert (DECL_P (* node));
+  gcc_assert (args != NULL_TREE);
+
+  if (TREE_CODE (* node) != FUNCTION_DECL)
+    {
+      warning (OPT_Wattributes, "%qE attribute only applies to functions",
+              name);
+      * no_add_attrs = true;
+    }
+
+  return NULL_TREE;
+}
+
 /* Table of RX specific attributes.  */
 const struct attribute_spec rx_attribute_table[] =
 {
@@ -2625,10 +2705,12 @@ const struct attribute_spec rx_attribute_table[] =
      affects_type_identity.  */
   { "fast_interrupt", 0, 0, true, false, false, rx_handle_func_attribute,
     false },
-  { "interrupt",      0, 0, true, false, false, rx_handle_func_attribute,
+  { "interrupt",      0, -1, true, false, false, rx_handle_func_attribute,
     false },
   { "naked",          0, 0, true, false, false, rx_handle_func_attribute,
     false },
+  { "vector",         1, -1, true, false, false, rx_handle_vector_attribute,
+    false },
   { NULL,             0, 0, false, false, false, NULL, false }
 };
 
@@ -3155,6 +3237,9 @@ rx_adjust_insn_length (rtx insn, int current_length)
   bool zero;
   int factor;
 
+  if (!INSN_P (insn))
+    return current_length;
+
   switch (INSN_CODE (insn))
     {
     default:
index 37465d4294e8b7236790b27bb594d0a1412a3dd1..4e1a6b3809fc74ef94feaae2b722ea6adfc1166c 100644 (file)
@@ -3089,6 +3089,28 @@ On RL78, use @code{brk_interrupt} instead of @code{interrupt} for
 handlers intended to be used with the @code{BRK} opcode (i.e.@: those
 that must end with @code{RETB} instead of @code{RETI}).
 
+On RX targets, you may specify one or more vector numbers as arguments
+to the attribute, as well as naming an alternate table name.
+Parameters are handled sequentially, so one handler can be assigned to
+multiple entries in multiple tables.  One may also pass the magic
+string @code{"$default"} which causes the function to be used for any
+unfilled slots in the current table.
+
+This example shows a simple assignment of a function to one vector in
+the default table (note that preprocessor macros may be used for
+chip-specific symbolic vector names):
+@smallexample
+void __attribute__ ((interrupt (5))) txd1_handler ();
+@end smallexample
+
+This example assigns a function to two slots in the default table
+(using preprocessor macros defined elsewhere) and makes it the default
+for the @code{dct} table:
+@smallexample
+void __attribute__ ((interrupt (RXD1_VECT,RXD2_VECT,"dct","$default")))
+       txd1_handler ();
+@end smallexample
+
 @item interrupt_handler
 @cindex interrupt handler functions on the Blackfin, m68k, H8/300 and SH processors
 Use this attribute on the Blackfin, m68k, H8/300, H8/300H, H8S, and SH to
@@ -4291,6 +4313,13 @@ When applied to a member function of a C++ class template, the
 attribute also means that the function is instantiated if the
 class itself is instantiated.
 
+@item vector
+@cindex @code{vector} attibute
+This RX attribute is similar to the @code{attribute}, including its
+parameters, but does not make the function an interrupt-handler type
+function (i.e. it retains the normal C function calling ABI).  See the
+@code{interrupt} attribute for a description of its arguments.
+
 @item version_id
 @cindex @code{version_id} attribute
 This IA-64 HP-UX attribute, attached to a global variable or function, renames a