2007-07-24 Rodrigo Kumpera <rkumpera@novell.com>
[mono.git] / mono / utils / mono-compiler.h
index f89dac2501abd0b664af6582c49af748c2c4bb20..e52e81d8e2c19e49aa523ad54e4865e7dab939d7 100644 (file)
@@ -9,10 +9,26 @@
 #ifdef HAVE_KW_THREAD
 #if HAVE_TLS_MODEL_ATTR
 
-#if defined(PIC) && defined(__x86_64__)
-#define MONO_TLS_FAST 
+/* 
+ * Define this if you want a faster libmono, which cannot be loaded dynamically as a 
+ * module.
+ */
+//#define PIC_INITIAL_EXEC
+
+#if defined (__powerpc__)
+#define MONO_TLS_FAST
+#elif defined(PIC)
+
+#ifdef PIC_INITIAL_EXEC
+#define MONO_TLS_FAST __attribute__((tls_model("initial-exec")))
+#else
+#define MONO_TLS_FAST __attribute__((tls_model("local-dynamic")))
+#endif
+
 #else
+
 #define MONO_TLS_FAST __attribute__((tls_model("local-exec")))
+
 #endif
 
 #else
 #endif
 
 #if defined(__GNUC__) && defined(__i386__)
-#define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("jmp 1f; .section writetext, \"awx\"; 1: movl $" #var "@ntpoff, %0; jmp 2f; .previous; 2:" : "=r" (offset));
+#if defined(PIC)
+#define MONO_THREAD_VAR_OFFSET(var,offset) do { int tmp; __asm ("call 1f; 1: popl %0; addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %0; movl " #var "@gotntpoff(%0), %1" : "=r" (tmp), "=r" (offset)); } while (0)
+#else
+#define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("movl $" #var "@ntpoff, %0" : "=r" (offset))
+#endif
+#elif defined(__x86_64__)
+#if defined(PIC)
+// This only works if libmono is linked into the application
+#define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;  __asm ("movq " #var "@GOTTPOFF(%%rip), %0" : "=r" (foo)); offset = foo; } while (0)
+#else
+#define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;  __asm ("movq $" #var "@TPOFF, %0" : "=r" (foo)); offset = foo; } while (0)
+#endif
+#elif defined(__ia64__) && !defined(__INTEL_COMPILER)
+#define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("addl %0 = @tprel(" #var "#), r0 ;;\n" : "=r" (offset))
 #else
 #define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
 #endif
 
+#if defined(PIC) && !defined(PIC_INITIAL_EXEC)
+/* 
+ * The above definitions do not seem to work if libmono is loaded dynamically as a module.
+ * See bug #78767.
+ */
+#undef MONO_THREAD_VAR_OFFSET
+#define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
+#endif
+
 #else /* no HAVE_KW_THREAD */
 
 #define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
 
 #endif
 
+/* Deal with Microsoft C compiler differences */
+#ifdef _MSC_VER
+
+#include <float.h>
+#define isnan(x)       _isnan(x)
+#define trunc(x)       floor((x))
+#define isinf(x)       (_isnan(x) ? 0 : (_fpclass(x) == _FPCLASS_NINF) ? -1 : (_fpclass(x) == _FPCLASS_PINF) ? 1 : 0)
+#define isnormal(x)    _finite(x)
+
+#define popen          _popen
+#define pclose         _pclose
+
+#include <direct.h>
+#define mkdir(x)       _mkdir(x)
+
+/* GCC specific functions aren't available */
+#define __builtin_return_address(x)    NULL
+
+#define __func__ __FUNCTION__
+
+#endif /* _MSC_VER */
+
+#if !defined(_MSC_VER) && HAVE_VISIBILITY_HIDDEN
+#define MONO_INTERNAL __attribute__ ((visibility ("hidden")))
+#else
+#define MONO_INTERNAL 
+#endif
+
 #endif /* __UTILS_MONO_COMPILER_H__*/