Re: [Patch,AVR,trunk,4.7]: Implement PR53256

2012-05-09 Thread Denis Chertykov
2012/5/7 Georg-Johann Lay a...@gjlay.de:
 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.


Approved.

Denis.


[Patch,AVR,trunk,4.7]: Implement PR53256

2012-05-07 Thread Georg-Johann Lay
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