avr.c (get_sequence_length): Add new function.
authorAnatoly Sokolov <aesok@post.ru>
Thu, 22 May 2008 18:59:15 +0000 (22:59 +0400)
committerAnatoly Sokolov <aesok@gcc.gnu.org>
Thu, 22 May 2008 18:59:15 +0000 (22:59 +0400)
* config/avr/avr.c (get_sequence_length): Add new function.
(expand_prologue, expand_epilogue): Remove duplicate code.

From-SVN: r135775

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

index 8e6029bf1a97ffe58f2f6602f0f5ffe22b6fedc6..968d0eac5a0223648ce541fe3145d61829cb1d52 100644 (file)
@@ -1,3 +1,8 @@
+2008-05-22  Anatoly Sokolov <aesok@post.ru>
+
+       * config/avr/avr.c (get_sequence_length): Add new function.
+       (expand_prologue, expand_epilogue): Remove duplicate code.
+
 2008-05-22  Rafael Espindola  <espindola@google.com>
 
        * see.c (see_pre_insert_extensions): Use copy_rtx to avoid invalid rtx
index 1293a4b3463feb2cfd58a6320eb127c50e262560..012a7e4fd1b5c5f5e89d8ae9d73d1b0f5ce7a8e9 100644 (file)
@@ -54,6 +54,7 @@ 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 get_sequence_length (rtx insns);
 static int sequent_regs_live (void);
 static const char *ptrreg_to_str (int);
 static const char *cond_string (enum rtx_code);
@@ -585,6 +586,20 @@ sequent_regs_live (void)
   return (cur_seq == live_seq) ? live_seq : 0;
 }
 
+/* Obtain the length sequence of insns.  */
+
+int
+get_sequence_length (rtx insns)
+{
+  rtx insn;
+  int length;
+  
+  for (insn = insns, length = 0; insn; insn = NEXT_INSN (insn))
+    length += get_attr_length (insn);
+               
+  return length;
+}
+
 /*  Output function prologue.  */
 
 void
@@ -718,12 +733,11 @@ expand_prologue (void)
               To avoid a complex logic, both methods are tested and shortest
               is selected.  */
               rtx myfp;
-              /*  First method.  */
+             rtx fp_plus_insns; 
+             rtx sp_plus_insns = NULL_RTX;
+
               if (TARGET_TINY_STACK)
                 {
-                  if (size < -63 || size > 63)
-                    warning (0, "large frame pointer change (%d) with -mtiny-stack", size);
-                    
                   /* The high byte (r29) doesn't change - prefer 'subi' (1 cycle)
                      over 'sbiw' (2 cycles, same size).  */
                   myfp = gen_rtx_REG (QImode, REGNO (frame_pointer_rtx));
@@ -733,51 +747,53 @@ expand_prologue (void)
                   /*  Normal sized addition.  */
                   myfp = frame_pointer_rtx;
                 }
