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