diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-08-01 19:35:43 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-08-01 19:35:43 +0000 |
commit | 22d4c40561074bc6fa54ded325e5cf53c7b7deb3 (patch) | |
tree | 3796e229da8b3ccd4452bbc829e238dac4572686 | |
parent | dbf9ddfb75e5b67f6b66bf222c0479c1a0d5d95c (diff) | |
download | gcc-22d4c40561074bc6fa54ded325e5cf53c7b7deb3.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@177071 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/avr/avr.h | 4 | ||||
-rw-r--r-- | 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 <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 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 "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 |