+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,
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