1 #ifndef __UTILS_MONO_COMPILER_H__
2 #define __UTILS_MONO_COMPILER_H__
5 * This file includes macros used in the runtime to encapsulate different
11 #if HAVE_TLS_MODEL_ATTR
13 #if defined(__PIC__) && !defined(PIC)
15 * Must be compiling -fPIE, for executables. Build PIC
16 * but with initial-exec.
17 * http://bugs.gentoo.org/show_bug.cgi?id=165547
20 #define PIC_INITIAL_EXEC
24 * Define this if you want a faster libmono, which cannot be loaded dynamically as a
27 //#define PIC_INITIAL_EXEC
31 #ifdef PIC_INITIAL_EXEC
32 #define MONO_TLS_FAST __attribute__((tls_model("initial-exec")))
34 #if defined (__powerpc__)
35 /* local dynamic requires a call to __tls_get_addr to look up the
36 TLS block address via the Dynamic Thread Vector. In this case Thread
37 Pointer relative offsets can't be used as this modules TLS was
38 allocated separately (none contiguoiusly) from the initial TLS
41 For now we will disable this. */
44 #define MONO_TLS_FAST __attribute__((tls_model("local-dynamic")))
50 #define MONO_TLS_FAST __attribute__((tls_model("local-exec")))
58 #if defined(__GNUC__) && defined(__i386__)
60 #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)
62 #define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("movl $" #var "@ntpoff, %0" : "=r" (offset))
64 #elif defined(__x86_64__)
66 // This only works if libmono is linked into the application
67 #define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo; __asm ("movq " #var "@GOTTPOFF(%%rip), %0" : "=r" (foo)); offset = foo; } while (0)
69 #define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo; __asm ("movq $" #var "@TPOFF, %0" : "=r" (foo)); offset = foo; } while (0)
71 #elif defined(__ia64__) && !defined(__INTEL_COMPILER)
73 #define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("addl %0 = @ltoff(@tprel(" #var "#)), gp ;; ld8 %0 = [%0]\n" : "=r" (offset))
75 #define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("addl %0 = @tprel(" #var "#), r0 ;;\n" : "=r" (offset))
77 #elif defined(__arm__) && defined(__ARM_EABI__) && !defined(PIC)
78 #define MONO_THREAD_VAR_OFFSET(var,offset) __asm (" ldr %0, 1f; b 2f; 1: .word " #var "(tpoff); 2:" : "=r" (offset))
79 #elif defined(__mono_ppc__) && defined(__GNUC__)
81 #ifdef PIC_INITIAL_EXEC
83 #if defined(__mono_ppc64__)
84 #define MONO_THREAD_VAR_OFFSET(var,offset) \
86 __asm ( "ld %0," #var "@got@tprel(2)\n" \
88 (offset) = off; } while (0)
90 /* must be powerpc32 */
91 #define MONO_THREAD_VAR_OFFSET(var,offset) \
92 __asm ( "lwz %0," #var "@got@tprel(30)\n" \
98 /* local dynamic requires a call to __tls_get_addr to look up the
99 TLS block address via the Dynamic Thread Vector. In this case Thread
100 Pointer relative offsets can't be used as this modules TLS was
101 allocated separately (none contiguoiusly) from the initial TLS
104 For now we will disable this. */
105 #define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
109 /* Must be local-exec TLS */
110 #define MONO_THREAD_VAR_OFFSET(var,offset) \
111 __asm ( "lis %0," #var "@tprel@ha\n" \
112 "addi %0,%0, " #var "@tprel@l\n" \
115 #elif defined(__s390x__)
117 // This only works if libmono is linked into the application
118 # define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo; \
119 __asm__ ("basr %%r1,0\n\t" \
121 ".quad " #var "@INDNTPOFF\n\t" \
123 "lg %%r2,4(%%r1)\n\t" \
124 "brasl %%r14,__tls_get_offset@PLT\n\t" \
127 : "1", "2", "14", "cc"); \
128 offset = foo; } while (0)
130 # define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo; \
131 __asm__ ("basr %%r1,0\n\t" \
133 ".quad " #var "@NTPOFF\n" \
135 "lg %0,4(%%r1)\n\t" \
136 : "=r" (foo) : : "1"); \
137 offset = foo; } while (0)
140 #define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
143 #if defined(PIC) && !defined(PIC_INITIAL_EXEC)
145 * The above definitions do not seem to work if libmono is loaded dynamically as a module.
148 #undef MONO_THREAD_VAR_OFFSET
149 #define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
152 #else /* no HAVE_KW_THREAD */
154 #define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
158 /* Deal with Microsoft C compiler differences */
162 #define isnan(x) _isnan(x)
163 #define trunc(x) (((x) < 0) ? ceil((x)) : floor((x)))
164 #define isinf(x) (_isnan(x) ? 0 : (_fpclass(x) == _FPCLASS_NINF) ? -1 : (_fpclass(x) == _FPCLASS_PINF) ? 1 : 0)
165 #define isnormal(x) _finite(x)
168 #define pclose _pclose
171 #define mkdir(x) _mkdir(x)
173 /* GCC specific functions aren't available */
174 #define __builtin_return_address(x) NULL
176 #define __func__ __FUNCTION__
178 #endif /* _MSC_VER */
180 #if !defined(_MSC_VER) && !defined(PLATFORM_SOLARIS) && !defined(_WIN32) && !defined(__CYGWIN__) && HAVE_VISIBILITY_HIDDEN
181 #define MONO_INTERNAL __attribute__ ((visibility ("hidden")))
183 #define MONO_LLVM_INTERNAL
185 #define MONO_LLVM_INTERNAL MONO_INTERNAL
188 #define MONO_INTERNAL
189 #define MONO_LLVM_INTERNAL
193 #define MONO_DEPRECATED __attribute__ ((deprecated))
195 #define MONO_DEPRECATED
198 #endif /* __UTILS_MONO_COMPILER_H__*/