Merge branch 'cecil-light'
[mono.git] / mono / utils / mono-compiler.h
1 #ifndef __UTILS_MONO_COMPILER_H__
2 #define __UTILS_MONO_COMPILER_H__
3
4 /*
5  * This file includes macros used in the runtime to encapsulate different
6  * compiler behaviours.
7  */
8 #include <config.h>
9
10 #ifdef HAVE_KW_THREAD
11 #if HAVE_TLS_MODEL_ATTR
12
13 #if defined(__PIC__) && !defined(PIC)
14 /*
15  * Must be compiling -fPIE, for executables.  Build PIC
16  * but with initial-exec.
17  * http://bugs.gentoo.org/show_bug.cgi?id=165547
18  */
19 #define PIC
20 #define PIC_INITIAL_EXEC
21 #endif
22
23 /* 
24  * Define this if you want a faster libmono, which cannot be loaded dynamically as a 
25  * module.
26  */
27 //#define PIC_INITIAL_EXEC
28
29 #if defined(PIC)
30
31 #ifdef PIC_INITIAL_EXEC
32 #define MONO_TLS_FAST __attribute__((tls_model("initial-exec")))
33 #else
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
39    block.
40
41    For now we will disable this. */
42 #define MONO_TLS_FAST
43 #else
44 #define MONO_TLS_FAST __attribute__((tls_model("local-dynamic")))
45 #endif
46 #endif
47
48 #else
49
50 #define MONO_TLS_FAST __attribute__((tls_model("local-exec")))
51
52 #endif
53
54 #else
55 #define MONO_TLS_FAST 
56 #endif
57
58 #if defined(__GNUC__) && defined(__i386__)
59 #if defined(PIC)
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)
61 #else
62 #define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("movl $" #var "@ntpoff, %0" : "=r" (offset))
63 #endif
64 #elif defined(__x86_64__)
65 #if defined(PIC)
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)
68 #else
69 #define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;  __asm ("movq $" #var "@TPOFF, %0" : "=r" (foo)); offset = foo; } while (0)
70 #endif
71 #elif defined(__ia64__) && !defined(__INTEL_COMPILER)
72 #if defined(PIC)
73 #define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("addl %0 = @ltoff(@tprel(" #var "#)), gp ;; ld8 %0 = [%0]\n" : "=r" (offset))
74 #else
75 #define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("addl %0 = @tprel(" #var "#), r0 ;;\n" : "=r" (offset))
76 #endif
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__)
80 #if defined(PIC)
81 #ifdef PIC_INITIAL_EXEC
82
83 #if defined(__mono_ppc64__)
84 #define MONO_THREAD_VAR_OFFSET(var,offset) \
85         do { long off; \
86         __asm ( "ld     %0," #var "@got@tprel(2)\n" \
87         : "=r" (off)); \
88         (offset) = off; } while (0)
89 #else
90 /* must be powerpc32 */
91 #define MONO_THREAD_VAR_OFFSET(var,offset) \
92         __asm ( "lwz    %0," #var "@got@tprel(30)\n" \
93         : "=r" (offset))
94 #endif
95
96 #else
97
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
102    block.
103
104    For now we will disable this. */
105 #define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
106
107 #endif
108 #else
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" \
113         : "=r" (offset))
114 #endif
115 #elif defined(__s390x__)
116 # if defined(PIC)
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"                     \
120                                                          "j     0f\n\t"                         \
121                                                          ".quad " #var "@INDNTPOFF\n\t"         \
122                                                          "0:\n\t"                               \
123                                                          "lg    %%r2,4(%%r1)\n\t"               \
124                                                          "brasl %%r14,__tls_get_offset@PLT\n\t" \
125                                                          "lgr   %0,%%r2\n\t"                    \
126                                                         : "=r" (foo) :                          \
127                                                         : "1", "2", "14", "cc");                \
128                                                 offset = foo; } while (0)
129 # else
130 #  define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;                                  \
131                                                 __asm__ ("basr  %%r1,0\n\t"                     \
132                                                          "j     0f\n\t"                         \
133                                                          ".quad " #var "@NTPOFF\n"              \
134                                                          "0:\n\t"                               \
135                                                          "lg    %0,4(%%r1)\n\t"                 \
136                                                         : "=r" (foo) : : "1");                  \
137                                                 offset = foo; } while (0)
138 # endif
139 #else
140 #define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
141 #endif
142
143 #if defined(PIC) && !defined(PIC_INITIAL_EXEC)
144 /* 
145  * The above definitions do not seem to work if libmono is loaded dynamically as a module.
146  * See bug #78767.
147  */
148 #undef MONO_THREAD_VAR_OFFSET
149 #define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
150 #endif
151
152 #else /* no HAVE_KW_THREAD */
153
154 #define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
155
156 #endif
157
158 /* Deal with Microsoft C compiler differences */
159 #ifdef _MSC_VER
160
161 #include <float.h>
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)
166
167 #define popen           _popen
168 #define pclose          _pclose
169
170 #include <direct.h>
171 #define mkdir(x)        _mkdir(x)
172
173 /* GCC specific functions aren't available */
174 #define __builtin_return_address(x)     NULL
175
176 #define __func__ __FUNCTION__
177
178 #endif /* _MSC_VER */
179
180 #if !defined(_MSC_VER) && !defined(PLATFORM_SOLARIS) && !defined(_WIN32) && !defined(__CYGWIN__) && HAVE_VISIBILITY_HIDDEN
181 #define MONO_INTERNAL __attribute__ ((visibility ("hidden")))
182 #if MONO_LLVM_LOADED
183 #define MONO_LLVM_INTERNAL 
184 #else
185 #define MONO_LLVM_INTERNAL MONO_INTERNAL
186 #endif
187 #else
188 #define MONO_INTERNAL 
189 #define MONO_LLVM_INTERNAL 
190 #endif
191
192 #if HAVE_DEPRECATED
193 #define MONO_DEPRECATED __attribute__ ((deprecated))
194 #else
195 #define MONO_DEPRECATED 
196 #endif
197
198 #endif /* __UTILS_MONO_COMPILER_H__*/
199