===================================================================
@@ -3086,12 +3086,34 @@ interrupt handler.
@end table
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
indicate that the specified function is an interrupt handler. The compiler
generates function entry and exit sequences suitable for use in an
interrupt handler when this attribute is present.
@@ -4288,12 +4310,19 @@ This is useful, for example, when the fu
inline assembly.
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
symbol to contain a version string, thus allowing for function level
versioning. HP-UX system header files may use function level versioning
for some system calls.
===================================================================
@@ -1807,15 +1807,74 @@ rx_expand_prologue (void)
gen_safe_add (stack_pointer_rtx, frame_pointer_rtx, NULL_RTX,
true);
}
}
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");
if (is_interrupt_func (NULL_TREE))
asm_fprintf (file, "\t; Note: Interrupt Handler\n");
@@ -2599,13 +2658,12 @@ rx_handle_func_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;
@@ -2615,23 +2673,47 @@ rx_handle_func_attribute (tree * node,
/* FIXME: We ought to check that the interrupt and exception
handler attributes have been applied to void functions. */
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[] =
{
/* Name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
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 }
};
/* Implement TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE. */
static void
@@ -3152,12 +3234,15 @@ int
rx_adjust_insn_length (rtx insn, int current_length)
{
rtx extend, mem, offset;
bool zero;
int factor;
+ if (!INSN_P (insn))
+ return current_length;
+
switch (INSN_CODE (insn))
{
default:
return current_length;
case CODE_FOR_plussi3_zero_extendhi: