Merge branch 'master' of win:c:/ghc/git/cygwin/.
[ghc.git] / includes / stg / TailCalls.h
1 /* -----------------------------------------------------------------------------
2 *
3 * (c) The GHC Team, 1998-2009
4 *
5 * Stuff for implementing proper tail jumps.
6 *
7 * Do not #include this file directly: #include "Rts.h" instead.
8 *
9 * To understand the structure of the RTS headers, see the wiki:
10 * http://hackage.haskell.org/trac/ghc/wiki/Commentary/SourceTree/Includes
11 *
12 * ---------------------------------------------------------------------------*/
13
14 #ifndef TAILCALLS_H
15 #define TAILCALLS_H
16
17 /* -----------------------------------------------------------------------------
18 Unmangled tail-jumping: use the mini interpretter.
19 -------------------------------------------------------------------------- */
20
21 #ifdef USE_MINIINTERPRETER
22
23 #define JMP_(cont) return((StgFunPtr)(cont))
24 #define FB_
25 #define FE_
26
27 #else
28
29 extern void __DISCARD__(void);
30
31 /* -----------------------------------------------------------------------------
32 Tail calling on x86
33 -------------------------------------------------------------------------- */
34
35 #if i386_HOST_ARCH
36
37 /* Note about discard: possibly there to fool GCC into clearing up
38 before we do the jump eg. if there are some arguments left on the C
39 stack that GCC hasn't popped yet. Also possibly to fool any
40 optimisations (a function call often acts as a barrier). Not sure
41 if any of this is necessary now -- SDM
42
43 Comment to above note: I don't think the __DISCARD__() in JMP_ is
44 necessary. Arguments should be popped from the C stack immediately
45 after returning from a function, as long as we pass -fno-defer-pop
46 to gcc. Moreover, a goto to a first-class label acts as a barrier
47 for optimisations in the same way a function call does.
48 -= chak
49 */
50
51 /* The goto here seems to cause gcc -O2 to delete all the code after
52 it - including the FE_ marker and the epilogue code - exactly what
53 we want! -- SDM
54 */
55
56 #define JMP_(cont) \
57 { \
58 void *__target; \
59 __DISCARD__(); \
60 __target = (void *)(cont); \
61 goto *__target; \
62 }
63
64 #endif /* i386_HOST_ARCH */
65
66 /* -----------------------------------------------------------------------------
67 Tail calling on x86_64
68 -------------------------------------------------------------------------- */
69
70 #if x86_64_HOST_ARCH
71
72 /*
73 NOTE about __DISCARD__():
74
75 On x86_64 this is necessary to work around bugs in the register
76 variable support in gcc. Without the __DISCARD__() call, gcc will
77 silently throw away assignements to global register variables that
78 happen before the jump.
79
80 Here's the example:
81
82 extern void g(void);
83 static void f(void) {
84 R1 = g;
85 __DISCARD__()
86 goto *R1;
87 }
88
89 without the dummy function call, gcc throws away the assignment to R1
90 (gcc 3.4.3) gcc bug #20359.
91 */
92
93 #define JMP_(cont) \
94 { \
95 __DISCARD__(); \
96 goto *(void *)(cont); \
97 }
98
99 #endif /* x86_64_HOST_ARCH */
100
101 /* -----------------------------------------------------------------------------
102 Tail calling on Sparc
103 -------------------------------------------------------------------------- */
104
105 #ifdef sparc_HOST_ARCH
106
107 #define JMP_(cont) ((F_) (cont))()
108 /* Oh so happily, the above turns into a "call" instruction,
109 which, on a SPARC, is nothing but a "jmpl" with the
110 return address in %o7 [which we don't care about].
111 */
112
113 /* Don't need these for sparc mangling */
114 #define FB_
115 #define FE_
116
117 #endif /* sparc_HOST_ARCH */
118
119 /* -----------------------------------------------------------------------------
120 Tail calling on PowerPC
121 -------------------------------------------------------------------------- */
122
123 #ifdef powerpc_HOST_ARCH
124
125 #define JMP_(cont) \
126 { \
127 void *target; \
128 target = (void *)(cont); \
129 __DISCARD__(); \
130 goto *target; \
131 }
132
133 /*
134 The __DISCARD__ is there because Apple's April 2002 Beta of GCC 3.1
135 sometimes generates incorrect code otherwise.
136 It tends to "forget" to update global register variables in the presence
137 of decrement/increment operators:
138 JMP_(*(--Sp)) is wrongly compiled as JMP_(Sp[-1]).
139 Calling __DISCARD__ in between works around this problem.
140 */
141
142 /*
143 I would _love_ to use the following instead,
144 but some versions of Apple's GCC fail to generate code for it
145 if it is called for a casted data pointer - which is exactly what
146 we are going to do...
147
148 #define JMP_(cont) ((F_) (cont))()
149 */
150
151 #endif /* powerpc_HOST_ARCH */
152
153 #ifdef powerpc64_HOST_ARCH
154 #define JMP_(cont) ((F_) (cont))()
155 #endif
156
157 /* -----------------------------------------------------------------------------
158 FUNBEGIN and FUNEND.
159
160 These are markers indicating the start and end of Real Code in a
161 function. All instructions between the actual start and end of the
162 function and these markers is shredded by the mangler.
163 -------------------------------------------------------------------------- */
164
165 /* The following __DISCARD__() has become necessary with gcc 2.96 on x86.
166 * It prevents gcc from moving stack manipulation code from the function
167 * body (aka the Real Code) into the function prologue, ie, from moving it
168 * over the --- BEGIN --- marker. It should be noted that (like some
169 * other black magic in GHC's code), there is no essential reason why gcc
170 * could not move some stack manipulation code across the __DISCARD__() -
171 * it just doesn't choose to do it at the moment.
172 * -= chak
173 */
174
175 #ifndef FB_
176 #define FB_ __asm__ volatile ("--- BEGIN ---"); __DISCARD__ ();
177 #endif
178
179 #ifndef FE_
180 #define FE_ __asm__ volatile ("--- END ---");
181 #endif
182
183 #endif /* !USE_MINIINTERPRETER */
184
185 #endif /* TAILCALLS_H */