re PR target/49881 ([AVR] Inefficient stack manipulation around calls)
authorRichard Henderson <rth@redhat.com>
Mon, 1 Aug 2011 19:35:43 +0000 (12:35 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Mon, 1 Aug 2011 19:35:43 +0000 (12:35 -0700)
PR target/49881
        * config/avr/avr.h (PUSH_ROUNDING): New.
        * config/avr/avr.md (pushqi1): Rename from *pushqi.
        (*pushhi, *pushsi, *pushsf): Remove.
        (MPUSH): New mode iterator.
        (push<MPUSH>1): New expander.

From-SVN: r177071

gcc/ChangeLog
gcc/config/avr/avr.h
gcc/config/avr/avr.md

index 3969d4daf6b971f517d5ad92d880b7b1beb0cd57..580c12f14439a17f9acfe3eb7a51445194df81b2 100644 (file)
@@ -1,3 +1,12 @@
+2011-08-01  Richard Henderson  <rth@redhat.com>
+
+       PR target/49881
+       * config/avr/avr.h (PUSH_ROUNDING): New.
+       * config/avr/avr.md (pushqi1): Rename from *pushqi.
+       (*pushhi, *pushsi, *pushsf): Remove.
+       (MPUSH): New mode iterator.
+       (push<MPUSH>1): New expander.
+
 2011-08-01  Anatoly Sokolov  <aesok@post.ru>
 
        * config/mmix/mmix.h (PREFERRED_RELOAD_CLASS,
index c03c1f38c7b21b4e7f7f649a8859daa39e397247..ebf8290866af3d564afdd206540d8d4dcfcbe3d0 100644 (file)
@@ -685,3 +685,7 @@ struct GTY(()) machine_function
   /* 'true' if a callee might be tail called */
   int sibcall_fails;
 };
+
+/* AVR does not round pushes, but the existance of this macro is
+   required in order for pushes to be generated.  */
+#define PUSH_ROUNDING(X)       (X)
index 55a883e9ab3fd3489bbcba24ed52f1458ebf6377..f60f9f0ee6393c9f7498a08c5ec9e0a26c38ff23 100644 (file)
   DONE;
 })
 
-
-(define_insn "*pushqi"
+(define_insn "pushqi1"
   [(set (mem:QI (post_dec:HI (reg:HI REG_SP)))
         (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
   ""
        push __zero_reg__"
   [(set_attr "length" "1,1")])
 
-(define_insn "*pushhi"
-  [(set (mem:HI (post_dec:HI (reg:HI REG_SP)))
-        (match_operand:HI 0 "reg_or_0_operand" "r,L"))]
-  ""
-  "@
-       push %B0\;push %A0
-       push __zero_reg__\;push __zero_reg__"
-  [(set_attr "length" "2,2")])
+;; All modes for a multi-byte push.  We must include complex modes here too,
+;; lest emit_single_push_insn "helpfully " create the auto-inc itself.
+(define_mode_iterator MPUSH
+  [(CQI "")
+   (HI "") (CHI "")
+   (SI "") (CSI "")
+   (DI "") (CDI "")
+   (SF "") (SC "")])
 
-(define_insn "*pushsi"
-  [(set (mem:SI (post_dec:HI (reg:HI REG_SP)))
-        (match_operand:SI 0 "reg_or_0_operand" "r,L"))]
+(define_expand "push<mode>1"
+  [(match_operand:MPUSH 0 "general_operand" "")]
   ""
-  "@
-       push %D0\;push %C0\;push %B0\;push %A0
-       push __zero_reg__\;push __zero_reg__\;push __zero_reg__\;push __zero_reg__"
-  [(set_attr "length" "4,4")])
-
-(define_insn "*pushsf"
-  [(set (mem:SF (post_dec:HI (reg:HI REG_SP)))
-        (match_operand:SF 0 "register_operand" "r"))]
-  ""
-  "push %D0
-       push %C0
-       push %B0
-       push %A0"
-  [(set_attr "length" "4")])
+{
+  int i;
+  for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
+    {
+      rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
+      if (part != const0_rtx)
+       part = force_reg (QImode, part);
+      emit_insn (gen_pushqi1 (part));
+    }
+  DONE;
+})
 
 ;;========================================================================
 ;; move byte