[project @ 2000-04-05 14:26:31 by panne]
[ghc-hetmet.git] / ghc / includes / TailCalls.h
1 /* -----------------------------------------------------------------------------
2  * $Id: TailCalls.h,v 1.5 2000/04/05 14:26:31 panne Exp $
3  *
4  * (c) The GHC Team, 1998-1999
5  *
6  * Stuff for implementing proper tail jumps.
7  *
8  * ---------------------------------------------------------------------------*/
9
10 #ifndef TAILCALLS_H
11 #define TAILCALLS_H
12
13 /* -----------------------------------------------------------------------------
14    Unmangled tail-jumping: use the mini interpretter.
15    -------------------------------------------------------------------------- */
16
17 #ifdef USE_MINIINTERPRETER
18
19 #define JMP_(cont) return(stgCast(StgFunPtr,cont))
20 #define FB_
21 #define FE_
22
23 #else
24
25 /* -----------------------------------------------------------------------------
26    Tail calling on x86
27    -------------------------------------------------------------------------- */
28
29 #if i386_TARGET_ARCH
30
31 extern void __DISCARD__(void);
32
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
38    */
39
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
42    we want! -- SDM
43    */
44
45 #define JMP_(cont)                      \
46     {                                   \
47       void *target;                     \
48       __DISCARD__();                    \
49       target = (void *)(cont);          \
50       goto *target;                     \
51     }
52
53 #endif /* i386_TARGET_ARCH */
54
55 /* -----------------------------------------------------------------------------
56    Tail calling on Sparc
57    -------------------------------------------------------------------------- */
58
59 #ifdef sparc_TARGET_ARCH
60
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].
65         */
66
67 /* Don't need these for sparc mangling */
68 #define FB_
69 #define FE_
70
71 #endif /* sparc_TARGET_ARCH */
72
73 /* -----------------------------------------------------------------------------
74    Tail calling on Alpha
75    -------------------------------------------------------------------------- */
76
77 #ifdef alpha_TARGET_ARCH
78
79 register void *_procedure __asm__("$27");
80
81 #define JMP_(cont)                              \
82     do { _procedure = (void *)(cont);           \
83          goto *_procedure;                      \
84        } while(0)
85
86 /* Don't need these for alpha mangling */
87 #define FB_
88 #define FE_
89
90 #endif /* alpha_TARGET_ARCH */
91
92 /* -----------------------------------------------------------------------------
93    Tail calling on HP
94    -------------------------------------------------------------------------- */
95
96 #ifdef hppa1_1_hp_hpux_TARGET
97
98 #define JMP_(cont)                              \
99     do { void *_procedure = (void *)(cont);     \
100          goto *_procedure;                      \
101        } while(0)
102
103 #endif /* hppa1_1_hp_hpux_TARGET */
104
105 /* -----------------------------------------------------------------------------
106   FUNBEGIN and FUNEND.
107
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   -------------------------------------------------------------------------- */
112
113 #ifndef FB_
114 #define FB_    __asm__ volatile ("--- BEGIN ---");
115 #endif
116
117 #ifndef FE_
118 #define FE_    __asm__ volatile ("--- END ---");
119 #endif
120
121 #endif /* !USE_MINIINTERPRETER */
122
123 #endif /* TAILCALLS_H */