This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[AVR][committed] Add 'OS_main' attribute. [2/2]


Hello.

This patch adds an 'OS_main' attribute to the AVR port. The 'main' functions
with 'OS_main' attribute do not save any "call-saved" registers, requiring
less stack space.

It is the second part of a changes, the 'OS_main' attribute now really work
now.

2008-05-31  Anatoly Sokolov  <aesok@post.ru>

        * config/avr/avr.md (UNSPECV_WRITE_SP_IRQ_ON): New constants.
        (UNSPECV_WRITE_SP_IRQ_OFF): (Ditto.).
        (movhi_sp_r_irq_off, movhi_sp_r_irq_on): New insn.
        * config/avr/avr.c (expand_prologue, expand_epilogue): Use 
        movhi_sp_r_irq_off and movhi_sp_r_irq_on insns for writing to the
        stack pointer register.
        (output_movhi): Remove code for interrupt specific writing to the 
        stack pointer register.


Index: gcc/config/avr/avr.md
===================================================================
--- gcc/config/avr/avr.md       (revision 136236)
+++ gcc/config/avr/avr.md       (working copy)
@@ -56,7 +56,9 @@
    (UNSPEC_CLI         3)
 
    (UNSPECV_PROLOGUE_SAVES     0)
-   (UNSPECV_EPILOGUE_RESTORES  1)])
+   (UNSPECV_EPILOGUE_RESTORES  1)
+   (UNSPECV_WRITE_SP_IRQ_ON    2)
+   (UNSPECV_WRITE_SP_IRQ_OFF   3)])
 
 (include "predicates.md")
 (include "constraints.md")
@@ -230,6 +232,28 @@
   [(set_attr "length" "5,2")
    (set_attr "cc" "none,none")])
 
+(define_insn "movhi_sp_r_irq_off"
+  [(set (match_operand:HI 0 "stack_register_operand" "=q")
+        (unspec_volatile:HI [(match_operand:HI 1 "register_operand"  "r")] 
+                           UNSPECV_WRITE_SP_IRQ_OFF))]
+  ""
+  "out __SP_H__, %B1
+       out __SP_L__, %A1"
+  [(set_attr "length" "2")
+   (set_attr "cc" "none")])
+
+(define_insn "movhi_sp_r_irq_on"
+  [(set (match_operand:HI 0 "stack_register_operand" "=q")
+        (unspec_volatile:HI [(match_operand:HI 1 "register_operand"  "r")] 
+                           UNSPECV_WRITE_SP_IRQ_ON))]
+  ""
+  "cli
+        out __SP_H__, %B1
+       sei
+       out __SP_L__, %A1"
+  [(set_attr "length" "4")
+   (set_attr "cc" "none")])
+
 (define_peephole2
   [(match_scratch:QI 2 "d")
    (set (match_operand:HI 0 "l_register_operand" "")
Index: gcc/config/avr/avr.c
===================================================================
--- gcc/config/avr/avr.c        (revision 136236)
+++ gcc/config/avr/avr.c        (working copy)
@@ -763,8 +763,32 @@
                                                            GET_MODE(myfp))));
               RTX_FRAME_RELATED_P (insn) = 1;
 
-              insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
-              RTX_FRAME_RELATED_P (insn) = 1;
+             /* Copy to stack pointer.  */
+             if (TARGET_TINY_STACK)
+               {
+                 insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
+                 RTX_FRAME_RELATED_P (insn) = 1;
+               }
+             else if (TARGET_NO_INTERRUPTS 
+                      || cfun->machine->is_signal
+                      || cfun->machine->is_OS_main)
+               {
+                 insn = 
+                   emit_insn (gen_movhi_sp_r_irq_off (stack_pointer_rtx, 
+                                                      frame_pointer_rtx));
+                 RTX_FRAME_RELATED_P (insn) = 1;               
+               }
+             else if (cfun->machine->is_interrupt)
+               {
+                 insn = emit_insn (gen_movhi_sp_r_irq_on (stack_pointer_rtx, 
+                                                          frame_pointer_rtx));
+                 RTX_FRAME_RELATED_P (insn) = 1;
+               }
+             else
+               {
+                 insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
+                 RTX_FRAME_RELATED_P (insn) = 1;
+               }
 
              fp_plus_insns = get_insns ();
              end_sequence ();
@@ -915,7 +939,25 @@
                                                          GET_MODE(myfp))));
 
              /* Copy to stack pointer.  */
-             emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
+             if (TARGET_TINY_STACK)
+               {
+                 emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
+               }
+             else if (TARGET_NO_INTERRUPTS 
+                      || cfun->machine->is_signal)
+               {
+                 emit_insn (gen_movhi_sp_r_irq_off (stack_pointer_rtx, 
+                                                    frame_pointer_rtx));
+               }
+             else if (cfun->machine->is_interrupt)
+               {
+                 emit_insn (gen_movhi_sp_r_irq_on (stack_pointer_rtx, 
+                                                   frame_pointer_rtx));
+               }
+             else
+               {
+                 emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
+               }
 
              fp_plus_insns = get_insns ();
              end_sequence ();        
@@ -1708,32 +1749,12 @@
          if (test_hard_reg_class (STACK_REG, dest))
            {
              if (TARGET_TINY_STACK)
-               {
-                 *l = 1;
-                 return AS2 (out,__SP_L__,%A1);
-               }
-              /*  Use simple load of stack pointer if no interrupts are used
-              or inside main or signal function prologue where they disabled.  */
-             else if (TARGET_NO_INTERRUPTS 
-                        || (reload_completed 
-                            && cfun->machine->is_signal 
-                            && prologue_epilogue_contains (insn)))
-                {
-                  *l = 2;
-                  return (AS2 (out,__SP_H__,%B1) CR_TAB
-                          AS2 (out,__SP_L__,%A1));
-                }
-              /*  In interrupt prolog we know interrupts are enabled.  */
-              else if (reload_completed 
-                        && cfun->machine->is_interrupt
-                        && prologue_epilogue_contains (insn))
-                {
-                  *l = 4;
-                  return ("cli"                   CR_TAB
-                           AS2 (out,__SP_H__,%B1) CR_TAB
-                           "sei"                   CR_TAB
-                           AS2 (out,__SP_L__,%A1));
-                }
+               return *l = 1, AS2 (out,__SP_L__,%A1);
+              /* Use simple load of stack pointer if no interrupts are 
+                used.  */
+             else if (TARGET_NO_INTERRUPTS)
+               return *l = 2, (AS2 (out,__SP_H__,%B1) CR_TAB
+                               AS2 (out,__SP_L__,%A1));
              *l = 5;
              return (AS2 (in,__tmp_reg__,__SREG__)  CR_TAB
                      "cli"                          CR_TAB


Anatoly.



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]