* config/avr/avr.h (AVR_HAVE_RAMPZ): Define.
authoraesok <aesok@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 12 Feb 2008 04:08:41 +0000 (04:08 +0000)
committeraesok <aesok@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 12 Feb 2008 04:08:41 +0000 (04:08 +0000)
* 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
gcc/config/avr/avr.c
gcc/config/avr/avr.h
gcc/config/avr/avr.md

index 32607e5..e7eca81 100644 (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
index 44ab3f3..68c0f18 100644 (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));
index 9368c01..d28cc1f 100644 (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
index f9c2500..68a6aa1 100644 (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)