This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/12111] New: sh-hms: sibling function call fails in interrupt handler with optimization
- From: "adx at swissonline dot ch" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 30 Aug 2003 18:13:48 -0000
- Subject: [Bug c/12111] New: sh-hms: sibling function call fails in interrupt handler with optimization
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12111
Summary: sh-hms: sibling function call fails in interrupt handler
with optimization
Product: gcc
Version: 3.3.1
Status: UNCONFIRMED
Severity: critical
Priority: P1
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: adx at swissonline dot ch
CC: gcc-bugs at gcc dot gnu dot org
GCC build triplet: i686-pc-linux-gnu
GCC host triplet: i386-mingw32
GCC target triplet: sh-hms
>>Compile and build information:
C:\USER\DITT\src\4q-sh\NWR\work>c:\gcc3-sh\bin\sh-hms-c++ -v -save-temps -m2 -c
-g -O2 -Wall -Wmissing-prototypes -fno-common -I..\include
-I..\..\common\include -Wa,-ahld sibling.c >sibling.l
Reading specs from C:\GCC3-SH\BIN\..\lib\gcc-lib\sh-hms\3.3.1\specs
Configured with: ../configure --prefix=/gcc3-sh --target=sh-hms
--host=i386-mingw32 --build=i686-pc-linux-gnu -v : (reconfigured) ../configure
--prefix=/gcc3-sh --target=sh-hms --host=i386-mingw32 --build=i686-pc-linux-gnu -v
Thread model: single
gcc version 3.3.1
C:\GCC3-SH\BIN\..\lib\gcc-lib\sh-hms\3.3.1\cc1plus.exe -E -D__GNUG__=3 -quiet
-v -I..\include -I..\..\common\include -iprefix
C:\GCC3-SH\BIN\../lib/gcc-lib/sh-hms\3.3.1\ -D__GNUC__=3 -D__GNUC_MINOR__=3
-D__GNUC_PATCHLEVEL__=1 sibling.c -m2 -Wall -Wmissing-prototypes -fno-common -O2
sibling.ii
ignoring nonexistent directory "C:/GCC3-SH/sh-hms/sys-include"
ignoring nonexistent directory "/gcc3-sh/sh-hms/sys-include"
#include "..." search starts here:
#include <...> search starts here:
../include
../../common/include
C:/GCC3-SH/include/c++/3.3.1
C:/GCC3-SH/include/c++/3.3.1/sh-hms
C:/GCC3-SH/include/c++/3.3.1/backward
C:/GCC3-SH/lib/gcc-lib/sh-hms/3.3.1/include
C:/GCC3-SH/sh-hms/include
/gcc3-sh/include/c++/3.3.1
/gcc3-sh/include/c++/3.3.1/sh-hms
/gcc3-sh/include/c++/3.3.1/backward
/gcc3-sh/include
/gcc3-sh/lib/gcc-lib/sh-hms/3.3.1/include
/gcc3-sh/sh-hms/include
End of search list.
C:\GCC3-SH\BIN\..\lib\gcc-lib\sh-hms\3.3.1\cc1plus.exe -fpreprocessed
sibling.ii -quiet -dumpbase sibling.c -m2 -auxbase sibling -g -O2 -Wall
-Wmissing-prototypes -version -fno-common -o c:\tmp/ccjpRigb.s
GNU C++ version 3.3.1 (sh-hms)
compiled by GNU C version egcs-2.91.66 19990314 (egcs-1.1.2 release).
GGC heuristics: --param ggc-min-expand=47 --param ggc-min-heapsize=32659
C:\GCC3-SH\BIN\..\lib\gcc-lib\sh-hms\3.3.1\..\..\..\..\sh-hms\bin\as.exe
--traditional-format -big -ahld -o sibling.o c:\tmp/ccjpRigb.s
>>The bug can be reproduced using the following source code (= sibling.c above):
void int_handler() __attribute__ ((interrupt_handler));
void foo(int event);
void int_handler(void)
{
foo(1);
}
>>Compiling like above yields the following assembly output:
.global __Z11int_handlerv
__Z11int_handlerv:
.def .bf; .val .; .scl 101; .line 7; .endef
mov.l r1,@-r15
mov.l r4,@-r15
mov.l r14,@-r15
mov r15,r14
.ln 2
mov r14,r15
mov.l @r15+,r14
mov.l @r15+,r4
mov.l @r15+,r1
jmp @r1
nop
.def .ef; .val .; .scl 101; .line 2; .endef
.def __Z11int_handlerv; .val .; .scl -1; .endef
.ident "GCC: (GNU) 3.3.1"
>>Obviously, r1 is not initialized with the jump address to foo.
>>If int_handler is not defined as interrupt handler, correct code is produced:
void int_handler();
void foo(int event);
void int_handler(void)
{
foo(1);
}
.global __Z11int_handlerv
__Z11int_handlerv:
.def .bf; .val .; .scl 101; .line 7; .endef
mov.l r14,@-r15
.ln 2
mov #1,r4
mov.l L2,r1
.ln 1
mov r15,r14
.ln 2
mov r14,r15
jmp @r1
mov.l @r15+,r14
L3:
.align 2
L2:
.long __Z3fooi
.def .ef; .val .; .scl 101; .line 2; .endef
.def __Z11int_handlerv; .val .; .scl -1; .endef
.ident "GCC: (GNU) 3.3.1"
>>Likewise, compiling as interrupt handler with -fno-optimize-sibling-calls
option produces correct code:
.global __Z11int_handlerv
__Z11int_handlerv:
.def .bf; .val .; .scl 101; .line 7; .endef
mov.l r0,@-r15
mov.l r1,@-r15
mov.l r2,@-r15
mov.l r3,@-r15
mov.l r4,@-r15
mov.l r5,@-r15
.ln 2
mov #1,r4
.ln 1
mov.l r6,@-r15
mov.l r7,@-r15
mov.l r14,@-r15
sts.l mach,@-r15
sts.l macl,@-r15
.ln 2
mov.l L2,r1
.ln 1
sts.l pr,@-r15
.ln 2
jsr @r1
mov r15,r14
.ln 3
mov r14,r15
lds.l @r15+,pr
lds.l @r15+,macl
lds.l @r15+,mach
mov.l @r15+,r14
mov.l @r15+,r7
mov.l @r15+,r6
mov.l @r15+,r5
mov.l @r15+,r4
mov.l @r15+,r3
mov.l @r15+,r2
mov.l @r15+,r1
mov.l @r15+,r0
rte
nop
L3:
.align 2
L2:
.long __Z3fooi
.def .ef; .val .; .scl 101; .line 3; .endef
.def __Z11int_handlerv; .val .; .scl -1; .endef
.ident "GCC: (GNU) 3.3.1"