[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-gcc-list] COMPILER Frame pointer bug!!!

From: dimmy
Subject: [avr-gcc-list] COMPILER Frame pointer bug!!!
Date: Sat, 17 Nov 2001 21:26:59 +0300
User-agent: Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:0.9.4) Gecko/20011001


I found  strange avr-gcc behaviour.

If you declare a function with a variable number of arguments or the number of arguments is over 18 (actually, total number of bytes, required for arguments) or you allocate over 18 bytes inside the function, then avr-gcc disables interrupts on enter to the function and does not enable them anymore.

This is valid only in case, when frame pointer cannot be eliminated or when no optimization enabled.
For example, the code:

char *newfmt(int n,  char *fmt, ...)
       char *p;
       va_list ap;
       int ind;
       int i;
char w[3000]; /* will never be used. the same result if the size of w is over 16 */

       va_start(ap, fmt);

       for (i=0; i<n;i++)
               ind = va_arg(ap, int);

       return (p);

will result as (avr-gcc -mmcu=atmega103 -O -S ):

/* prologue: frame size=3000 */
       push r10
       push r11
       push r12
       push r13
       push r14
       push r15
       push r16
       push r17
       push r28
       push r29
       in r28,__SP_L__
       in r29,__SP_H__
       subi r28,lo8(3000)
       sbci r29,hi8(3000)
       in __tmp_reg__,__SREG__
       out __SP_H__,r29
       out __SREG__,__tmp_reg__
       out __SP_L__,r28
/* prologue end (size=19) */

And no 'sei' instruction in the function body!!!
Actully, in function's epilogue, gcc disables interrupts as well.

I'll contact the originator of the compiler later.

If you cannot wait and want to fix this bug right now, you have to recompile the gcc sources.
The patch is here:
diff -u gcc/config/avr/avr.c.orig gcc/config/avr/avr.c
--- gcc/config/avr/avr.c.orig   Sat Nov 17 21:18:14 2001
+++ gcc/config/avr/avr.c        Sat Nov 17 21:24:28 2001
@@ -511,13 +511,14 @@
      fprintf (file, AS2 (out, __SREG__, __tmp_reg__) CR_TAB);
-  else if (do_sei)
+  fprintf (file, AS2 (out, __SP_L__, r28) "\n")
+  if (do_sei)
      fprintf (file, "sei" CR_TAB);
-  fprintf (file, AS2 (out, __SP_L__, r28) "\n");

  return size;

So, just be carefull -

1. make shure, gcc can omit frame pointer within a function call
2. declare vars as global or static,
3 if you cannot do 1 or 2, apply patch

Hope it helps,

reply via email to

[Prev in Thread] Current Thread [Next in Thread]