From 172c08a54430cef4d0833d88d3b22013780e0280 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 1 Aug 2011 12:35:43 -0700 Subject: [PATCH] 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. (push1): New expander. From-SVN: r177071 --- gcc/ChangeLog | 9 ++++++++ gcc/config/avr/avr.h | 4 ++++ gcc/config/avr/avr.md | 49 +++++++++++++++++++------------------------ 3 files changed, 35 insertions(+), 27 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3969d4daf6b..580c12f1443 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2011-08-01 Richard Henderson + + 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. + (push1): New expander. + 2011-08-01 Anatoly Sokolov * config/mmix/mmix.h (PREFERRED_RELOAD_CLASS, diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h index c03c1f38c7b..ebf8290866a 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 55a883e9ab3..f60f9f0ee63 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 "push1" + [(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) - 1; i >= 0; --i) + { + rtx part = simplify_gen_subreg (QImode, operands[0], mode, i); + if (part != const0_rtx) + part = force_reg (QImode, part); + emit_insn (gen_pushqi1 (part)); + } + DONE; +}) ;;======================================================================== ;; move byte -- 2.30.2