aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2011-08-01 12:35:43 -0700
committerRichard Henderson <rth@gcc.gnu.org>2011-08-01 12:35:43 -0700
commit172c08a54430cef4d0833d88d3b22013780e0280 (patch)
tree3796e229da8b3ccd4452bbc829e238dac4572686 /gcc
parent750867b7f4a6cf9086e925e89147fb763291b853 (diff)
downloadgcc-172c08a54430cef4d0833d88d3b22013780e0280.zip
gcc-172c08a54430cef4d0833d88d3b22013780e0280.tar.gz
gcc-172c08a54430cef4d0833d88d3b22013780e0280.tar.bz2
re PR target/49881 ([AVR] Inefficient stack manipulation around calls)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/avr/avr.h4
-rw-r--r--gcc/config/avr/avr.md49
3 files changed, 35 insertions, 27 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3969d4d..580c12f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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,
diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h
index c03c1f3..ebf8290 100644
--- a/gcc/config/avr/avr.h
+++ b/gcc/config/avr/avr.h
@@ -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)
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 55a883e..f60f9f0 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -202,8 +202,7 @@
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"))]
""
@@ -212,33 +211,29 @@
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