public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* PATCH: AVR - Set and save/restore EIND on avr6
@ 2008-04-17 14:34 Tristan Gingold
  2008-04-28 16:11 ` Ping: " Tristan Gingold
  0 siblings, 1 reply; 3+ messages in thread
From: Tristan Gingold @ 2008-04-17 14:34 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 606 bytes --]

Hi,

the call_prologue doesn't work on avr6 as EIJMP is used while EIND is  
not set.
This patch sets EIND on avr6 before calling __prologue_saves__, and  
save/restore EIND in
interrupt/signal functions.

Tristan.

2008-04-17  Tristan Gingold  <gingold@adacore.com>

	* config/avr/avr.md (EIND_ADDR): Define.
	(call_prologue_saves_avr6): Add.
	* config/avr/avr.c (expand_prologue): On 3_BYTE_PC mcus save EIND
	if interrupt or signal and use avr6 variant of prologue_saves.
	(expand_epilogue): Restore EIND on 3_BYTE_PC mcus if interrupt or
	signal.
	(avr_file_start): Declare __EIND__ on 3_BYTE_PC mcus.

[-- Attachment #2: avr.diff --]
[-- Type: application/octet-stream, Size: 4519 bytes --]

2008-04-17  Tristan Gingold  <gingold@adacore.com>

	* config/avr/avr.md (EIND_ADDR): Define.
	(call_prologue_saves_avr6): Add.
	* config/avr/avr.c (expand_prologue): On 3_BYTE_PC mcus save EIND
	if interrupt or signal and use avr6 variant of prologue_saves.
	(expand_epilogue): Restore EIND on 3_BYTE_PC mcus if interrupt or
	signal.
	(avr_file_start): Declare __EIND__ on 3_BYTE_PC mcus.

--- config/avr/avr.md	(revision 134344)
+++ config/avr/avr.md	(working copy)
@@ -49,6 +49,7 @@
    
    (SREG_ADDR   0x5F)
    (RAMPZ_ADDR  0x5B)
+   (EIND_ADDR   0x5C)
    
    (UNSPEC_STRLEN	0)
    (UNSPEC_INDEX_JMP	1)
@@ -79,7 +80,7 @@
 		       (const_string "no"))))
   
 
-;; The size of instructions in bytes.
+;; The size of instructions in words.
 ;; XXX may depend from "cc"
 
 (define_attr "length" ""
@@ -2776,7 +2777,7 @@
                            (match_operand:HI 1 "immediate_operand" "")))
    (use (reg:HI REG_X))
    (clobber (reg:HI REG_Z))]
-  ""
+  "!AVR_3_BYTE_PC"
   "ldi r30,pm_lo8(1f)
 	ldi r31,pm_hi8(1f)
 	%~jmp __prologue_saves__+((18 - %0) * 2)
@@ -2787,6 +2788,25 @@
 					(const_int 5))])
   (set_attr "cc" "clobber")
   ])
+
+(define_insn "call_prologue_saves_avr6"
+  [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
+   (match_operand:HI 0 "immediate_operand" "")
+   (set (reg:HI REG_SP) (minus:HI 
+                           (reg:HI REG_SP)
+                           (match_operand:HI 1 "immediate_operand" "")))
+   (use (reg:HI REG_X))
+   (clobber (reg:HI REG_Z))]
+  "AVR_3_BYTE_PC"
+  "ldi r30,pm_hh8(1f)
+	out __EIND__,r30
+	ldi r31,pm_hi8(1f)
+	ldi r30,pm_lo8(1f)
+	jmp __prologue_saves__+((18 - %0) * 2)
+1:"
+  [(set_attr "length" "8")
+  (set_attr "cc" "clobber")
+  ])
   
 ;  epilogue  restores using library
 (define_insn "epilogue_restores"
Index: config/avr/avr.c
===================================================================
--- config/avr/avr.c	(revision 134344)
+++ config/avr/avr.c	(working copy)
@@ -647,8 +647,8 @@
       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)))
+      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)));
@@ -657,6 +657,16 @@
           RTX_FRAME_RELATED_P (insn) = 1;
         }
 	
+      /* Push EIND.  */
+      if (AVR_3_BYTE_PC)
+        {
+          insn = emit_move_insn (tmp_reg_rtx, 
+                                 gen_rtx_MEM (QImode, GEN_INT (EIND_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;
@@ -666,13 +676,20 @@
     }
   if (minimize && (frame_pointer_needed || live_seq > 6)) 
     {
+      rtx nregs;
+      rtx spsize;
+
       insn = emit_move_insn (gen_rtx_REG (HImode, REG_X), 
                              gen_int_mode (size, HImode));
       RTX_FRAME_RELATED_P (insn) = 1;
 
-      insn = 
-        emit_insn (gen_call_prologue_saves (gen_int_mode (live_seq, HImode),
-					    gen_int_mode (size + live_seq, HImode)));
+      nregs = gen_int_mode (live_seq, HImode);
+      spsize = gen_int_mode (size + live_seq, HImode);
+      if (AVR_3_BYTE_PC)
+	insn = gen_call_prologue_saves_avr6 (nregs, spsize);
+      else
+	insn = gen_call_prologue_saves (nregs, spsize);
+      insn = emit_insn (insn);
       RTX_FRAME_RELATED_P (insn) = 1;
     }
   else
@@ -919,6 +936,14 @@
         }
       if (cfun->machine->is_interrupt || cfun->machine->is_signal)
         {
+          /* Restore EIND using tmp reg as scratch.  */
+	  if(AVR_3_BYTE_PC)
+            {
+	      emit_insn (gen_popqi (tmp_reg_rtx));
+	      emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(EIND_ADDR)), 
+			      tmp_reg_rtx);
+	    }
+
           /* 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)))
@@ -4819,6 +4844,8 @@
   fputs ("__SREG__ = 0x3f\n"
 	 "__SP_H__ = 0x3e\n"
 	 "__SP_L__ = 0x3d\n", asm_out_file);
+  if (AVR_3_BYTE_PC)
+    fputs ("__EIND__ = 0x3c\n", asm_out_file);
   
   fputs ("__tmp_reg__ = 0\n" 
          "__zero_reg__ = 1\n", asm_out_file);

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Ping: PATCH: AVR - Set and save/restore EIND on avr6
  2008-04-17 14:34 PATCH: AVR - Set and save/restore EIND on avr6 Tristan Gingold
@ 2008-04-28 16:11 ` Tristan Gingold
       [not found]   ` <258DDD1F44B6ED4AAFD4370847CF58D5014C9731@csomb01.corp.atmel.com>
  0 siblings, 1 reply; 3+ messages in thread
From: Tristan Gingold @ 2008-04-28 16:11 UTC (permalink / raw)
  To: gcc-patches


http://gcc.gnu.org/ml/gcc-patches/2008-04/msg01363.html

On Apr 17, 2008, at 2:25 PM, Tristan Gingold wrote:
> Hi,
>
> the call_prologue doesn't work on avr6 as EIJMP is used while EIND  
> is not set.
> This patch sets EIND on avr6 before calling __prologue_saves__, and  
> save/restore EIND in
> interrupt/signal functions.
>
> Tristan.
>
> 2008-04-17  Tristan Gingold  <gingold@adacore.com>
>
> 	* config/avr/avr.md (EIND_ADDR): Define.
> 	(call_prologue_saves_avr6): Add.
> 	* config/avr/avr.c (expand_prologue): On 3_BYTE_PC mcus save EIND
> 	if interrupt or signal and use avr6 variant of prologue_saves.
> 	(expand_epilogue): Restore EIND on 3_BYTE_PC mcus if interrupt or
> 	signal.
> 	(avr_file_start): Declare __EIND__ on 3_BYTE_PC mcus.<avr.diff>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Ping: PATCH: AVR - Set and save/restore EIND on avr6
       [not found]       ` <6DD3D198500E4124B98825B7C80AF4D8@Vista>
