diff options
author | Anatoly Sokolov <aesok@post.ru> | 2008-05-31 19:01:16 +0400 |
---|---|---|
committer | Anatoly Sokolov <aesok@gcc.gnu.org> | 2008-05-31 19:01:16 +0400 |
commit | 794cb45e0be66af6533262e255dd276a1cfb3bd8 (patch) | |
tree | 73ff27f3d67fad9fc3708299409936b8bb768ea0 /gcc/config/avr | |
parent | 39f8a3b00c99fff50a211449cd10e326eabca8f4 (diff) | |
download | gcc-794cb45e0be66af6533262e255dd276a1cfb3bd8.zip gcc-794cb45e0be66af6533262e255dd276a1cfb3bd8.tar.gz gcc-794cb45e0be66af6533262e255dd276a1cfb3bd8.tar.bz2 |
avr.md (UNSPECV_WRITE_SP_IRQ_ON): New constants.
* 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.
From-SVN: r136238
Diffstat (limited to 'gcc/config/avr')
-rw-r--r-- | gcc/config/avr/avr.c | 80 | ||||
-rw-r--r-- | gcc/config/avr/avr.md | 26 |
2 files changed, 76 insertions, 30 deletions
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index d2cc33a..bde58f0 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -763,8 +763,32 @@ expand_prologue (void) 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 (); @@ -915,7 +939,25 @@ expand_epilogue (void) 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 (); @@ -1708,32 +1750,12 @@ output_movhi (rtx insn, rtx operands[], int *l) 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 diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index ffbbefa..a4914c4 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -56,7 +56,9 @@ (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") @@ -230,6 +232,28 @@ [(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" "") |