[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 |
Hi,
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
-fpeephole
; -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-cse-after-loop
; -frerun-loop-opt -fdelete-null-pointer-checks -fsched-interblock
; -fsched-spec -fbranch-count-reg -freorder-blocks
-freorder-functions
; -frename-registers -fcprop-registers -fcommon -fverbose-asm
; -fgnu-linker -fregmove -foptimize-register-move -fargument-alias
; -fstrict-aliasing -fmerge-constants -fzero-initialized-in-bss
-fident
; -fpeephole2 -fguess-branch-probability -fmath-errno
-ftrapping-math
; -minit-stack=__stack -mmcu=atmega128
.text
.global test
.type test, @function
test:
/* 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__
cli
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__
cli
out __SP_H__,r29
out __SREG__,__tmp_reg__
out __SP_L__,r28
pop r29
pop r28
ret
/* 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
- [avr-gcc-list] Bug in __builtin_return_address() ???,
John Devereux <=