summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraesok <aesok@138bc75d-0d04-0410-961f-82ee72b054a4>2008-05-31 15:01:16 +0000
committeraesok <aesok@138bc75d-0d04-0410-961f-82ee72b054a4>2008-05-31 15:01:16 +0000
commite858c92304a22e56e8b23d26a68521ef9a077ce2 (patch)
tree73ff27f3d67fad9fc3708299409936b8bb768ea0
parentb3b7419f70aca999e8d2c78336822351fed43cc1 (diff)
downloadppe42-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/ChangeLog11
-rw-r--r--gcc/config/avr/avr.c80
-rw-r--r--gcc/config/avr/avr.md26
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" "")
OpenPOWER on IntegriCloud