PR target/49881
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 1 Aug 2011 19:35:43 +0000 (19:35 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 1 Aug 2011 19:35:43 +0000 (19:35 +0000)
        * 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.

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

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

index 3969d4d..580c12f 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 c03c1f3..ebf8290 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 55a883e..f60f9f0 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