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)
60 CALLER_RESTORE_Base /* has to be first! */
71 CALLER_RESTORE_FltReg1
72 CALLER_RESTORE_FltReg2
73 CALLER_RESTORE_FltReg3
74 CALLER_RESTORE_FltReg4
75 CALLER_RESTORE_DblReg1
76 CALLER_RESTORE_DblReg2
84 CALLER_RESTORE_Liveness
85 CALLER_RESTORE_Activity
88 /* These next two are restore-only */
89 CALLER_RESTORE_StdUpdRetVec
90 CALLER_RESTORE_StkStub
94 # endif /* defined(CALLER_SAVES_SYSTEM) || defined(CALLER_SAVES_USER) */
96 # if defined(CALLER_SAVES_SYSTEM)
98 callWrapper_safe(STG_NO_ARGS)
116 CALLER_RESTORE_Base /* has to be first! */
125 CALLER_RESTORE_Liveness
126 CALLER_RESTORE_Activity
129 /* These next two are restore-only */
130 CALLER_RESTORE_StdUpdRetVec
131 CALLER_RESTORE_StkStub
135 # endif /* defined(CALLER_SAVES_SYSTEM) */
140 Anyone changing the definition of @callWrapper_GC@ should make
141 appropriate changes in the compiler (absCSyn/PprAbsC.lhs :: pprCCall).
143 The reason is that \tr{_ccall_GC_} and \tr{_casm_GC_} generate code like this:
148 _ccall_result = << do the call/asm>>;
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
161 EXTFUN(EnterNodeCode);
163 void PerformGC_wrapper PROTO((W_)) WRAPPER_NAME(PerformGC);
164 void PerformGC_wrapper(args)
167 WRAPPER_SETUP(PerformGC)
174 void StackOverflow_wrapper PROTO((W_,W_)) WRAPPER_NAME(StackOverflow);
175 void StackOverflow_wrapper(args1,args2)
178 WRAPPER_SETUP(StackOverflow)
179 if(StackOverflow(args1,args2)) {
185 void Yield_wrapper PROTO((W_)) WRAPPER_NAME(Yield);
186 void Yield_wrapper(args)
198 void PerformReschedule_wrapper PROTO((W_, W_)) WRAPPER_NAME(PerformReschedule);
199 void PerformReschedule_wrapper(liveness, always_reenter_node)
201 W_ always_reenter_node;
203 WRAPPER_SETUP(PerformReschedule)
204 PerformReschedule(liveness, always_reenter_node);
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.
218 SEPARATE_WRAPPER_RESTORE
220 #endif /* defined(__STG_GCC_REGS__) */
222 /* We can perform a runtime check that we have used @_ccall_GC_@ when
223 appropriate using this flag. */
224 StgInt inCCallGC = 0;
229 if (inCCallGC == 0) {
230 fprintf(stderr, "Error: entering a closure from C without using _ccall_GC_\n");
236 Hack for -UGRAN setup. % HWL
240 void PerformReschedule_wrapper PROTO((W_, W_));
241 void PerformReschedule_wrapper(liveness, always_reenter_node)
243 W_ always_reenter_node;