rx.c (add_vector_labels): New.

* 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
This commit is contained in:
DJ Delorie 2014-05-27 20:37:00 -04:00 committed by DJ Delorie
parent fa07538edf
commit 69c7a374a1
3 changed files with 128 additions and 2 deletions

View 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

View 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:

View 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