OSDN Git Service

2008-08-06 Marc Gauthier <marc@tensilica.com>
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / gcc.dg / sibcall-4.c
1 /* Simple check that sibling calls are performed from a
2    void non-leaf-function taking no arguments calling a function which
3    is about the same as itself.
4
5    Copyright (C) 2002 Free Software Foundation Inc.
6    Contributed by Hans-Peter Nilsson  <hp@bitrange.com>  */
7
8 /* { dg-do run { xfail arc-*-* avr-*-* cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* m68hc1?-*-* mcore-*-* mn10300-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } } */
9 /* -mlongcall disables sibcall patterns.  */
10 /* { dg-skip-if "" { powerpc*-*-* } { "-mlongcall" } { "" } } */
11 /* { dg-options "-O2 -foptimize-sibling-calls" } */
12
13 /* The option -foptimize-sibling-calls is the default, but serves as
14    marker.  This test is xfailed on targets without sibcall patterns
15    (except targets where the test does not work due to the return address
16    not saved on the regular stack).  */
17
18 extern void abort (void);
19 extern void exit (int);
20
21 /* Sibcalls are not supported in MIPS16 mode, which has direct calls but
22    not direct jumps.  */
23 #ifdef __mips
24 #define ATTR __attribute__((nomips16))
25 #else
26 #define ATTR
27 #endif
28
29 static ATTR void recurser_void1 (void);
30 static ATTR void recurser_void2 (void);
31 extern void track (void);
32
33 int n = 0;
34 int main ()
35 {
36   recurser_void1 ();
37   exit (0);
38 }
39
40 /* The functions should get the same stack-frame, and best way to make it
41    reasonably sure is to make them have the same contents (regarding the
42    n tests).  */
43
44 static void __attribute__((noinline)) ATTR
45 recurser_void1 (void)
46 {
47   if (n == 0 || n == 7 || n == 8)
48     track ();
49
50   if (n == 10)
51     return;
52   n++;
53   recurser_void2 ();
54 }
55
56 static void __attribute__((noinline)) ATTR
57 recurser_void2 (void)
58 {
59   if (n == 0 || n == 7 || n == 8)
60     track ();
61
62   if (n == 10)
63     return;
64   n++;
65   recurser_void1 ();
66 }
67
68 void *trackpoint;
69
70 void
71 track ()
72 {
73   char stackpos[1];
74
75   if (n == 0)
76     trackpoint = stackpos;
77   else if ((n != 7 && n != 8) || trackpoint != stackpos)
78     abort ();
79 }