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
This commit is contained in:
Anatoly Sokolov 2008-02-12 07:08:41 +03:00 committed by Anatoly Sokolov
parent 46abada07f
commit d6f77715ea
4 changed files with 36 additions and 8 deletions

View File

@ -1,3 +1,10 @@
2008-02-12 Anatoly Sokolov <aesok@post.ru>
* 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.
2008-02-11 Kai Tietz <kai.tietz@onevision.com>
* config/i386/cygwin.asm: (__alloca): Correct calling

View File

@ -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));

View File

@ -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

View File

@ -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)