summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorscox <scox@138bc75d-0d04-0410-961f-82ee72b054a4>1998-12-11 11:18:26 +0000
committerscox <scox@138bc75d-0d04-0410-961f-82ee72b054a4>1998-12-11 11:18:26 +0000
commit49f630e150fc65e85948989ecc33569c08f7d378 (patch)
tree08e45a7cef0ba9d63098e6b579443435a90a4a90 /gcc/config
parent72890be35da1f4268f6fd48530c5d764f9e3afe8 (diff)
downloadgcc-49f630e150fc65e85948989ecc33569c08f7d378.tar.gz
* sh.c (print_operand): lookup interrupt_handler attribute instead
of relying on static variable. * (calc_live_regs): Likewise. * (sh_pragma_insert_attributes): Create interrupt_handler attribute if a pragma was specified * (sh_valid_machine_decl_attribute): Don't set static flag. * sh.h (PRAGMA_INSERT_ATTRIBUTES): New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@24265 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/sh/sh.c53
-rw-r--r--gcc/config/sh/sh.h4
2 files changed, 53 insertions, 4 deletions
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index cb40718c057..2eb4674c7d0 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -226,13 +226,25 @@ print_operand (stream, x, code)
fprintf (stream, "%s", LOCAL_LABEL_PREFIX);
break;
case '@':
+ {
+ int interrupt_handler;
+
+ if ((lookup_attribute
+ ("interrupt_handler",
+ DECL_MACHINE_ATTRIBUTES (current_function_decl)))
+ != NULL_TREE)
+ interrupt_handler = 1;
+ else
+ interrupt_handler = 0;
+
if (trap_exit)
fprintf (stream, "trapa #%d", trap_exit);
- else if (pragma_interrupt)
+ else if (interrupt_handler)
fprintf (stream, "rte");
else
fprintf (stream, "rts");
break;
+ }
case '#':
/* Output a nop if there's nothing in the delay slot. */
if (dbr_sequence_length () == 0)
@@ -3615,13 +3627,22 @@ calc_live_regs (count_ptr, live_regs_mask2)
int reg;
int live_regs_mask = 0;
int count;
+ int interrupt_handler;
+
+ if ((lookup_attribute
+ ("interrupt_handler",
+ DECL_MACHINE_ATTRIBUTES (current_function_decl)))
+ != NULL_TREE)
+ interrupt_handler = 1;
+ else
+ interrupt_handler = 0;
*live_regs_mask2 = 0;
/* If we can save a lot of saves by switching to double mode, do that. */
if (TARGET_SH4 && TARGET_FMOVD && TARGET_FPU_SINGLE)
for (count = 0, reg = FIRST_FP_REG; reg <= LAST_FP_REG; reg += 2)
if (regs_ever_live[reg] && regs_ever_live[reg+1]
- && (! call_used_regs[reg] || (pragma_interrupt && ! pragma_trapa))
+ && (! call_used_regs[reg] || (interrupt_handler && ! pragma_trapa))
&& ++count > 2)
{
target_flags &= ~FPU_SINGLE_BIT;
@@ -3629,7 +3650,7 @@ calc_live_regs (count_ptr, live_regs_mask2)
}
for (count = 0, reg = FIRST_PSEUDO_REGISTER - 1; reg >= 0; reg--)
{
- if ((pragma_interrupt && ! pragma_trapa)
+ if ((interrupt_handler && ! pragma_trapa)
? (/* Need to save all the regs ever live. */
(regs_ever_live[reg]
|| (call_used_regs[reg]
@@ -3951,6 +3972,31 @@ sh_handle_pragma (p_getc, p_ungetc, pname)
return retval;
}
+
+/* Generate 'handle_interrupt' attribute for decls */
+
+void
+sh_pragma_insert_attributes (node, attributes, prefix)
+ tree node;
+ tree * attributes;
+ tree * prefix;
+{
+ tree a;
+
+ if (! pragma_interrupt
+ || TREE_CODE (node) != FUNCTION_DECL)
+ return;
+
+ /* We are only interested in fields. */
+ if (TREE_CODE_CLASS (TREE_CODE (node)) != 'd')
+ return;
+
+ /* Add a 'handle_interrupt' attribute. */
+ * attributes = tree_cons (get_identifier ("interrupt_handler"), NULL, * attributes);
+
+ return;
+}
+
/* Return nonzero if ATTR is a valid attribute for DECL.
ATTRIBUTES are any existing attributes and ARGS are the arguments
supplied with ATTR.
@@ -3979,7 +4025,6 @@ sh_valid_machine_decl_attribute (decl, attributes, attr, args)
if (is_attribute_p ("interrupt_handler", attr))
{
- pragma_interrupt = 1;
return 1;
}
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index c32b13a000d..e2bf8c7bed9 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -2062,6 +2062,10 @@ extern int sh_valid_machine_decl_attribute ();
#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \
sh_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
+extern void sh_pragma_insert_attributes ();
+#define PRAGMA_INSERT_ATTRIBUTES(node, pattr, prefix_attr) \
+ sh_pragma_insert_attributes (node, pattr, prefix_attr)
+
extern int sh_flag_remove_dead_before_cse;
extern int rtx_equal_function_value_matters;
extern struct rtx_def *fpscr_rtx;