aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/avr
diff options
context:
space:
mode:
authorAnatoly Sokolov <aesok@post.ru>2008-02-12 07:08:41 +0300
committerAnatoly Sokolov <aesok@gcc.gnu.org>2008-02-12 07:08:41 +0300
commitd6f77715ea2c787e01a4cd67fc3554b043abe2b2 (patch)
tree3f10bc35bd4e46779dfc0ba2ab513f8e88fbf83e /gcc/config/avr
parent46abada07fd5354741fa2d12147b0ff22b858fb4 (diff)
downloadgcc-d6f77715ea2c787e01a4cd67fc3554b043abe2b2.zip
gcc-d6f77715ea2c787e01a4cd67fc3554b043abe2b2.tar.gz
gcc-d6f77715ea2c787e01a4cd67fc3554b043abe2b2.tar.bz2
avr.h (AVR_HAVE_RAMPZ): Define.
* config/avr/avr.h (AVR_HAVE_RAMPZ): Define. * config/avr/avr.c (expand_prologue): Save RAMPZ register. (expand_epilogue): Restore RAMPZ register. * config/avr/avr.md (RAMPZ_ADDR): New constant. From-SVN: r132252
Diffstat (limited to 'gcc/config/avr')
-rw-r--r--gcc/config/avr/avr.c29
-rw-r--r--gcc/config/avr/avr.h5
-rw-r--r--gcc/config/avr/avr.md3
3 files changed, 29 insertions, 8 deletions
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 44ab3f3..68c0f18 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -586,6 +586,7 @@ void
expand_prologue (void)
{
int live_seq;
+ HARD_REG_SET set;
int minimize;
HOST_WIDE_INT size = get_frame_size();
/* Define templates for push instructions. */
@@ -609,6 +610,7 @@ expand_prologue (void)
return;
}
+ avr_regs_to_save (&set);
live_seq = sequent_regs_live ();
minimize = (TARGET_CALL_PROLOGUES
&& !cfun->machine->is_interrupt
@@ -639,7 +641,18 @@ expand_prologue (void)
RTX_FRAME_RELATED_P (insn) = 1;
insn = emit_move_insn (pushbyte, tmp_reg_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
-
+
+ /* Push RAMPZ. */
+ if(AVR_HAVE_RAMPZ
+ && (TEST_HARD_REG_BIT (set, REG_Z) && TEST_HARD_REG_BIT (set, REG_Z + 1)))
+ {
+ insn = emit_move_insn (tmp_reg_rtx,
+ gen_rtx_MEM (QImode, GEN_INT (RAMPZ_ADDR)));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ insn = emit_move_insn (pushbyte, tmp_reg_rtx);
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+
/* Clear zero reg. */
insn = emit_move_insn (zero_reg_rtx, const0_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
@@ -660,8 +673,6 @@ expand_prologue (void)
}
else
{
- HARD_REG_SET set;
- avr_regs_to_save (&set);
int reg;
for (reg = 0; reg < 32; ++reg)
{
@@ -811,6 +822,7 @@ expand_epilogue (void)
{
int reg;
int live_seq;
+ HARD_REG_SET set;
int minimize;
HOST_WIDE_INT size = get_frame_size();
@@ -821,6 +833,7 @@ expand_epilogue (void)
return;
}
+ avr_regs_to_save (&set);
live_seq = sequent_regs_live ();
minimize = (TARGET_CALL_PROLOGUES
&& !cfun->machine->is_interrupt
@@ -895,8 +908,6 @@ expand_epilogue (void)
}
}
/* Restore used registers. */
- HARD_REG_SET set;
- avr_regs_to_save (&set);
for (reg = 31; reg >= 0; --reg)
{
if (TEST_HARD_REG_BIT (set, reg))
@@ -904,6 +915,14 @@ expand_epilogue (void)
}
if (cfun->machine->is_interrupt || cfun->machine->is_signal)
{
+ /* Restore RAMPZ using tmp reg as scratch. */
+ if(AVR_HAVE_RAMPZ
+ && (TEST_HARD_REG_BIT (set, REG_Z) && TEST_HARD_REG_BIT (set, REG_Z + 1)))
+ {
+ emit_insn (gen_popqi (tmp_reg_rtx));
+ emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(RAMPZ_ADDR)),
+ tmp_reg_rtx);
+ }
/* Restore SREG using tmp reg as scratch. */
emit_insn (gen_popqi (tmp_reg_rtx));
diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h
index 9368c0134..d28cc1f 100644
--- a/gcc/config/avr/avr.h
+++ b/gcc/config/avr/avr.h
@@ -1,7 +1,7 @@
/* Definitions of target machine for GNU compiler,
for ATMEL AVR at90s8515, ATmega103/103L, ATmega603/603L microcontrollers.
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+ 2008 Free Software Foundation, Inc.
Contributed by Denis Chertykov (denisc@overta.ru)
This file is part of GCC.
@@ -99,6 +99,7 @@ extern GTY(()) section *progmem_section;
#define AVR_HAVE_MUL (avr_have_mul_p)
#define AVR_HAVE_MOVW (avr_have_movw_lpmx_p)
#define AVR_HAVE_LPMX (avr_have_movw_lpmx_p)
+#define AVR_HAVE_RAMPZ (avr_current_arch->have_elpm)
#define AVR_2_BYTE_PC 1
#define AVR_3_BYTE_PC 0
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index f9c25003..68a6aa1 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -1,7 +1,7 @@
;; -*- Mode: Scheme -*-
;; Machine description for GNU compiler,
;; for ATMEL AVR micro controllers.
-;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007
+;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008
;; Free Software Foundation, Inc.
;; Contributed by Denis Chertykov (denisc@overta.ru)
@@ -47,6 +47,7 @@
(ZERO_REGNO 1) ; zero register r1
(SREG_ADDR 0x5F)
+ (RAMPZ_ADDR 0x5B)
(UNSPEC_STRLEN 0)
(UNSPEC_INDEX_JMP 1)