Hi,

Here are some patches.   Please take a look and tell me if what I did
with setjmp makes any sense.  I don't really use longjmp so it's not
fully tested, and it is only to handle a case which is very difficult
to create.

I have tested the gcc patch and my program is working very well now.

There is still a major issue of what to do in bootloaders.  It appears
that the trampolines do not get generated for bootloaders.. and how
can they?  For bootloaders the compiler should use eijmp and eicall
and set EIND to the bootloader segment at startup.  But what if
longjmp is used and what if application code is called?  I'm not sure
what the best solution is here, but currently I'm just glad my
bootloader doesn't need indirect jumps.

Sean
Index: gcc/config/avr/libgcc.S
===================================================================
--- gcc/config/avr/libgcc.S	(revision 147314)
+++ gcc/config/avr/libgcc.S	(working copy)
@@ -590,11 +642,7 @@ __prologue_saves__:
 	out	__SP_H__,r29
 	out	__SREG__,__tmp_reg__
 	out	__SP_L__,r28
-#if defined (__AVR_HAVE_EIJMP_EICALL__)
-	eijmp
-#else
 	ijmp
-#endif
 
 .endfunc
 #endif /* defined (L_prologue) */
@@ -675,12 +723,7 @@ __tablejump__:
 	lpm	__tmp_reg__, Z+
 	lpm	r31, Z
 	mov	r30, __tmp_reg__
-
-#if defined (__AVR_HAVE_EIJMP_EICALL__)
-	eijmp
-#else
 	ijmp
-#endif
 
 #else
 	lpm
@@ -688,7 +731,7 @@ __tablejump__:
 	push	r0
 	lpm
 	push	r0
-#if defined (__AVR_HAVE_EIJMP_EICALL__)
+#if defined (__AVR_3_BYTE_PC__)
         push    __zero_reg__
 #endif
 	ret
@@ -876,19 +919,14 @@ __tablejump_elpm__:
 	elpm	__tmp_reg__, Z+
 	elpm	r31, Z
 	mov	r30, __tmp_reg__
-#if defined (__AVR_HAVE_EIJMP_EICALL__)
-	eijmp
-#else
 	ijmp
-#endif
-
 #else
 	elpm
 	adiw	r30, 1
 	push	r0
 	elpm
 	push	r0
-#if defined (__AVR_HAVE_EIJMP_EICALL__)
+#if defined (__AVR_3_BYTE_PC__)
         push    __zero_reg__
 #endif
 	ret
Index: gcc/config/avr/avr.md
===================================================================
--- gcc/config/avr/avr.md	(revision 147314)
+++ gcc/config/avr/avr.md	(working copy)
@@ -2741,22 +2823,22 @@ (define_insn "call_insn"
   "(register_operand (operands[0], HImode) || CONSTANT_P (operands[0]))"
   "*{
   if (which_alternative==0)
-     return \"%!icall\";
+     return \"icall\";
   else if (which_alternative==1)
     {
       if (AVR_HAVE_MOVW)
 	return (AS2 (movw, r30, %0) CR_TAB
-               \"%!icall\");
+               \"icall\");
       else
 	return (AS2 (mov, r30, %A0) CR_TAB
 		AS2 (mov, r31, %B0) CR_TAB
-		\"%!icall\");
+		\"icall\");
     }
   else if (which_alternative==2)
     return AS1(%~call,%c0);
   return (AS2 (ldi,r30,lo8(%0)) CR_TAB
           AS2 (ldi,r31,hi8(%0)) CR_TAB
-          \"%!icall\");
+          \"icall\");
 }"
   [(set_attr "cc" "clobber,clobber,clobber,clobber")
    (set_attr_alternative "length"
@@ -2778,22 +2860,22 @@ (define_insn "call_value_insn"
   "(register_operand (operands[0], VOIDmode) || CONSTANT_P (operands[0]))"
   "*{
   if (which_alternative==0)
-     return \"%!icall\";
+     return \"icall\";
   else if (which_alternative==1)
     {
       if (AVR_HAVE_MOVW)
 	return (AS2 (movw, r30, %1) CR_TAB
-		\"%!icall\");
+		\"icall\");
       else
 	return (AS2 (mov, r30, %A1) CR_TAB
 		AS2 (mov, r31, %B1) CR_TAB
-		\"%!icall\");
+		\"icall\");
     }
   else if (which_alternative==2)
     return AS1(%~call,%c1);
   return (AS2 (ldi, r30, lo8(%1)) CR_TAB
           AS2 (ldi, r31, hi8(%1)) CR_TAB
-          \"%!icall\");
+          \"icall\");
 }"
   [(set_attr "cc" "clobber,clobber,clobber,clobber")
    (set_attr_alternative "length"
@@ -2816,20 +2898,13 @@ (define_insn "nop"
 ; indirect jump
 (define_insn "indirect_jump"
   [(set (pc) (match_operand:HI 0 "register_operand" "!z,*r"))]
-  "!AVR_HAVE_EIJMP_EICALL"
+  ""
   "@
 	ijmp
 	push %A0\;push %B0\;ret"
   [(set_attr "length" "1,3")
    (set_attr "cc" "none,none")])
 
-(define_insn "*indirect_jump_avr6"
-  [(set (pc) (match_operand:HI 0 "register_operand" "z"))]
-  "AVR_HAVE_EIJMP_EICALL"
-  "eijmp"
-  [(set_attr "length" "1")
-   (set_attr "cc" "none")])
-
 ;; table jump
 
 ;; Table made from "rjmp" instructions for <=8K devices.
@@ -2867,7 +2942,7 @@ (define_insn "*tablejump_enh"
 	lpm __tmp_reg__,Z+
 	lpm r31,Z
 	mov r30,__tmp_reg__
-	%!ijmp"
+	ijmp"
   [(set_attr "length" "6")
    (set_attr "cc" "clobber")])
 
Index: libc/stdlib/setjmp.S
===================================================================
RCS file: /sources/avr-libc/avr-libc/libc/stdlib/setjmp.S,v
retrieving revision 1.7
diff -u -r1.7 setjmp.S
--- libc/stdlib/setjmp.S	1 Apr 2009 23:11:00 -0000	1.7
+++ libc/stdlib/setjmp.S	10 May 2009 05:36:28 -0000
@@ -155,6 +155,12 @@
 #if  defined(__AVR_3_BYTE_PC__) && __AVR_3_BYTE_PC__
 	ld	__tmp_reg__, X+
 .L_eijmp:
+	brid	.L_eijmp_nointerrupt
+	cli
+	out	AVR_EXTENDED_INDIRECT_ADDR, __tmp_reg__
+	sei
+	eijmp
+.L_eijmp_nointerrupt:
 	out	AVR_EXTENDED_INDIRECT_ADDR, __tmp_reg__
 	eijmp
 #else
_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list

Reply via email to