AVR-LibC switched from using either signal /or/ interrupt function
attribute to using both at the same time.
This was never documented or implemented but worked accidentally for
some time, but results in wrong code for 4.7+
This patch adds better documentation of these attributes and makes
'interrupt' silently override 'signal'.
Besides that, some more sanity checking is done for function attributes.
ASM_DECLARE_FUNCTION_NAME just served to check isr names.
All the checking is done in the new hook TARGET_SET_CURRENT_FUNCTION
now so that ASM_DECLARE_FUNCTION_NAME from defaults.h can be used,
thus some clean-up in elf.h
Ok for trunk and 4.7?
Johann
PR target/53256
* config/avr/elf.h (ASM_DECLARE_FUNCTION_NAME): Remove.
* config/avr/avr-protos.h (avr_asm_declare_function_name): Remove.
* config/avr/avr.h (struct machine_function): Add attributes_checked_p.
* config/avr/avr.c (avr_asm_declare_function_name): Remove.
(expand_prologue): Move initialization of cfun-machine-is_naked,
is_interrupt, is_signal, is_OS_task, is_OS_main from here to...
(avr_regs_to_save): Ditto.
(avr_set_current_function): ...this new static function.
(TARGET_SET_CURRENT_FUNCTION): New define.
(avr_function_ok_for_sibcall): Use cfun-machine-is_* instead of
checking attributes of current_function_decl.
(signal_function_p): Rename to avr_signal_function_p.
(interrupt_function_p): Rename to avr_interrupt_function_p.
* doc/extend.texi (Function Attributes): Better explanation of
'interrupt' and 'signal for AVR. Move 'ifunc' down for
alphabetical order.
Index: config/avr/elf.h
===
--- config/avr/elf.h (revision 187252)
+++ config/avr/elf.h (working copy)
@@ -32,11 +32,6 @@
#undef STRING_LIMIT
#define STRING_LIMIT ((unsigned) 64)
-/* Take care of `signal' and `interrupt' attributes. */
-#undef ASM_DECLARE_FUNCTION_NAME
-#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
- avr_asm_declare_function_name ((FILE), (NAME), (DECL))
-
/* Output alignment 2**1 for jump tables. */
#undef ASM_OUTPUT_BEFORE_CASE_LABEL
#define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE, PREFIX, NUM, TABLE) \
Index: config/avr/avr-protos.h
===
--- config/avr/avr-protos.h (revision 187252)
+++ config/avr/avr-protos.h (working copy)
@@ -26,7 +26,6 @@ extern int function_arg_regno_p (int r);
extern void avr_cpu_cpp_builtins (struct cpp_reader * pfile);
extern enum reg_class avr_regno_reg_class (int r);
extern void asm_globalize_label (FILE *file, const char *name);
-extern void avr_asm_declare_function_name (FILE *, const char *, tree);
extern void order_regs_for_local_alloc (void);
extern int avr_initial_elimination_offset (int from, int to);
extern int avr_simple_epilogue (void);
Index: config/avr/avr.c
===
--- config/avr/avr.c (revision 187259)
+++ config/avr/avr.c (working copy)
@@ -138,12 +138,6 @@ static const char* out_movqi_mr_r (rtx,
static const char* out_movhi_mr_r (rtx, rtx[], int*);
static const char* out_movsi_mr_r (rtx, rtx[], int*);
-static int avr_naked_function_p (tree);
-static int interrupt_function_p (tree);
-static int signal_function_p (tree);
-static int avr_OS_task_function_p (tree);
-static int avr_OS_main_function_p (tree);
-static int avr_regs_to_save (HARD_REG_SET *);
static int get_sequence_length (rtx insns);
static int sequent_regs_live (void);
static const char *ptrreg_to_str (int);
@@ -491,7 +485,7 @@ avr_naked_function_p (tree func)
by the interrupt attribute. */
static int
-interrupt_function_p (tree func)
+avr_interrupt_function_p (tree func)
{
return avr_lookup_function_attribute1 (func, interrupt);
}
@@ -500,7 +494,7 @@ interrupt_function_p (tree func)
by the signal attribute. */
static int
-signal_function_p (tree func)
+avr_signal_function_p (tree func)
{
return avr_lookup_function_attribute1 (func, signal);
}
@@ -522,6 +516,80 @@ avr_OS_main_function_p (tree func)
}
+/* Implement `TARGET_SET_CURRENT_FUNCTION'. */
+/* Sanity cheching for above function attributes. */
+
+static void
+avr_set_current_function (tree decl)
+{
+ location_t loc;
+ const char *isr;
+
+ if (decl == NULL_TREE
+ || current_function_decl == NULL_TREE
+ || current_function_decl == error_mark_node
+ || cfun-machine-attributes_checked_p)
+return;
+
+ loc = DECL_SOURCE_LOCATION (decl);
+
+ cfun-machine-is_naked = avr_naked_function_p (decl);
+ cfun-machine-is_signal = avr_signal_function_p (decl);
+ cfun-machine-is_interrupt = avr_interrupt_function_p (decl);
+ cfun-machine-is_OS_task = avr_OS_task_function_p (decl);
+ cfun-machine-is_OS_main = avr_OS_main_function_p (decl);
+
+ isr = cfun-machine-is_interrupt ? interrupt : signal;
+
+ /* Too much