1 /* -----------------------------------------------------------------------------
2 * $Id: TailCalls.h,v 1.5 2000/04/05 14:26:31 panne Exp $
4 * (c) The GHC Team, 1998-1999
6 * Stuff for implementing proper tail jumps.
8 * ---------------------------------------------------------------------------*/
13 /* -----------------------------------------------------------------------------
14 Unmangled tail-jumping: use the mini interpretter.
15 -------------------------------------------------------------------------- */
17 #ifdef USE_MINIINTERPRETER
19 #define JMP_(cont) return(stgCast(StgFunPtr,cont))
25 /* -----------------------------------------------------------------------------
27 -------------------------------------------------------------------------- */
31 extern void __DISCARD__(void);
33 /* Note about discard: possibly there to fool GCC into clearing up
34 before we do the jump eg. if there are some arguments left on the C
35 stack that GCC hasn't popped yet. Also possibly to fool any
36 optimisations (a function call often acts as a barrier). Not sure
37 if any of this is necessary now -- SDM
40 /* The goto here seems to cause gcc -O2 to delete all the code after
41 it - including the FE_ marker and the epilogue code - exactly what
49 target = (void *)(cont); \
53 #endif /* i386_TARGET_ARCH */
55 /* -----------------------------------------------------------------------------
57 -------------------------------------------------------------------------- */
59 #ifdef sparc_TARGET_ARCH
61 #define JMP_(cont) ((F_) (cont))()
62 /* Oh so happily, the above turns into a "call" instruction,
63 which, on a SPARC, is nothing but a "jmpl" with the
64 return address in %o7 [which we don't care about].
67 /* Don't need these for sparc mangling */
71 #endif /* sparc_TARGET_ARCH */
73 /* -----------------------------------------------------------------------------
75 -------------------------------------------------------------------------- */
77 #ifdef alpha_TARGET_ARCH
79 register void *_procedure __asm__("$27");
82 do { _procedure = (void *)(cont); \
86 /* Don't need these for alpha mangling */
90 #endif /* alpha_TARGET_ARCH */
92 /* -----------------------------------------------------------------------------
94 -------------------------------------------------------------------------- */
96 #ifdef hppa1_1_hp_hpux_TARGET
99 do { void *_procedure = (void *)(cont); \
103 #endif /* hppa1_1_hp_hpux_TARGET */
105 /* -----------------------------------------------------------------------------
108 These are markers indicating the start and end of Real Code in a
109 function. All instructions between the actual start and end of the
110 function and these markers is shredded by the mangler.
111 -------------------------------------------------------------------------- */
114 #define FB_ __asm__ volatile ("--- BEGIN ---");
118 #define FE_ __asm__ volatile ("--- END ---");
121 #endif /* !USE_MINIINTERPRETER */
123 #endif /* TAILCALLS_H */