-              /* Calculate length.  */ 
-              int method1_length;
-              method1_length =
-               get_attr_length (gen_move_insn (frame_pointer_rtx, stack_pointer_rtx));
-              method1_length +=
-               get_attr_length (gen_move_insn (myfp, 
-                                                gen_rtx_PLUS (GET_MODE(myfp), myfp,
-                                                              gen_int_mode (-size, 
-                                                                           GET_MODE(myfp)))));
-              method1_length += 
-               get_attr_length (gen_move_insn (stack_pointer_rtx, frame_pointer_rtx));
-              
+
+             /* Method 1-Adjust frame pointer.  */
+             start_sequence ();
+
+              insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
+              RTX_FRAME_RELATED_P (insn) = 1;
+
+              insn = 
+               emit_move_insn (myfp,
+                               gen_rtx_PLUS (GET_MODE(myfp), myfp, 
+                                             gen_int_mode (-size, 
+                                                           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;
+
+             fp_plus_insns = get_insns ();
+             end_sequence ();
+
              /* Method 2-Adjust Stack pointer.  */
-              int sp_plus_length = 0;
               if (size <= 6)
                 {
-                  sp_plus_length = 
-                   get_attr_length (gen_move_insn (stack_pointer_rtx,
-                                                    gen_rtx_PLUS (HImode, stack_pointer_rtx,
-                                                                  gen_int_mode (-size, 
-                                                                               HImode))));
-                 sp_plus_length += 
-                   get_attr_length (gen_move_insn (frame_pointer_rtx, stack_pointer_rtx));
+                 start_sequence ();
+
+                 insn = 
+                   emit_move_insn (stack_pointer_rtx,
+                                   gen_rtx_PLUS (HImode, 
+                                                 stack_pointer_rtx, 
+                                                 gen_int_mode (-size, 
+                                                               HImode)));
+                 RTX_FRAME_RELATED_P (insn) = 1;
+                 
+                 insn = 
+                   emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
+                 RTX_FRAME_RELATED_P (insn) = 1;
+
+                 sp_plus_insns = get_insns ();
+                 end_sequence ();
                 }
+
               /* Use shortest method.  */
-              if (size <= 6 && (sp_plus_length < method1_length))
-                {
-                  insn = emit_move_insn (stack_pointer_rtx,
-                                         gen_rtx_PLUS (HImode, stack_pointer_rtx, 
-                                                       gen_int_mode (-size, HImode)));
-                  RTX_FRAME_RELATED_P (insn) = 1;
-                 insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
-                  RTX_FRAME_RELATED_P (insn) = 1;
-                }
+              if (size <= 6 && (get_sequence_length (sp_plus_insns) 
+                                < get_sequence_length (fp_plus_insns)))
+               emit_insn (sp_plus_insns);
               else
-                {              
-                  insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
-                  RTX_FRAME_RELATED_P (insn) = 1;
-                  insn = emit_move_insn (myfp,
-                                         gen_rtx_PLUS (GET_MODE(myfp), myfp, 
-                                                       gen_int_mode (-size, 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;
-                }
+               emit_insn (fp_plus_insns);
             }
         }
     }
@@ -872,42 +888,56 @@ expand_epilogue (void)
          if (size)
            {
               /* Try two methods to adjust stack and select shortest.  */
-              int fp_plus_length;
+             rtx myfp;
+             rtx fp_plus_insns;
+             rtx sp_plus_insns = NULL_RTX;
+             
+             if (TARGET_TINY_STACK)
+                {
+                  /* The high byte (r29) doesn't change - prefer 'subi' 
+                     (1 cycle) over 'sbiw' (2 cycles, same size).  */
+                  myfp = gen_rtx_REG (QImode, REGNO (frame_pointer_rtx));
+                }
+              else 
+                {
+                  /* Normal sized addition.  */
+                  myfp = frame_pointer_rtx;
+                }
+             
               /* Method 1-Adjust frame pointer.  */
-              fp_plus_length = 
-               get_attr_length (gen_move_insn (frame_pointer_rtx,
-                                                gen_rtx_PLUS (HImode, frame_pointer_rtx,
-                                                              gen_int_mode (size,
-                                                                           HImode))));
-              /* Copy to stack pointer.  */
-              fp_plus_length += 
-               get_attr_length (gen_move_insn (stack_pointer_rtx, frame_pointer_rtx));    
-          
+             start_sequence ();
+
+             emit_move_insn (myfp,
+                             gen_rtx_PLUS (HImode, myfp,
+                                           gen_int_mode (size, 
+                                                         GET_MODE(myfp))));
+
+             /* Copy to stack pointer.  */
+             emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
+
+             fp_plus_insns = get_insns ();
+             end_sequence ();        
+
               /* Method 2-Adjust Stack pointer.  */
-              int sp_plus_length = 0;
               if (size <= 5)
                 {
-                  sp_plus_length = 
-                   get_attr_length (gen_move_insn (stack_pointer_rtx,
-                                                    gen_rtx_PLUS (HImode, stack_pointer_rtx,
-                                                                  gen_int_mode (size,
-                                                                               HImode))));
+                 start_sequence ();
+
+                 emit_move_insn (stack_pointer_rtx,
+                                 gen_rtx_PLUS (HImode, stack_pointer_rtx,
+                                               gen_int_mode (size, 
+                                                             HImode)));
+
+                 sp_plus_insns = get_insns ();
+                 end_sequence ();
                 }
+
               /* Use shortest method.  */
-              if (size <= 5 && (sp_plus_length < fp_plus_length))
-                {
-                  emit_move_insn (stack_pointer_rtx,
-                                  gen_rtx_PLUS (HImode, stack_pointer_rtx,
-                                                gen_int_mode (size, HImode)));
-                }
+              if (size <= 5 && (get_sequence_length (sp_plus_insns) 
+                                < get_sequence_length (fp_plus_insns)))
+               emit_insn (sp_plus_insns);
               else
-                {
-                  emit_move_insn (frame_pointer_rtx,
-                                  gen_rtx_PLUS (HImode, frame_pointer_rtx,
-                                                gen_int_mode (size, HImode)));
-                  /* Copy to stack pointer.  */
-                  emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
-                }
+               emit_insn (fp_plus_insns);
             }
          if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
            {