* config/avr/avr.md (UNSPECV_WRITE_SP_IRQ_ON): New constants.
authoraesok <aesok@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 31 May 2008 15:01:16 +0000 (15:01 +0000)
committeraesok <aesok@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 31 May 2008 15:01:16 +0000 (15:01 +0000)
(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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@136238 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/avr/avr.c
gcc/config/avr/avr.md

index 41a7306..e50465a 100644 (file)
@@ -1,3 +1,14 @@
+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.
+
 2008-05-31  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/34244
index d2cc33a..bde58f0 100644 (file)
@@ -763,8 +763,32 @@ expand_prologue (void)
                                                            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 @@ expand_epilogue (void)
                                                          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 +1750,12 @@ output_movhi (rtx insn, rtx operands[], int *l)
          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
index ffbbefa..a4914c4 100644 (file)
@@ -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")
   [(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" "")