diff options
author | aesok <aesok@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-05-31 15:01:16 +0000 |
---|---|---|
committer | aesok <aesok@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-05-31 15:01:16 +0000 |
commit | e858c92304a22e56e8b23d26a68521ef9a077ce2 (patch) | |
tree | 73ff27f3d67fad9fc3708299409936b8bb768ea0 | |
parent | b3b7419f70aca999e8d2c78336822351fed43cc1 (diff) | |
download | ppe42-gcc-e858c92304a22e56e8b23d26a68521ef9a077ce2.tar.gz ppe42-gcc-e858c92304a22e56e8b23d26a68521ef9a077ce2.zip |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@136238 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/config/avr/avr.c | 80 | ||||
-rw-r--r-- | gcc/config/avr/avr.md | 26 |
3 files changed, 87 insertions, 30 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 41a7306da3a..e50465a7631 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +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 diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index d2cc33a0293..bde58f029b6 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 ffbbefa74ef..a4914c4aa61 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" "") |