1 %************************************************************************
3 \section[CallWrap_C.lc]{``callWrapper'' stuff that can be written in C}
5 %************************************************************************
8 #define MAIN_REG_MAP /* These routines are all a bit special */
9 #define CALLWRAPPER_C /* Don't give standard declarations for wrappers */
13 %************************************************************************
15 \subsection[call-wrapping]{Routines to ``wrap'' special calls to C}
17 %************************************************************************
19 In most cases, this requires some assembly-language hacking (see the
20 discussion in @COptWraps.lh@.)
23 #if defined(__STG_GCC_REGS__)
25 # if defined(CALLER_SAVES_SYSTEM) || defined(CALLER_SAVES_USER)
27 callWrapper(STG_NO_ARGS)
59 CALLER_RESTORE_Base /* has to be first! */
70 CALLER_RESTORE_FltReg1
71 CALLER_RESTORE_FltReg2
72 CALLER_RESTORE_FltReg3
73 CALLER_RESTORE_FltReg4
74 CALLER_RESTORE_DblReg1
75 CALLER_RESTORE_DblReg2
83 CALLER_RESTORE_Liveness
86 /* These next two are restore-only */
87 CALLER_RESTORE_StdUpdRetVec
88 CALLER_RESTORE_StkStub
92 # endif /* defined(CALLER_SAVES_SYSTEM) || defined(CALLER_SAVES_USER) */
94 # if defined(CALLER_SAVES_SYSTEM)
96 callWrapper_safe(STG_NO_ARGS)
113 CALLER_RESTORE_Base /* has to be first! */
122 CALLER_RESTORE_Liveness
125 /* These next two are restore-only */
126 CALLER_RESTORE_StdUpdRetVec
127 CALLER_RESTORE_StkStub
131 # endif /* defined(CALLER_SAVES_SYSTEM) */
136 Anyone changing the definition of @callWrapper_GC@ should make
137 appropriate changes in the compiler (absCSyn/PprAbsC.lhs :: pprCCall).
139 The reason is that \tr{_ccall_GC_} and \tr{_casm_GC_} generate code like this:
144 _ccall_result = << do the call/asm>>;
150 This avoids limiting _ccall_GC_ to 6 arguments and makes it possible
151 to implement _ccall_GC_. (The local variable avoids the need for some
152 of the deeper magic hidden inside @GC_SETUP@, @GC_CCALL@ and
157 EXTFUN(EnterNodeCode);
159 void *__temp_esp, *__temp_eax;
161 void PerformGC_wrapper PROTO((W_)) WRAPPER_NAME(PerformGC);
162 void PerformGC_wrapper(args)
168 WRAPPER_SETUP(PerformGC,ret_addr,args)
170 WRAPPER_SETUP(PerformGC, ignore_me, ignore_me)
178 void __DISCARD__ (STG_NO_ARGS) { /*nothing*/ }
180 void StackOverflow_wrapper PROTO((W_,W_)) WRAPPER_NAME(StackOverflow);
181 void StackOverflow_wrapper(args1,args2)
185 void *ret_addr, *ignore_me;
186 WRAPPER_SETUP(StackOverflow,ret_addr,ignore_me)
188 WRAPPER_SETUP(StackOverflow, ignore_me, ignore_me)
190 if(StackOverflow(args1,args2)) {
196 void Yield_wrapper PROTO((W_)) WRAPPER_NAME(Yield);
197 void Yield_wrapper(args)
201 void *ret_addr, *ignore_me;
202 WRAPPER_SETUP(Yield, ret_addr, ignore_me)
204 WRAPPER_SETUP(Yield, ignore_me, ignore_me)
214 void PerformReschedule_wrapper PROTO((W_, W_)) WRAPPER_NAME(PerformReschedule);
215 void PerformReschedule_wrapper(liveness, always_reenter_node)
217 W_ always_reenter_node;
220 void *ret_addr, *ignore_me;
221 WRAPPER_SETUP(PerformReschedule, ret_addr, ignore_me)
223 WRAPPER_SETUP(PerformReschedule, ignore_me, ignore_me)
225 PerformReschedule(liveness, always_reenter_node);
232 * In the threaded world, context switches may occur during one of these
233 * wrapped calls, and when we come back, our stack will have been trashed.
234 * If gcc, in all of its cleverness, tries to store any temporary values on
235 * the stack, we need to separate the restoration function. See the sparc
236 * code for an example.
239 SEPARATE_WRAPPER_RESTORE
241 #endif /* defined(__STG_GCC_REGS__) */
243 /* We can perform a runtime check that we have used @_ccall_GC_@ when
244 appropriate using this flag. */
245 StgInt inCCallGC = 0;
250 if (inCCallGC == 0) {
251 fprintf(stderr, "Error: entering a closure from C without using _ccall_GC_\n");
257 Hack for -UGRAN setup. % HWL
261 void PerformReschedule_wrapper PROTO((W_, W_));
262 void PerformReschedule_wrapper(liveness, always_reenter_node)
264 W_ always_reenter_node;