[xbuild] Evaluate Import with MSBuildThisFile* properties set.
[mono.git] / mono / mini / mini.h
1 #ifndef __MONO_MINI_H__
2 #define __MONO_MINI_H__
3
4 #include "config.h"
5 #include <glib.h>
6 #include <signal.h>
7 #ifdef HAVE_SYS_TYPES_H
8 #include <sys/types.h>
9 #endif
10 #include <mono/metadata/loader.h>
11 #include <mono/metadata/mempool.h>
12 #include <mono/utils/monobitset.h>
13 #include <mono/metadata/class.h>
14 #include <mono/metadata/object.h>
15 #include <mono/metadata/opcodes.h>
16 #include <mono/metadata/tabledefs.h>
17 #include <mono/metadata/domain-internals.h>
18 #include "mono/metadata/class-internals.h"
19 #include "mono/metadata/object-internals.h"
20 #include <mono/metadata/profiler-private.h>
21 #include <mono/metadata/debug-helpers.h>
22 #include <mono/utils/mono-compiler.h>
23 #include <mono/utils/mono-machine.h>
24 #include <mono/utils/mono-stack-unwinding.h>
25
26 #define MONO_BREAKPOINT_ARRAY_SIZE 64
27
28 #include "mini-arch.h"
29 #include "regalloc.h"
30 #include "declsec.h"
31 #include "mini-unwind.h"
32
33 #ifndef G_LIKELY
34 #define G_LIKELY(a) (a)
35 #define G_UNLIKELY(a) (a)
36 #endif
37
38 #ifndef G_MAXINT32
39 #define G_MAXINT32 2147483647
40 #endif
41
42 #ifndef G_MININT32
43 #define G_MININT32 (-G_MAXINT32 - 1)
44 #endif
45
46 #ifndef __GNUC__
47 /*#define __alignof__(a) sizeof(a)*/
48 #define __alignof__(type) G_STRUCT_OFFSET(struct { char c; type x; }, x)
49 #endif
50
51 #if DISABLE_LOGGING
52 #define MINI_DEBUG(level,limit,code)
53 #else
54 #define MINI_DEBUG(level,limit,code) do {if (G_UNLIKELY ((level) >= (limit))) code} while (0)
55 #endif
56
57 #if !defined(DISABLE_TASKLETS) && defined(MONO_ARCH_SUPPORT_TASKLETS) && defined(__GNUC__)
58 #define MONO_SUPPORT_TASKLETS 1
59 #endif
60
61 #if ENABLE_LLVM
62 #define COMPILE_LLVM(cfg) ((cfg)->compile_llvm)
63 #define LLVM_ENABLED TRUE
64 #else
65 #define COMPILE_LLVM(cfg) (0)
66 #define LLVM_ENABLED FALSE
67 #endif
68
69 #ifdef MONO_ARCH_SOFT_FLOAT
70 #define COMPILE_SOFT_FLOAT(cfg) (!COMPILE_LLVM ((cfg)))
71 #else
72 #define COMPILE_SOFT_FLOAT(cfg) 0
73 #endif
74
75 #ifdef ENABLE_LLVM
76 #define LLVM_CHECK_VERSION(major,minor) \
77         ((LLVM_MAJOR_VERSION > (major)) ||                                                                      \
78          ((LLVM_MAJOR_VERSION == (major)) && (LLVM_MINOR_VERSION >= (minor))))
79 #else
80 #define LLVM_CHECK_VERSION(major,minor) 0
81 #endif
82
83 /* 
84  * Whenever we are using mono's LLVM branch.
85  * This can be used in if statements, code which references new definitions from the branch
86  * still needs an #ifdef LLVM_MONO_BRANCH.
87  */
88 #ifdef LLVM_MONO_BRANCH
89 #define IS_LLVM_MONO_BRANCH 1
90 #else
91 #define IS_LLVM_MONO_BRANCH 0
92 #endif
93
94 #define NOT_IMPLEMENTED do { g_assert_not_reached (); } while (0)
95
96 /* for 32 bit systems */
97 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
98 #define MINI_LS_WORD_IDX 0
99 #define MINI_MS_WORD_IDX 1
100 #else
101 #define MINI_LS_WORD_IDX 1
102 #define MINI_MS_WORD_IDX 0
103 #endif
104 #define MINI_LS_WORD_OFFSET (MINI_LS_WORD_IDX * 4)
105 #define MINI_MS_WORD_OFFSET (MINI_MS_WORD_IDX * 4)
106 #define inst_ls_word data.op[MINI_LS_WORD_IDX].const_val
107 #define inst_ms_word data.op[MINI_MS_WORD_IDX].const_val
108
109 #ifndef DISABLE_AOT
110 #define MONO_USE_AOT_COMPILER
111 #endif
112
113 /* Version number of the AOT file format */
114 #define MONO_AOT_FILE_VERSION 75
115
116 //TODO: This is x86/amd64 specific.
117 #define mono_simd_shuffle_mask(a,b,c,d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6))
118
119 /* Constants used to encode different types of methods in AOT */
120 enum {
121         MONO_AOT_METHODREF_MIN = 240,
122         /* Method encoded using its name */
123         MONO_AOT_METHODREF_WRAPPER_NAME = 250,
124         /* Runtime provided methods on arrays */
125         MONO_AOT_METHODREF_ARRAY = 251,
126         MONO_AOT_METHODREF_NO_AOT_TRAMPOLINE = 252,
127         /* Wrappers */
128         MONO_AOT_METHODREF_WRAPPER = 253,
129         /* Methods on generic instances */
130         MONO_AOT_METHODREF_GINST = 254,
131         /* Methods resolve using a METHODSPEC token */
132         MONO_AOT_METHODREF_METHODSPEC = 255,
133 };
134
135 /* Trampolines which we have a lot of */
136 typedef enum {
137         MONO_AOT_TRAMP_SPECIFIC = 0,
138         MONO_AOT_TRAMP_STATIC_RGCTX = 1,
139         MONO_AOT_TRAMP_IMT_THUNK = 2,
140         MONO_AOT_TRAMP_NUM = 3
141 } MonoAotTrampoline;
142
143 typedef enum {
144         MONO_AOT_FILE_FLAG_WITH_LLVM = 1,
145         MONO_AOT_FILE_FLAG_FULL_AOT = 2,
146         MONO_AOT_FILE_FLAG_DEBUG = 4
147 } MonoAotFileFlags;
148
149 /* This structure is stored in the AOT file */
150 typedef struct MonoAotFileInfo
151 {
152         /* The version number of the AOT file format, should match MONO_AOT_FILE_VERSION */
153         guint32 version;
154         /* For alignment */
155         guint32 dummy;
156
157         /* All the pointers should be at the start to avoid alignment problems */
158
159         /* Mono's Global Offset Table */
160         gpointer got;
161         /* Compiled code for methods */
162         gpointer methods;
163         /* Mono EH Frame created by llc when using LLVM */
164         gpointer mono_eh_frame;
165         /* Data blob */
166         gpointer blob;
167         gpointer class_name_table;
168         gpointer class_info_offsets;
169         gpointer method_info_offsets;
170         gpointer ex_info_offsets;
171         gpointer code_offsets;
172         gpointer extra_method_info_offsets;
173         gpointer extra_method_table;
174         gpointer got_info_offsets;
175         gpointer methods_end;
176         gpointer unwind_info;
177         gpointer mem_end;
178         gpointer image_table;
179         /* Start of Mono's Program Linkage Table */
180         gpointer plt;
181         /* End of Mono's Program Linkage Table */
182         gpointer plt_end;
183         /* The GUID of the assembly which the AOT image was generated from */
184         gpointer assembly_guid;
185         /*
186          * The runtime version string for AOT images generated using 'bind-to-runtime-version',
187          * NULL otherwise.
188          */
189         gpointer runtime_version;
190         /* Blocks of various kinds of trampolines */
191         gpointer specific_trampolines;
192         gpointer static_rgctx_trampolines;
193         gpointer imt_thunks;
194         /*
195          * The end of LLVM generated thumb code, or NULL.
196          */
197         gpointer thumb_end;
198         /* In static mode, points to a table of global symbols for trampolines etc */
199         gpointer globals;
200         /* Points to a string containing the assembly name*/
201         gpointer assembly_name;
202
203         /* The index of the first GOT slot used by the PLT */
204         guint32 plt_got_offset_base;
205         /* Number of entries in the GOT */
206         guint32 got_size;
207         /* Number of entries in the PLT */
208         guint32 plt_size;
209         /* Number of methods */
210         guint32 nmethods;
211         /* A union of MonoAotFileFlags */
212         guint32 flags;
213         /* Optimization flags used to compile the module */
214         guint32 opts;
215         /* Index of the blob entry holding the GC used by this module */
216         gint32 gc_name_index;
217
218         /* Number of trampolines */
219         guint32 num_trampolines [MONO_AOT_TRAMP_NUM];
220         /* The indexes of the first GOT slots used by the trampolines */
221         guint32 trampoline_got_offset_base [MONO_AOT_TRAMP_NUM];
222         /* The size of one trampoline */
223         guint32 trampoline_size [MONO_AOT_TRAMP_NUM];
224
225         /* These are used for sanity checking object layout problems when cross-compiling */
226         guint32 double_align, long_align;
227 } MonoAotFileInfo;
228
229 /* Per-domain information maintained by the JIT */
230 typedef struct
231 {
232         /* Maps MonoMethod's to a GSList of GOT slot addresses pointing to its code */
233         GHashTable *jump_target_got_slot_hash;
234         GHashTable *jump_target_hash;
235         /* Maps methods/klasses to the address of the given type of trampoline */
236         GHashTable *class_init_trampoline_hash;
237         GHashTable *jump_trampoline_hash;
238         GHashTable *jit_trampoline_hash;
239         GHashTable *delegate_trampoline_hash;
240         GHashTable *static_rgctx_trampoline_hash;
241         GHashTable *llvm_vcall_trampoline_hash;
242         /* maps MonoMethod -> MonoJitDynamicMethodInfo */
243         GHashTable *dynamic_code_hash;
244         GHashTable *method_code_hash;
245         /* Maps methods to a RuntimeInvokeInfo structure */
246         GHashTable *runtime_invoke_hash;
247         /* Maps MonoMethod to a GPtrArray containing sequence point locations */
248         GHashTable *seq_points;
249         /* Debugger agent data */
250         gpointer agent_info;
251         /* Maps MonoMethod to an arch-specific structure */
252         GHashTable *arch_seq_points;
253 } MonoJitDomainInfo;
254
255 typedef struct {
256         MonoJitInfo *ji;
257         MonoCodeManager *code_mp;
258 } MonoJitDynamicMethodInfo;
259
260 #define domain_jit_info(domain) ((MonoJitDomainInfo*)((domain)->runtime_info))
261
262 /* Contains a list of ips which needs to be patched when a method is compiled */
263 typedef struct {
264         GSList *list;
265 } MonoJumpList;
266
267 /* Arch-specific */
268 typedef struct {
269         int dummy;
270 } MonoDynCallInfo;
271
272 /*
273  * Information about a stack frame.
274  * FIXME This typedef exists only to avoid tons of code rewriting
275  */
276 typedef MonoStackFrameInfo StackFrameInfo;
277
278 typedef struct {
279         int il_offset, native_offset;
280         /* Indexes of successor sequence points */
281         int *next;
282         /* Number of entries in next */
283         int next_len;
284 } SeqPoint;
285
286 typedef struct {
287         int len;
288         SeqPoint seq_points [MONO_ZERO_LEN_ARRAY];
289 } MonoSeqPointInfo;
290
291 #if 0
292 #define mono_bitset_foreach_bit(set,b,n) \
293         for (b = 0; b < n; b++)\
294                 if (mono_bitset_test_fast(set,b))
295 #define mono_bitset_foreach_bit_rev(set,b,n) \
296         for (b = n - 1; b >= 0; b--)\
297                 if (mono_bitset_test_fast(set,b))
298 #else
299 #define mono_bitset_foreach_bit(set,b,n) \
300         for (b = mono_bitset_find_start (set); b < n && b >= 0; b = mono_bitset_find_first (set, b))
301 #define mono_bitset_foreach_bit_rev(set,b,n) \
302         for (b = mono_bitset_find_last (set, n - 1); b >= 0; b = b ? mono_bitset_find_last (set, b) : -1)
303  
304 #endif
305
306 /*
307  * Pull the list of opcodes
308  */
309 #define OPDEF(a,b,c,d,e,f,g,h,i,j) \
310         a = i,
311
312 enum {
313 #include "mono/cil/opcode.def"
314         CEE_LASTOP
315 };
316 #undef OPDEF
317
318 #define MONO_VARINFO(cfg,varnum) (&(cfg)->vars [varnum])
319
320 #define MONO_INST_NULLIFY_SREGS(dest) do {                              \
321                 (dest)->sreg1 = (dest)->sreg2 = (dest)->sreg3 = -1;     \
322         } while (0)
323
324 #define MONO_INST_NEW(cfg,dest,op) do { \
325                 (dest) = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoInst));       \
326                 (dest)->opcode = (op);  \
327                 (dest)->dreg = -1;                          \
328                 MONO_INST_NULLIFY_SREGS ((dest));           \
329         (dest)->cil_code = (cfg)->ip;  \
330         } while (0)
331
332 #define MONO_INST_NEW_CALL(cfg,dest,op) do {    \
333                 (dest) = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoCallInst));   \
334                 (dest)->inst.opcode = (op);     \
335                 (dest)->inst.dreg = -1;                                 \
336                 MONO_INST_NULLIFY_SREGS (&(dest)->inst);                \
337         (dest)->inst.cil_code = (cfg)->ip;  \
338         } while (0)
339
340 #define MONO_INST_NEW_CALL_ARG(cfg,dest,op) do {        \
341                 (dest) = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoCallArgParm));        \
342                 (dest)->ins.opcode = (op);      \
343         } while (0)
344
345 #define MONO_ADD_INS(b,inst) do {       \
346                 if ((b)->last_ins) {    \
347                         (b)->last_ins->next = (inst);   \
348             (inst)->prev = (b)->last_ins;   \
349                         (b)->last_ins = (inst); \
350                 } else {        \
351                         (b)->code = (b)->last_ins = (inst);     \
352                 }       \
353         } while (0)
354
355 #define NULLIFY_INS(ins) do { \
356         (ins)->opcode = OP_NOP; \
357         (ins)->dreg = -1;                               \
358         MONO_INST_NULLIFY_SREGS ((ins));                \
359     } while (0)
360
361 /* Remove INS from BB */
362 #define MONO_REMOVE_INS(bb,ins) do { \
363         if ((ins)->prev) \
364             (ins)->prev->next = (ins)->next; \
365         if ((ins)->next) \
366             (ins)->next->prev = (ins)->prev; \
367         if ((bb)->code == (ins)) \
368             (bb)->code = (ins)->next; \
369         if ((bb)->last_ins == (ins)) \
370             (bb)->last_ins = (ins)->prev; \
371     } while (0)
372
373 /* Remove INS from BB and nullify it */
374 #define MONO_DELETE_INS(bb,ins) do { \
375         MONO_REMOVE_INS ((bb), (ins)); \
376         NULLIFY_INS ((ins)); \
377     } while (0)
378
379 /* 
380  * this is used to determine when some branch optimizations are possible: we exclude FP compares
381  * because they have weird semantics with NaNs.
382  */
383 #define MONO_IS_COND_BRANCH_OP(ins) (((ins)->opcode >= OP_LBEQ && (ins)->opcode <= OP_LBLT_UN) || ((ins)->opcode >= OP_FBEQ && (ins)->opcode <= OP_FBLT_UN) || ((ins)->opcode >= OP_IBEQ && (ins)->opcode <= OP_IBLT_UN))
384 #define MONO_IS_COND_BRANCH_NOFP(ins) (MONO_IS_COND_BRANCH_OP(ins) && !(((ins)->opcode >= OP_FBEQ) && ((ins)->opcode <= OP_FBLT_UN)) && (!(ins)->inst_left || (ins)->inst_left->inst_left->type != STACK_R8))
385
386 #define MONO_IS_BRANCH_OP(ins) (MONO_IS_COND_BRANCH_OP(ins) || ((ins)->opcode == OP_BR) || ((ins)->opcode == OP_BR_REG) || ((ins)->opcode == OP_SWITCH))
387
388 #define MONO_IS_COND_EXC(ins) ((((ins)->opcode >= OP_COND_EXC_EQ) && ((ins)->opcode <= OP_COND_EXC_LT_UN)) || (((ins)->opcode >= OP_COND_EXC_IEQ) && ((ins)->opcode <= OP_COND_EXC_ILT_UN)))
389
390 #define MONO_IS_SETCC(ins) ((((ins)->opcode >= OP_CEQ) && ((ins)->opcode <= OP_CLT_UN)) || (((ins)->opcode >= OP_ICEQ) && ((ins)->opcode <= OP_ICLT_UN)) || (((ins)->opcode >= OP_LCEQ) && ((ins)->opcode <= OP_LCLT_UN)) || (((ins)->opcode >= OP_FCEQ) && ((ins)->opcode <= OP_FCLT_UN)))
391
392
393 #define MONO_IS_LOAD_MEMBASE(ins) (((ins)->opcode >= OP_LOAD_MEMBASE) && ((ins)->opcode <= OP_LOADV_MEMBASE))
394 #define MONO_IS_STORE_MEMBASE(ins) (((ins)->opcode >= OP_STORE_MEMBASE_REG) && ((ins)->opcode <= OP_STOREV_MEMBASE))
395 #define MONO_IS_STORE_MEMINDEX(ins) (((ins)->opcode >= OP_STORE_MEMINDEX) && ((ins)->opcode <= OP_STORER8_MEMINDEX))
396
397 #define MONO_IS_CALL(ins) (((ins->opcode >= OP_VOIDCALL) && (ins->opcode <= OP_VOIDCALL_MEMBASE)) || ((ins->opcode >= OP_FCALL) && (ins->opcode <= OP_FCALL_MEMBASE)) || ((ins->opcode >= OP_LCALL) && (ins->opcode <= OP_LCALL_MEMBASE)) || ((ins->opcode >= OP_VCALL) && (ins->opcode <= OP_VCALL_MEMBASE)) || ((ins->opcode >= OP_CALL) && (ins->opcode <= OP_CALL_MEMBASE)) || ((ins->opcode >= OP_VCALL2) && (ins->opcode <= OP_VCALL2_MEMBASE)) || (ins->opcode == OP_TAILCALL))
398
399 #define MONO_IS_JUMP_TABLE(ins) (((ins)->opcode == OP_JUMP_TABLE) ? TRUE : ((((ins)->opcode == OP_AOTCONST) && (ins->inst_i1 == (gpointer)MONO_PATCH_INFO_SWITCH)) ? TRUE : ((ins)->opcode == OP_SWITCH) ? TRUE : ((((ins)->opcode == OP_GOT_ENTRY) && ((ins)->inst_right->inst_i1 == (gpointer)MONO_PATCH_INFO_SWITCH)) ? TRUE : FALSE)))
400
401 #define MONO_JUMP_TABLE_FROM_INS(ins) (((ins)->opcode == OP_JUMP_TABLE) ? (ins)->inst_p0 : (((ins)->opcode == OP_AOTCONST) && (ins->inst_i1 == (gpointer)MONO_PATCH_INFO_SWITCH) ? (ins)->inst_p0 : (((ins)->opcode == OP_SWITCH) ? (ins)->inst_p0 : ((((ins)->opcode == OP_GOT_ENTRY) && ((ins)->inst_right->inst_i1 == (gpointer)MONO_PATCH_INFO_SWITCH)) ? (ins)->inst_right->inst_p0 : NULL))))
402
403 /* FIXME: Add more instructions */
404 #define MONO_INS_HAS_NO_SIDE_EFFECT(ins) (MONO_IS_MOVE (ins) || (ins->opcode == OP_ICONST) || (ins->opcode == OP_I8CONST) || MONO_IS_ZERO (ins) || (ins->opcode == OP_ADD_IMM) || (ins->opcode == OP_R8CONST) || (ins->opcode == OP_LADD_IMM) || (ins->opcode == OP_ISUB_IMM) || (ins->opcode == OP_IADD_IMM) || (ins->opcode == OP_INEG) || (ins->opcode == OP_LNEG) || (ins->opcode == OP_ISUB) || (ins->opcode == OP_CMOV_IGE) || (ins->opcode == OP_ISHL_IMM) || (ins->opcode == OP_ISHR_IMM) || (ins->opcode == OP_ISHR_UN_IMM) || (ins->opcode == OP_IAND_IMM) || (ins->opcode == OP_ICONV_TO_U1) || (ins->opcode == OP_ICONV_TO_I1) || (ins->opcode == OP_SEXT_I4) || (ins->opcode == OP_LCONV_TO_U1) || (ins->opcode == OP_ICONV_TO_U2) || (ins->opcode == OP_ICONV_TO_I2) || (ins->opcode == OP_LCONV_TO_I2) || (ins->opcode == OP_LDADDR))
405
406 #define MONO_METHOD_IS_FINAL(m) (((m)->flags & METHOD_ATTRIBUTE_FINAL) || ((m)->klass && ((m)->klass->flags & TYPE_ATTRIBUTE_SEALED)))
407
408
409 #ifdef MONO_ARCH_SIMD_INTRINSICS
410
411 #define MONO_IS_PHI(ins) (((ins)->opcode == OP_PHI) || ((ins)->opcode == OP_FPHI) || ((ins)->opcode == OP_VPHI)  || ((ins)->opcode == OP_XPHI))
412 #define MONO_IS_MOVE(ins) (((ins)->opcode == OP_MOVE) || ((ins)->opcode == OP_FMOVE) || ((ins)->opcode == OP_VMOVE) || ((ins)->opcode == OP_XMOVE))
413 #define MONO_IS_NON_FP_MOVE(ins) (((ins)->opcode == OP_MOVE) || ((ins)->opcode == OP_VMOVE) || ((ins)->opcode == OP_XMOVE))
414 #define MONO_IS_REAL_MOVE(ins) (((ins)->opcode == OP_MOVE) || ((ins)->opcode == OP_FMOVE) || ((ins)->opcode == OP_XMOVE))
415 #define MONO_IS_ZERO(ins) (((ins)->opcode == OP_VZERO) || ((ins)->opcode == OP_XZERO))
416
417 #define MONO_CLASS_IS_SIMD(cfg, klass) (((cfg)->opt & MONO_OPT_SIMD) && (klass)->simd_type)
418
419 #else
420
421 #define MONO_IS_PHI(ins) (((ins)->opcode == OP_PHI) || ((ins)->opcode == OP_FPHI) || ((ins)->opcode == OP_VPHI))
422 #define MONO_IS_MOVE(ins) (((ins)->opcode == OP_MOVE) || ((ins)->opcode == OP_FMOVE) || ((ins)->opcode == OP_VMOVE))
423 #define MONO_IS_NON_FP_MOVE(ins) (((ins)->opcode == OP_MOVE) || ((ins)->opcode == OP_VMOVE))
424 /*A real MOVE is one that isn't decomposed such as a VMOVE or LMOVE*/
425 #define MONO_IS_REAL_MOVE(ins) (((ins)->opcode == OP_MOVE) || ((ins)->opcode == OP_FMOVE))
426 #define MONO_IS_ZERO(ins) ((ins)->opcode == OP_VZERO)
427
428 #define MONO_CLASS_IS_SIMD(cfg, klass) (0)
429
430 #endif
431
432 typedef struct MonoInstList MonoInstList;
433 typedef struct MonoInst MonoInst;
434 typedef struct MonoCallInst MonoCallInst;
435 typedef struct MonoCallArgParm MonoCallArgParm;
436 typedef struct MonoMethodVar MonoMethodVar;
437 typedef struct MonoBasicBlock MonoBasicBlock;
438 typedef struct MonoLMF MonoLMF;
439 typedef struct MonoSpillInfo MonoSpillInfo;
440 typedef struct MonoTraceSpec MonoTraceSpec;
441
442 extern guint32 mono_jit_tls_id;
443 extern MonoTraceSpec *mono_jit_trace_calls;
444 extern gboolean mono_break_on_exc;
445 extern int mono_exc_esp_offset;
446 extern gboolean mono_compile_aot;
447 extern gboolean mono_aot_only;
448 extern gboolean mono_use_imt;
449 extern MonoMethodDesc *mono_inject_async_exc_method;
450 extern int mono_inject_async_exc_pos;
451 extern MonoMethodDesc *mono_break_at_bb_method;
452 extern int mono_break_at_bb_bb_num;
453 extern gboolean check_for_pending_exc;
454 extern gboolean disable_vtypes_in_regs;
455 extern gboolean mono_verify_all;
456 extern gboolean mono_dont_free_global_codeman;
457 extern gboolean mono_do_x86_stack_align;
458 extern const char *mono_build_date;
459 extern gboolean mono_do_signal_chaining;
460 extern gboolean mono_use_llvm;
461
462 #define INS_INFO(opcode) (&ins_info [((opcode) - OP_START - 1) * 4])
463
464 extern const char ins_info[];
465 extern const gint8 ins_sreg_counts [];
466
467 #define mono_inst_get_num_src_registers(ins) (ins_sreg_counts [(ins)->opcode - OP_START - 1])
468 #define mono_inst_get_src_registers(ins, regs) (((regs) [0] = (ins)->sreg1), ((regs) [1] = (ins)->sreg2), ((regs) [2] = (ins)->sreg3), mono_inst_get_num_src_registers ((ins)))
469
470 #define MONO_BB_FOR_EACH_INS(bb, ins) for ((ins) = (bb)->code; (ins); (ins) = (ins)->next)
471
472 #define MONO_BB_FOR_EACH_INS_SAFE(bb, n, ins) for ((ins) = (bb)->code, n = (ins) ? (ins)->next : NULL; (ins); (ins) = (n), (n) = (ins) ? (ins)->next : NULL)
473
474 #define MONO_BB_FOR_EACH_INS_REVERSE_SAFE(bb, p, ins) for ((ins) = (bb)->last_ins, p = (ins) ? (ins)->prev : NULL; (ins); (ins) = (p), (p) = (ins) ? (ins)->prev : NULL)
475
476 #define mono_bb_first_ins(bb) (bb)->code
477
478 struct MonoSpillInfo {
479         int offset;
480 };
481
482 /*
483  * Information about a call site for the GC map creation code
484  */
485 typedef struct {
486         /* The next offset after the call instruction */
487         int pc_offset;
488         /* The basic block containing the call site */
489         MonoBasicBlock *bb;
490         /* 
491          * The set of variables live at the call site.
492          * Has length cfg->num_varinfo in bits.
493          */
494         guint8 *liveness;
495         /*
496          * List of OP_GC_PARAM_SLOT_LIVENESS_DEF instructions defining the param slots
497          * used by this call.
498          */
499         GSList *param_slots;
500 } GCCallSite;
501
502 /*
503  * The IR-level extended basic block.  
504  *
505  * A basic block can have multiple exits just fine, as long as the point of
506  * 'departure' is the last instruction in the basic block. Extended basic
507  * blocks, on the other hand, may have instructions that leave the block
508  * midstream. The important thing is that they cannot be _entered_
509  * midstream, ie, execution of a basic block (or extened bb) always start
510  * at the beginning of the block, never in the middle.
511  */
512 struct MonoBasicBlock {
513         MonoInst *last_ins;
514
515         /* the next basic block in the order it appears in IL */
516         MonoBasicBlock *next_bb;
517
518         /*
519          * Before instruction selection it is the first tree in the
520          * forest and the first item in the list of trees. After
521          * instruction selection it is the first instruction and the
522          * first item in the list of instructions.
523          */
524         MonoInst *code;
525
526         /* unique block number identification */
527         gint32 block_num;
528         
529         gint32 dfn;
530
531         /* Basic blocks: incoming and outgoing counts and pointers */
532         /* Each bb should only appear once in each array */
533         gint16 out_count, in_count;
534         MonoBasicBlock **in_bb;
535         MonoBasicBlock **out_bb;
536
537         /* Points to the start of the CIL code that initiated this BB */
538         unsigned char* cil_code;
539
540         /* Length of the CIL block */
541         gint32 cil_length;
542
543         /* The offset of the generated code, used for fixups */
544         int native_offset;
545         /* The length of the generated code, doesn't include alignment padding */
546         int native_length;
547         /* The real native offset, which includes alignment padding too */
548         int real_native_offset;
549         int max_offset;
550         int max_length;
551
552         /* Visited and reachable flags */
553         guint32 flags;
554
555         /*
556          * SSA and loop based flags
557          */
558         MonoBitSet *dominators;
559         MonoBitSet *dfrontier;
560         MonoBasicBlock *idom;
561         GSList *dominated;
562         /* fast dominator algorithm */
563         MonoBasicBlock *df_parent, *ancestor, *child, *label;
564         int size, sdom, idomn;
565         
566         /* loop nesting and recognition */
567         GList *loop_blocks;
568         gint8  nesting;
569         gint8  loop_body_start;
570
571         /* 
572          * Whenever the bblock is rarely executed so it should be emitted after
573          * the function epilog.
574          */
575         guint out_of_line : 1;
576         /* Caches the result of uselessness calculation during optimize_branches */
577         guint not_useless : 1;
578         /* Whenever the decompose_array_access_opts () pass needs to process this bblock */
579         guint has_array_access : 1;
580         /* Whenever this bblock is extended, ie. it has branches inside it */
581         guint extended : 1;
582         /* Whenever this bblock contains a OP_JUMP_TABLE instruction */
583         guint has_jump_table : 1;
584         /* Whenever this bblock contains an OP_CALL_HANDLER instruction */
585         guint has_call_handler : 1;
586         /* Whenever this bblock starts a try block */
587         guint try_start : 1;
588         /*
589          * If this is set, extend the try range started by this bblock by an arch specific
590          * number of bytes to encompass the end of the previous bblock (e.g. a Monitor.Enter
591          * call).
592          */
593         guint extend_try_block : 1;
594         
595         /* use for liveness analysis */
596         MonoBitSet *gen_set;
597         MonoBitSet *kill_set;
598         MonoBitSet *live_in_set;
599         MonoBitSet *live_out_set;
600
601         /* fields to deal with non-empty stack slots at bb boundary */
602         guint16 out_scount, in_scount;
603         MonoInst **out_stack;
604         MonoInst **in_stack;
605
606         /* we use that to prevent merging of bblocks covered by different clauses*/
607         guint real_offset;
608
609         GSList *seq_points;
610         MonoInst *last_seq_point;
611
612         GSList *spill_slot_defs;
613
614         /* List of call sites in this bblock sorted by pc_offset */
615         GSList *gc_callsites;
616
617         /*
618          * The region encodes whether the basic block is inside
619          * a finally, catch, filter or none of these.
620          *
621          * If the value is -1, then it is neither finally, catch nor filter
622          *
623          * Otherwise the format is:
624          *
625          *  Bits: |     0-3      |       4-7      |     8-31
626          *        |              |                |
627          *        | clause-flags |   MONO_REGION  | clause-index 
628          *
629          */
630         guint region;
631
632         /* The current symbolic register number, used in local register allocation. */
633         guint32 max_vreg;
634 };
635
636 /* BBlock flags */
637 enum {
638         BB_VISITED              = 1 << 0,
639         BB_REACHABLE            = 1 << 1,
640         BB_EXCEPTION_DEAD_OBJ   = 1 << 2,
641         BB_EXCEPTION_UNSAFE     = 1 << 3,
642         BB_EXCEPTION_HANDLER    = 1 << 4,
643         /* for Native Client, mark the blocks that can be jumped to indirectly */
644         BB_INDIRECT_JUMP_TARGET = 1 << 5 
645 };
646
647 typedef struct MonoMemcpyArgs {
648         int size, align;
649 } MonoMemcpyArgs;
650
651 typedef enum {
652         LLVMArgNone,
653         LLVMArgInIReg,
654         LLVMArgInFPReg,
655         LLVMArgVtypeInReg,
656         LLVMArgVtypeByVal,
657         LLVMArgVtypeRetAddr /* On on cinfo->ret */
658 } LLVMArgStorage;
659
660 typedef struct {
661         LLVMArgStorage storage;
662
663         /* Only if storage == ArgValuetypeInReg */
664         LLVMArgStorage pair_storage [2];
665 } LLVMArgInfo;
666
667 typedef struct {
668         LLVMArgInfo ret;
669         /* Whenever there is an rgctx argument */
670         gboolean rgctx_arg;
671         /* Whenever there is an IMT argument */
672         gboolean imt_arg;
673         /* 
674          * The position of the vret arg in the argument list.
675          * Only if ret->storage == ArgVtypeRetAddr.
676          * Should be 0 or 1.
677          */
678         int vret_arg_index;
679         /* args [0] is for the this argument if it exists */
680         LLVMArgInfo args [1];
681 } LLVMCallInfo;
682
683 #define MONO_MAX_SRC_REGS       3
684
685 struct MonoInst {
686         guint16 opcode;
687         guint8  type; /* stack type */
688         guint8  flags;
689         
690         /* used by the register allocator */
691         gint32 dreg, sreg1, sreg2, sreg3;
692
693         MonoInst *next, *prev;
694
695         union {
696                 union {
697                         MonoInst *src;
698                         MonoMethodVar *var;
699                         mgreg_t const_val;
700 #if (SIZEOF_REGISTER > SIZEOF_VOID_P) && (G_BYTE_ORDER == G_BIG_ENDIAN)
701                         struct {
702                                 gpointer p[SIZEOF_REGISTER/SIZEOF_VOID_P];
703                         } pdata;
704 #else
705                         gpointer p;
706 #endif
707                         MonoMethod *method;
708                         MonoMethodSignature *signature;
709                         MonoBasicBlock **many_blocks;
710                         MonoBasicBlock *target_block;
711                         MonoInst **args;
712                         MonoType *vtype;
713                         MonoClass *klass;
714                         int *phi_args;
715                         MonoCallInst *call_inst;
716                         MonoExceptionClause *exception_clause;
717                 } op [2];
718                 gint64 i8const;
719                 double r8const;
720         } data;
721
722         const unsigned char* cil_code; /* for debugging and bblock splitting */
723
724         /* used mostly by the backend to store additional info it may need */
725         union {
726                 gint32 reg3;
727                 gint32 arg_info;
728                 gint32 size;
729                 MonoMemcpyArgs *memcpy_args; /* in OP_MEMSET and OP_MEMCPY */
730                 gpointer data;
731                 gint shift_amount;
732                 gboolean is_pinvoke; /* for variables in the unmanaged marshal format */
733                 gboolean record_cast_details; /* For CEE_CASTCLASS */
734                 MonoInst *spill_var; /* for OP_ICONV_TO_R8_RAW and OP_FCONV_TO_R8_X */
735                 guint16 source_opcode; /*OP_XCONV_R8_TO_I4 needs to know which op was used to do proper widening*/
736                 int pc_offset; /* OP_GC_LIVERANGE_START/END */
737         } backend;
738         
739         MonoClass *klass;
740 };
741         
742 struct MonoCallInst {
743         MonoInst inst;
744         MonoMethodSignature *signature;
745         MonoMethod *method;
746         MonoInst **args;
747         MonoInst *out_args;
748         MonoInst *vret_var;
749         gconstpointer fptr;
750         guint stack_usage;
751         guint virtual : 1;
752         guint tail_call : 1;
753         /* If this is TRUE, 'fptr' points to a MonoJumpInfo instead of an address. */
754         guint fptr_is_patch : 1;
755         /*
756          * If this is true, then the call returns a vtype in a register using the same 
757          * calling convention as OP_CALL.
758          */
759         guint vret_in_reg : 1;
760         /* Whenever there is an IMT argument and it is dynamic */
761         guint dynamic_imt_arg : 1;
762         /* Whenever there is an RGCTX argument */
763         guint32 rgctx_reg : 1;
764         regmask_t used_iregs;
765         regmask_t used_fregs;
766         GSList *out_ireg_args;
767         GSList *out_freg_args;
768         GSList *outarg_vts;
769 #ifdef ENABLE_LLVM
770         LLVMCallInfo *cinfo;
771         int rgctx_arg_reg, imt_arg_reg;
772 #endif
773 };
774
775 struct MonoCallArgParm {
776         MonoInst ins;
777         gint32 size;
778         gint32 offset;
779         gint32 offPrm;
780 };
781
782 /* 
783  * flags for MonoInst
784  * Note: some of the values overlap, because they can't appear
785  * in the same MonoInst.
786  */
787 enum {
788         MONO_INST_HAS_METHOD = 1,
789         MONO_INST_INIT       = 1, /* in localloc */
790         MONO_INST_SINGLE_STEP_LOC = 1, /* in SEQ_POINT */
791         MONO_INST_IS_DEAD    = 2,
792         MONO_INST_TAILCALL   = 4,
793         MONO_INST_VOLATILE   = 4,
794         MONO_INST_NOTYPECHECK    = 4,
795         MONO_INST_UNALIGNED  = 8,
796     MONO_INST_CFOLD_TAKEN = 8, /* On branches */
797     MONO_INST_CFOLD_NOT_TAKEN = 16, /* On branches */
798         MONO_INST_DEFINITION_HAS_SIDE_EFFECTS = 8,
799         /* the address of the variable has been taken */
800         MONO_INST_INDIRECT   = 16,
801         MONO_INST_NORANGECHECK   = 16,
802         /* On loads, the source address can be null */
803         MONO_INST_FAULT = 32,
804         /* 
805          * On variables, identifies LMF variables. These variables have a dummy type (int), but
806          * require stack space for a MonoLMF struct.
807          */
808         MONO_INST_LMF = 32,
809         /* On loads, the source address points to a constant value */
810         MONO_INST_CONSTANT_LOAD = 64,
811         /* On variables, the variable needs GC tracking */
812         MONO_INST_GC_TRACK = 128,
813         /*
814          * Set on instructions during code emission which make calls, i.e. OP_CALL, OP_THROW.
815          * backend.pc_offset will be set to the pc offset at the end of the native call instructions.
816          */
817         MONO_INST_GC_CALLSITE = 128
818 };
819
820 #define inst_c0 data.op[0].const_val
821 #define inst_c1 data.op[1].const_val
822 #define inst_i0 data.op[0].src
823 #define inst_i1 data.op[1].src
824 #if (SIZEOF_REGISTER > SIZEOF_VOID_P) && (G_BYTE_ORDER == G_BIG_ENDIAN)
825 #define inst_p0 data.op[0].pdata.p[SIZEOF_REGISTER/SIZEOF_VOID_P - 1]
826 #define inst_p1 data.op[1].pdata.p[SIZEOF_REGISTER/SIZEOF_VOID_P - 1]
827 #else
828 #define inst_p0 data.op[0].p
829 #define inst_p1 data.op[1].p
830 #endif
831 #define inst_l  data.i8const
832 #define inst_r  data.r8const
833 #define inst_left  data.op[0].src
834 #define inst_right data.op[1].src
835
836 #define inst_newa_len   data.op[0].src
837 #define inst_newa_class data.op[1].klass
838
839 #define inst_var    data.op[0].var
840 #define inst_vtype  data.op[1].vtype
841 /* in branch instructions */
842 #define inst_many_bb   data.op[1].many_blocks
843 #define inst_target_bb data.op[0].target_block
844 #define inst_true_bb   data.op[1].many_blocks[0]
845 #define inst_false_bb  data.op[1].many_blocks[1]
846
847 #define inst_basereg sreg1
848 #define inst_indexreg sreg2
849 #define inst_destbasereg dreg
850 #define inst_offset data.op[0].const_val
851 #define inst_imm    data.op[1].const_val
852 #define inst_call   data.op[1].call_inst
853
854 #define inst_phi_args   data.op[1].phi_args
855 #define inst_eh_block    data.op[1].exception_clause
856
857 /* instruction description for use in regalloc/scheduling */
858 enum {
859         MONO_INST_DEST,
860         MONO_INST_SRC1,         /* we depend on the SRCs to be consecutive */
861         MONO_INST_SRC2,
862         MONO_INST_SRC3,
863         MONO_INST_LEN,
864         MONO_INST_CLOB,
865         /* Unused, commented out to reduce the size of the mdesc tables
866         MONO_INST_FLAGS,
867         MONO_INST_COST,
868         MONO_INST_DELAY,
869         MONO_INST_RES,
870         */
871         MONO_INST_MAX
872 };
873
874 typedef union {
875         struct {
876                 guint16 tid; /* tree number */
877                 guint16 bid; /* block number */
878         } pos ;
879         guint32 abs_pos; 
880 } MonoPosition;
881
882 typedef struct {
883         MonoPosition first_use, last_use;
884 } MonoLiveRange;
885
886 typedef struct MonoLiveRange2 MonoLiveRange2;
887
888 struct MonoLiveRange2 {
889         int from, to;
890         MonoLiveRange2 *next;
891 };
892
893 typedef struct {
894         /* List of live ranges sorted by 'from' */
895         MonoLiveRange2 *range;
896         MonoLiveRange2 *last_range;
897 } MonoLiveInterval;
898
899 /*
900  * Additional information about a variable
901  */
902 struct MonoMethodVar {
903         guint           idx; /* inside cfg->varinfo, cfg->vars */
904         MonoLiveRange   range; /* generated by liveness analysis */
905         MonoLiveInterval *interval; /* generated by liveness analysis */
906         int             reg; /* != -1 if allocated into a register */
907         int             spill_costs;
908         MonoBitSet     *def_in; /* used by SSA */
909         MonoInst       *def;    /* used by SSA */
910         MonoBasicBlock *def_bb; /* used by SSA */
911         GList          *uses;   /* used by SSA */
912         char            cpstate;  /* used by SSA conditional  constant propagation */
913         /* The native offsets corresponding to the live range of the variable */
914         gint32         live_range_start, live_range_end;
915         /* 
916          * cfg->varinfo [idx]->dreg could be replaced for OP_REGVAR, this contains the 
917          * original vreg.
918          */
919         gint32         vreg;
920 };
921
922 /*
923  * Stores state need to resume exception handling when using LLVM
924  */
925 typedef struct {
926         MonoJitInfo *ji;
927         int clause_index;
928         MonoContext ctx, new_ctx;
929         /* FIXME: GC */
930         gpointer        ex_obj;
931         MonoLMF *lmf;
932         int first_filter_idx, filter_idx;
933 } ResumeState;
934
935 typedef struct {
936         gpointer          end_of_stack;
937         guint32           stack_size;
938 #if !defined(HAVE_KW_THREAD) || !defined(MONO_ARCH_ENABLE_MONO_LMF_VAR)
939         MonoLMF          *lmf;
940 #endif
941         MonoLMF          *first_lmf;
942         gpointer         restore_stack_prot;
943         guint32          handling_stack_ovf;
944         gpointer         signal_stack;
945         guint32          signal_stack_size;
946         gpointer         stack_ovf_guard_base;
947         guint32          stack_ovf_guard_size;
948         guint            stack_ovf_valloced : 1;
949         void            (*abort_func) (MonoObject *object);
950         /* Used to implement --debug=casts */
951         MonoClass       *class_cast_from, *class_cast_to;
952
953         /* Stores state needed by handler block with a guard */
954         MonoContext     ex_ctx;
955         ResumeState resume_state;
956
957         /*Variabled use to implement handler blocks (finally/catch/etc) guards during interruption*/
958         /* handler block return address */
959         gpointer handler_block_return_address;
960
961         /* handler block been guarded. It's safe to store this even for dynamic methods since there
962         is an activation on stack making sure it will remain alive.*/
963         MonoJitExceptionInfo *handler_block;
964
965         /* context to be used by the guard trampoline when resuming interruption.*/
966         MonoContext handler_block_context;
967         /* 
968          * Stores the state at the exception throw site to be used by mono_stack_walk ()
969          * when it is called from profiler functions during exception handling.
970          */
971         MonoContext orig_ex_ctx;
972         gboolean orig_ex_ctx_set;
973 } MonoJitTlsData;
974
975 /*
976  * This structure is an extension of MonoLMF and contains extra information.
977  */
978 typedef struct {
979         struct MonoLMF lmf;
980         gboolean debugger_invoke;
981         MonoContext ctx; /* if debugger_invoke is TRUE */
982 } MonoLMFExt;
983
984 typedef enum {
985 #define PATCH_INFO(a,b) MONO_PATCH_INFO_ ## a,
986 #include "patch-info.h"
987 #undef PATCH_INFO
988         MONO_PATCH_INFO_NUM
989 } MonoJumpInfoType;
990
991 /*
992  * We need to store the image which the token refers to along with the token,
993  * since the image might not be the same as the image of the method which
994  * contains the relocation, because of inlining.
995  */
996 typedef struct MonoJumpInfoToken {
997         MonoImage *image;
998         guint32 token;
999         gboolean has_context;
1000         MonoGenericContext context;
1001 } MonoJumpInfoToken;
1002
1003 typedef struct MonoJumpInfoBBTable {
1004         MonoBasicBlock **table;
1005         int table_size;
1006 } MonoJumpInfoBBTable;
1007
1008 typedef struct MonoJumpInfoRgctxEntry MonoJumpInfoRgctxEntry;
1009
1010 /* Contains information describing an LLVM IMT trampoline */
1011 typedef struct MonoJumpInfoImtTramp {
1012         MonoMethod *method;
1013         int vt_offset;
1014 } MonoJumpInfoImtTramp;
1015
1016 typedef struct MonoJumpInfo MonoJumpInfo;
1017 struct MonoJumpInfo {
1018         MonoJumpInfo *next;
1019         union {
1020                 int i;
1021                 guint8 *p;
1022                 MonoInst *label;
1023         } ip;
1024
1025         MonoJumpInfoType type;
1026         union {
1027                 gconstpointer   target;
1028 #if SIZEOF_VOID_P == 8
1029                 gint64          offset;
1030 #else
1031                 int             offset;
1032 #endif
1033                 MonoBasicBlock *bb;
1034                 MonoInst       *inst;
1035                 MonoMethod     *method;
1036                 MonoClass      *klass;
1037                 MonoClassField *field;
1038                 MonoImage      *image;
1039                 MonoVTable     *vtable;
1040                 const char     *name;
1041                 MonoJumpInfoToken  *token;
1042                 MonoJumpInfoBBTable *table;
1043                 MonoJumpInfoRgctxEntry *rgctx_entry;
1044                 MonoJumpInfoImtTramp *imt_tramp;
1045         } data;
1046 };
1047  
1048 /* Contains information describing an rgctx entry */
1049 struct MonoJumpInfoRgctxEntry {
1050         MonoMethod *method;
1051         gboolean in_mrgctx;
1052         MonoJumpInfo *data; /* describes the data to be loaded */
1053         int info_type;
1054 };
1055
1056 typedef enum {
1057         MONO_TRAMPOLINE_JIT,
1058         MONO_TRAMPOLINE_JUMP,
1059         MONO_TRAMPOLINE_CLASS_INIT,
1060         MONO_TRAMPOLINE_GENERIC_CLASS_INIT,
1061         MONO_TRAMPOLINE_RGCTX_LAZY_FETCH,
1062         MONO_TRAMPOLINE_AOT,
1063         MONO_TRAMPOLINE_AOT_PLT,
1064         MONO_TRAMPOLINE_DELEGATE,
1065         MONO_TRAMPOLINE_RESTORE_STACK_PROT,
1066         MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING,
1067         MONO_TRAMPOLINE_MONITOR_ENTER,
1068         MONO_TRAMPOLINE_MONITOR_EXIT,
1069         MONO_TRAMPOLINE_VCALL,
1070 #ifdef MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD
1071         MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD,
1072 #endif
1073         MONO_TRAMPOLINE_NUM
1074 } MonoTrampolineType;
1075
1076 #define MONO_TRAMPOLINE_TYPE_MUST_RETURN(t)             \
1077         ((t) == MONO_TRAMPOLINE_CLASS_INIT ||           \
1078          (t) == MONO_TRAMPOLINE_GENERIC_CLASS_INIT ||   \
1079          (t) == MONO_TRAMPOLINE_RESTORE_STACK_PROT ||   \
1080          (t) == MONO_TRAMPOLINE_RGCTX_LAZY_FETCH ||     \
1081          (t) == MONO_TRAMPOLINE_MONITOR_ENTER ||        \
1082          (t) == MONO_TRAMPOLINE_MONITOR_EXIT)
1083
1084 /* optimization flags */
1085 #define OPTFLAG(id,shift,name,descr) MONO_OPT_ ## id = 1 << shift,
1086 enum {
1087 #include "optflags-def.h"
1088         MONO_OPT_LAST
1089 };
1090
1091 /* Bit-fields in the MonoBasicBlock.region */
1092 #define MONO_REGION_TRY       0
1093 #define MONO_REGION_FINALLY  16
1094 #define MONO_REGION_CATCH    32
1095 #define MONO_REGION_FAULT    64         /* Currently unused */
1096 #define MONO_REGION_FILTER  128
1097
1098 #define MONO_BBLOCK_IS_IN_REGION(bblock, regtype) (((bblock)->region & (0xf << 4)) == (regtype))
1099
1100 #define MONO_REGION_FLAGS(region) ((region) & 0x7)
1101
1102 #define get_vreg_to_inst(cfg, vreg) ((vreg) < (cfg)->vreg_to_inst_len ? (cfg)->vreg_to_inst [(vreg)] : NULL)
1103
1104 #define vreg_is_volatile(cfg, vreg) (G_UNLIKELY (get_vreg_to_inst ((cfg), (vreg)) && (get_vreg_to_inst ((cfg), (vreg))->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT))))
1105
1106 #define vreg_is_ref(cfg, vreg) ((vreg) < (cfg)->vreg_is_ref_len ? (cfg)->vreg_is_ref [(vreg)] : 0)
1107 #define vreg_is_mp(cfg, vreg) ((vreg) < (cfg)->vreg_is_mp_len ? (cfg)->vreg_is_mp [(vreg)] : 0)
1108
1109 /*
1110  * Control Flow Graph and compilation unit information
1111  */
1112 typedef struct {
1113         MonoMethod      *method;
1114         MonoMethodHeader *header;
1115         MonoMemPool     *mempool;
1116         MonoInst       **varinfo;
1117         MonoMethodVar   *vars;
1118         MonoInst        *ret;
1119         MonoBasicBlock  *bb_entry;
1120         MonoBasicBlock  *bb_exit;
1121         MonoBasicBlock  *bb_init;
1122         MonoBasicBlock **bblocks;
1123         MonoBasicBlock **cil_offset_to_bb;
1124         MonoMemPool     *state_pool; /* used by instruction selection */
1125         MonoBasicBlock  *cbb;        /* used by instruction selection */
1126         MonoInst        *prev_ins;   /* in decompose */
1127         MonoJumpInfo    *patch_info;
1128         MonoJitInfo     *jit_info;
1129         MonoJitDynamicMethodInfo *dynamic_info;
1130         guint            num_bblocks, max_block_num;
1131         guint            locals_start;
1132         guint            num_varinfo; /* used items in varinfo */
1133         guint            varinfo_count; /* total storage in varinfo */
1134         gint             stack_offset;
1135         gint             max_ireg;
1136         gint             cil_offset_to_bb_len;
1137         MonoRegState    *rs;
1138         MonoSpillInfo   *spill_info [16]; /* machine register spills */
1139         gint             spill_count;
1140         gint             spill_info_len [16];
1141         /* unsigned char   *cil_code; */
1142         MonoMethod      *inlined_method; /* the method which is currently inlined */
1143         MonoInst        *domainvar; /* a cache for the current domain */
1144         MonoInst        *got_var; /* Global Offset Table variable */
1145         MonoInst        **locals;
1146         MonoInst        *rgctx_var; /* Runtime generic context variable (for static generic methods) */
1147         MonoInst        **args;
1148         MonoType        **arg_types;
1149         MonoMethod      *current_method; /* The method currently processed by method_to_ir () */
1150         MonoMethod      *method_to_register; /* The method to register in JIT info tables */
1151         MonoGenericContext *generic_context;
1152
1153         /* 
1154          * This variable represents the hidden argument holding the vtype
1155          * return address. If the method returns something other than a vtype, or
1156          * the vtype is returned in registers this is NULL.
1157          */
1158         MonoInst        *vret_addr;
1159
1160         /*
1161          * This is used to initialize the cil_code field of MonoInst's.
1162          */
1163         const unsigned char *ip;
1164         
1165         struct MonoAliasingInformation *aliasing_info;
1166
1167         /* A hashtable of region ID-> SP var mappings */
1168         /* An SP var is a place to store the stack pointer (used by handlers)*/
1169         GHashTable      *spvars;
1170
1171         /* A hashtable of region ID -> EX var mappings */
1172         /* An EX var stores the exception object passed to catch/filter blocks */
1173         GHashTable      *exvars;
1174
1175         GList           *ldstr_list; /* used by AOT */
1176         
1177         MonoDomain      *domain;
1178
1179         guint            real_offset;
1180         GHashTable      *cbb_hash;
1181
1182         /* The current virtual register number */
1183         guint32 next_vreg;
1184
1185         MonoGenericSharingContext *generic_sharing_context;
1186
1187         unsigned char   *cil_start;
1188 #ifdef __native_client_codegen__
1189         /* this alloc is not aligned, native_code */
1190         /* is the 32-byte aligned version of this */
1191         unsigned char   *native_code_alloc;
1192 #endif
1193         unsigned char   *native_code;
1194         guint            code_size;
1195         guint            code_len;
1196         guint            prolog_end;
1197         guint            epilog_begin;
1198         regmask_t        used_int_regs;
1199         guint32          opt;
1200         guint32          prof_options;
1201         guint32          flags;
1202         guint32          comp_done;
1203         guint32          verbose_level;
1204         guint32          stack_usage;
1205         guint32          param_area;
1206         guint32          frame_reg;
1207         gint32           sig_cookie;
1208         guint            disable_aot : 1;
1209         guint            disable_ssa : 1;
1210         guint            disable_llvm : 1;
1211         guint            enable_extended_bblocks : 1;
1212         guint            run_cctors : 1;
1213         guint            need_lmf_area : 1;
1214         guint            compile_aot : 1;
1215         guint            compile_llvm : 1;
1216         guint            got_var_allocated : 1;
1217         guint            ret_var_is_local : 1;
1218         guint            ret_var_set : 1;
1219         guint            globalra : 1;
1220         guint            unverifiable : 1;
1221         guint            skip_visibility : 1;
1222         guint            disable_reuse_registers : 1;
1223         guint            disable_reuse_stack_slots : 1;
1224         guint            disable_reuse_ref_stack_slots : 1;
1225         guint            disable_ref_noref_stack_slot_share : 1;
1226         guint            disable_initlocals_opt : 1;
1227         guint            disable_initlocals_opt_refs : 1;
1228         guint            disable_omit_fp : 1;
1229         guint            disable_vreg_to_lvreg : 1;
1230         guint            disable_deadce_vars : 1;
1231         guint            disable_out_of_line_bblocks : 1;
1232         guint            gen_write_barriers : 1;
1233         guint            init_ref_vars : 1;
1234         guint            extend_live_ranges : 1;
1235         guint            compute_precise_live_ranges : 1;
1236         guint            has_got_slots : 1;
1237         guint            uses_rgctx_reg : 1;
1238         guint            uses_vtable_reg : 1;
1239         guint            uses_simd_intrinsics : 1;
1240         guint            keep_cil_nops : 1;
1241         guint            gen_seq_points : 1;
1242         guint            explicit_null_checks : 1;
1243         guint            compute_gc_maps : 1;
1244         gpointer         debug_info;
1245         guint32          lmf_offset;
1246     guint16          *intvars;
1247         MonoProfileCoverageInfo *coverage_info;
1248         GHashTable       *token_info_hash;
1249         MonoCompileArch  arch;
1250         guint32          inline_depth;
1251         guint32          exception_type;        /* MONO_EXCEPTION_* */
1252         guint32          exception_data;
1253         char*            exception_message;
1254         gpointer         exception_ptr;
1255
1256         guint8 *         encoded_unwind_ops;
1257         guint32          encoded_unwind_ops_len;
1258         GSList*          unwind_ops;
1259
1260         /* Fields used by the local reg allocator */
1261         void*            reginfo;
1262         int              reginfo_len;
1263
1264         /* Maps vregs to their associated MonoInst's */
1265         /* vregs with an associated MonoInst are 'global' while others are 'local' */
1266         MonoInst **vreg_to_inst;
1267
1268         /* Size of above array */
1269         guint32 vreg_to_inst_len;
1270
1271         /* Marks vregs which hold a GC ref */
1272         /* FIXME: Use a bitmap */
1273         gboolean *vreg_is_ref;
1274
1275         /* Size of above array */
1276         guint32 vreg_is_ref_len;
1277
1278         /* Marks vregs which hold a managed pointer */
1279         /* FIXME: Use a bitmap */
1280         gboolean *vreg_is_mp;
1281
1282         /* Size of above array */
1283         guint32 vreg_is_mp_len;
1284
1285         /* 
1286          * The original method to compile, differs from 'method' when doing generic
1287          * sharing.
1288          */
1289         MonoMethod *orig_method;
1290
1291         /* Patches which describe absolute addresses embedded into the native code */
1292         GHashTable *abs_patches;
1293
1294         /* If the arch passes valuetypes by address, then for methods
1295            which use JMP the arch code should use these local
1296            variables to store the addresses of incoming valuetypes.
1297            The addresses should be stored in mono_arch_emit_prolog()
1298            and can be used when emitting code for OP_JMP.  See
1299            mini-ppc.c. */
1300         MonoInst **tailcall_valuetype_addrs;
1301
1302         /* Used to implement iconv_to_r8_raw on archs that can't do raw
1303         copy between an ireg and a freg. This is an int32 var.*/
1304         MonoInst *iconv_raw_var;
1305
1306         /* Used to implement fconv_to_r8_x. This is a double (8 bytes) var.*/
1307         MonoInst *fconv_to_r8_x_var;
1308
1309         /*Use to implement simd constructors. This is a vector (16 bytes) var.*/
1310         MonoInst *simd_ctor_var;
1311
1312         /* Used to implement dyn_call */
1313         MonoInst *dyn_call_var;
1314
1315         /*
1316          * List of sequence points represented as IL offset+native offset pairs.
1317          * Allocated using glib.
1318          * IL offset can be -1 or 0xffffff to refer to the sequence points
1319          * inside the prolog and epilog used to implement method entry/exit events.
1320          */
1321         GPtrArray *seq_points;
1322
1323         /* The encoded sequence point info */
1324         MonoSeqPointInfo *seq_point_info;
1325
1326         /* Method headers which need to be freed after compilation */
1327         GSList *headers_to_free;
1328
1329         /* Used by AOT */
1330         guint32 got_offset, ex_info_offset, method_info_offset;
1331         /* Symbol used to refer to this method in generated assembly */
1332         char *asm_symbol;
1333         char *llvm_method_name;
1334
1335         MonoJitExceptionInfo *llvm_ex_info;
1336         guint32 llvm_ex_info_len;
1337         int llvm_this_reg, llvm_this_offset;
1338
1339         GSList *try_block_holes;
1340
1341         /* GC Maps */
1342    
1343         /* The offsets of the locals area relative to the frame pointer */
1344         gint locals_min_stack_offset, locals_max_stack_offset;
1345
1346         /* The final CFA rule at the end of the prolog */
1347         int cfa_reg, cfa_offset;
1348
1349         /* Points to a MonoCompileGC */
1350         gpointer gc_info;
1351
1352         /*
1353          * The encoded GC map along with its size. This contains binary data so it can be saved in an AOT
1354          * image etc, but it requires a 4 byte alignment.
1355          */
1356         guint8 *gc_map;
1357         guint32 gc_map_size;
1358 } MonoCompile;
1359
1360 typedef enum {
1361         MONO_CFG_HAS_ALLOCA = 1 << 0,
1362         MONO_CFG_HAS_CALLS  = 1 << 1,
1363         MONO_CFG_HAS_LDELEMA  = 1 << 2,
1364         MONO_CFG_HAS_VARARGS  = 1 << 3,
1365         MONO_CFG_HAS_TAIL     = 1 << 4,
1366         MONO_CFG_HAS_FPOUT    = 1 << 5, /* there are fp values passed in int registers */
1367         MONO_CFG_HAS_SPILLUP  = 1 << 6, /* spill var slots are allocated from bottom to top */
1368         MONO_CFG_HAS_CHECK_THIS  = 1 << 7,
1369         MONO_CFG_HAS_ARRAY_ACCESS = 1 << 8
1370 } MonoCompileFlags;
1371
1372 typedef struct {
1373         gulong methods_compiled;
1374         gulong methods_aot;
1375         gulong methods_lookups;
1376         gulong allocate_var;
1377         gulong cil_code_size;
1378         gulong native_code_size;
1379         gulong code_reallocs;
1380         gulong max_code_size_ratio;
1381         gulong biggest_method_size;
1382         gulong allocated_code_size;
1383         gulong inlineable_methods;
1384         gulong inlined_methods;
1385         gulong basic_blocks;
1386         gulong max_basic_blocks;
1387         gulong locals_stack_size;
1388         gulong regvars;
1389         gulong cas_declsec_check;
1390         gulong cas_linkdemand_icall;
1391         gulong cas_linkdemand_pinvoke;
1392         gulong cas_linkdemand_aptc;
1393         gulong cas_linkdemand;
1394         gulong cas_demand_generation;
1395         gulong generic_virtual_invocations;
1396     int methods_with_llvm;
1397         int methods_without_llvm;
1398         char *max_ratio_method;
1399         char *biggest_method;
1400         double jit_time;
1401         gboolean enabled;
1402 } MonoJitStats;
1403
1404 extern MonoJitStats mono_jit_stats;
1405
1406 /* opcodes: value assigned after all the CIL opcodes */
1407 #ifdef MINI_OP
1408 #undef MINI_OP
1409 #endif
1410 #ifdef MINI_OP3
1411 #undef MINI_OP3
1412 #endif
1413 #define MINI_OP(a,b,dest,src1,src2) a,
1414 #define MINI_OP3(a,b,dest,src1,src2,src3) a,
1415 enum {
1416         OP_START = MONO_CEE_LAST - 1,
1417 #include "mini-ops.h"
1418         OP_LAST
1419 };
1420 #undef MINI_OP
1421 #undef MINI_OP3
1422
1423 #if SIZEOF_VOID_P == 8
1424 #define OP_PCONST OP_I8CONST
1425 #define OP_PADD OP_LADD
1426 #define OP_PADD_IMM OP_LADD_IMM
1427 #define OP_PAND_IMM OP_LAND_IMM
1428 #define OP_PSUB OP_LSUB
1429 #define OP_PMUL OP_LMUL
1430 #define OP_PMUL_IMM OP_LMUL_IMM
1431 #define OP_PNEG OP_LNEG
1432 #define OP_PCONV_TO_I1 OP_LCONV_TO_I1
1433 #define OP_PCONV_TO_U1 OP_LCONV_TO_U1
1434 #define OP_PCONV_TO_I2 OP_LCONV_TO_I2
1435 #define OP_PCONV_TO_U2 OP_LCONV_TO_U2
1436 #define OP_PCONV_TO_OVF_I1_UN OP_LCONV_TO_OVF_I1_UN
1437 #define OP_PCONV_TO_OVF_I1 OP_LCONV_TO_OVF_I1
1438 #define OP_PBEQ OP_LBEQ
1439 #define OP_PCEQ OP_LCEQ
1440 #define OP_PBNE_UN OP_LBNE_UN
1441 #define OP_PBGE_UN OP_LBGE_UN
1442 #define OP_PBLT_UN OP_LBLT_UN
1443 #define OP_PBGE OP_LBGE
1444 #define OP_STOREP_MEMBASE_REG OP_STOREI8_MEMBASE_REG
1445 #define OP_STOREP_MEMBASE_IMM OP_STOREI8_MEMBASE_IMM
1446 #else
1447 #define OP_PCONST OP_ICONST
1448 #define OP_PADD OP_IADD
1449 #define OP_PADD_IMM OP_IADD_IMM
1450 #define OP_PAND_IMM OP_IAND_IMM
1451 #define OP_PSUB OP_ISUB
1452 #define OP_PMUL OP_IMUL
1453 #define OP_PMUL_IMM OP_IMUL_IMM
1454 #define OP_PNEG OP_INEG
1455 #define OP_PCONV_TO_I1 OP_ICONV_TO_I1
1456 #define OP_PCONV_TO_U1 OP_ICONV_TO_U1
1457 #define OP_PCONV_TO_I2 OP_ICONV_TO_I2
1458 #define OP_PCONV_TO_U2 OP_ICONV_TO_U2
1459 #define OP_PCONV_TO_OVF_I1_UN OP_ICONV_TO_OVF_I1_UN
1460 #define OP_PCONV_TO_OVF_I1 OP_ICONV_TO_OVF_I1
1461 #define OP_PBEQ OP_IBEQ
1462 #define OP_PCEQ OP_ICEQ
1463 #define OP_PBNE_UN OP_IBNE_UN
1464 #define OP_PBGE_UN OP_IBGE_UN
1465 #define OP_PBLT_UN OP_IBLT_UN
1466 #define OP_PBGE OP_IBGE
1467 #define OP_STOREP_MEMBASE_REG OP_STOREI4_MEMBASE_REG
1468 #define OP_STOREP_MEMBASE_IMM OP_STOREI4_MEMBASE_IMM
1469 #endif
1470
1471 /* Opcodes to load/store regsize quantities */
1472 #if defined (__mono_ilp32__)
1473 #define OP_LOADR_MEMBASE OP_LOADI8_MEMBASE
1474 #define OP_STORER_MEMBASE_REG OP_STOREI8_MEMBASE_REG
1475 #else
1476 #define OP_LOADR_MEMBASE OP_LOAD_MEMBASE
1477 #define OP_STORER_MEMBASE_REG OP_STORE_MEMBASE_REG
1478 #endif
1479
1480 typedef enum {
1481         STACK_INV,
1482         STACK_I4,
1483         STACK_I8,
1484         STACK_PTR,
1485         STACK_R8,
1486         STACK_MP,
1487         STACK_OBJ,
1488         STACK_VTYPE,
1489         STACK_MAX
1490 } MonoStackType;
1491
1492 typedef struct {
1493         union {
1494                 double   r8;
1495                 gint32   i4;
1496                 gint64   i8;
1497                 gpointer p;
1498                 MonoClass *klass;
1499         } data;
1500         int type;
1501 } StackSlot;
1502
1503 #if HAVE_ARRAY_ELEM_INIT
1504 extern const guint8 mono_burg_arity [];
1505 #else
1506 extern guint8 mono_burg_arity [];
1507 #endif
1508
1509 extern const char MONO_ARCH_CPU_SPEC [] MONO_INTERNAL;
1510 #define MONO_ARCH_CPU_SPEC_IDX_COMBINE(a) a ## _idx
1511 #define MONO_ARCH_CPU_SPEC_IDX(a) MONO_ARCH_CPU_SPEC_IDX_COMBINE(a)
1512 extern const guint16 MONO_ARCH_CPU_SPEC_IDX(MONO_ARCH_CPU_SPEC) [] MONO_INTERNAL;
1513 #define ins_get_spec(op) ((const char*)&MONO_ARCH_CPU_SPEC + MONO_ARCH_CPU_SPEC_IDX(MONO_ARCH_CPU_SPEC)[(op) - OP_LOAD])
1514
1515 enum {
1516         MONO_COMP_DOM = 1,
1517         MONO_COMP_IDOM = 2,
1518         MONO_COMP_DFRONTIER = 4,
1519         MONO_COMP_DOM_REV = 8,
1520         MONO_COMP_LIVENESS = 16,
1521         MONO_COMP_SSA = 32,
1522         MONO_COMP_SSA_DEF_USE = 64,
1523         MONO_COMP_REACHABILITY = 128,
1524         MONO_COMP_LOOPS = 256
1525 };
1526
1527 typedef enum {
1528         MONO_GRAPH_CFG = 1,
1529         MONO_GRAPH_DTREE = 2,
1530         MONO_GRAPH_CFG_CODE = 4,
1531         MONO_GRAPH_CFG_SSA = 8,
1532         MONO_GRAPH_CFG_OPTCODE = 16
1533 } MonoGraphOptions;
1534
1535 typedef struct {
1536         guint16 size;
1537         guint16 offset;
1538         guint8  pad;
1539 } MonoJitArgumentInfo;
1540
1541 typedef struct {
1542         gboolean handle_sigint;
1543         gboolean keep_delegates;
1544         gboolean reverse_pinvoke_exceptions;
1545         gboolean collect_pagefault_stats;
1546         gboolean break_on_unverified;
1547         gboolean better_cast_details;
1548         gboolean mdb_optimizations;
1549         gboolean no_gdb_backtrace;
1550         gboolean suspend_on_sigsegv;
1551         gboolean suspend_on_unhandled;
1552         gboolean dyn_runtime_invoke;
1553         gboolean gdb;
1554         gboolean gen_seq_points;
1555         gboolean explicit_null_checks;
1556         /*
1557          * Fill stack frames with 0x2a in method prologs. This helps with the
1558          * debugging of the stack marking code in the GC.
1559          */
1560         gboolean init_stacks;
1561 } MonoDebugOptions;
1562
1563 enum {
1564         BRANCH_NOT_TAKEN,
1565         BRANCH_TAKEN,
1566         BRANCH_UNDEF
1567 };
1568
1569 typedef enum {
1570         CMP_EQ,
1571         CMP_NE,
1572         CMP_LE,
1573         CMP_GE,
1574         CMP_LT,
1575         CMP_GT,
1576         CMP_LE_UN,
1577         CMP_GE_UN,
1578         CMP_LT_UN,
1579         CMP_GT_UN
1580 } CompRelation;
1581
1582 typedef enum {
1583         CMP_TYPE_L,
1584         CMP_TYPE_I,
1585         CMP_TYPE_F
1586 } CompType;
1587
1588 /* Implicit exceptions */
1589 enum {
1590         MONO_EXC_INDEX_OUT_OF_RANGE,
1591         MONO_EXC_OVERFLOW,
1592         MONO_EXC_ARITHMETIC,
1593         MONO_EXC_DIVIDE_BY_ZERO,
1594         MONO_EXC_INVALID_CAST,
1595         MONO_EXC_NULL_REF,
1596         MONO_EXC_ARRAY_TYPE_MISMATCH,
1597         MONO_EXC_ARGUMENT,
1598         MONO_EXC_INTRINS_NUM
1599 };
1600
1601 enum {
1602         MINI_TOKEN_SOURCE_CLASS,
1603         MINI_TOKEN_SOURCE_METHOD,
1604         MINI_TOKEN_SOURCE_FIELD
1605 };
1606
1607  /* 
1608   * Information about a trampoline function.
1609   */
1610  typedef struct
1611  {
1612         /* 
1613          * The native code of the trampoline. Not owned by this structure.
1614          */
1615         guint8 *code;
1616         guint32 code_size;
1617         /*
1618          * The name of the trampoline which can be used in AOT/xdebug. Owned by this
1619          * structure.
1620          */
1621         char *name;
1622         /* 
1623          * Patches required by the trampoline when aot-ing. Owned by this structure.
1624          */
1625         MonoJumpInfo *ji;
1626         /*
1627          * Unwind information. Owned by this structure.
1628          */
1629         GSList *unwind_ops;
1630 } MonoTrampInfo;
1631
1632 typedef void (*MonoInstFunc) (MonoInst *tree, gpointer data);
1633
1634 /* main function */
1635 int         mono_main                      (int argc, char* argv[]);
1636 void        mono_set_defaults              (int verbose_level, guint32 opts);
1637 MonoDomain* mini_init                      (const char *filename, const char *runtime_version) MONO_INTERNAL;
1638 void        mini_cleanup                   (MonoDomain *domain) MONO_INTERNAL;
1639 MonoDebugOptions *mini_get_debug_options   (void) MONO_INTERNAL;
1640 char*       mono_get_runtime_build_info    (void) MONO_INTERNAL;
1641
1642 /* helper methods */
1643 void      mono_disable_optimizations       (guint32 opts) MONO_INTERNAL;
1644 MonoJumpInfoToken* mono_jump_info_token_new (MonoMemPool *mp, MonoImage *image, guint32 token) MONO_INTERNAL;
1645 MonoJumpInfoToken* mono_jump_info_token_new2 (MonoMemPool *mp, MonoImage *image, guint32 token, MonoGenericContext *context) MONO_INTERNAL;
1646 MonoInst* mono_find_spvar_for_region        (MonoCompile *cfg, int region) MONO_INTERNAL;
1647 MonoInst* mono_find_exvar_for_offset        (MonoCompile *cfg, int offset) MONO_INTERNAL;
1648 int       mono_get_block_region_notry       (MonoCompile *cfg, int region) MONO_LLVM_INTERNAL;
1649
1650 void      mono_precompile_assemblies        (void) MONO_INTERNAL;
1651 int       mono_parse_default_optimizations  (const char* p);
1652 void      mono_bblock_add_inst              (MonoBasicBlock *bb, MonoInst *inst) MONO_LLVM_INTERNAL;
1653 void      mono_bblock_insert_after_ins      (MonoBasicBlock *bb, MonoInst *ins, MonoInst *ins_to_insert) MONO_INTERNAL;
1654 void      mono_bblock_insert_before_ins     (MonoBasicBlock *bb, MonoInst *ins, MonoInst *ins_to_insert) MONO_INTERNAL;
1655 void      mono_verify_bblock                (MonoBasicBlock *bb) MONO_INTERNAL;
1656 void      mono_verify_cfg                   (MonoCompile *cfg) MONO_INTERNAL;
1657 void      mono_constant_fold                (MonoCompile *cfg) MONO_INTERNAL;
1658 MonoInst* mono_constant_fold_ins            (MonoCompile *cfg, MonoInst *ins, MonoInst *arg1, MonoInst *arg2, gboolean overwrite) MONO_INTERNAL;
1659 int       mono_eval_cond_branch             (MonoInst *branch) MONO_INTERNAL;
1660 int       mono_is_power_of_two              (guint32 val) MONO_LLVM_INTERNAL;
1661 void      mono_cprop_local                  (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst **acp, int acp_size) MONO_INTERNAL;
1662 MonoInst* mono_compile_create_var           (MonoCompile *cfg, MonoType *type, int opcode) MONO_INTERNAL;
1663 MonoInst* mono_compile_create_var_for_vreg  (MonoCompile *cfg, MonoType *type, int opcode, int vreg) MONO_INTERNAL;
1664 void      mono_compile_make_var_load        (MonoCompile *cfg, MonoInst *dest, gssize var_index) MONO_INTERNAL;
1665 MonoInst* mono_compile_create_var_load      (MonoCompile *cfg, gssize var_index) MONO_INTERNAL;
1666 MonoInst* mono_compile_create_var_store     (MonoCompile *cfg, gssize var_index, MonoInst *value) MONO_INTERNAL;
1667 MonoType* mono_type_from_stack_type         (MonoInst *ins) MONO_INTERNAL;
1668 guint32   mono_alloc_ireg                   (MonoCompile *cfg) MONO_LLVM_INTERNAL;
1669 guint32   mono_alloc_freg                   (MonoCompile *cfg) MONO_LLVM_INTERNAL;
1670 guint32   mono_alloc_preg                   (MonoCompile *cfg) MONO_LLVM_INTERNAL;
1671 guint32   mono_alloc_dreg                   (MonoCompile *cfg, MonoStackType stack_type) MONO_INTERNAL;
1672 guint32   mono_alloc_ireg_ref               (MonoCompile *cfg) MONO_LLVM_INTERNAL;
1673 guint32   mono_alloc_ireg_mp                (MonoCompile *cfg) MONO_LLVM_INTERNAL;
1674 guint32   mono_alloc_ireg_copy              (MonoCompile *cfg, guint32 vreg) MONO_LLVM_INTERNAL;
1675 void      mono_mark_vreg_as_ref             (MonoCompile *cfg, int vreg) MONO_INTERNAL;
1676 void      mono_mark_vreg_as_mp              (MonoCompile *cfg, int vreg) MONO_INTERNAL;
1677
1678 void      mono_link_bblock                  (MonoCompile *cfg, MonoBasicBlock *from, MonoBasicBlock* to) MONO_INTERNAL;
1679 void      mono_unlink_bblock                (MonoCompile *cfg, MonoBasicBlock *from, MonoBasicBlock* to) MONO_INTERNAL;
1680 gboolean  mono_bblocks_linked               (MonoBasicBlock *bb1, MonoBasicBlock *bb2) MONO_INTERNAL;
1681 void      mono_remove_bblock                (MonoCompile *cfg, MonoBasicBlock *bb) MONO_INTERNAL;
1682 void      mono_nullify_basic_block          (MonoBasicBlock *bb) MONO_INTERNAL;
1683 void      mono_merge_basic_blocks           (MonoCompile *cfg, MonoBasicBlock *bb, MonoBasicBlock *bbn) MONO_INTERNAL;
1684 void      mono_optimize_branches            (MonoCompile *cfg) MONO_INTERNAL;
1685
1686 void      mono_blockset_print               (MonoCompile *cfg, MonoBitSet *set, const char *name, guint idom) MONO_INTERNAL;
1687 void      mono_print_ins_index              (int i, MonoInst *ins) MONO_INTERNAL;
1688 void      mono_print_ins                    (MonoInst *ins) MONO_INTERNAL;
1689 void      mono_print_bb                     (MonoBasicBlock *bb, const char *msg) MONO_INTERNAL;
1690 void      mono_print_code                   (MonoCompile *cfg, const char *msg) MONO_INTERNAL;
1691 void      mono_print_method_from_ip         (void *ip);
1692 char     *mono_pmip                         (void *ip);
1693 const char* mono_inst_name                  (int op);
1694 void      mono_inst_set_src_registers       (MonoInst *ins, int *regs) MONO_INTERNAL;
1695 int       mono_op_to_op_imm                 (int opcode) MONO_INTERNAL;
1696 int       mono_op_imm_to_op                 (int opcode) MONO_INTERNAL;
1697 int       mono_load_membase_to_load_mem     (int opcode) MONO_INTERNAL;
1698 guint     mono_type_to_load_membase         (MonoCompile *cfg, MonoType *type) MONO_INTERNAL;
1699 guint     mono_type_to_store_membase        (MonoCompile *cfg, MonoType *type) MONO_INTERNAL;
1700 guint     mini_type_to_stind                (MonoCompile* cfg, MonoType *type) MONO_INTERNAL;
1701 guint32   mono_reverse_branch_op            (guint32 opcode) MONO_INTERNAL;
1702 void      mono_disassemble_code             (MonoCompile *cfg, guint8 *code, int size, char *id) MONO_INTERNAL;
1703 void      mono_add_patch_info               (MonoCompile *cfg, int ip, MonoJumpInfoType type, gconstpointer target) MONO_LLVM_INTERNAL;
1704 void      mono_remove_patch_info            (MonoCompile *cfg, int ip) MONO_INTERNAL;
1705 MonoJumpInfo* mono_patch_info_dup_mp        (MonoMemPool *mp, MonoJumpInfo *patch_info) MONO_INTERNAL;
1706 guint     mono_patch_info_hash (gconstpointer data) MONO_INTERNAL;
1707 gint      mono_patch_info_equal (gconstpointer ka, gconstpointer kb) MONO_INTERNAL;
1708 MonoJumpInfo *mono_patch_info_list_prepend  (MonoJumpInfo *list, int ip, MonoJumpInfoType type, gconstpointer target) MONO_INTERNAL;
1709 gpointer  mono_resolve_patch_target         (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *patch_info, gboolean run_cctors) MONO_LLVM_INTERNAL;
1710 gpointer  mono_jit_find_compiled_method_with_jit_info (MonoDomain *domain, MonoMethod *method, MonoJitInfo **ji) MONO_INTERNAL;
1711 gpointer  mono_jit_find_compiled_method     (MonoDomain *domain, MonoMethod *method) MONO_INTERNAL;
1712 gpointer  mono_jit_compile_method           (MonoMethod *method) MONO_INTERNAL;
1713 MonoLMF * mono_get_lmf                      (void) MONO_INTERNAL;
1714 MonoLMF** mono_get_lmf_addr                 (void) MONO_INTERNAL;
1715 void      mono_set_lmf                      (MonoLMF *lmf) MONO_INTERNAL;
1716 void      mono_jit_thread_attach            (MonoDomain *domain);
1717 guint32   mono_get_jit_tls_key              (void) MONO_INTERNAL;
1718 gint32    mono_get_jit_tls_offset           (void) MONO_INTERNAL;
1719 gint32    mono_get_lmf_tls_offset           (void) MONO_INTERNAL;
1720 gint32    mono_get_lmf_addr_tls_offset      (void) MONO_INTERNAL;
1721 MonoInst* mono_get_jit_tls_intrinsic        (MonoCompile *cfg) MONO_INTERNAL;
1722 MonoInst* mono_get_domain_intrinsic         (MonoCompile* cfg) MONO_INTERNAL;
1723 MonoInst* mono_get_thread_intrinsic         (MonoCompile* cfg) MONO_INTERNAL;
1724 GList    *mono_varlist_insert_sorted        (MonoCompile *cfg, GList *list, MonoMethodVar *mv, int sort_type) MONO_INTERNAL;
1725 GList    *mono_varlist_sort                 (MonoCompile *cfg, GList *list, int sort_type) MONO_INTERNAL;
1726 void      mono_analyze_liveness             (MonoCompile *cfg) MONO_INTERNAL;
1727 void      mono_analyze_liveness_gc          (MonoCompile *cfg) MONO_INTERNAL;
1728 void      mono_linear_scan                  (MonoCompile *cfg, GList *vars, GList *regs, regmask_t *used_mask) MONO_INTERNAL;
1729 void      mono_global_regalloc              (MonoCompile *cfg) MONO_INTERNAL;
1730 void      mono_create_jump_table            (MonoCompile *cfg, MonoInst *label, MonoBasicBlock **bbs, int num_blocks) MONO_INTERNAL;
1731 int       mono_compile_assembly             (MonoAssembly *ass, guint32 opts, const char *aot_options) MONO_INTERNAL;
1732 MonoCompile *mini_method_compile            (MonoMethod *method, guint32 opts, MonoDomain *domain, gboolean run_cctors, gboolean compile_aot, int parts) MONO_INTERNAL;
1733 void      mono_destroy_compile              (MonoCompile *cfg) MONO_INTERNAL;
1734 MonoJitICallInfo *mono_find_jit_opcode_emulation (int opcode) MONO_INTERNAL;
1735 void      mono_print_ins_index (int i, MonoInst *ins) MONO_INTERNAL;
1736 void      mono_print_ins (MonoInst *ins) MONO_INTERNAL;
1737 gboolean  mini_assembly_can_skip_verification (MonoDomain *domain, MonoMethod *method) MONO_INTERNAL;
1738 gboolean mono_compile_is_broken (MonoCompile *cfg, MonoMethod *method, gboolean fail_compile) MONO_INTERNAL;
1739 MonoInst *mono_get_got_var (MonoCompile *cfg) MONO_INTERNAL;
1740 void      mono_add_seq_point (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins, int native_offset) MONO_INTERNAL;
1741 MonoInst* mono_emit_jit_icall (MonoCompile *cfg, gconstpointer func, MonoInst **args) MONO_INTERNAL;
1742 MonoInst* mono_emit_method_call (MonoCompile *cfg, MonoMethod *method, MonoInst **args, MonoInst *this) MONO_INTERNAL;
1743 void      mono_create_helper_signatures (void) MONO_INTERNAL;
1744
1745 gboolean  mini_class_is_system_array (MonoClass *klass) MONO_INTERNAL;
1746 MonoMethodSignature *mono_get_element_address_signature (int arity) MONO_INTERNAL;
1747 MonoJitICallInfo    *mono_get_element_address_icall (int rank) MONO_INTERNAL;
1748 MonoJitICallInfo    *mono_get_array_new_va_icall (int rank) MONO_INTERNAL;
1749
1750 void      mono_linterval_add_range          (MonoCompile *cfg, MonoLiveInterval *interval, int from, int to) MONO_INTERNAL;
1751 void      mono_linterval_print              (MonoLiveInterval *interval) MONO_INTERNAL;
1752 void      mono_linterval_print_nl (MonoLiveInterval *interval) MONO_INTERNAL;
1753 gboolean  mono_linterval_covers             (MonoLiveInterval *interval, int pos) MONO_INTERNAL;
1754 gint32    mono_linterval_get_intersect_pos  (MonoLiveInterval *i1, MonoLiveInterval *i2) MONO_INTERNAL;
1755 void      mono_linterval_split              (MonoCompile *cfg, MonoLiveInterval *interval, MonoLiveInterval **i1, MonoLiveInterval **i2, int pos) MONO_INTERNAL;
1756 void      mono_liveness_handle_exception_clauses (MonoCompile *cfg) MONO_INTERNAL;
1757
1758 /* Native Client functions */
1759 gpointer mono_realloc_native_code(MonoCompile *cfg);
1760 #ifdef __native_client_codegen__
1761 void mono_nacl_align_inst(guint8 **pcode, int instlen);
1762 void mono_nacl_align_call(guint8 **start, guint8 **pcode);
1763 guint8 *mono_nacl_pad_call(guint8 *code, guint8 ilength);
1764 guint8 *mono_nacl_align(guint8 *code);
1765 void mono_nacl_fix_patches(const guint8 *code, MonoJumpInfo *ji);
1766 /* Defined for each arch */
1767 guint8 *mono_arch_nacl_pad(guint8 *code, int pad);
1768 guint8 *mono_arch_nacl_skip_nops(guint8 *code);
1769
1770 extern const guint kNaClAlignment;
1771 extern const guint kNaClAlignmentMask;
1772 #endif
1773
1774 #if defined(__native_client__) || defined(__native_client_codegen__)
1775 void mono_nacl_gc();
1776 #endif
1777
1778 #if defined(__native_client_codegen__) || defined(__native_client__)
1779 #define NACL_SIZE(a, b) (b)
1780 #else
1781 #define NACL_SIZE(a, b) (a)
1782 #endif
1783
1784 /* AOT */
1785 void      mono_aot_init                     (void) MONO_INTERNAL;
1786 void      mono_aot_cleanup                  (void) MONO_INTERNAL;
1787 gpointer  mono_aot_get_method               (MonoDomain *domain,
1788                                                                                          MonoMethod *method) MONO_INTERNAL;
1789 gpointer  mono_aot_get_method_from_token    (MonoDomain *domain, MonoImage *image, guint32 token) MONO_INTERNAL;
1790 gboolean  mono_aot_is_got_entry             (guint8 *code, guint8 *addr) MONO_INTERNAL;
1791 guint8*   mono_aot_get_plt_entry            (guint8 *code) MONO_INTERNAL;
1792 guint32   mono_aot_get_plt_info_offset      (mgreg_t *regs, guint8 *code) MONO_INTERNAL;
1793 gboolean  mono_aot_get_cached_class_info    (MonoClass *klass, MonoCachedClassInfo *res) MONO_INTERNAL;
1794 gboolean  mono_aot_get_class_from_name      (MonoImage *image, const char *name_space, const char *name, MonoClass **klass) MONO_INTERNAL;
1795 MonoJitInfo* mono_aot_find_jit_info         (MonoDomain *domain, MonoImage *image, gpointer addr) MONO_INTERNAL;
1796 gpointer mono_aot_plt_resolve               (gpointer aot_module, guint32 plt_info_offset, guint8 *code) MONO_INTERNAL;
1797 void     mono_aot_patch_plt_entry (guint8 *code, gpointer *got, mgreg_t *regs, guint8 *addr) MONO_INTERNAL;
1798 gpointer mono_aot_get_method_from_vt_slot   (MonoDomain *domain, MonoVTable *vtable, int slot) MONO_INTERNAL;
1799 gpointer mono_aot_create_specific_trampoline   (MonoImage *image, gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len) MONO_INTERNAL;
1800 gpointer mono_aot_get_trampoline            (const char *name) MONO_INTERNAL;
1801 gpointer mono_aot_get_unbox_trampoline      (MonoMethod *method) MONO_INTERNAL;
1802 gpointer mono_aot_get_lazy_fetch_trampoline (guint32 slot) MONO_INTERNAL;
1803 gpointer mono_aot_get_static_rgctx_trampoline (gpointer ctx, gpointer addr) MONO_INTERNAL;
1804 gpointer mono_aot_get_imt_thunk             (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckItem **imt_entries, int count, gpointer fail_tramp) MONO_INTERNAL;
1805 guint8*  mono_aot_get_unwind_info           (MonoJitInfo *ji, guint32 *unwind_info_len) MONO_INTERNAL;
1806 guint32  mono_aot_method_hash               (MonoMethod *method) MONO_INTERNAL;
1807 char*    mono_aot_wrapper_name              (MonoMethod *method) MONO_INTERNAL;
1808 MonoMethod* mono_aot_get_array_helper_from_wrapper (MonoMethod *method) MONO_INTERNAL;
1809 guint32  mono_aot_get_got_offset            (MonoJumpInfo *ji) MONO_LLVM_INTERNAL;
1810 char*    mono_aot_get_method_name           (MonoCompile *cfg) MONO_LLVM_INTERNAL;
1811 char*    mono_aot_get_plt_symbol            (MonoJumpInfoType type, gconstpointer data) MONO_LLVM_INTERNAL;
1812 MonoJumpInfo* mono_aot_patch_info_dup       (MonoJumpInfo* ji) MONO_LLVM_INTERNAL;
1813 void     mono_aot_set_make_unreadable       (gboolean unreadable) MONO_INTERNAL;
1814 gboolean mono_aot_is_pagefault              (void *ptr) MONO_INTERNAL;
1815 void     mono_aot_handle_pagefault          (void *ptr) MONO_INTERNAL;
1816 void     mono_aot_register_jit_icall        (const char *name, gpointer addr) MONO_INTERNAL;
1817
1818 /* This is an exported function */
1819 void     mono_aot_register_globals          (gpointer *globals);
1820 /* This too */
1821 void     mono_aot_register_module           (gpointer *aot_info);
1822
1823 void     mono_xdebug_init                   (char *xdebug_opts) MONO_INTERNAL;
1824 void     mono_save_xdebug_info              (MonoCompile *cfg) MONO_INTERNAL;
1825 void     mono_save_trampoline_xdebug_info   (MonoTrampInfo *info) MONO_INTERNAL;
1826 /* This is an exported function */
1827 void     mono_xdebug_flush                  (void);
1828
1829 /* LLVM backend */
1830 void     mono_llvm_init                     (void) MONO_LLVM_INTERNAL;
1831 void     mono_llvm_cleanup                  (void) MONO_LLVM_INTERNAL;
1832 void     mono_llvm_emit_method              (MonoCompile *cfg) MONO_LLVM_INTERNAL;
1833 void     mono_llvm_emit_call                (MonoCompile *cfg, MonoCallInst *call) MONO_LLVM_INTERNAL;
1834 void     mono_llvm_create_aot_module        (const char *got_symbol) MONO_LLVM_INTERNAL;
1835 void     mono_llvm_emit_aot_module          (const char *filename, int got_size) MONO_LLVM_INTERNAL;
1836 void     mono_llvm_check_method_supported   (MonoCompile *cfg) MONO_LLVM_INTERNAL;
1837
1838 gboolean  mono_method_blittable             (MonoMethod *method) MONO_INTERNAL;
1839 gboolean  mono_method_same_domain           (MonoJitInfo *caller, MonoJitInfo *callee) MONO_INTERNAL;
1840
1841 void      mono_register_opcode_emulation    (int opcode, const char* name, const char *sigstr, gpointer func, gboolean no_throw) MONO_INTERNAL;
1842 void      mono_draw_graph                   (MonoCompile *cfg, MonoGraphOptions draw_options) MONO_INTERNAL;
1843 void      mono_add_ins_to_end               (MonoBasicBlock *bb, MonoInst *inst) MONO_INTERNAL;
1844 gpointer  mono_create_ftnptr                (MonoDomain *domain, gpointer addr) MONO_INTERNAL;
1845
1846 void      mono_replace_ins                  (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins, MonoInst **prev, MonoBasicBlock *first_bb, MonoBasicBlock *last_bb);
1847
1848 int               mono_find_method_opcode      (MonoMethod *method) MONO_INTERNAL;
1849 MonoJitICallInfo *mono_register_jit_icall      (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save) MONO_INTERNAL;
1850 gconstpointer     mono_icall_get_wrapper       (MonoJitICallInfo* callinfo) MONO_LLVM_INTERNAL;
1851
1852 void              mono_trampolines_init (void) MONO_INTERNAL;
1853 void              mono_trampolines_cleanup (void) MONO_INTERNAL;
1854 guint8 *          mono_get_trampoline_code (MonoTrampolineType tramp_type) MONO_INTERNAL;
1855 gpointer          mono_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len) MONO_INTERNAL;
1856 gpointer          mono_create_jump_trampoline (MonoDomain *domain, 
1857                                                                                            MonoMethod *method, 
1858                                                                                            gboolean add_sync_wrapper) MONO_INTERNAL;
1859 gpointer          mono_create_class_init_trampoline (MonoVTable *vtable) MONO_INTERNAL;
1860 gpointer          mono_create_generic_class_init_trampoline (void) MONO_INTERNAL;
1861 gpointer          mono_create_jit_trampoline (MonoMethod *method) MONO_INTERNAL;
1862 gpointer          mono_create_jit_trampoline_from_token (MonoImage *image, guint32 token) MONO_INTERNAL;
1863 gpointer          mono_create_jit_trampoline_in_domain (MonoDomain *domain, MonoMethod *method) MONO_LLVM_INTERNAL;
1864 gpointer          mono_create_delegate_trampoline (MonoClass *klass) MONO_INTERNAL;
1865 gpointer          mono_create_rgctx_lazy_fetch_trampoline (guint32 offset) MONO_INTERNAL;
1866 gpointer          mono_create_monitor_enter_trampoline (void) MONO_INTERNAL;
1867 gpointer          mono_create_monitor_exit_trampoline (void) MONO_INTERNAL;
1868 gpointer          mono_create_static_rgctx_trampoline (MonoMethod *m, gpointer addr) MONO_INTERNAL;
1869 gpointer          mono_create_llvm_imt_trampoline (MonoDomain *domain, MonoMethod *m, int vt_offset) MONO_LLVM_INTERNAL;
1870 MonoVTable*       mono_find_class_init_trampoline_by_addr (gconstpointer addr) MONO_INTERNAL;
1871 guint32           mono_find_rgctx_lazy_fetch_trampoline_by_addr (gconstpointer addr) MONO_INTERNAL;
1872 gpointer          mono_magic_trampoline (mgreg_t *regs, guint8 *code, gpointer arg, guint8* tramp) MONO_INTERNAL;
1873 gpointer          mono_generic_virtual_remoting_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, guint8 *tramp) MONO_INTERNAL;
1874 gpointer          mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *tramp_data, guint8* tramp) MONO_INTERNAL;
1875 gpointer          mono_aot_trampoline (mgreg_t *regs, guint8 *code, guint8 *token_info, 
1876                                                                            guint8* tramp) MONO_INTERNAL;
1877 gpointer          mono_aot_plt_trampoline (mgreg_t *regs, guint8 *code, guint8 *token_info, 
1878                                                                                    guint8* tramp) MONO_INTERNAL;
1879 void              mono_class_init_trampoline (mgreg_t *regs, guint8 *code, MonoVTable *vtable, guint8 *tramp) MONO_INTERNAL;
1880 void              mono_generic_class_init_trampoline (mgreg_t *regs, guint8 *code, MonoVTable *vtable, guint8 *tramp) MONO_INTERNAL;
1881 void              mono_monitor_enter_trampoline (mgreg_t *regs, guint8 *code, MonoObject *obj, guint8 *tramp) MONO_INTERNAL;
1882 void              mono_monitor_exit_trampoline (mgreg_t *regs, guint8 *code, MonoObject *obj, guint8 *tramp) MONO_INTERNAL;
1883 gconstpointer     mono_get_trampoline_func (MonoTrampolineType tramp_type);
1884 gpointer          mini_get_vtable_trampoline (int slot_index) MONO_INTERNAL;
1885 char*             mono_get_generic_trampoline_name (MonoTrampolineType tramp_type) MONO_INTERNAL;
1886 char*             mono_get_rgctx_fetch_trampoline_name (int slot) MONO_INTERNAL;
1887
1888 gboolean          mono_running_on_valgrind (void) MONO_INTERNAL;
1889 void*             mono_global_codeman_reserve (int size) MONO_INTERNAL;
1890 void*             nacl_global_codeman_get_dest(void *data) MONO_INTERNAL;
1891 void              mono_global_codeman_commit(void *data, int size, int newsize) MONO_INTERNAL;
1892 void              nacl_global_codeman_validate(guint8 **buf_base, int buf_size, guint8 **code_end) MONO_INTERNAL;
1893 const char       *mono_regname_full (int reg, int bank) MONO_INTERNAL;
1894 gint32*           mono_allocate_stack_slots (MonoCompile *cfg, gboolean backward, guint32 *stack_size, guint32 *stack_align) MONO_INTERNAL;
1895 void              mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb) MONO_INTERNAL;
1896 MonoInst         *mono_branch_optimize_exception_target (MonoCompile *cfg, MonoBasicBlock *bb, const char * exname) MONO_INTERNAL;
1897 void              mono_remove_critical_edges (MonoCompile *cfg) MONO_INTERNAL;
1898 gboolean          mono_is_regsize_var (MonoType *t) MONO_INTERNAL;
1899 void              mini_emit_memcpy (MonoCompile *cfg, int destreg, int doffset, int srcreg, int soffset, int size, int align) MONO_INTERNAL;
1900 CompRelation      mono_opcode_to_cond (int opcode) MONO_LLVM_INTERNAL;
1901 CompType          mono_opcode_to_type (int opcode, int cmp_opcode) MONO_INTERNAL;
1902 CompRelation      mono_negate_cond (CompRelation cond) MONO_INTERNAL;
1903 int               mono_op_imm_to_op (int opcode) MONO_INTERNAL;
1904 void              mono_decompose_op_imm (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins) MONO_INTERNAL;
1905 void              mono_peephole_ins (MonoBasicBlock *bb, MonoInst *ins) MONO_INTERNAL;
1906 MonoUnwindOp     *mono_create_unwind_op (int when, 
1907                                                                                  int tag, int reg, 
1908                                                                                  int val) MONO_INTERNAL;
1909 void              mono_emit_unwind_op (MonoCompile *cfg, int when, 
1910                                                                            int tag, int reg, 
1911                                                                            int val) MONO_INTERNAL;
1912 MonoTrampInfo*    mono_tramp_info_create (const char *name, guint8 *code, guint32 code_size, MonoJumpInfo *ji, GSList *unwind_ops) MONO_INTERNAL;
1913 void              mono_tramp_info_free (MonoTrampInfo *info) MONO_INTERNAL;
1914
1915 int               mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_bblock, MonoBasicBlock *end_bblock, 
1916                                                                          MonoInst *return_var, GList *dont_inline, MonoInst **inline_args, 
1917                                                                          guint inline_offset, gboolean is_virtual_call) MONO_INTERNAL;
1918
1919 MonoInst         *mono_decompose_opcode (MonoCompile *cfg, MonoInst *ins) MONO_INTERNAL;
1920 void              mono_decompose_long_opts (MonoCompile *cfg) MONO_INTERNAL;
1921 void              mono_decompose_vtype_opts (MonoCompile *cfg) MONO_INTERNAL;
1922 void              mono_decompose_array_access_opts (MonoCompile *cfg) MONO_INTERNAL;
1923 void              mono_decompose_soft_float (MonoCompile *cfg) MONO_INTERNAL;
1924 void              mono_handle_global_vregs (MonoCompile *cfg) MONO_INTERNAL;
1925 void              mono_spill_global_vars (MonoCompile *cfg, gboolean *need_local_opts) MONO_INTERNAL;
1926 void              mono_if_conversion (MonoCompile *cfg) MONO_INTERNAL;
1927
1928 /* methods that must be provided by the arch-specific port */
1929 void      mono_arch_init                        (void) MONO_INTERNAL;
1930 void      mono_arch_cleanup                     (void) MONO_INTERNAL;
1931 void      mono_arch_cpu_init                    (void) MONO_INTERNAL;
1932 guint32   mono_arch_cpu_optimizazions           (guint32 *exclude_mask) MONO_INTERNAL;
1933 void      mono_arch_instrument_mem_needs        (MonoMethod *method, int *stack, int *code) MONO_INTERNAL;
1934 void     *mono_arch_instrument_prolog           (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments) MONO_INTERNAL;
1935 void     *mono_arch_instrument_epilog           (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments) MONO_INTERNAL;
1936 void     *mono_arch_instrument_epilog_full     (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments, gboolean preserve_argument_registers) MONO_INTERNAL;
1937 void      mono_codegen                          (MonoCompile *cfg) MONO_INTERNAL;
1938 void      mono_call_inst_add_outarg_reg         (MonoCompile *cfg, MonoCallInst *call, int vreg, int hreg, int bank) MONO_LLVM_INTERNAL;
1939 void      mono_call_inst_add_outarg_vt          (MonoCompile *cfg, MonoCallInst *call, MonoInst *outarg_vt) MONO_INTERNAL;
1940 const char *mono_arch_regname                   (int reg) MONO_INTERNAL;
1941 const char *mono_arch_fregname                  (int reg) MONO_INTERNAL;
1942 void      mono_arch_exceptions_init             (void) MONO_INTERNAL;
1943 guchar*   mono_arch_create_generic_trampoline   (MonoTrampolineType tramp_type, MonoTrampInfo **info, gboolean aot) MONO_INTERNAL;
1944 gpointer  mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info, gboolean aot) MONO_INTERNAL;
1945 gpointer  mono_arch_create_generic_class_init_trampoline (MonoTrampInfo **info, gboolean aot) MONO_INTERNAL;
1946 gpointer  mono_arch_get_nullified_class_init_trampoline (MonoTrampInfo **info) MONO_INTERNAL;
1947 gpointer  mono_arch_create_monitor_enter_trampoline (MonoTrampInfo **info, gboolean aot) MONO_INTERNAL;
1948 gpointer  mono_arch_create_monitor_exit_trampoline (MonoTrampInfo **info, gboolean aot) MONO_INTERNAL;
1949 GList    *mono_arch_get_allocatable_int_vars    (MonoCompile *cfg) MONO_INTERNAL;
1950 GList    *mono_arch_get_global_int_regs         (MonoCompile *cfg) MONO_INTERNAL;
1951 GList    *mono_arch_get_global_fp_regs          (MonoCompile *cfg) MONO_INTERNAL;
1952 GList    *mono_arch_get_iregs_clobbered_by_call (MonoCallInst *call) MONO_INTERNAL;
1953 GList    *mono_arch_get_fregs_clobbered_by_call (MonoCallInst *call) MONO_INTERNAL;
1954 guint32   mono_arch_regalloc_cost               (MonoCompile *cfg, MonoMethodVar *vmv) MONO_INTERNAL;
1955 void      mono_arch_patch_code                  (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *ji, MonoCodeManager *dyn_code_mp, gboolean run_cctors) MONO_INTERNAL;
1956 void      mono_arch_flush_icache                (guint8 *code, gint size) MONO_INTERNAL;
1957 int       mono_arch_max_epilog_size             (MonoCompile *cfg) MONO_INTERNAL;
1958 guint8   *mono_arch_emit_prolog                 (MonoCompile *cfg) MONO_INTERNAL;
1959 void      mono_arch_emit_epilog                 (MonoCompile *cfg) MONO_INTERNAL;
1960 void      mono_arch_emit_exceptions             (MonoCompile *cfg) MONO_INTERNAL;
1961 void      mono_arch_lowering_pass               (MonoCompile *cfg, MonoBasicBlock *bb) MONO_INTERNAL;
1962 void      mono_arch_peephole_pass_1             (MonoCompile *cfg, MonoBasicBlock *bb) MONO_INTERNAL;
1963 void      mono_arch_peephole_pass_2             (MonoCompile *cfg, MonoBasicBlock *bb) MONO_INTERNAL;
1964 void      mono_arch_output_basic_block          (MonoCompile *cfg, MonoBasicBlock *bb) MONO_INTERNAL;
1965 void      mono_arch_setup_jit_tls_data          (MonoJitTlsData *tls) MONO_INTERNAL;
1966 void      mono_arch_free_jit_tls_data           (MonoJitTlsData *tls) MONO_INTERNAL;
1967 void      mono_arch_fill_argument_info          (MonoCompile *cfg) MONO_INTERNAL;
1968 void      mono_arch_allocate_vars               (MonoCompile *m) MONO_INTERNAL;
1969 int       mono_arch_get_argument_info           (MonoMethodSignature *csig, int param_count, MonoJitArgumentInfo *arg_info) MONO_INTERNAL;
1970 gboolean  mono_arch_print_tree                  (MonoInst *tree, int arity) MONO_INTERNAL;
1971 void      mono_arch_emit_call                   (MonoCompile *cfg, MonoCallInst *call) MONO_INTERNAL;
1972 void      mono_arch_emit_outarg_vt              (MonoCompile *cfg, MonoInst *ins, MonoInst *src) MONO_INTERNAL;
1973 void      mono_arch_emit_setret                 (MonoCompile *cfg, MonoMethod *method, MonoInst *val) MONO_INTERNAL;
1974 MonoDynCallInfo *mono_arch_dyn_call_prepare     (MonoMethodSignature *sig) MONO_INTERNAL;
1975 void      mono_arch_dyn_call_free               (MonoDynCallInfo *info) MONO_INTERNAL;
1976 void      mono_arch_start_dyn_call              (MonoDynCallInfo *info, gpointer **args, guint8 *ret, guint8 *buf, int buf_len) MONO_INTERNAL;
1977 void      mono_arch_finish_dyn_call             (MonoDynCallInfo *info, guint8 *buf) MONO_INTERNAL;
1978 MonoInst *mono_arch_emit_inst_for_method        (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args) MONO_INTERNAL;
1979 void      mono_arch_decompose_opts              (MonoCompile *cfg, MonoInst *ins) MONO_INTERNAL;
1980 void      mono_arch_decompose_long_opts         (MonoCompile *cfg, MonoInst *ins) MONO_INTERNAL;
1981 GSList*   mono_arch_get_delegate_invoke_impls   (void) MONO_INTERNAL;
1982 LLVMCallInfo* mono_arch_get_llvm_call_info      (MonoCompile *cfg, MonoMethodSignature *sig) MONO_LLVM_INTERNAL;
1983 guint8*   mono_arch_emit_load_got_addr          (guint8 *start, guint8 *code, MonoCompile *cfg, MonoJumpInfo **ji) MONO_INTERNAL;
1984 guint8*   mono_arch_emit_load_aotconst          (guint8 *start, guint8 *code, MonoJumpInfo **ji, int tramp_type, gconstpointer target) MONO_INTERNAL;
1985 GSList*   mono_arch_get_cie_program             (void) MONO_INTERNAL;
1986 void      mono_arch_set_target                  (char *mtriple) MONO_INTERNAL;
1987
1988 /* Soft Debug support */
1989 #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
1990 void      mono_arch_set_breakpoint              (MonoJitInfo *ji, guint8 *ip) MONO_INTERNAL;
1991 void      mono_arch_clear_breakpoint            (MonoJitInfo *ji, guint8 *ip) MONO_INTERNAL;
1992 void      mono_arch_start_single_stepping       (void) MONO_INTERNAL;
1993 void      mono_arch_stop_single_stepping        (void) MONO_INTERNAL;
1994 gboolean  mono_arch_is_single_step_event        (void *info, void *sigctx) MONO_INTERNAL;
1995 gboolean  mono_arch_is_breakpoint_event         (void *info, void *sigctx) MONO_INTERNAL;
1996 guint8*   mono_arch_get_ip_for_single_step      (MonoJitInfo *ji, MonoContext *ctx) MONO_INTERNAL;
1997 guint8*   mono_arch_get_ip_for_breakpoint       (MonoJitInfo *ji, MonoContext *ctx) MONO_INTERNAL;
1998 void     mono_arch_skip_breakpoint              (MonoContext *ctx) MONO_INTERNAL;
1999 void     mono_arch_skip_single_step             (MonoContext *ctx) MONO_INTERNAL;
2000 gpointer mono_arch_get_seq_point_info           (MonoDomain *domain, guint8 *code) MONO_INTERNAL;
2001 void     mono_arch_setup_resume_sighandler_ctx  (MonoContext *ctx, gpointer func) MONO_INTERNAL;
2002 #endif
2003
2004 gboolean
2005 mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, 
2006                                                  MonoJitInfo *ji, MonoContext *ctx, 
2007                                                  MonoContext *new_ctx, MonoLMF **lmf,
2008                                                  mgreg_t **save_locations,
2009                                                  StackFrameInfo *frame_info) MONO_INTERNAL;
2010 gpointer  mono_arch_get_throw_exception_by_name (void) MONO_INTERNAL;
2011 gpointer mono_arch_get_call_filter              (MonoTrampInfo **info, gboolean aot) MONO_INTERNAL;
2012 gpointer mono_arch_get_restore_context          (MonoTrampInfo **info, gboolean aot) MONO_INTERNAL;
2013 gpointer  mono_arch_get_throw_exception         (MonoTrampInfo **info, gboolean aot) MONO_INTERNAL;
2014 gpointer  mono_arch_get_rethrow_exception       (MonoTrampInfo **info, gboolean aot) MONO_INTERNAL;
2015 gpointer  mono_arch_get_throw_corlib_exception  (MonoTrampInfo **info, gboolean aot) MONO_INTERNAL;
2016 gpointer  mono_arch_get_throw_pending_exception (MonoTrampInfo **info, gboolean aot) MONO_INTERNAL;
2017 gboolean mono_arch_handle_exception             (void *sigctx, gpointer obj, gboolean test_only) MONO_INTERNAL;
2018 void     mono_arch_handle_altstack_exception    (void *sigctx, gpointer fault_addr, gboolean stack_ovf) MONO_INTERNAL;
2019 gboolean mono_handle_soft_stack_ovf             (MonoJitTlsData *jit_tls, MonoJitInfo *ji, void *ctx, guint8* fault_addr) MONO_INTERNAL;
2020 void     mono_handle_hard_stack_ovf             (MonoJitTlsData *jit_tls, MonoJitInfo *ji, void *ctx, guint8* fault_addr) MONO_INTERNAL;
2021 gpointer mono_arch_ip_from_context              (void *sigctx) MONO_INTERNAL;
2022 void     mono_arch_sigctx_to_monoctx            (void *sigctx, MonoContext *ctx) MONO_INTERNAL;
2023 void     mono_arch_monoctx_to_sigctx            (MonoContext *mctx, void *ctx) MONO_INTERNAL;
2024 gpointer mono_arch_context_get_int_reg          (MonoContext *ctx, int reg) MONO_INTERNAL;
2025 void     mono_arch_flush_register_windows       (void) MONO_INTERNAL;
2026 gboolean mono_arch_is_inst_imm                  (gint64 imm) MONO_INTERNAL;
2027 MonoInst* mono_arch_get_domain_intrinsic        (MonoCompile* cfg) MONO_INTERNAL;
2028 gboolean mono_arch_is_int_overflow              (void *sigctx, void *info) MONO_INTERNAL;
2029 void     mono_arch_invalidate_method            (MonoJitInfo *ji, void *func, gpointer func_arg) MONO_INTERNAL;
2030 guint32  mono_arch_get_patch_offset             (guint8 *code) MONO_INTERNAL;
2031 gpointer*mono_arch_get_delegate_method_ptr_addr (guint8* code, mgreg_t *regs) MONO_INTERNAL;
2032 void     mono_arch_create_vars                  (MonoCompile *cfg) MONO_INTERNAL;
2033 void     mono_arch_save_unwind_info             (MonoCompile *cfg) MONO_INTERNAL;
2034 void     mono_arch_register_lowlevel_calls      (void) MONO_INTERNAL;
2035 gpointer mono_arch_get_unbox_trampoline         (MonoMethod *m, gpointer addr) MONO_INTERNAL;
2036 gpointer mono_arch_get_static_rgctx_trampoline  (MonoMethod *m, MonoMethodRuntimeGenericContext *mrgctx, gpointer addr) MONO_INTERNAL;
2037 gpointer  mono_arch_get_llvm_imt_trampoline     (MonoDomain *domain, MonoMethod *method, int vt_offset) MONO_INTERNAL;
2038 void     mono_arch_patch_callsite               (guint8 *method_start, guint8 *code, guint8 *addr) MONO_INTERNAL;
2039 void     mono_arch_patch_plt_entry              (guint8 *code, gpointer *got, mgreg_t *regs, guint8 *addr) MONO_INTERNAL;
2040 void     mono_arch_nullify_class_init_trampoline(guint8 *code, mgreg_t *regs) MONO_INTERNAL;
2041 void     mono_arch_nullify_plt_entry            (guint8 *code, mgreg_t *regs) MONO_INTERNAL;
2042 int      mono_arch_get_this_arg_reg             (guint8 *code) MONO_INTERNAL;
2043 gpointer mono_arch_get_this_arg_from_call       (mgreg_t *regs, guint8 *code) MONO_INTERNAL;
2044 gpointer mono_arch_get_delegate_invoke_impl     (MonoMethodSignature *sig, gboolean has_target) MONO_INTERNAL;
2045 gpointer mono_arch_create_specific_trampoline   (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len) MONO_INTERNAL;
2046 void        mono_arch_emit_imt_argument         (MonoCompile *cfg, MonoCallInst *call, MonoInst *imt_arg) MONO_INTERNAL;
2047 MonoMethod* mono_arch_find_imt_method           (mgreg_t *regs, guint8 *code) MONO_INTERNAL;
2048 MonoVTable* mono_arch_find_static_call_vtable   (mgreg_t *regs, guint8 *code) MONO_INTERNAL;
2049 gpointer    mono_arch_build_imt_thunk           (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckItem **imt_entries, int count, gpointer fail_tramp) MONO_INTERNAL;
2050 void    mono_arch_notify_pending_exc            (void) MONO_INTERNAL;
2051 guint8* mono_arch_get_call_target               (guint8 *code) MONO_INTERNAL;
2052 guint32 mono_arch_get_plt_info_offset           (guint8 *plt_entry, mgreg_t *regs, guint8 *code) MONO_INTERNAL;
2053 GSList *mono_arch_get_trampolines               (gboolean aot) MONO_INTERNAL;
2054
2055 /* Handle block guard */
2056 gpointer mono_arch_install_handler_block_guard (MonoJitInfo *ji, MonoJitExceptionInfo *clause, MonoContext *ctx, gpointer new_value) MONO_INTERNAL;
2057 gpointer mono_arch_create_handler_block_trampoline (void) MONO_INTERNAL;
2058 gpointer mono_create_handler_block_trampoline (void) MONO_INTERNAL;
2059 gboolean mono_install_handler_block_guard (MonoInternalThread *thread, MonoContext *ctx) MONO_INTERNAL;
2060
2061 /* Exception handling */
2062 typedef gboolean (*MonoJitStackWalk)            (StackFrameInfo *frame, MonoContext *ctx, gpointer data);
2063
2064 void     mono_exceptions_init                   (void) MONO_INTERNAL;
2065 gboolean mono_handle_exception                  (MonoContext *ctx, gpointer obj,
2066                                                  gpointer original_ip, gboolean test_only) MONO_INTERNAL;
2067 void     mono_handle_native_sigsegv             (int signal, void *sigctx) MONO_INTERNAL;
2068 void     mono_print_thread_dump                 (void *sigctx);
2069 void     mono_print_thread_dump_from_ctx        (MonoContext *ctx);
2070 void     mono_walk_stack_with_ctx               (MonoJitStackWalk func, MonoContext *start_ctx, MonoUnwindOptions unwind_options, void *user_data) MONO_INTERNAL;
2071 void     mono_walk_stack_with_state             (MonoJitStackWalk func, MonoThreadUnwindState *state, MonoUnwindOptions unwind_options, void *user_data) MONO_INTERNAL;
2072 void     mono_walk_stack                        (MonoJitStackWalk func, MonoUnwindOptions options, void *user_data) MONO_INTERNAL;
2073 gboolean mono_thread_state_init_from_sigctx     (MonoThreadUnwindState *ctx, void *sigctx) MONO_INTERNAL;
2074 gboolean mono_thread_state_init_from_current    (MonoThreadUnwindState *ctx) MONO_INTERNAL;
2075 gboolean mono_thread_state_init_from_monoctx    (MonoThreadUnwindState *ctx, MonoContext *mctx) MONO_INTERNAL;
2076
2077 void     mono_setup_altstack                    (MonoJitTlsData *tls) MONO_INTERNAL;
2078 void     mono_free_altstack                     (MonoJitTlsData *tls) MONO_INTERNAL;
2079 gpointer mono_altstack_restore_prot             (mgreg_t *regs, guint8 *code, gpointer *tramp_data, guint8* tramp) MONO_INTERNAL;
2080 MonoJitInfo* mini_jit_info_table_find           (MonoDomain *domain, char *addr, MonoDomain **out_domain) MONO_INTERNAL;
2081 void     mono_resume_unwind                     (MonoContext *ctx) MONO_LLVM_INTERNAL;
2082
2083 MonoJitInfo * mono_find_jit_info                (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInfo *res, MonoJitInfo *prev_ji, MonoContext *ctx, MonoContext *new_ctx, char **trace, MonoLMF **lmf, int *native_offset, gboolean *managed) MONO_INTERNAL;
2084
2085 gboolean
2086 mono_find_jit_info_ext (MonoDomain *domain, MonoJitTlsData *jit_tls, 
2087                                                 MonoJitInfo *prev_ji, MonoContext *ctx,
2088                                                 MonoContext *new_ctx, char **trace, MonoLMF **lmf,
2089                                                 mgreg_t **save_locations,
2090                                                 StackFrameInfo *frame) MONO_INTERNAL;
2091
2092 gpointer mono_get_throw_exception               (void) MONO_INTERNAL;
2093 gpointer mono_get_rethrow_exception             (void) MONO_INTERNAL;
2094 gpointer mono_get_call_filter                   (void) MONO_INTERNAL;
2095 gpointer mono_get_restore_context               (void) MONO_INTERNAL;
2096 gpointer mono_get_throw_exception_by_name       (void) MONO_INTERNAL;
2097 gpointer mono_get_throw_corlib_exception        (void) MONO_INTERNAL;
2098
2099 MonoArray *ves_icall_get_trace                  (MonoException *exc, gint32 skip, MonoBoolean need_file_info) MONO_INTERNAL;
2100 MonoBoolean ves_icall_get_frame_info            (gint32 skip, MonoBoolean need_file_info, 
2101                                                  MonoReflectionMethod **method, 
2102                                                  gint32 *iloffset, gint32 *native_offset,
2103                                                  MonoString **file, gint32 *line, gint32 *column) MONO_INTERNAL;
2104 MonoString *ves_icall_System_Exception_get_trace (MonoException *exc) MONO_INTERNAL;
2105 void mono_set_cast_details                      (MonoClass *from, MonoClass *to) MONO_INTERNAL;
2106
2107 /* Dominator/SSA methods */
2108 void        mono_compile_dominator_info         (MonoCompile *cfg, int dom_flags) MONO_INTERNAL;
2109 void        mono_compute_natural_loops          (MonoCompile *cfg) MONO_INTERNAL;
2110 MonoBitSet* mono_compile_iterated_dfrontier     (MonoCompile *cfg, MonoBitSet *set) MONO_INTERNAL;
2111 void        mono_ssa_compute                    (MonoCompile *cfg) MONO_INTERNAL;
2112 void        mono_ssa_remove                     (MonoCompile *cfg) MONO_INTERNAL;
2113 void        mono_ssa_cprop                      (MonoCompile *cfg) MONO_INTERNAL;
2114 void        mono_ssa_deadce                     (MonoCompile *cfg) MONO_INTERNAL;
2115 void        mono_ssa_strength_reduction         (MonoCompile *cfg) MONO_INTERNAL;
2116 void        mono_free_loop_info                 (MonoCompile *cfg) MONO_INTERNAL;
2117
2118 void        mono_ssa_compute2                   (MonoCompile *cfg);
2119 void        mono_ssa_remove2                    (MonoCompile *cfg);
2120 void        mono_ssa_cprop2                     (MonoCompile *cfg);
2121 void        mono_ssa_deadce2                    (MonoCompile *cfg);
2122
2123 /* debugging support */
2124 void      mono_debug_init_method                (MonoCompile *cfg, MonoBasicBlock *start_block,
2125                                                  guint32 breakpoint_id) MONO_INTERNAL;
2126 void      mono_debug_open_method                (MonoCompile *cfg) MONO_INTERNAL;
2127 void      mono_debug_close_method               (MonoCompile *cfg) MONO_INTERNAL;
2128 void      mono_debug_free_method                (MonoCompile *cfg) MONO_INTERNAL;
2129 void      mono_debug_open_block                 (MonoCompile *cfg, MonoBasicBlock *bb, guint32 address) MONO_INTERNAL;
2130 void      mono_debug_record_line_number         (MonoCompile *cfg, MonoInst *ins, guint32 address) MONO_INTERNAL;
2131 void      mono_debug_serialize_debug_info       (MonoCompile *cfg, guint8 **out_buf, guint32 *buf_len) MONO_INTERNAL;
2132 void      mono_debug_add_aot_method             (MonoDomain *domain,
2133                                                  MonoMethod *method, guint8 *code_start, 
2134                                                  guint8 *debug_info, guint32 debug_info_len) MONO_INTERNAL;
2135 void      mono_debug_add_icall_wrapper          (MonoMethod *method, MonoJitICallInfo* info) MONO_INTERNAL;
2136 void      mono_debug_print_vars                 (gpointer ip, gboolean only_arguments);
2137 void      mono_debugger_run_finally             (MonoContext *start_ctx);
2138
2139 extern gssize mono_breakpoint_info_index [MONO_BREAKPOINT_ARRAY_SIZE];
2140
2141 gboolean mono_breakpoint_clean_code (guint8 *method_start, guint8 *code, int offset, guint8 *buf, int size);
2142
2143 #ifdef MONO_DEBUGGER_SUPPORTED
2144
2145 /* Mono Debugger support */
2146 void      mini_debugger_init                    (void);
2147 int       mini_debugger_main                    (MonoDomain *domain, MonoAssembly *assembly, int argc, char **argv);
2148 gboolean  mini_debug_running_inside_mdb         (void);
2149 void      mini_debugger_set_attach_ok           (void);
2150
2151 #endif
2152
2153 /* Tracing */
2154 MonoTraceSpec *mono_trace_parse_options         (const char *options) MONO_INTERNAL;
2155 void           mono_trace_set_assembly          (MonoAssembly *assembly) MONO_INTERNAL;
2156 gboolean       mono_trace_eval                  (MonoMethod *method) MONO_INTERNAL;
2157
2158 extern void
2159 mono_perform_abc_removal (MonoCompile *cfg) MONO_INTERNAL;
2160 extern void
2161 mono_perform_abc_removal (MonoCompile *cfg) MONO_INTERNAL;
2162 extern void
2163 mono_perform_ssapre (MonoCompile *cfg) MONO_INTERNAL;
2164 extern void
2165 mono_local_cprop (MonoCompile *cfg) MONO_INTERNAL;
2166 extern void
2167 mono_local_cprop (MonoCompile *cfg);
2168 extern void
2169 mono_local_deadce (MonoCompile *cfg);
2170
2171 /* CAS - stack walk */
2172 MonoSecurityFrame* ves_icall_System_Security_SecurityFrame_GetSecurityFrame (gint32 skip) MONO_INTERNAL;
2173 MonoArray* ves_icall_System_Security_SecurityFrame_GetSecurityStack (gint32 skip) MONO_INTERNAL;
2174
2175 /* Generic sharing */
2176
2177
2178 void
2179 mono_set_generic_sharing_supported (gboolean supported) MONO_INTERNAL;
2180
2181 gboolean
2182 mono_class_generic_sharing_enabled (MonoClass *class) MONO_INTERNAL;
2183
2184 gpointer
2185 mono_class_fill_runtime_generic_context (MonoVTable *class_vtable, guint32 slot) MONO_INTERNAL;
2186
2187 gpointer
2188 mono_method_fill_runtime_generic_context (MonoMethodRuntimeGenericContext *mrgctx, guint32 slot) MONO_INTERNAL;
2189
2190 MonoMethodRuntimeGenericContext*
2191 mono_method_lookup_rgctx (MonoVTable *class_vtable, MonoGenericInst *method_inst) MONO_INTERNAL;
2192
2193 gboolean
2194 mono_method_needs_static_rgctx_invoke (MonoMethod *method, gboolean allow_type_vars) MONO_INTERNAL;
2195
2196 int
2197 mono_class_rgctx_get_array_size (int n, gboolean mrgctx) MONO_INTERNAL;
2198
2199 guint32
2200 mono_method_lookup_or_register_other_info (MonoMethod *method, gboolean in_mrgctx, gpointer data,
2201         int info_type, MonoGenericContext *generic_context) MONO_INTERNAL;
2202
2203 MonoGenericContext
2204 mono_method_construct_object_context (MonoMethod *method) MONO_INTERNAL;
2205
2206 MonoMethod*
2207 mono_method_get_declaring_generic_method (MonoMethod *method) MONO_INTERNAL;
2208
2209 int
2210 mono_generic_context_check_used (MonoGenericContext *context) MONO_INTERNAL;
2211
2212 int
2213 mono_class_check_context_used (MonoClass *class) MONO_INTERNAL;
2214
2215 gboolean
2216 mono_generic_context_is_sharable (MonoGenericContext *context, gboolean allow_type_vars) MONO_INTERNAL;
2217
2218 gboolean
2219 mono_generic_context_is_sharable_full (MonoGenericContext *context, gboolean allow_type_vars, gboolean allow_partial) MONO_INTERNAL;
2220
2221 gboolean
2222 mono_method_is_generic_impl (MonoMethod *method) MONO_INTERNAL;
2223
2224 gboolean
2225 mono_method_is_generic_sharable_impl (MonoMethod *method, gboolean allow_type_vars) MONO_INTERNAL;
2226
2227 gboolean
2228 mono_method_is_generic_sharable_impl_full (MonoMethod *method, gboolean allow_type_vars, gboolean allow_partial) MONO_INTERNAL;
2229
2230 gboolean
2231 mono_is_partially_sharable_inst (MonoGenericInst *inst) MONO_INTERNAL;
2232
2233 MonoGenericSharingContext* mono_get_generic_context_from_code (guint8 *code) MONO_INTERNAL;
2234
2235 MonoGenericContext* mini_method_get_context (MonoMethod *method) MONO_INTERNAL;
2236
2237 int mono_method_check_context_used (MonoMethod *method) MONO_INTERNAL;
2238
2239 gboolean mono_generic_context_equal_deep (MonoGenericContext *context1, MonoGenericContext *context2) MONO_INTERNAL;
2240
2241 gpointer mono_helper_get_rgctx_other_ptr (MonoClass *caller_class, MonoVTable *vtable,
2242                                           guint32 token, guint32 token_source, guint32 rgctx_type,
2243                                           gint32 rgctx_index) MONO_INTERNAL;
2244
2245 void mono_generic_sharing_init (void) MONO_INTERNAL;
2246 void mono_generic_sharing_cleanup (void) MONO_INTERNAL;
2247
2248 MonoClass* mini_class_get_container_class (MonoClass *class) MONO_INTERNAL;
2249 MonoGenericContext* mini_class_get_context (MonoClass *class) MONO_INTERNAL;
2250
2251 MonoType* mini_get_basic_type_from_generic (MonoGenericSharingContext *gsctx, MonoType *type) MONO_INTERNAL;
2252 MonoType* mini_type_get_underlying_type (MonoGenericSharingContext *gsctx, MonoType *type) MONO_INTERNAL;
2253 MonoMethod* mini_get_shared_method (MonoMethod *method) MONO_INTERNAL;
2254 MonoMethod* mini_get_shared_method_to_register (MonoMethod *method) MONO_INTERNAL;
2255
2256 int mini_type_stack_size (MonoGenericSharingContext *gsctx, MonoType *t, int *align) MONO_INTERNAL;
2257 int mini_type_stack_size_full (MonoGenericSharingContext *gsctx, MonoType *t, guint32 *align, gboolean pinvoke) MONO_INTERNAL;
2258 void type_to_eval_stack_type (MonoCompile *cfg, MonoType *type, MonoInst *inst) MONO_INTERNAL;
2259 guint mono_type_to_regmove (MonoCompile *cfg, MonoType *type) MONO_INTERNAL;
2260
2261 void mono_cfg_add_try_hole (MonoCompile *cfg, MonoExceptionClause *clause, guint8 *start, MonoBasicBlock *bb) MONO_INTERNAL;
2262
2263 void mono_cfg_set_exception (MonoCompile *cfg, int type) MONO_INTERNAL;
2264 gboolean mini_type_is_reference (MonoCompile *cfg, MonoType *type) MONO_INTERNAL;
2265
2266
2267 /* wapihandles.c */
2268 int mini_wapi_hps (int argc, char **argv) MONO_INTERNAL;
2269
2270 int mini_wapi_semdel (int argc, char **argv) MONO_INTERNAL;
2271
2272 int mini_wapi_seminfo (int argc, char **argv) MONO_INTERNAL;
2273
2274 /* SIMD support */
2275
2276 /*
2277 This enum MUST be kept in sync with its managed mirror Mono.Simd.AccelMode.
2278  */
2279 enum {
2280         SIMD_VERSION_SSE1       = 1 << 0,
2281         SIMD_VERSION_SSE2       = 1 << 1,
2282         SIMD_VERSION_SSE3       = 1 << 2,
2283         SIMD_VERSION_SSSE3      = 1 << 3,
2284         SIMD_VERSION_SSE41      = 1 << 4,
2285         SIMD_VERSION_SSE42      = 1 << 5,
2286         SIMD_VERSION_SSE4a      = 1 << 6,
2287         SIMD_VERSION_ALL        = SIMD_VERSION_SSE1 | SIMD_VERSION_SSE2 |
2288                           SIMD_VERSION_SSE3 | SIMD_VERSION_SSSE3 |
2289                           SIMD_VERSION_SSE41 | SIMD_VERSION_SSE42 |
2290                           SIMD_VERSION_SSE4a,
2291
2292         /* this value marks the end of the bit indexes used in 
2293          * this emum.
2294          */
2295         SIMD_VERSION_INDEX_END = 6 
2296 };
2297
2298 #define MASK(x) (1 << x)
2299
2300 enum {
2301         SIMD_COMP_EQ,
2302         SIMD_COMP_LT,
2303         SIMD_COMP_LE,
2304         SIMD_COMP_UNORD,
2305         SIMD_COMP_NEQ,
2306         SIMD_COMP_NLT,
2307         SIMD_COMP_NLE,
2308         SIMD_COMP_ORD
2309 };
2310
2311 enum {
2312         SIMD_PREFETCH_MODE_NTA,
2313         SIMD_PREFETCH_MODE_0,
2314         SIMD_PREFETCH_MODE_1,
2315         SIMD_PREFETCH_MODE_2,
2316 };
2317
2318 const char *mono_arch_xregname (int reg) MONO_INTERNAL;
2319 void        mono_simd_simplify_indirection (MonoCompile *cfg) MONO_INTERNAL;
2320 MonoInst*   mono_emit_simd_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args) MONO_INTERNAL;
2321 guint32     mono_arch_cpu_enumerate_simd_versions (void) MONO_INTERNAL;
2322 void        mono_simd_intrinsics_init (void) MONO_INTERNAL;
2323
2324 #ifdef __linux__
2325 /* maybe enable also for other systems? */
2326 #define ENABLE_JIT_MAP 1
2327 void mono_enable_jit_map (void) MONO_INTERNAL;
2328 void mono_emit_jit_map   (MonoJitInfo *jinfo) MONO_INTERNAL;
2329 void mono_emit_jit_tramp (void *start, int size, const char *desc) MONO_INTERNAL;
2330 gboolean mono_jit_map_is_enabled (void) MONO_INTERNAL;
2331 #else
2332 #define mono_enable_jit_map()
2333 #define mono_emit_jit_map(ji)
2334 #define mono_emit_jit_tramp(s,z,d)
2335 #define mono_jit_map_is_enabled() (0)
2336 #endif
2337
2338 /*
2339  * Per-OS implementation functions.
2340  */
2341 void mono_runtime_install_handlers (void) MONO_INTERNAL;
2342 void mono_runtime_cleanup_handlers (void) MONO_INTERNAL;
2343 void mono_runtime_setup_stat_profiler (void) MONO_INTERNAL;
2344 void mono_runtime_shutdown_stat_profiler (void) MONO_INTERNAL;
2345 void mono_runtime_posix_install_handlers (void) MONO_INTERNAL;
2346 pid_t mono_runtime_syscall_fork (void) MONO_INTERNAL;
2347 gboolean mono_gdb_render_native_backtraces (void) MONO_INTERNAL;
2348
2349 /*
2350  * Signal handling
2351  */
2352 #ifdef MONO_GET_CONTEXT
2353 #define GET_CONTEXT MONO_GET_CONTEXT
2354 #endif
2355
2356 #ifndef GET_CONTEXT
2357 #ifdef HOST_WIN32
2358 #define GET_CONTEXT \
2359     void *ctx = context;
2360 #else
2361 #ifdef MONO_ARCH_USE_SIGACTION
2362 #define GET_CONTEXT \
2363     void *ctx = context;
2364 #elif defined(__HAIKU__)
2365 #define GET_CONTEXT \
2366         void *ctx = &regs;
2367 #else
2368 #define GET_CONTEXT \
2369         void **_p = (void **)&_dummy; \
2370         struct sigcontext *ctx = (struct sigcontext *)++_p;
2371 #endif
2372 #endif
2373 #endif
2374
2375 #ifdef MONO_ARCH_USE_SIGACTION
2376 #define SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy, siginfo_t *info, void *context)
2377 #define SIG_HANDLER_PARAMS _dummy, info, context
2378 #elif defined(HOST_WIN32)
2379 #define SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy, EXCEPTION_POINTERS *info, void *context)
2380 #define SIG_HANDLER_PARAMS _dummy, info, context
2381 #elif defined(__HAIKU__)
2382 #define SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy, void *userData, vregs regs)
2383 #define SIG_HANDLER_PARAMS _dummy, userData, regs
2384 #else
2385 #define SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy)
2386 #define SIG_HANDLER_PARAMS _dummy
2387 #endif
2388
2389 void SIG_HANDLER_SIGNATURE (mono_sigfpe_signal_handler)  MONO_INTERNAL;
2390 void SIG_HANDLER_SIGNATURE (mono_sigill_signal_handler)  MONO_INTERNAL;
2391 void SIG_HANDLER_SIGNATURE (mono_sigsegv_signal_handler) MONO_INTERNAL;
2392 void SIG_HANDLER_SIGNATURE (mono_sigint_signal_handler)  MONO_INTERNAL;
2393 gboolean SIG_HANDLER_SIGNATURE (mono_chain_signal) MONO_INTERNAL;
2394
2395 /* for MONO_WRAPPER_UNKNOWN/MANAGED_TO_MANAGED subtypes */
2396 enum {
2397         MONO_AOT_WRAPPER_MONO_ENTER,
2398         MONO_AOT_WRAPPER_MONO_EXIT,
2399         MONO_AOT_WRAPPER_ELEMENT_ADDR,
2400         MONO_AOT_WRAPPER_PTR_TO_STRUCTURE,
2401         MONO_AOT_WRAPPER_STRUCTURE_TO_PTR,
2402         MONO_AOT_WRAPPER_CASTCLASS_WITH_CACHE,
2403         MONO_AOT_WRAPPER_LAST
2404 };
2405
2406 #endif /* __MONO_MINI_H__ */