@ 2008-04-29 11:27         ` Tristan Gingold
  0 siblings, 0 replies; 3+ messages in thread
From: Tristan Gingold @ 2008-04-29 11:27 UTC (permalink / raw)
  To: Anatoly Sokolov; +Cc: Eric Weddington, Andrew Hutchinson, gcc-patches


On Apr 28, 2008, at 7:44 PM, Anatoly Sokolov wrote:
> Hi.
>
> In my opinion this patch incorrect. The EIND registr should ALWAYS  
> contain high (3) byte of '.trampolines' section. Your patch changes  
> EIND.

Ok, I missed the indirect call case.

But we don't generate trampoline for prologue_saves:

   "ldi r30,pm_lo8(1f)
    ldi r31,pm_hi8(1f)
  %~jmp __prologue_saves__+((18 - %0) * 2)
1:"

and as a consequence prologue_saves doesn't return at the right  
address if the code in high in memory.

Should we fix this relocs ?

Tristan.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2008-04-29  8:33 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-04-17 14:34 PATCH: AVR - Set and save/restore EIND on avr6 Tristan Gingold
2008-04-28 16:11 ` Ping: " Tristan Gingold
     [not found]   ` <258DDD1F44B6ED4AAFD4370847CF58D5014C9731@csomb01.corp.atmel.com>
     [not found]     ` <F6E862EA-5474-43E1-97FD-ED595587121A@adacore.com>
     [not found]       ` <6DD3D198500E4124B98825B7C80AF4D8@Vista>
2008-04-29 11:27         ` Tristan Gingold

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).