[Top][All Lists]

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

[avr-gcc-list] Bug in __builtin_return_address() ???

From: John Devereux
Subject: [avr-gcc-list] Bug in __builtin_return_address() ???
Date: Mon, 16 Dec 2002 21:18:25 +0000
User-agent: Mutt/1.4i


I seem to have a problem in the builtin function for obtaining a
functions return address, __builtin_return_address(). It seems to
generate wrong code when the function generates a stack frame. Of
course it may be my understanding that is wrong....

My test case is

void * volatile p;
void test(void)
  volatile int x[10]; // forces a stack frame
  p = __builtin_return_address(0);

The generated assembly with my comments is:

     .file     "main.c"
     .arch atmega128
__SREG__ = 0x3f
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__tmp_reg__ = 0
__zero_reg__ = 1
             .global __do_copy_data
             .global __do_clear_bss
 ;  GNU C version 3.3 20021111 (experimental) (avr)
 ;  compiled by GNU C version 3.2 (mingw special 20020817-1).
 ;  options passed:  -I. -iprefix -D__GNUC__=3 -D__GNUC_MINOR__=3
 ;  -D__GNUC_PATCHLEVEL__=0 -DTARGET=AVR -mmcu=atmega128
-auxbase-strip -O9
 ;  -Wall -Wstrict-prototypes -fverbose-asm
 ;  options enabled:  -fdefer-pop -fomit-frame-pointer
 ;  -foptimize-sibling-calls -fcse-follow-jumps -fcse-skip-blocks
 ;  -fexpensive-optimizations -fthread-jumps -fstrength-reduce
 ;  -fforce-mem -ffunction-cse -fkeep-static-consts -fcaller-saves
 ;  -freg-struct-return -fgcse -fgcse-lm -fgcse-sm -floop-optimize
 ;  -fcrossjumping -fif-conversion -fif-conversion2
 ;  -frerun-loop-opt -fdelete-null-pointer-checks -fsched-interblock
 ;  -fsched-spec -fbranch-count-reg -freorder-blocks
 ;  -frename-registers -fcprop-registers -fcommon -fverbose-asm
 ;  -fgnu-linker -fregmove -foptimize-register-move -fargument-alias
 ;  -fstrict-aliasing -fmerge-constants -fzero-initialized-in-bss
 ;  -fpeephole2 -fguess-branch-probability -fmath-errno
 ;  -minit-stack=__stack -mmcu=atmega128

.global test
        .type   test, @function
/* prologue: frame size=20 */
   push r28
   push r29
   in r28,__SP_L__
   in r29,__SP_H__

Loads stack pointer into Y. Stack pointer points one below the stack
location containing the return address

   sbiw r28,20
   in __tmp_reg__,__SREG__
   out __SP_H__,r29
   out __SREG__,__tmp_reg__
   out __SP_L__,r28

Adjusts Y, and SP, to point to base of frame. Y longer points to
(stack location containing the return address) -1.

/* prologue end (size=10) */
   ldd r18,Y+1
   ldd r19,Y+2

The above line seems to be ignoring the stack frame for the local
variables. My understanding is that it is trying to get the return
address from *Y+1. It should be more like *Y+21 shouldn't it?

   sts (p)+1,r19         ;   p
   sts p,r18              ;   p

p now has garbage in it.

/* epilogue: frame size=20 */
   adiw r28,20
   in __tmp_reg__,__SREG__
   out __SP_H__,r29
   out __SREG__,__tmp_reg__
   out __SP_L__,r28
   pop r29
   pop r28
/* epilogue end (size=9) */
/* function test size 25 (6) */
   .size    test, .-test
   .comm p,2,1
/* File "main.c": code   25 = 0x0019 (   6), prologues  10, epilogues
 9 */
avr-gcc-list at http://avr1.org

reply via email to

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