+2008-05-31 Anatoly Sokolov <aesok@post.ru>
+
+ * config/avr/avr.md (UNSPECV_WRITE_SP_IRQ_ON): New constants.
+ (UNSPECV_WRITE_SP_IRQ_OFF): (Ditto.).
+ (movhi_sp_r_irq_off, movhi_sp_r_irq_on): New insn.
+ * config/avr/avr.c (expand_prologue, expand_epilogue): Use
+ movhi_sp_r_irq_off and movhi_sp_r_irq_on insns for writing to the
+ stack pointer register.
+ (output_movhi): Remove code for interrupt specific writing to the
+ stack pointer register.
+
2008-05-31 Richard Guenther <rguenther@suse.de>
PR tree-optimization/34244
GET_MODE(myfp))));
RTX_FRAME_RELATED_P (insn) = 1;
- insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
- RTX_FRAME_RELATED_P (insn) = 1;
+ /* Copy to stack pointer. */
+ if (TARGET_TINY_STACK)
+ {
+ insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+ else if (TARGET_NO_INTERRUPTS
+ || cfun->machine->is_signal
+ || cfun->machine->is_OS_main)
+ {
+ insn =
+ emit_insn (gen_movhi_sp_r_irq_off (stack_pointer_rtx,
+ frame_pointer_rtx));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+ else if (cfun->machine->is_interrupt)
+ {
+ insn = emit_insn (gen_movhi_sp_r_irq_on (stack_pointer_rtx,
+ frame_pointer_rtx));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+ else
+ {
+ insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
fp_plus_insns = get_insns ();
end_sequence ();
GET_MODE(myfp))));
/* Copy to stack pointer. */
- emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
+ if (TARGET_TINY_STACK)
+ {
+ emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
+ }
+ else if (TARGET_NO_INTERRUPTS
+ || cfun->machine->is_signal)
+ {
+ emit_insn (gen_movhi_sp_r_irq_off (stack_pointer_rtx,
+ frame_pointer_rtx));
+ }
+ else if (cfun->machine->is_interrupt)
+ {
+ emit_insn (gen_movhi_sp_r_irq_on (stack_pointer_rtx,
+ frame_pointer_rtx));
+ }
+ else
+ {
+ emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
+ }
fp_plus_insns = get_insns ();
end_sequence ();
if (test_hard_reg_class (STACK_REG, dest))
{
if (TARGET_TINY_STACK)
- {
- *l = 1;
- return AS2 (out,__SP_L__,%A1);
- }
- /* Use simple load of stack pointer if no interrupts are used
- or inside main or signal function prologue where they disabled. */
- else if (TARGET_NO_INTERRUPTS
- || (reload_completed
- && cfun->machine->is_signal
- && prologue_epilogue_contains (insn)))
- {
- *l = 2;
- return (AS2 (out,__SP_H__,%B1) CR_TAB
- AS2 (out,__SP_L__,%A1));
- }
- /* In interrupt prolog we know interrupts are enabled. */
- else if (reload_completed
- && cfun->machine->is_interrupt
- && prologue_epilogue_contains (insn))
- {
- *l = 4;
- return ("cli" CR_TAB
- AS2 (out,__SP_H__,%B1) CR_TAB
- "sei" CR_TAB
- AS2 (out,__SP_L__,%A1));
- }
+ return *l = 1, AS2 (out,__SP_L__,%A1);
+ /* Use simple load of stack pointer if no interrupts are
+ used. */
+ else if (TARGET_NO_INTERRUPTS)
+ return *l = 2, (AS2 (out,__SP_H__,%B1) CR_TAB
+ AS2 (out,__SP_L__,%A1));
*l = 5;
return (AS2 (in,__tmp_reg__,__SREG__) CR_TAB
"cli" CR_TAB
(UNSPEC_CLI 3)
(UNSPECV_PROLOGUE_SAVES 0)
- (UNSPECV_EPILOGUE_RESTORES 1)])
+ (UNSPECV_EPILOGUE_RESTORES 1)
+ (UNSPECV_WRITE_SP_IRQ_ON 2)
+ (UNSPECV_WRITE_SP_IRQ_OFF 3)])
(include "predicates.md")
(include "constraints.md")
[(set_attr "length" "5,2")
(set_attr "cc" "none,none")])
+(define_insn "movhi_sp_r_irq_off"
+ [(set (match_operand:HI 0 "stack_register_operand" "=q")
+ (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r")]
+ UNSPECV_WRITE_SP_IRQ_OFF))]
+ ""
+ "out __SP_H__, %B1
+ out __SP_L__, %A1"
+ [(set_attr "length" "2")
+ (set_attr "cc" "none")])
+
+(define_insn "movhi_sp_r_irq_on"
+ [(set (match_operand:HI 0 "stack_register_operand" "=q")
+ (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r")]
+ UNSPECV_WRITE_SP_IRQ_ON))]
+ ""
+ "cli
+ out __SP_H__, %B1
+ sei
+ out __SP_L__, %A1"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none")])
+
(define_peephole2
[(match_scratch:QI 2 "d")
(set (match_operand:HI 0 "l_register_operand" "")