(fix-header.o): Likewise.
(scan-decls.o): Likewise.
+Fri Dec 11 11:02:49 1998 Stan Cox <scox@cygnus.com>
+
+ * 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.
+
Fri Dec 11 12:56:07 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
* reload1.c (reload_combine): Use BASIC_BLOCK_LIVE_AT_START
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)
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;
}
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]
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.
if (is_attribute_p ("interrupt_handler", attr))
{
- pragma_interrupt = 1;
return 1;
}
#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;