+#endif
+
+/* -----------------------------------------------------------------------------
+ Module initialisation
+ -------------------------------------------------------------------------- */
+
+#define PUSH_INIT_STACK(reg_function) \
+ *(Sp++) = (W_)reg_function
+
+#define POP_INIT_STACK() \
+ *(--Sp)
+
+#define START_MOD_INIT(reg_mod_name) \
+ static int _module_registered = 0; \
+ FN_(reg_mod_name) { \
+ FB_; \
+ if (! _module_registered) { \
+ _module_registered = 1; \
+ {
+ /* extern decls go here, followed by init code */
+
+#define REGISTER_FOREIGN_EXPORT(reg_fe_binder) \
+ STGCALL1(getStablePtr,reg_fe_binder)
+
+#define REGISTER_IMPORT(reg_mod_name) \
+ PUSH_INIT_STACK(reg_mod_name)
+
+#define END_MOD_INIT() \
+ }}; \
+ JMP_(POP_INIT_STACK()); \
+ FE_ }
+
+/* -----------------------------------------------------------------------------
+ Support for _ccall_GC_ and _casm_GC.
+ -------------------------------------------------------------------------- */
+
+/*
+ * Suspending/resuming threads for doing external C-calls (_ccall_GC).
+ * These functions are defined in rts/Schedule.c.
+ */
+StgInt suspendThread ( StgRegTable *cap );
+StgRegTable * resumeThread ( StgInt );
+
+#define SUSPEND_THREAD(token) \
+ SaveThreadState(); \
+ token = suspendThread(BaseReg);
+
+#ifdef SMP
+#define RESUME_THREAD(token) \
+ BaseReg = resumeThread(token); \
+ LoadThreadState();
+#else
+#define RESUME_THREAD(token) \
+ (void)resumeThread(token); \
+ LoadThreadState();
+#endif
+