[project @ 1996-01-08 20:28:12 by partain]
[ghc-hetmet.git] / ghc / runtime / c-as-asm / CallWrap_C.lc
1 %************************************************************************
2 %*                                                                      *
3 \section[CallWrap_C.lc]{``callWrapper'' stuff that can be written in C}
4 %*                                                                      *
5 %************************************************************************
6
7 \begin{code}
8 #define MAIN_REG_MAP        /* These routines are all a bit special */
9 #define CALLWRAPPER_C       /* Don't give standard declarations for wrappers */
10 #include "rtsdefs.h"
11 \end{code}
12
13 %************************************************************************
14 %*                                                                      *
15 \subsection[call-wrapping]{Routines to ``wrap'' special calls to C}
16 %*                                                                      *
17 %************************************************************************
18
19 In most cases, this requires some assembly-language hacking (see the
20 discussion in @COptWraps.lh@.)
21
22 \begin{code}
23 #if defined(__STG_GCC_REGS__)
24
25 # if defined(CALLER_SAVES_SYSTEM) || defined(CALLER_SAVES_USER)
26 void
27 callWrapper(STG_NO_ARGS)
28 {
29     MAGIC_CALL_SETUP
30
31     CALLER_SAVE_Base
32     CALLER_SAVE_StkO
33     CALLER_SAVE_R1
34     CALLER_SAVE_R2
35     CALLER_SAVE_R3
36     CALLER_SAVE_R4
37     CALLER_SAVE_R5
38     CALLER_SAVE_R6
39     CALLER_SAVE_R7
40     CALLER_SAVE_R8
41     CALLER_SAVE_FltReg1
42     CALLER_SAVE_FltReg2
43     CALLER_SAVE_FltReg3
44     CALLER_SAVE_FltReg4
45     CALLER_SAVE_DblReg1
46     CALLER_SAVE_DblReg2
47     CALLER_SAVE_Tag
48     CALLER_SAVE_SpA
49     CALLER_SAVE_SuA
50     CALLER_SAVE_SpB
51     CALLER_SAVE_SuB
52     CALLER_SAVE_Hp
53     CALLER_SAVE_HpLim
54     CALLER_SAVE_Liveness
55     CALLER_SAVE_Activity
56     CALLER_SAVE_Ret
57
58     MAGIC_CALL
59
60     CALLER_RESTORE_Base     /* has to be first! */
61
62     CALLER_RESTORE_StkO
63     CALLER_RESTORE_R1
64     CALLER_RESTORE_R2
65     CALLER_RESTORE_R3
66     CALLER_RESTORE_R4
67     CALLER_RESTORE_R5
68     CALLER_RESTORE_R6
69     CALLER_RESTORE_R7
70     CALLER_RESTORE_R8
71     CALLER_RESTORE_FltReg1
72     CALLER_RESTORE_FltReg2
73     CALLER_RESTORE_FltReg3
74     CALLER_RESTORE_FltReg4
75     CALLER_RESTORE_DblReg1
76     CALLER_RESTORE_DblReg2
77     CALLER_RESTORE_Tag
78     CALLER_RESTORE_SpA
79     CALLER_RESTORE_SuA
80     CALLER_RESTORE_SpB
81     CALLER_RESTORE_SuB
82     CALLER_RESTORE_Hp
83     CALLER_RESTORE_HpLim
84     CALLER_RESTORE_Liveness
85     CALLER_RESTORE_Activity
86     CALLER_RESTORE_Ret
87     
88     /* These next two are restore-only */
89     CALLER_RESTORE_StdUpdRetVec
90     CALLER_RESTORE_StkStub
91
92     MAGIC_RETURN
93 }
94 # endif /* defined(CALLER_SAVES_SYSTEM) || defined(CALLER_SAVES_USER) */
95
96 # if defined(CALLER_SAVES_SYSTEM)
97 void
98 callWrapper_safe(STG_NO_ARGS)
99 {
100     MAGIC_CALL_SETUP
101
102     CALLER_SAVE_Base
103     CALLER_SAVE_StkO
104     CALLER_SAVE_SpA
105     CALLER_SAVE_SuA
106     CALLER_SAVE_SpB
107     CALLER_SAVE_SuB
108     CALLER_SAVE_Hp
109     CALLER_SAVE_HpLim
110     CALLER_SAVE_Liveness
111     CALLER_SAVE_Activity
112     CALLER_SAVE_Ret
113
114     MAGIC_CALL
115
116     CALLER_RESTORE_Base /* has to be first! */
117
118     CALLER_RESTORE_StkO
119     CALLER_RESTORE_SpA
120     CALLER_RESTORE_SuA
121     CALLER_RESTORE_SpB
122     CALLER_RESTORE_SuB
123     CALLER_RESTORE_Hp
124     CALLER_RESTORE_HpLim
125     CALLER_RESTORE_Liveness
126     CALLER_RESTORE_Activity
127     CALLER_RESTORE_Ret
128     
129     /* These next two are restore-only */
130     CALLER_RESTORE_StdUpdRetVec
131     CALLER_RESTORE_StkStub
132
133     MAGIC_RETURN
134 }
135 # endif /* defined(CALLER_SAVES_SYSTEM) */
136
137 /* 
138 Nota Bene: 
139
140 Anyone changing the definition of @callWrapper_GC@ should make
141 appropriate changes in the compiler (absCSyn/PprAbsC.lhs :: pprCCall).
142
143 The reason is that \tr{_ccall_GC_} and \tr{_casm_GC_} generate code like this:
144 \begin{verbatim}
145    { R _ccall_result;
146      SaveAllStgRegs();
147      inCCallGC+=1;
148      _ccall_result = << do the call/asm>>;
149      inCCallGC-=1;
150      RestoreAllStgRegs();
151    }
152 \end{verbatim}
153
154 This avoids limiting _ccall_GC_ to 6 arguments and makes it possible
155 to implement _ccall_GC_.  (The local variable avoids the need for some
156 of the deeper magic hidden inside @GC_SETUP@, @GC_CCALL@ and
157 @GC_RETURN@.)
158
159 ADR */
160
161 EXTFUN(EnterNodeCode);
162
163 void PerformGC_wrapper PROTO((W_))          WRAPPER_NAME(PerformGC);
164 void PerformGC_wrapper(args)
165 W_ args;
166 {
167     WRAPPER_SETUP(PerformGC)
168     PerformGC(args);
169     WRAPPER_RETURN(0)
170 }
171
172 # ifdef CONCURRENT
173
174 void StackOverflow_wrapper PROTO((W_,W_))   WRAPPER_NAME(StackOverflow);
175 void StackOverflow_wrapper(args1,args2)
176 W_ args1, args2;
177 {
178     WRAPPER_SETUP(StackOverflow)
179     if(StackOverflow(args1,args2)) {
180         WRAPPER_RETURN(1)
181     }
182     WRAPPER_RETURN(0)
183 }
184
185 void Yield_wrapper PROTO((W_))              WRAPPER_NAME(Yield);
186 void Yield_wrapper(args)
187 W_ args;
188 {
189     WRAPPER_SETUP(Yield)
190     Yield(args);
191     WRAPPER_RETURN(0)
192 }
193
194 # endif
195
196 # ifdef GRAN
197
198 void PerformReschedule_wrapper PROTO((W_, W_))      WRAPPER_NAME(PerformReschedule);
199 void PerformReschedule_wrapper(liveness, always_reenter_node)
200   W_ liveness;
201   W_  always_reenter_node;
202 {
203     WRAPPER_SETUP(PerformReschedule)
204     PerformReschedule(liveness, always_reenter_node);
205     WRAPPER_RETURN(0)
206 }
207
208 # endif /* GRAN */
209
210 /* 
211  * In the threaded world, context switches may occur during one of these
212  * wrapped calls, and when we come back, our stack will have been trashed.
213  * If gcc, in all of its cleverness, tries to store any temporary values on
214  * the stack, we need to separate the restoration function.  See the sparc
215  * code for an example.
216  */
217
218 SEPARATE_WRAPPER_RESTORE
219
220 #endif /* defined(__STG_GCC_REGS__) */
221
222 /* We can perform a runtime check that we have used @_ccall_GC_@ when
223    appropriate using this flag. */
224 StgInt inCCallGC = 0;
225
226 void
227 checkInCCallGC()
228 {
229   if (inCCallGC == 0) {
230     fprintf(stderr, "Error: entering a closure from C without using _ccall_GC_\n");
231     EXIT(EXIT_FAILURE);
232   }
233 }
234 \end{code}
235
236 Hack for -UGRAN setup. % HWL
237
238 \begin{code}
239 #ifndef GRAN
240 void PerformReschedule_wrapper PROTO((W_, W_));
241 void PerformReschedule_wrapper(liveness, always_reenter_node)
242   W_ liveness;
243   W_  always_reenter_node;
244 { }
245 #endif
246 \end{code}