From 637dc5b6ced8fca546e2468e25997e5fc87a0e30 Mon Sep 17 00:00:00 2001 From: aesok Date: Tue, 12 Feb 2008 04:08:41 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@132252 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 +++++++ gcc/config/avr/avr.c | 29 ++++++++++++++++++++++++----- gcc/config/avr/avr.h | 5 +++-- gcc/config/avr/avr.md | 3 ++- 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 32607e5..e7eca81 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2008-02-12 Anatoly Sokolov + + * 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 * config/i386/cygwin.asm: (__alloca): Correct calling 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 f9c2500..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) -- 2.7.4