diff options
author | Anatoly Sokolov <aesok@post.ru> | 2008-05-21 01:23:08 +0400 |
---|---|---|
committer | Anatoly Sokolov <aesok@gcc.gnu.org> | 2008-05-21 01:23:08 +0400 |
commit | 9b678d960153d0d2b24ad300a93018ad6e813eda (patch) | |
tree | d455bc879e35c4b2d758d86cf249ce5132469a48 /gcc | |
parent | ede2e423f8612d5a09c1d34cdf1c5f90763519ba (diff) | |
download | gcc-9b678d960153d0d2b24ad300a93018ad6e813eda.zip gcc-9b678d960153d0d2b24ad300a93018ad6e813eda.tar.gz gcc-9b678d960153d0d2b24ad300a93018ad6e813eda.tar.bz2 |
avr.h (machine_function): Add 'is_OS_main' field.
* config/avr/avr.h (machine_function): Add 'is_OS_main' field.
* config/avr/avr.c (avr_OS_main_function_p): Add new function.
(avr_attribute_table): Add 'OS_main' function attribute.
(avr_regs_to_save, expand_prologue, expand_epilogue): Handle
functions with 'OS_main' attribute.
From-SVN: r135681
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/avr/avr.c | 27 | ||||
-rw-r--r-- | gcc/config/avr/avr.h | 6 |
3 files changed, 36 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cdc2b9d..6763695 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2008-05-20 Anatoly Sokolov <aesok@post.ru> + + * config/avr/avr.h (machine_function): Add 'is_OS_main' field. + * config/avr/avr.c (avr_OS_main_function_p): Add new function. + (avr_attribute_table): Add 'OS_main' function attribute. + (avr_regs_to_save, expand_prologue, expand_epilogue): Handle + functions with 'OS_main' attribute. + 2008-05-20 Richard Guenther <rguenther@suse.de> PR tree-optimization/35204 diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 9a86053..1293a4b 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -52,6 +52,7 @@ 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 sequent_regs_live (void); static const char *ptrreg_to_str (int); @@ -446,6 +447,19 @@ avr_OS_task_function_p (tree func) return a != NULL_TREE; } +/* Return nonzero if FUNC is a OS_main function. */ + +static int +avr_OS_main_function_p (tree func) +{ + tree a; + + gcc_assert (TREE_CODE (func) == FUNCTION_DECL); + + a = lookup_attribute ("OS_main", TYPE_ATTRIBUTES (TREE_TYPE (func))); + return a != NULL_TREE; +} + /* Return the number of hard registers to push/pop in the prologue/epilogue of the current function, and optionally store these registers in SET. */ @@ -464,9 +478,10 @@ avr_regs_to_save (HARD_REG_SET *set) count = 0; /* No need to save any registers if the function never returns or - is have "OS_task" attribute. */ + is have "OS_task" or "OS_main" attribute. */ if (TREE_THIS_VOLATILE (current_function_decl) - || cfun->machine->is_OS_task) + || cfun->machine->is_OS_task + || cfun->machine->is_OS_main) return 0; for (reg = 0; reg < 32; reg++) @@ -593,6 +608,7 @@ expand_prologue (void) cfun->machine->is_interrupt = interrupt_function_p (current_function_decl); cfun->machine->is_signal = signal_function_p (current_function_decl); cfun->machine->is_OS_task = avr_OS_task_function_p (current_function_decl); + cfun->machine->is_OS_main = avr_OS_main_function_p (current_function_decl); /* Prologue: naked. */ if (cfun->machine->is_naked) @@ -606,6 +622,7 @@ expand_prologue (void) && !cfun->machine->is_interrupt && !cfun->machine->is_signal && !cfun->machine->is_OS_task + && !cfun->machine->is_OS_main && live_seq); if (cfun->machine->is_interrupt || cfun->machine->is_signal) @@ -675,7 +692,7 @@ expand_prologue (void) } if (frame_pointer_needed) { - if(!cfun->machine->is_OS_task) + if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main)) { /* Push frame pointer. */ insn = emit_move_insn (pushword, frame_pointer_rtx); @@ -829,6 +846,7 @@ expand_epilogue (void) && !cfun->machine->is_interrupt && !cfun->machine->is_signal && !cfun->machine->is_OS_task + && !cfun->machine->is_OS_main && live_seq); if (minimize && (frame_pointer_needed || live_seq > 4)) @@ -891,7 +909,7 @@ expand_epilogue (void) emit_move_insn (stack_pointer_rtx, frame_pointer_rtx); } } - if(!cfun->machine->is_OS_task) + if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main)) { /* Restore previous frame_pointer. */ emit_insn (gen_pophi (frame_pointer_rtx)); @@ -4593,6 +4611,7 @@ const struct attribute_spec avr_attribute_table[] = { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute }, { "naked", 0, 0, false, true, true, avr_handle_fntype_attribute }, { "OS_task", 0, 0, false, true, true, avr_handle_fntype_attribute }, + { "OS_main", 0, 0, false, true, true, avr_handle_fntype_attribute }, { NULL, 0, 0, false, false, false, NULL } }; diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h index 5261d9d..4cd0f24 100644 --- a/gcc/config/avr/avr.h +++ b/gcc/config/avr/avr.h @@ -1042,7 +1042,11 @@ struct machine_function GTY(()) as specified by the "signal" attribute. */ int is_signal; - /* 'true' - if current function is a signal function + /* 'true' - if current function is a 'task' function as specified by the "OS_task" attribute. */ int is_OS_task; + + /* 'true' - if current function is a 'main' function + as specified by the "OS_main" attribute. */ + int is_OS_main; }; |