[project @ 1998-12-15 09:41:57 by simonm]
[ghc-hetmet.git] / ghc / rts / StgRun.S
1 /* -----------------------------------------------------------------------------
2  * $Id: StgRun.S,v 1.2 1998/12/15 09:41:57 simonm Exp $
3  *
4  * Tiny assembler 'layer' between the C and STG worlds.
5  * 
6  * To run an STG function from C land, call
7  *
8  *              rv = StgRun(f);
9  *
10  * where "f" is the STG function to call.
11  *
12  * In the end, "f" must JMP to StgReturn (defined below),
13  * passing the return-value "rv" in R1,
14  * to return to the caller of StgRun returning "rv" in
15  * the whatever way C returns a value.
16  *
17  * NOTE: StgRun/StgReturn do *NOT* load or store Hp or any
18  * other registers (other than saving the C callee-saves 
19  * registers).  Instead, the called function "f" must do that
20  * in STG land.
21  * -------------------------------------------------------------------------- */
22
23 #include "config.h"
24 #include "Constants.h"  
25
26 #ifndef USE_MINIINTERPRETER
27         
28 /* 
29  * GCC will have assumed that pushing/popping of C-stack frames is
30  * going on when it generated its code, and used stack space
31  * accordingly.  However, we actually {\em post-process away} all
32  * such stack-framery (see \tr{ghc/driver/ghc-asm.lprl}). Things will
33  * be OK however, if we initially make sure there are
34  * @RESERVED_C_STACK_BYTES@ on the C-stack to begin with, for local
35  * variables.  
36  */
37
38 /* -----------------------------------------------------------------------------
39    x86 architecture
40    -------------------------------------------------------------------------- */
41         
42 #if i386_TARGET_ARCH    
43
44 .text
45         .align 2
46
47 #ifdef LEADING_UNDERSCORE       
48 .globl _StgRun
49 _StgRun:
50 #else   
51 .globl StgRun
52 StgRun:
53 #endif
54         pushl %ebp              /* standard frame-pointer stuff */
55         movl %esp,%ebp
56
57         /*
58          * leave a giant chunk of C-stack for temporaries in the STG world.
59          */
60         subl $RESERVED_C_STACK_BYTES + 4*SIZEOF_LONG,%esp
61
62         /* 
63          * save callee-saves registers on behalf of the STG code.
64          */
65         leal RESERVED_C_STACK_BYTES(%esp),%eax
66         movl %ebx,0(%eax)
67         movl %esi,4(%eax)
68         movl %edi,8(%eax)
69         movl %ebp,12(%eax)
70
71         /*
72          * grab the function argument from the stack, and jump to it.
73          */
74         movl 8(%ebp),%eax
75         jmp *%eax
76
77         .align 2
78
79 #ifdef LEADING_UNDERSCORE
80 .globl _StgReturn
81 _StgReturn:
82 #else   
83 .globl StgReturn
84 StgReturn:
85 #endif  
86         movl %esi,%eax   /* Return value in R1  */
87
88         /*
89          * restore callee-saves registers.  (Don't stomp on %eax!)
90          */
91         leal RESERVED_C_STACK_BYTES(%esp),%edx
92         movl 0(%edx),%ebx       /* restore the registers saved above */
93         movl 4(%edx),%esi
94         movl 8(%edx),%edi
95         movl 12(%edx),%ebp
96
97         movl %ebp, %esp         /* restore the C stack state */
98         popl %ebp
99         ret
100
101 #endif /* i386_TARGET_ARCH */
102
103 /* -----------------------------------------------------------------------------
104    Alpha architecture
105    -------------------------------------------------------------------------- */
106         
107 /* -----------------------------------------------------------------------------
108    hppa1.1-hp-hpux architecture
109    -------------------------------------------------------------------------- */
110         
111 /* -----------------------------------------------------------------------------
112    MIPS architecture
113    -------------------------------------------------------------------------- */
114         
115 #endif /* !USE_MINIINTERPRETER */