Merge pull request #2802 from BrzVlad/feature-evacuation-opt2
[mono.git] / mono / utils / mono-compiler.h
index bad994cc29338cd5bfdc17376e665dfe2a3414b6..04bc26e4f53ff3ef3796dc25ba3536144b6ba48d 100644 (file)
@@ -7,13 +7,32 @@
  */
 #include <config.h>
 
+/*
+ * When embedding, you have to define MONO_ZERO_LEN_ARRAY before including any
+ * other Mono header file if you use a different compiler from the one used to
+ * build Mono.
+ */
+#ifndef MONO_ZERO_LEN_ARRAY
+#ifdef __GNUC__
+#define MONO_ZERO_LEN_ARRAY 0
+#else
+#define MONO_ZERO_LEN_ARRAY 1
+#endif
+#endif
+
+#ifdef __GNUC__
+#define MONO_ATTR_USED __attribute__ ((used))
+#else
+#define MONO_ATTR_USED
+#endif
+
 #ifdef HAVE_KW_THREAD
 
 #define MONO_HAVE_FAST_TLS
 #define MONO_FAST_TLS_SET(x,y) x = y
 #define MONO_FAST_TLS_GET(x) x
 #define MONO_FAST_TLS_INIT(x)
-#define MONO_FAST_TLS_DECLARE(x) static __thread gpointer x MONO_TLS_FAST;
+#define MONO_FAST_TLS_DECLARE(x) static __thread gpointer x MONO_TLS_FAST MONO_ATTR_USED;
 
 #if HAVE_TLS_MODEL_ATTR
 
        : "=r" (offset))
 #endif
 #elif defined(__s390x__)
-# if defined(PIC)
+# if defined(__PIC__)
+#  if !defined(__PIE__)
 // This only works if libmono is linked into the application
-#  define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;                                 \
-                                               __asm__ ("basr  %%r1,0\n\t"                     \
-                                                        "j     0f\n\t"                         \
-                                                        ".quad " #var "@TLSGD\n\t"             \
+#   define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;                                \
+                                               __asm__ ("basr  %%r1,0\n\t"                     \
+                                                        "j     0f\n\t"                         \
+                                                        ".quad " #var "@TLSGD\n"               \
                                                         "0:\n\t"                               \
-                                                        "lg    %%r2,4(%%r1)\n\t"               \
+                                                        "lg    %%r2,4(%%r1)\n\t"               \
                                                         "brasl %%r14,__tls_get_offset@PLT:tls_gdcall:"#var"\n\t" \
                                                         "lgr   %0,%%r2\n\t"                    \
                                                        : "=r" (foo) :                          \
                                                        : "1", "2", "14", "cc");                \
                                                offset = foo; } while (0)
+#  elif __PIE__ == 1
+#   define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;                                        \
+                                               __asm__ ("lg    %0," #var "@GOTNTPOFF(%%r12)\n\t"       \
+                                                        : "=r" (foo));                                 \
+                                               offset = foo; } while (0)
+#  elif __PIE__ == 2
+#   define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;                                \
+                                               __asm__ ("larl  %%r1," #var "@INDNTPOFF\n\t"    \
+                                                        "lg    %0,0(%%r1)\n\t"                 \
+                                                        : "=r" (foo) :                         \
+                                                        : "1", "cc");                          \
+                                               offset = foo; } while (0)
+#  endif
 # else
-#  define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;                                 \
-                                               __asm__ ("basr  %%r1,0\n\t"                     \
-                                                        "j     0f\n\t"                         \
-                                                        ".quad " #var "@NTPOFF\n"              \
-                                                        "0:\n\t"                               \
-                                                        "lg    %0,4(%%r1)\n\t"                 \
-                                                       : "=r" (foo) : : "1");                  \
+#  define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;                         \
+                                               __asm__ ("basr  %%r1,0\n\t"             \
+                                                        "j     0f\n\t"                 \
+                                                        ".quad " #var "@NTPOFF\n"      \
+                                                        "0:\n\t"                       \
+                                                        "lg    %0,4(%%r1)\n\t"         \
+                                                       : "=r" (foo) : : "1");          \
                                                offset = foo; } while (0)
 # endif
-
 #else
 #define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
 #endif
 #define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
 #endif
 
-#elif defined(TARGET_MACH) && (defined(__i386__) || defined(__x86_64__))
+#elif !defined(MONO_CROSS_COMPILE) && defined(PLATFORM_MACOSX) && (defined(__i386__) || defined(__x86_64__))
 
-#define MONO_HAVE_FAST_TLS
+#define MONO_HAVE_FAST_TLS 1
 #define MONO_FAST_TLS_SET(x,y) pthread_setspecific(x, y)
 #define MONO_FAST_TLS_GET(x) pthread_getspecific(x)
 #define MONO_FAST_TLS_ADDR(x) (mono_mach_get_tls_address_from_thread (pthread_self (), x))
 #define MONO_FAST_TLS_DECLARE(x) static pthread_key_t x;
 
 #define MONO_THREAD_VAR_OFFSET(x,y) ({ \
-       typeof(x) _x = (x);                     \
+       __typeof__(x) _x = (x);                 \
        pthread_key_t _y;       \
        (void) (&_x == &_y);            \
        y = (gint32) x; })
+
+#elif !defined(MONO_CROSS_COMPILE) && (defined(PLATFORM_ANDROID) || defined(TARGET_IOS)) && defined(TARGET_ARM)
+
+#define MONO_HAVE_FAST_TLS
+#define MONO_FAST_TLS_SET(x,y) pthread_setspecific(x, y)
+#define MONO_FAST_TLS_GET(x) pthread_getspecific(x)
+#define MONO_FAST_TLS_INIT(x) pthread_key_create(&x, NULL)
+#define MONO_FAST_TLS_DECLARE(x) static pthread_key_t x;
+
+#define MONO_THREAD_VAR_OFFSET(var, offset) do { offset = (int)var; } while (0)
+
 #else /* no HAVE_KW_THREAD */
 
 #define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
@@ -236,14 +279,12 @@ typedef SSIZE_T ssize_t;
 #endif /* _MSC_VER */
 
 #if !defined(_MSC_VER) && !defined(PLATFORM_SOLARIS) && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MONOTOUCH) && HAVE_VISIBILITY_HIDDEN
-#define MONO_INTERNAL __attribute__ ((visibility ("hidden")))
 #if MONO_LLVM_LOADED
-#define MONO_LLVM_INTERNAL 
+#define MONO_LLVM_INTERNAL MONO_API
 #else
-#define MONO_LLVM_INTERNAL MONO_INTERNAL
+#define MONO_LLVM_INTERNAL
 #endif
 #else
-#define MONO_INTERNAL 
 #define MONO_LLVM_INTERNAL 
 #endif
 
@@ -269,5 +310,11 @@ typedef SSIZE_T ssize_t;
 #define MONO_NEVER_INLINE
 #endif
 
+#ifdef __GNUC__
+#define MONO_COLD __attribute__((cold))
+#else
+#define MONO_COLD
+#endif
+
 #endif /* __UTILS_MONO_COMPILER_H__*/