1 #ifndef __UTILS_MONO_COMPILER_H__
2 #define __UTILS_MONO_COMPILER_H__
5 * This file includes macros used in the runtime to encapsulate different
12 #define MONO_HAVE_FAST_TLS
13 #define MONO_FAST_TLS_SET(x,y) x = y
14 #define MONO_FAST_TLS_GET(x) x
15 #define MONO_FAST_TLS_INIT(x)
16 #define MONO_FAST_TLS_DECLARE(x) static __thread gpointer x MONO_TLS_FAST;
18 #if HAVE_TLS_MODEL_ATTR
20 #if defined(__PIC__) && !defined(PIC)
22 * Must be compiling -fPIE, for executables. Build PIC
23 * but with initial-exec.
24 * http://bugs.gentoo.org/show_bug.cgi?id=165547
27 #define PIC_INITIAL_EXEC
31 * Define this if you want a faster libmono, which cannot be loaded dynamically as a
34 //#define PIC_INITIAL_EXEC
38 #ifdef PIC_INITIAL_EXEC
39 #define MONO_TLS_FAST __attribute__((tls_model("initial-exec")))
41 #if defined (__powerpc__)
42 /* local dynamic requires a call to __tls_get_addr to look up the
43 TLS block address via the Dynamic Thread Vector. In this case Thread
44 Pointer relative offsets can't be used as this modules TLS was
45 allocated separately (none contiguoiusly) from the initial TLS
48 For now we will disable this. */
51 #define MONO_TLS_FAST __attribute__((tls_model("local-dynamic")))
57 #define MONO_TLS_FAST __attribute__((tls_model("local-exec")))
65 #if defined(__GNUC__) && defined(__i386__)
67 #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)
69 #define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("movl $" #var "@ntpoff, %0" : "=r" (offset))
71 #elif defined(__x86_64__)
73 // This only works if libmono is linked into the application
74 #define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo; __asm ("movq " #var "@GOTTPOFF(%%rip), %0" : "=r" (foo)); offset = foo; } while (0)
76 #define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo; __asm ("movq $" #var "@TPOFF, %0" : "=r" (foo)); offset = foo; } while (0)
78 #elif defined(__ia64__) && !defined(__INTEL_COMPILER)
80 #define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("addl %0 = @ltoff(@tprel(" #var "#)), gp ;; ld8 %0 = [%0]\n" : "=r" (offset))
82 #define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("addl %0 = @tprel(" #var "#), r0 ;;\n" : "=r" (offset))
84 #elif defined(__arm__) && defined(__ARM_EABI__) && !defined(PIC)
85 #define MONO_THREAD_VAR_OFFSET(var,offset) __asm (" ldr %0, 1f; b 2f; 1: .word " #var "(tpoff); 2:" : "=r" (offset))
86 #elif defined(__mono_ppc__) && defined(__GNUC__)
88 #ifdef PIC_INITIAL_EXEC
90 #if defined(__mono_ppc64__)
91 #define MONO_THREAD_VAR_OFFSET(var,offset) \
93 __asm ( "ld %0," #var "@got@tprel(2)\n" \
95 (offset) = off; } while (0)
97 /* must be powerpc32 */
98 #define MONO_THREAD_VAR_OFFSET(var,offset) \
99 __asm ( "lwz %0," #var "@got@tprel(30)\n" \
105 /* local dynamic requires a call to __tls_get_addr to look up the
106 TLS block address via the Dynamic Thread Vector. In this case Thread
107 Pointer relative offsets can't be used as this modules TLS was
108 allocated separately (none contiguoiusly) from the initial TLS
111 For now we will disable this. */
112 #define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
116 /* Must be local-exec TLS */
117 #define MONO_THREAD_VAR_OFFSET(var,offset) \
118 __asm ( "lis %0," #var "@tprel@ha\n" \
119 "addi %0,%0, " #var "@tprel@l\n" \
122 #elif defined(__s390x__)
124 // This only works if libmono is linked into the application
125 # define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo; \
126 __asm__ ("basr %%r1,0\n\t" \
128 ".quad " #var "@TLSGD\n\t" \
130 "lg %%r2,4(%%r1)\n\t" \
131 "brasl %%r14,__tls_get_offset@PLT:tls_gdcall:"#var"\n\t" \
134 : "1", "2", "14", "cc"); \
135 offset = foo; } while (0)
137 # define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo; \
138 __asm__ ("basr %%r1,0\n\t" \
140 ".quad " #var "@NTPOFF\n" \
142 "lg %0,4(%%r1)\n\t" \
143 : "=r" (foo) : : "1"); \
144 offset = foo; } while (0)
148 #define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
151 #if defined(PIC) && !defined(PIC_INITIAL_EXEC)
153 * The above definitions do not seem to work if libmono is loaded dynamically as a module.
156 #undef MONO_THREAD_VAR_OFFSET
157 #define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
160 #elif defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__))
162 #define MONO_HAVE_FAST_TLS
163 #define MONO_FAST_TLS_SET(x,y) pthread_setspecific(x, y)
164 #define MONO_FAST_TLS_GET(x) pthread_getspecific(x)
165 #define MONO_FAST_TLS_ADDR(x) (mono_mach_get_tls_address_from_thread (pthread_self (), x))
166 #define MONO_FAST_TLS_INIT(x) pthread_key_create(&x, NULL)
167 #define MONO_FAST_TLS_DECLARE(x) static pthread_key_t x;
169 #define MONO_THREAD_VAR_OFFSET(x,y) ({ \
170 typeof(x) _x = (x); \
172 (void) (&_x == &_y); \
174 #else /* no HAVE_KW_THREAD */
176 #define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
178 /*Macros to facilitate user code*/
179 #define MONO_FAST_TLS_INIT(x)
182 #if defined(MONO_HAVE_FAST_TLS) && !defined(MONO_FAST_TLS_ADDR)
183 #define MONO_FAST_TLS_ADDR(x) (&(x))
187 /* Deal with Microsoft C compiler differences */
192 #define isnan(x) _isnan(x)
193 #define trunc(x) (((x) < 0) ? ceil((x)) : floor((x)))
194 #define isinf(x) (_isnan(x) ? 0 : (_fpclass(x) == _FPCLASS_NINF) ? -1 : (_fpclass(x) == _FPCLASS_PINF) ? 1 : 0)
195 #define isnormal(x) _finite(x)
198 #define pclose _pclose
201 #define mkdir(x) _mkdir(x)
203 /* GCC specific functions aren't available */
204 #define __builtin_return_address(x) NULL
206 #define __func__ __FUNCTION__
208 #endif /* _MSC_VER */
210 #if !defined(_MSC_VER) && !defined(PLATFORM_SOLARIS) && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MONOTOUCH) && HAVE_VISIBILITY_HIDDEN
211 #define MONO_INTERNAL __attribute__ ((visibility ("hidden")))
213 #define MONO_LLVM_INTERNAL
215 #define MONO_LLVM_INTERNAL MONO_INTERNAL
218 #define MONO_INTERNAL
219 #define MONO_LLVM_INTERNAL
223 #define MONO_DEPRECATED __attribute__ ((deprecated))
225 #define MONO_DEPRECATED
229 #define MONO_ALWAYS_INLINE __attribute__((always_inline))
230 #elif defined(_MSC_VER)
231 #define MONO_ALWAYS_INLINE __forceinline
233 #define MONO_ALWAYS_INLINE
236 #endif /* __UTILS_MONO_COMPILER_H__*/