avr.h (machine_function): Add 'is_OS_main' field.
authorAnatoly Sokolov <aesok@post.ru>
Tue, 20 May 2008 21:23:08 +0000 (01:23 +0400)
committerAnatoly Sokolov <aesok@gcc.gnu.org>
Tue, 20 May 2008 21:23:08 +0000 (01:23 +0400)
* 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

gcc/ChangeLog
gcc/config/avr/avr.c
gcc/config/avr/avr.h

index cdc2b9dd0e0ee48407e0939f5291bf81e161c857..676369520a83b35a263f4c1bc0c688a3e3d05d39 100644 (file)
@@ -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
index 9a860533e9a576894e82b25e1ae2645f7673680c..1293a4b3463feb2cfd58a6320eb127c50e262560 100644 (file)
@@ -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 }
 };
 
index 5261d9d6ba547939762a9c413a315098d5401eef..4cd0f24517e7cca7d9b1867821ff0bcb5e527a0f 100644 (file)
@@ -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;
 };