-// OK, stop reading here, because it's getting obscene.
-
-#if defined(__GNUC__) && defined(__OPTIMIZE__) && !(defined(__hppa__) && (__GNUC__ == 2) && (__GNUC_MINOR__ < 8)) && !defined(NO_PROVIDE_REQUIRE)
- #ifdef ASM_UNDERSCORE
- #define ASM_UNDERSCORE_PREFIX "_"
- #else
- #define ASM_UNDERSCORE_PREFIX ""
- #endif
- // Globalize a label defined in the same translation unit.
- // See macro ASM_GLOBALIZE_LABEL in the gcc sources.
- #if defined(__i386__) || defined(__m68k__) || defined(__mips__) || defined(__mips64__) || defined(__alpha__) || defined(__rs6000__) || defined(__s390__)
- // Some m68k systems use "xdef" or "global" or ".global"...
- #define CL_GLOBALIZE_LABEL(label) __asm__("\t.globl " label);
- #endif
- #if defined(__sparc__) || defined(__sparc64__) || defined(__arm__) || defined(__ia64__)
- // Some arm systems use "EXPORT" or ".globl"...
- #define CL_GLOBALIZE_LABEL(label) __asm__("\t.global " label);
- #endif
- #if defined(__hppa__)
- #define CL_GLOBALIZE_LABEL(label) __asm__("\t.EXPORT " label ",ENTRY,PRIV_LEV=3");
- #endif
- #if defined(__m88k__)
- #define CL_GLOBALIZE_LABEL(label) __asm__("\tglobal " label);
- #endif
- #if defined(__convex__)
- #define CL_GLOBALIZE_LABEL(label) __asm__(".globl " label);
- #endif
- #ifndef CL_GLOBALIZE_LABEL
- #define CL_GLOBALIZE_LABEL(label)
- #endif
- #if defined(__rs6000__) || defined(_WIN32)
- #define CL_GLOBALIZE_JUMP_LABEL(label) CL_GLOBALIZE_LABEL(#label)
- #else
- #define CL_GLOBALIZE_JUMP_LABEL(label)
- #endif
- #ifdef CL_NEED_GLOBALIZE_CTORDTOR
- #define CL_GLOBALIZE_CTORDTOR_LABEL(label) CL_GLOBALIZE_LABEL(label)
- #else
- #define CL_GLOBALIZE_CTORDTOR_LABEL(label)
- #endif
- // Output a label inside a function.
- // See macro ASM_OUTPUT_LABEL in the gcc sources.
- #if defined(__hppa__)
- // Some hppa (Linux) systems want `label:', HPUX used to use just `label'.
- // I tried to find out, but was unable to find the assembler on my HPUX-11
- // boxen so decided to potentially ditch the support (no joke). Please
- // send an email if you can explain to me what's going on! (-rbk. 07/2001)
- #define CL_OUTPUT_LABEL(label) ASM_VOLATILE ("\n" label ":")
- #else
- #define CL_OUTPUT_LABEL(label) ASM_VOLATILE ("\n" label ":")
- #endif
- // ASM_VOLATILE(string) is for asms without arguments only!!
- #if ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 91)) || (__GNUC__ >= 3)
- // avoid warning caused by the volatile keyword
- #define ASM_VOLATILE __asm__
- #else
- // need volatile to avoid reordering
- #define ASM_VOLATILE __asm__ __volatile__
- #endif
- // CL_JUMP_TO(addr) jumps to an address, like goto *(void*)(addr),
- // except that the latter inhibits inlining of the function containing it
- // in gcc-2.95. For new CPUs, look for "jump" and "indirect_jump" in gcc's
- // machine description.
- #if defined(__i386__)
- #define CL_JUMP_TO(addr) ASM_VOLATILE("jmp %*%0" : : "rm" ((void*)(addr)))
- #endif
- #if defined(__m68k__)
- #define CL_JUMP_TO(addr) ASM_VOLATILE("jmp %0@" : : "a" ((void*)(addr)))
- #endif
- #if defined(__mips__)
- #define CL_JUMP_TO(addr) ASM_VOLATILE("%*j %0" : : "d" ((void*)(addr)))
- #endif
- #if defined(__sparc__) || defined(__sparc64__)
- #define CL_JUMP_TO(addr) ASM_VOLATILE("jmp %0\n\tnop" : : "r" ((void*)(addr)))
- #endif
- #if defined(__alpha__)
- #define CL_JUMP_TO(addr) ASM_VOLATILE("jmp $31,(%0),0" : : "r" ((void*)(addr)))
- #endif
- #if defined(__hppa__)
- //#define CL_JUMP_TO(addr) ASM_VOLATILE("bv,n 0(%0)" : : "r" ((void*)(addr)))
- #define CL_JUMP_TO(addr) ASM_VOLATILE("b " #addr "\n\tnop")
- #endif
- #if defined(__arm__)
- #define CL_JUMP_TO(addr) ASM_VOLATILE("mov pc,%0" : : "r" ((void*)(addr)))
- #endif
- #if defined(__rs6000__) || defined(__powerpc__) || defined(__ppc__)
- //#define CL_JUMP_TO(addr) ASM_VOLATILE("mtctr %0\n\tbctr" : : "r" ((void*)(addr)))
- #define CL_JUMP_TO(addr) ASM_VOLATILE("b " #addr)
- #endif
- #if defined(__m88k__)
- #define CL_JUMP_TO(addr) ASM_VOLATILE("jmp %0" : : "r" ((void*)(addr)))
- #endif
- #if defined(__convex__)
- #define CL_JUMP_TO(addr) ASM_VOLATILE("jmp (%0)" : : "r" ((void*)(addr)))
- #endif
- #if defined(__ia64__)
- #define CL_JUMP_TO(addr) ASM_VOLATILE("br " #addr)
- #endif
- #if defined(__s390__)
- #define CL_JUMP_TO(addr) ASM_VOLATILE("br %0" : : "a" ((void*)(addr)))
- #endif
- #ifdef CL_GLOBAL_DESTRUCTOR_PREFIX
- #define CL_PROVIDE(module) \
- extern "C" void cl_module__##module##__firstglobalfun () {} \
- extern "C" void cl_module__##module##__ctorend (void); \
- extern "C" void cl_module__##module##__dtorend (void); \
- CL_GLOBALIZE_JUMP_LABEL(cl_module__##module##__ctorend) \
- CL_GLOBALIZE_JUMP_LABEL(cl_module__##module##__dtorend) \
- CL_GLOBALIZE_CTORDTOR_LABEL( \
- ASM_UNDERSCORE_PREFIX CL_GLOBAL_CONSTRUCTOR_PREFIX \
- "cl_module__" #module "__firstglobalfun") \
- CL_GLOBALIZE_CTORDTOR_LABEL( \
- ASM_UNDERSCORE_PREFIX CL_GLOBAL_DESTRUCTOR_PREFIX \
- "cl_module__" #module "__firstglobalfun") \
- static int cl_module__##module##__counter; \
- struct cl_module__##module##__controller { \
- inline cl_module__##module##__controller () \
- { if (cl_module__##module##__counter++) \
- { CL_JUMP_TO(cl_module__##module##__ctorend); } \
- } \
- inline ~cl_module__##module##__controller () \
- { CL_OUTPUT_LABEL (ASM_UNDERSCORE_PREFIX "cl_module__" #module "__dtorend"); } \
- }; \
- static cl_module__##module##__controller cl_module__##module##__ctordummy;
- #define CL_PROVIDE_END(module) \
- struct cl_module__##module##__destroyer { \
- inline cl_module__##module##__destroyer () \
- { CL_OUTPUT_LABEL (ASM_UNDERSCORE_PREFIX "cl_module__" #module "__ctorend"); } \
- inline ~cl_module__##module##__destroyer () \
- { if (--cl_module__##module##__counter) \
- { CL_JUMP_TO(cl_module__##module##__dtorend); } \
- } \
- }; \
- static cl_module__##module##__destroyer cl_module__##module##__dtordummy;
- #define CL_REQUIRE(module) \
- extern "C" void cl_module__##module##__ctor (void) \
- __asm__ (ASM_UNDERSCORE_PREFIX CL_GLOBAL_CONSTRUCTOR_PREFIX \
- "cl_module__" #module "__firstglobalfun"); \
- extern "C" void cl_module__##module##__dtor (void) \
- __asm__ (ASM_UNDERSCORE_PREFIX CL_GLOBAL_DESTRUCTOR_PREFIX \
- "cl_module__" #module "__firstglobalfun"); \
- struct _CL_REQUIRE_CLASSNAME(module,__LINE__) { \
- inline _CL_REQUIRE_CLASSNAME(module,__LINE__) () \
- { cl_module__##module##__ctor (); } \
- inline ~_CL_REQUIRE_CLASSNAME(module,__LINE__) () \
- { cl_module__##module##__dtor (); } \
- }; \
- static _CL_REQUIRE_CLASSNAME(module,__LINE__) \
- _CL_REQUIRE_CLASSNAME(module##_requirer,__LINE__);
- #else
- // gcc-3.0 -fuse-cxa-atexit doesn't have a single per-module destructor
- // function anymore. Instead, for each object's static constructor it
- // executes, it pushes the corresponding object's destructor onto a list.
- // Thus we need to hack the constructors only.
- #define CL_PROVIDE(module) \
- extern "C" void cl_module__##module##__firstglobalfun () {} \
- extern "C" void cl_module__##module##__ctorend (void); \
- CL_GLOBALIZE_JUMP_LABEL(cl_module__##module##__ctorend) \
- CL_GLOBALIZE_CTORDTOR_LABEL( \
- ASM_UNDERSCORE_PREFIX CL_GLOBAL_CONSTRUCTOR_PREFIX \
- "cl_module__" #module "__firstglobalfun") \
- static int cl_module__##module##__counter; \
- struct cl_module__##module##__controller { \
- inline cl_module__##module##__controller () \
- { if (cl_module__##module##__counter++) \
- { CL_JUMP_TO(cl_module__##module##__ctorend); } \
- } \
- }; \
- static cl_module__##module##__controller cl_module__##module##__ctordummy;
- #define CL_PROVIDE_END(module) \
- struct cl_module__##module##__destroyer { \
- inline cl_module__##module##__destroyer () \
- { CL_OUTPUT_LABEL (ASM_UNDERSCORE_PREFIX "cl_module__" #module "__ctorend"); } \
- }; \
- static cl_module__##module##__destroyer cl_module__##module##__dtordummy;
- #define CL_REQUIRE(module) \
- extern "C" void cl_module__##module##__ctor (void) \
- __asm__ (ASM_UNDERSCORE_PREFIX CL_GLOBAL_CONSTRUCTOR_PREFIX \
- "cl_module__" #module "__firstglobalfun"); \
- struct _CL_REQUIRE_CLASSNAME(module,__LINE__) { \
- inline _CL_REQUIRE_CLASSNAME(module,__LINE__) () \
- { cl_module__##module##__ctor (); } \
- }; \
- static _CL_REQUIRE_CLASSNAME(module,__LINE__) \
- _CL_REQUIRE_CLASSNAME(module##_requirer,__LINE__);
- #endif
- #define _CL_REQUIRE_CLASSNAME(module,line) __CL_REQUIRE_CLASSNAME(module,line)
- #define __CL_REQUIRE_CLASSNAME(module,line) cl_module__##module##__##line
-#else
- #define CL_PROVIDE(module)
- #define CL_PROVIDE_END(module)
- #define CL_REQUIRE(module)
-#endif