--- avr_org.c Sun Sep 2 01:28:30 2007 +++ avr.c Fri Apr 4 13:15:07 2008 @@ -430,6 +430,46 @@ return a != NULL_TREE; } + +void +avr_declare_function_name (FILE *file, const char *name, tree decl) +{ + tree a = NULL_TREE; + int vector = -1; + + if (TREE_CODE (decl) == FUNCTION_DECL) + a = lookup_attribute ("signal", DECL_ATTRIBUTES (decl)); + + if (a) + a = TREE_VALUE (a); + + if (a) + a = TREE_VALUE (a); + + if (a) + vector = TREE_INT_CST_LOW (a); + + ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function"); + ASM_OUTPUT_LABEL (file, name); + + if (vector != -1) + { + /* Minimul sanity check for valid interrupt vector number. */ + if (vector > 0 && vector <= MAX_INTERRUPT_NUMBER) + { + fprintf (file, ".global __vector_%d\n", vector); + fprintf (file, "__vector_%d:\n", vector); + } + else + { + if (vector > 100000) + warning (0, "The name of the vector number for interrupt %qs appears to be misspelt", name); + else + warning (0, "Interrupt vector number %d is outside valid range.", vector); + } + } +} + /* Return the number of hard registers to push/pop in the prologue/epilogue of the current function, and optionally store these registers in SET. */ @@ -4650,7 +4690,7 @@ { /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ { "progmem", 0, 0, false, false, false, avr_handle_progmem_attribute }, - { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute }, + { "signal", 0, 1, true, false, false, avr_handle_fndecl_attribute }, { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute }, { "naked", 0, 0, false, true, true, avr_handle_fntype_attribute }, { NULL, 0, 0, false, false, false, NULL } @@ -4704,7 +4744,7 @@ static tree avr_handle_fndecl_attribute (tree *node, tree name, - tree args ATTRIBUTE_UNUSED, + tree args, int flags ATTRIBUTE_UNUSED, bool *no_add_attrs) { @@ -4714,7 +4754,7 @@ IDENTIFIER_POINTER (name)); *no_add_attrs = true; } - else + else if (args == NULL_TREE) { const char *func_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (*node)); const char *attr = IDENTIFIER_POINTER (name); @@ -4727,16 +4767,14 @@ { if (strncmp (func_name, "__vector", strlen ("__vector")) != 0) { - warning (0, "%qs appears to be a misspelled interrupt handler", - func_name); + warning (0, "%qs appears to be a misspelled interrupt handler", func_name); } } else if (strncmp (attr, "signal", strlen ("signal")) == 0) { if (strncmp (func_name, "__vector", strlen ("__vector")) != 0) { - warning (0, "%qs appears to be a misspelled signal handler", - func_name); + warning (0, "%qs appears to be a misspelled signal handler", func_name); } } } --- avr-protos_org.h Sun Sep 2 01:28:30 2007 +++ avr-protos.h Wed Mar 26 21:45:46 2008 @@ -42,6 +42,7 @@ #ifdef TREE_CODE extern void asm_output_external (FILE *file, tree decl, char *name); extern int avr_progmem_p (tree decl, tree attributes); +extern void avr_declare_function_name (FILE *file, const char *name, tree decl); #ifdef RTX_CODE /* inside TREE_CODE */ extern rtx avr_function_value (tree type, tree func); --- avr_org.h Tue Sep 4 07:03:50 2007 +++ avr.h Sat Mar 29 12:11:53 2008 @@ -81,6 +81,8 @@ #define POINTER_SIZE 16 +/* Upper boundary of valid interrupt vectors */ +#define MAX_INTERRUPT_NUMBER 56 /* Maximum sized of reasonable data type DImode or Dfmode ... */ @@ -522,10 +524,7 @@ specific tm.h file (depending upon the particulars of your assembler). */ #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ -do { \ - ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function"); \ - ASM_OUTPUT_LABEL (FILE, NAME); \ -} while (0) + avr_declare_function_name (FILE, NAME, DECL) #define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \ do { \