2008-10-06 Zoltan Varga <vargaz@gmail.com>
[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 #include <mono/metadata/loader.h>
8 #include <mono/metadata/mempool.h>
9 #include <mono/utils/monobitset.h>
10 #include <mono/metadata/class.h>
11 #include <mono/metadata/object.h>
12 #include <mono/metadata/opcodes.h>
13 #include <mono/metadata/tabledefs.h>
14 #include <mono/metadata/domain-internals.h>
15 #include "mono/metadata/class-internals.h"
16 #include "mono/metadata/object-internals.h"
17 #include <mono/metadata/profiler-private.h>
18 #include <mono/metadata/debug-helpers.h>
19 #include <mono/utils/mono-compiler.h>
20
21 #define MONO_BREAKPOINT_ARRAY_SIZE 64
22
23 #include "mini-arch.h"
24 #include "regalloc.h"
25 #include "declsec.h"
26
27 #ifndef G_LIKELY
28 #define G_LIKELY(a) (a)
29 #define G_UNLIKELY(a) (a)
30 #endif
31
32 #ifndef G_MAXINT32
33 #define G_MAXINT32 2147483647
34 #endif
35
36 #ifndef G_MININT32
37 #define G_MININT32 (-G_MAXINT32 - 1)
38 #endif
39
40 #if DISABLE_LOGGING
41 #define MINI_DEBUG(level,limit,code)
42 #else
43 #define MINI_DEBUG(level,limit,code) do {if (G_UNLIKELY ((level) >= (limit))) code} while (0)
44 #endif
45
46 #define NOT_IMPLEMENTED do { g_assert_not_reached (); } while (0)
47
48 #ifndef DISABLE_AOT
49 #define MONO_USE_AOT_COMPILER
50 #endif
51
52 /* for 32 bit systems */
53 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
54 #define MINI_LS_WORD_IDX 0
55 #define MINI_MS_WORD_IDX 1
56 #else
57 #define MINI_LS_WORD_IDX 1
58 #define MINI_MS_WORD_IDX 0
59 #endif
60 #define MINI_LS_WORD_OFFSET (MINI_LS_WORD_IDX * 4)
61 #define MINI_MS_WORD_OFFSET (MINI_MS_WORD_IDX * 4)
62 #define inst_ls_word data.op[MINI_LS_WORD_IDX].const_val
63 #define inst_ms_word data.op[MINI_MS_WORD_IDX].const_val
64
65 #define MONO_FAKE_IMT_METHOD ((MonoMethod*)GINT_TO_POINTER(-1))
66 #define MONO_FAKE_VTABLE_METHOD ((MonoMethod*)GINT_TO_POINTER(-2))
67
68 /* Version number of the AOT file format */
69 #define MONO_AOT_FILE_VERSION "39"
70  
71 /* Per-domain information maintained by the JIT */
72 typedef struct
73 {
74         /* Maps MonoMethod's to a GSList of GOT slot addresses pointing to its code */
75         GHashTable *jump_target_got_slot_hash;
76         GHashTable *jump_target_hash;
77         /* Maps methods/klasses to the address of the given type of trampoline */
78         GHashTable *class_init_trampoline_hash;
79         GHashTable *jump_trampoline_hash;
80         GHashTable *jit_trampoline_hash;
81         GHashTable *delegate_trampoline_hash;
82         /* maps MonoMethod -> MonoJitDynamicMethodInfo */
83         GHashTable *dynamic_code_hash;
84         GHashTable *method_code_hash;
85 } MonoJitDomainInfo;
86
87 typedef struct {
88         MonoJitInfo *ji;
89         MonoCodeManager *code_mp;
90 } MonoJitDynamicMethodInfo;
91
92 #define domain_jit_info(domain) ((MonoJitDomainInfo*)((domain)->runtime_info))
93
94 #if 0
95 #define mono_bitset_foreach_bit(set,b,n) \
96         for (b = 0; b < n; b++)\
97                 if (mono_bitset_test_fast(set,b))
98 #define mono_bitset_foreach_bit_rev(set,b,n) \
99         for (b = n - 1; b >= 0; b--)\
100                 if (mono_bitset_test_fast(set,b))
101 #else
102 #define mono_bitset_foreach_bit(set,b,n) \
103         for (b = mono_bitset_find_start (set); b < n && b >= 0; b = mono_bitset_find_first (set, b))
104 #define mono_bitset_foreach_bit_rev(set,b,n) \
105         for (b = mono_bitset_find_last (set, n - 1); b >= 0; b = b ? mono_bitset_find_last (set, b) : -1)
106  
107 #endif
108
109 /*
110  * Pull the list of opcodes
111  */
112 #define OPDEF(a,b,c,d,e,f,g,h,i,j) \
113         a = i,
114
115 enum {
116 #include "mono/cil/opcode.def"
117         CEE_LASTOP
118 };
119 #undef OPDEF
120
121 #define MONO_VARINFO(cfg,varnum) (&(cfg)->vars [varnum])
122
123 #define MONO_INST_NEW(cfg,dest,op) do { \
124                 (dest) = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoInst));       \
125                 (dest)->opcode = (op);  \
126         (dest)->dreg = (dest)->sreg1 = (dest)->sreg2 = -1;  \
127         (dest)->cil_code = (cfg)->ip;  \
128         (dest)->cil_code = (cfg)->ip; \
129         } while (0)
130
131 #define MONO_INST_NEW_CALL(cfg,dest,op) do {    \
132                 (dest) = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoCallInst));   \
133                 (dest)->inst.opcode = (op);     \
134         (dest)->inst.dreg = (dest)->inst.sreg1 = (dest)->inst.sreg2 = -1;  \
135         (dest)->inst.cil_code = (cfg)->ip;  \
136         } while (0)
137
138 #define MONO_INST_NEW_CALL_ARG(cfg,dest,op) do {        \
139                 (dest) = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoCallArgParm));        \
140                 (dest)->ins.opcode = (op);      \
141         } while (0)
142
143 #define MONO_ADD_INS(b,inst) do {       \
144                 if ((b)->last_ins) {    \
145                         (b)->last_ins->next = (inst);   \
146             (inst)->prev = (b)->last_ins;   \
147                         (b)->last_ins = (inst); \
148                 } else {        \
149                         (b)->code = (b)->last_ins = (inst);     \
150                 }       \
151         } while (0)
152
153 #define NULLIFY_INS(ins) do { \
154         (ins)->opcode = OP_NOP; \
155         (ins)->dreg = (ins)->sreg1 = (ins)->sreg2 = -1; \
156                 (ins)->ssa_op = MONO_SSA_NOP; \
157     } while (0)
158
159 /* Remove INS from BB */
160 #define MONO_REMOVE_INS(bb,ins) do { \
161         if ((ins)->prev) \
162             (ins)->prev->next = (ins)->next; \
163         if ((ins)->next) \
164             (ins)->next->prev = (ins)->prev; \
165         if ((bb)->code == (ins)) \
166             (bb)->code = (ins)->next; \
167         if ((bb)->last_ins == (ins)) \
168             (bb)->last_ins = (ins)->prev; \
169     } while (0)
170
171 /* Remove INS from BB and nullify it */
172 #define MONO_DELETE_INS(bb,ins) do { \
173         MONO_REMOVE_INS ((bb), (ins)); \
174         NULLIFY_INS ((ins)); \
175     } while (0)
176
177 /* 
178  * this is used to determine when some branch optimizations are possible: we exclude FP compares
179  * because they have weird semantics with NaNs.
180  */
181 #define MONO_IS_COND_BRANCH_OP(ins) (((ins)->opcode >= CEE_BEQ && (ins)->opcode <= CEE_BLT_UN) || ((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))
182 #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))
183
184 #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))
185
186 #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)))
187
188 #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)))
189
190 #define MONO_IS_PHI(ins) (((ins)->opcode == OP_PHI) || ((ins)->opcode == OP_FPHI) || ((ins)->opcode == OP_VPHI))
191
192 #define MONO_IS_LOAD_MEMBASE(ins) (((ins)->opcode >= OP_LOAD_MEMBASE) && ((ins)->opcode <= OP_LOADV_MEMBASE))
193 #define MONO_IS_STORE_MEMBASE(ins) (((ins)->opcode >= OP_STORE_MEMBASE_REG) && ((ins)->opcode <= OP_STOREV_MEMBASE))
194 #define MONO_IS_STORE_MEMINDEX(ins) (((ins)->opcode >= OP_STORE_MEMINDEX) && ((ins)->opcode <= OP_STORER8_MEMINDEX))
195
196 #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))
197
198 #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)))
199
200 #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))))
201
202 /* FIXME: Add more instructions */
203 #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))
204
205
206
207 #ifdef MONO_ARCH_SIMD_INTRINSICS
208
209 #define MONO_IS_MOVE(ins) (((ins)->opcode == OP_MOVE) || ((ins)->opcode == OP_FMOVE) || ((ins)->opcode == OP_VMOVE) || ((ins)->opcode == OP_XMOVE))
210 #define MONO_IS_NON_FP_MOVE(ins) (((ins)->opcode == OP_MOVE) || ((ins)->opcode == OP_VMOVE) || ((ins)->opcode == OP_XMOVE))
211 #define MONO_IS_REAL_MOVE(ins) (((ins)->opcode == OP_MOVE) || ((ins)->opcode == OP_FMOVE) || ((ins)->opcode == OP_XMOVE))
212 #define MONO_IS_ZERO(ins) (((ins)->opcode == OP_VZERO) || ((ins)->opcode == OP_XZERO))
213
214 #define MONO_CLASS_IS_SIMD(cfg, klass) (((cfg)->opt & MONO_OPT_SIMD) && (klass)->simd_type)
215
216 #else
217
218 #define MONO_IS_MOVE(ins) (((ins)->opcode == OP_MOVE) || ((ins)->opcode == OP_FMOVE) || ((ins)->opcode == OP_VMOVE))
219 #define MONO_IS_NON_FP_MOVE(ins) (((ins)->opcode == OP_MOVE) || ((ins)->opcode == OP_VMOVE))
220 /*A real MOVE is one that isn't decomposed such as a VMOVE or LMOVE*/
221 #define MONO_IS_REAL_MOVE(ins) (((ins)->opcode == OP_MOVE) || ((ins)->opcode == OP_FMOVE))
222 #define MONO_IS_ZERO(ins) ((ins)->opcode == OP_VZERO)
223
224 #define MONO_CLASS_IS_SIMD(cfg, klass) (0)
225
226 #endif
227
228 typedef struct MonoInstList MonoInstList;
229 typedef struct MonoInst MonoInst;
230 typedef struct MonoCallInst MonoCallInst;
231 typedef struct MonoCallArgParm MonoCallArgParm;
232 typedef struct MonoEdge MonoEdge;
233 typedef struct MonoMethodVar MonoMethodVar;
234 typedef struct MonoBasicBlock MonoBasicBlock;
235 typedef struct MonoLMF MonoLMF;
236 typedef struct MonoSpillInfo MonoSpillInfo;
237 typedef struct MonoTraceSpec MonoTraceSpec;
238
239 extern guint32 mono_jit_tls_id;
240 extern MonoTraceSpec *mono_jit_trace_calls;
241 extern gboolean mono_break_on_exc;
242 extern int mono_exc_esp_offset;
243 #ifdef DISABLE_AOT
244 #define mono_compile_aot 0
245 #else
246 extern gboolean mono_compile_aot;
247 #endif
248 extern gboolean mono_aot_only;
249 extern gboolean mono_use_imt;
250 extern MonoMethodDesc *mono_inject_async_exc_method;
251 extern int mono_inject_async_exc_pos;
252 extern MonoMethodDesc *mono_break_at_bb_method;
253 extern int mono_break_at_bb_bb_num;
254 extern gboolean check_for_pending_exc;
255 extern gboolean disable_vtypes_in_regs;
256 extern gboolean mono_verify_all;
257 extern gboolean mono_dont_free_global_codeman;
258
259 #define INS_INFO(opcode) (&ins_info [((opcode) - OP_START - 1) * 3])
260
261 extern const char ins_info[];
262
263 #define MONO_BB_FOR_EACH_INS(bb, ins) for ((ins) = (bb)->code; (ins); (ins) = (ins)->next)
264
265 #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)
266
267 #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)
268
269 #define mono_bb_first_ins(bb) (bb)->code
270
271 #if 0
272
273 static inline void
274 MONO_INST_LIST_ADD_TAIL (MonoInstList *new, MonoInstList *head)
275 {
276         __MONO_INST_LIST_ADD (new, head->prev, head);
277 }
278
279 static inline void
280 __MONO_INST_LIST_DEL (MonoInstList *prev, MonoInstList *next)
281 {
282         next->prev = prev;
283         prev->next = next;
284 }
285
286 static inline void
287 __MONO_INST_LIST_SPLICE (MonoInstList *list, MonoInstList *head)
288 {
289         MonoInstList *first = list->next;
290         MonoInstList *last = list->prev;
291         MonoInstList *at = head->next;
292
293         first->prev = head;
294         head->next = first;
295
296         last->next = at;
297         at->prev = last;
298 }
299
300 static inline void
301 MONO_INST_LIST_SPLICE (MonoInstList *list, MonoInstList *head) 
302 {
303         if (!MONO_INST_LIST_EMPTY (list))
304                 __MONO_INST_LIST_SPLICE (list, head);
305 }
306
307 static inline void
308 MONO_INST_LIST_SPLICE_TAIL (MonoInstList *list, MonoInstList *head) 
309 {
310         if (!MONO_INST_LIST_EMPTY (list))
311                 __MONO_INST_LIST_SPLICE (list, head->prev);
312 }
313
314 static inline void
315 MONO_INST_LIST_SPLICE_INIT (MonoInstList *list, MonoInstList *head)
316 {
317         if (!MONO_INST_LIST_EMPTY (list)) {
318                 __MONO_INST_LIST_SPLICE (list, head);
319                 MONO_INST_LIST_INIT (list);
320         }
321 }
322
323 static inline void
324 MONO_INST_LIST_SPLICE_TAIL_INIT (MonoInstList *list, MonoInstList *head)
325 {
326         if (!MONO_INST_LIST_EMPTY (list)) {
327                 __MONO_INST_LIST_SPLICE (list, head->prev);
328                 MONO_INST_LIST_INIT (list);
329         }
330 }
331
332 /*#define mono_container_of(ptr, type, member) ({                       \
333         const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
334         (type *)( (char *)__mptr - offsetof(type,member) );})
335
336 #define MONO_INST_LIST_ENTRY(ptr, type, member) \
337         mono_container_of(ptr, type, member)*/
338
339 #define MONO_INST_LIST_ENTRY(ptr, type, member) \
340         ((type *)(gpointer)(ptr))
341
342 #define MONO_INST_LIST_FIRST_ENTRY(ptr, type, member) \
343         MONO_INST_LIST_ENTRY((ptr)->next, type, member)
344
345 #define MONO_INST_LIST_LAST_ENTRY(ptr, type, member) \
346         MONO_INST_LIST_ENTRY((ptr)->prev, type, member)
347
348 #define MONO_INST_LIST_FOR_EACH(pos, head) \
349         for (pos = (head)->next; pos != (head); pos = pos->next)
350
351 #define MONO_INST_LIST_FOR_EACH_PREV(pos, head) \
352         for (pos = (head)->prev; pos != (head); pos = pos->prev)
353
354 #define MONO_INST_LIST_FOR_EACH_SAFE(pos, n, head) \
355         for (pos = (head)->next, n = pos->next; pos != (head); \
356                 pos = n, n = pos->next)
357
358 #define MONO_INST_LIST_FOR_EACH_PREV_SAFE(pos, n, head) \
359         for (pos = (head)->prev, n = pos->prev; pos != (head); \
360                 pos = n, n = pos->prev)
361
362 #define MONO_INST_LIST_FOR_EACH_ENTRY(pos, head, member) \
363         for (pos = MONO_INST_LIST_ENTRY ((head)->next, MonoInst, member);\
364              &pos->member != (head);\
365              pos = MONO_INST_LIST_ENTRY (pos->member.next, MonoInst, member))
366
367 #define MONO_INST_LIST_FOR_EACH_ENTRY_REVERSE(pos, head, member) \
368         for (pos = MONO_INST_LIST_ENTRY ((head)->prev, MonoInst, member);\
369              &pos->member != (head);\
370              pos = MONO_INST_LIST_ENTRY (pos->member.prev, MonoInst, member))
371
372 #define MONO_INST_LIST_FOR_EACH_ENTRY_SAFE(pos, n, head, member) \
373         for (pos = MONO_INST_LIST_ENTRY ((head)->next, MonoInst, member),\
374                 n = MONO_INST_LIST_ENTRY (pos->member.next, MonoInst, member);\
375              &pos->member != (head);                                    \
376              pos = n, n = MONO_INST_LIST_ENTRY (n->member.next, MonoInst, member))
377
378 #define MONO_BB_FOR_EACH_INS(bb, ins) MONO_INST_LIST_FOR_EACH_ENTRY ((ins), &((bb)->ins_list), node)
379
380 #define MONO_BB_FOR_EACH_INS_SAFE(bb, next, ins) MONO_INST_LIST_FOR_EACH_ENTRY_SAFE ((ins), (next), &((bb)->ins_list), node)
381
382 #define MONO_BB_FOR_EACH_INS_REVERSE(bb, ins) MONO_INST_LIST_FOR_EACH_ENTRY_REVERSE ((ins), &((bb)->ins_list), node)
383
384 #endif
385
386 struct MonoEdge {
387         MonoEdge *next;
388         MonoBasicBlock *bb;
389         /* add edge type? */
390 };
391
392 struct MonoSpillInfo {
393         int offset;
394 };
395
396 /*
397  * The IR-level extended basic block.  
398  *
399  * A basic block can have multiple exits just fine, as long as the point of
400  * 'departure' is the last instruction in the basic block. Extended basic
401  * blocks, on the other hand, may have instructions that leave the block
402  * midstream. The important thing is that they cannot be _entered_
403  * midstream, ie, execution of a basic block (or extened bb) always start
404  * at the beginning of the block, never in the middle.
405  */
406 struct MonoBasicBlock {
407         MonoInst *last_ins;
408
409         /* the next basic block in the order it appears in IL */
410         MonoBasicBlock *next_bb;
411
412         /*
413          * Before instruction selection it is the first tree in the
414          * forest and the first item in the list of trees. After
415          * instruction selection it is the first instruction and the
416          * first item in the list of instructions.
417          */
418         MonoInst *code;
419
420         /* unique block number identification */
421         gint32 block_num;
422         
423         gint32 dfn;
424
425         /* Basic blocks: incoming and outgoing counts and pointers */
426         /* Each bb should only appear once in each array */
427         gint16 out_count, in_count;
428         MonoBasicBlock **in_bb;
429         MonoBasicBlock **out_bb;
430
431         /* Points to the start of the CIL code that initiated this BB */
432         unsigned char* cil_code;
433
434         /* Length of the CIL block */
435         gint32 cil_length;
436
437         /* The address of the generated code, used for fixups */
438         int native_offset;
439         int max_offset;
440
441         /* Visited and reachable flags */
442         guint32 flags;
443
444         /*
445          * SSA and loop based flags
446          */
447         MonoBitSet *dominators;
448         MonoBitSet *dfrontier;
449         MonoBasicBlock *idom;
450         GSList *dominated;
451         /* fast dominator algorithm */
452         MonoBasicBlock *df_parent, *ancestor, *child, *label;
453         MonoEdge *bucket;
454         int size, sdom, idomn;
455         
456         /* loop nesting and recognition */
457         GList *loop_blocks;
458         gint8  nesting;
459         gint8  loop_body_start;
460
461         /* 
462          * Whenever the bblock is rarely executed so it should be emitted after
463          * the function epilog.
464          */
465         guint out_of_line : 1;
466         /* Caches the result of uselessness calculation during optimize_branches */
467         guint not_useless : 1;
468         /* Whenever the decompose_array_access_opts () pass needs to process this bblock */
469         guint has_array_access : 1;
470         /* Whenever this bblock is extended, ie. it has branches inside it */
471         guint extended : 1;
472         
473         /* use for liveness analysis */
474         MonoBitSet *gen_set;
475         MonoBitSet *kill_set;
476         MonoBitSet *live_in_set;
477         MonoBitSet *live_out_set;
478
479         /* fields to deal with non-empty stack slots at bb boundary */
480         guint16 out_scount, in_scount;
481         MonoInst **out_stack;
482         MonoInst **in_stack;
483
484         /* we use that to prevent merging of bblocks covered by different clauses*/
485         guint real_offset;
486
487         /*
488          * The region encodes whether the basic block is inside
489          * a finally, catch, filter or none of these.
490          *
491          * If the value is -1, then it is neither finally, catch nor filter
492          *
493          * Otherwise the format is:
494          *
495          *  Bits: |     0-3      |       4-7      |     8-31
496          *        |              |                |
497          *        | clause-flags |   MONO_REGION  | clause-index 
498          *
499          */
500         guint region;
501
502         /* The current symbolic register number, used in local register allocation. */
503         guint32 max_vreg;
504 };
505
506 /* BBlock flags */
507 enum {
508         BB_VISITED            = 1 << 0,
509         BB_REACHABLE          = 1 << 1,
510         BB_EXCEPTION_DEAD_OBJ = 1 << 2,
511         BB_EXCEPTION_UNSAFE   = 1 << 3,
512         BB_EXCEPTION_HANDLER  = 1 << 4
513 };
514
515 typedef struct MonoMemcpyArgs {
516         int size, align;
517 } MonoMemcpyArgs;
518
519 struct MonoInst {
520         guint16 opcode;
521         guint8  type; /* stack type */
522         guint   ssa_op : 3;
523         guint8  flags  : 5;
524         
525         /* used by the register allocator */
526         gint32 dreg, sreg1, sreg2;
527
528         MonoInst *next, *prev;
529
530         union {
531                 union {
532                         MonoInst *src;
533                         MonoMethodVar *var;
534                         gssize const_val;
535                         gpointer p;
536                         MonoMethod *method;
537                         MonoMethodSignature *signature;
538                         MonoBasicBlock **many_blocks;
539                         MonoBasicBlock *target_block;
540                         MonoInst **args;
541                         MonoType *vtype;
542                         MonoClass *klass;
543                         int *phi_args;
544                         MonoCallInst *call_inst;
545                 } op [2];
546                 gint64 i8const;
547                 double r8const;
548         } data;
549
550         const unsigned char* cil_code; /* for debugging and bblock splitting */
551
552         /* used mostly by the backend to store additional info it may need */
553         union {
554                 gint32 reg3;
555                 gint32 arg_info;
556                 gint32 size;
557                 MonoMemcpyArgs *memcpy_args; /* in OP_MEMSET and OP_MEMCPY */
558                 gpointer data;
559                 gint shift_amount;
560                 gboolean is_pinvoke; /* for variables in the unmanaged marshal format */
561                 gboolean record_cast_details; /* For CEE_CASTCLASS */
562                 MonoInst *spill_var; /* for OP_ICONV_TO_R8_RAW */
563         } backend;
564         
565         MonoClass *klass;
566 };
567         
568 struct MonoCallInst {
569         MonoInst inst;
570         MonoMethodSignature *signature;
571         MonoMethod *method;
572         MonoInst **args;
573         MonoInst *out_args;
574         MonoInst *vret_var;
575         gconstpointer fptr;
576         guint stack_usage;
577         guint virtual : 1;
578         guint tail_call : 1;
579         /* If this is TRUE, 'fptr' points to a MonoJumpInfo instead of an address. */
580         guint fptr_is_patch : 1;
581         /*
582          * If this is true, then the call returns a vtype in a register using the same 
583          * calling convention as OP_CALL.
584          */
585         guint vret_in_reg : 1;
586         /* Whenever there is an IMT argument and it is dynamic */
587         guint dynamic_imt_arg : 1;
588         regmask_t used_iregs;
589         regmask_t used_fregs;
590         GSList *out_ireg_args;
591         GSList *out_freg_args;
592 };
593
594 struct MonoCallArgParm {
595         MonoInst ins;
596         gint32 size;
597         gint32 offset;
598         gint32 offPrm;
599 };
600
601 /* 
602  * flags for MonoInst
603  * Note: some of the values overlap, because they can't appear
604  * in the same MonoInst.
605  */
606 enum {
607         MONO_INST_HAS_METHOD = 1,
608         /* temp local created by a DUP: used only within a BB */
609         MONO_INST_IS_TEMP    = 1,
610         MONO_INST_INIT       = 1, /* in localloc */
611         MONO_INST_IS_DEAD    = 2,
612         MONO_INST_TAILCALL   = 4,
613         MONO_INST_VOLATILE   = 4,
614         MONO_INST_BRLABEL    = 4,
615         MONO_INST_NOTYPECHECK    = 4,
616         MONO_INST_UNALIGNED  = 8,
617     MONO_INST_CFOLD_TAKEN = 8, /* On branches */
618     MONO_INST_CFOLD_NOT_TAKEN = 16, /* On branches */
619         MONO_INST_DEFINITION_HAS_SIDE_EFFECTS = 8,
620         /* the address of the variable has been taken */
621         MONO_INST_INDIRECT   = 16,
622         MONO_INST_NORANGECHECK   = 16
623 };
624
625 #define inst_c0 data.op[0].const_val
626 #define inst_c1 data.op[1].const_val
627 #define inst_i0 data.op[0].src
628 #define inst_i1 data.op[1].src
629 #define inst_p0 data.op[0].p
630 #define inst_p1 data.op[1].p
631 #define inst_l  data.i8const
632 #define inst_r  data.r8const
633 #define inst_left  data.op[0].src
634 #define inst_right data.op[1].src
635
636 #define inst_newa_len   data.op[0].src
637 #define inst_newa_class data.op[1].klass
638
639 #define inst_var    data.op[0].var
640 #define inst_vtype  data.op[1].vtype
641 /* in branch instructions */
642 #define inst_many_bb   data.op[1].many_blocks
643 #define inst_target_bb data.op[0].target_block
644 #define inst_true_bb   data.op[1].many_blocks[0]
645 #define inst_false_bb  data.op[1].many_blocks[1]
646
647 #define inst_basereg sreg1
648 #define inst_indexreg sreg2
649 #define inst_destbasereg dreg
650 #define inst_offset data.op[0].const_val
651 #define inst_imm    data.op[1].const_val
652 #define inst_call   data.op[1].call_inst
653
654 #define inst_phi_args   data.op[1].phi_args
655
656 /* instruction description for use in regalloc/scheduling */
657 enum {
658         MONO_INST_DEST,
659         MONO_INST_SRC1,
660         MONO_INST_SRC2,
661         MONO_INST_LEN,
662         MONO_INST_CLOB,
663         /* Unused, commented out to reduce the size of the mdesc tables
664         MONO_INST_FLAGS,
665         MONO_INST_COST,
666         MONO_INST_DELAY,
667         MONO_INST_RES,
668         */
669         MONO_INST_MAX
670 };
671
672 typedef union {
673         struct {
674                 guint16 tid; /* tree number */
675                 guint16 bid; /* block number */
676         } pos ;
677         guint32 abs_pos; 
678 } MonoPosition;
679
680 typedef struct {
681         MonoPosition first_use, last_use;
682 } MonoLiveRange;
683
684 typedef struct MonoLiveRange2 MonoLiveRange2;
685
686 struct MonoLiveRange2 {
687         int from, to;
688         MonoLiveRange2 *next;
689 };
690
691 typedef struct {
692         /* List of live ranges sorted by 'from' */
693         MonoLiveRange2 *range;
694         MonoLiveRange2 *last_range;
695 } MonoLiveInterval;
696
697 /*
698  * Additional information about a variable
699  */
700 struct MonoMethodVar {
701         guint           idx; /* inside cfg->varinfo, cfg->vars */
702         MonoLiveRange   range; /* generated by liveness analysis */
703         MonoLiveInterval *interval; /* generated by liveness analysis */
704         int             reg; /* != -1 if allocated into a register */
705         int             spill_costs;
706         MonoBitSet     *def_in; /* used by SSA */
707         MonoInst       *def;    /* used by SSA */
708         MonoBasicBlock *def_bb; /* used by SSA */
709         GList          *uses;   /* used by SSA */
710         char            cpstate;  /* used by SSA conditional  constant propagation */
711 };
712
713 typedef struct {
714         gpointer          end_of_stack;
715         guint32           stack_size;
716 #if !defined(HAVE_KW_THREAD) || !defined(MONO_ARCH_ENABLE_MONO_LMF_VAR)
717         MonoLMF          *lmf;
718 #endif
719         MonoLMF          *first_lmf;
720         gpointer         restore_stack_prot;
721         guint32          handling_stack_ovf;
722         gpointer         signal_stack;
723         guint32          signal_stack_size;
724         gpointer         stack_ovf_guard_base;
725         guint32          stack_ovf_guard_size;
726         void            (*abort_func) (MonoObject *object);
727         /* Used to implement --debug=casts */
728         MonoClass       *class_cast_from, *class_cast_to;
729 } MonoJitTlsData;
730
731 typedef enum {
732 #define PATCH_INFO(a,b) MONO_PATCH_INFO_ ## a,
733 #include "patch-info.h"
734 #undef PATCH_INFO
735         MONO_PATCH_INFO_NUM
736 } MonoJumpInfoType;
737
738 /*
739  * We need to store the image which the token refers to along with the token,
740  * since the image might not be the same as the image of the method which
741  * contains the relocation, because of inlining.
742  */
743 typedef struct MonoJumpInfoToken {
744         MonoImage *image;
745         guint32 token;
746 } MonoJumpInfoToken;
747
748 typedef struct MonoJumpInfoBBTable {
749         MonoBasicBlock **table;
750         int table_size;
751 } MonoJumpInfoBBTable;
752
753 typedef struct MonoJumpInfoRgctxEntry MonoJumpInfoRgctxEntry;
754
755 typedef struct MonoJumpInfo MonoJumpInfo;
756 struct MonoJumpInfo {
757         MonoJumpInfo *next;
758         union {
759                 int i;
760                 guint8 *p;
761                 MonoInst *label;
762         } ip;
763
764         MonoJumpInfoType type;
765         union {
766                 gconstpointer   target;
767 #if SIZEOF_VOID_P == 8
768                 gint64          offset;
769 #else
770                 int             offset;
771 #endif
772                 MonoBasicBlock *bb;
773                 MonoInst       *inst;
774                 MonoMethod     *method;
775                 MonoClass      *klass;
776                 MonoClassField *field;
777                 MonoImage      *image;
778                 MonoVTable     *vtable;
779                 const char     *name;
780                 MonoJumpInfoToken  *token;
781                 MonoJumpInfoBBTable *table;
782                 MonoJumpInfoRgctxEntry *rgctx_entry;
783         } data;
784 };
785  
786 /* Contains information describing an rgctx entry */
787 struct MonoJumpInfoRgctxEntry {
788         MonoMethod *method;
789         gboolean in_mrgctx;
790         MonoJumpInfo *data; /* describes the data to be loaded */
791         int info_type;
792 };
793
794 typedef enum {
795         MONO_TRAMPOLINE_JIT,
796         MONO_TRAMPOLINE_JUMP,
797         MONO_TRAMPOLINE_CLASS_INIT,
798         MONO_TRAMPOLINE_GENERIC_CLASS_INIT,
799         MONO_TRAMPOLINE_RGCTX_LAZY_FETCH,
800         MONO_TRAMPOLINE_AOT,
801         MONO_TRAMPOLINE_AOT_PLT,
802         MONO_TRAMPOLINE_DELEGATE,
803         MONO_TRAMPOLINE_RESTORE_STACK_PROT,
804         MONO_TRAMPOLINE_NUM
805 } MonoTrampolineType;
806
807 /* optimization flags */
808 #define OPTFLAG(id,shift,name,descr) MONO_OPT_ ## id = 1 << shift,
809 enum {
810 #include "optflags-def.h"
811         MONO_OPT_LAST
812 };
813
814 /* Bit-fields in the MonoBasicBlock.region */
815 #define MONO_REGION_TRY       0
816 #define MONO_REGION_FINALLY  16
817 #define MONO_REGION_CATCH    32
818 #define MONO_REGION_FAULT    64         /* Currently unused */
819 #define MONO_REGION_FILTER  128
820
821 #define MONO_BBLOCK_IS_IN_REGION(bblock, regtype) (((bblock)->region & (0xf << 4)) == (regtype))
822
823 #define get_vreg_to_inst(cfg, vreg) ((vreg) < (cfg)->vreg_to_inst_len ? (cfg)->vreg_to_inst [(vreg)] : NULL)
824
825 #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))))
826
827 /*
828  * Control Flow Graph and compilation unit information
829  */
830 typedef struct {
831         MonoMethod      *method;
832         MonoMemPool     *mempool;
833         MonoInst       **varinfo;
834         MonoMethodVar   *vars;
835         MonoInst        *ret;
836         MonoBasicBlock  *bb_entry;
837         MonoBasicBlock  *bb_exit;
838         MonoBasicBlock  *bb_init;
839         MonoBasicBlock **bblocks;
840         MonoBasicBlock **cil_offset_to_bb;
841         MonoMemPool     *state_pool; /* used by instruction selection */
842         MonoBasicBlock  *cbb;        /* used by instruction selection */
843         MonoInst        *prev_ins;   /* in decompose */
844         MonoJumpInfo    *patch_info;
845         MonoJitInfo     *jit_info;
846         MonoJitDynamicMethodInfo *dynamic_info;
847         guint            num_bblocks;
848         guint            locals_start;
849         guint            num_varinfo; /* used items in varinfo */
850         guint            varinfo_count; /* total storage in varinfo */
851         gint             stack_offset;
852         gint             max_ireg;
853         gint             cil_offset_to_bb_len;
854         MonoRegState    *rs;
855         MonoSpillInfo   *spill_info [16]; /* machine register spills */
856         gint             spill_count;
857         gint             spill_info_len [16];
858         /* unsigned char   *cil_code; */
859         MonoMethod      *inlined_method; /* the method which is currently inlined */
860         MonoInst        *domainvar; /* a cache for the current domain */
861         MonoInst        *got_var; /* Global Offset Table variable */
862         MonoInst        **locals;
863         MonoInst        *rgctx_var; /* Runtime generic context variable (for static generic methods) */
864         MonoInst        **args;
865         MonoType        **arg_types;
866         MonoMethod      *current_method; /* The method currently processed by method_to_ir () */
867         MonoGenericContext *generic_context;
868
869         /* 
870          * This variable represents the hidden argument holding the vtype
871          * return address. If the method returns something other than a vtype, or
872          * the vtype is returned in registers this is NULL.
873          */
874         MonoInst        *vret_addr;
875
876         /*
877          * This is used to initialize the cil_code field of MonoInst's.
878          */
879         const unsigned char *ip;
880         
881         struct MonoAliasingInformation *aliasing_info;
882
883         /* A hashtable of region ID-> SP var mappings */
884         /* An SP var is a place to store the stack pointer (used by handlers)*/
885         GHashTable      *spvars;
886
887         /* A hashtable of region ID -> EX var mappings */
888         /* An EX var stores the exception object passed to catch/filter blocks */
889         GHashTable      *exvars;
890
891         GList           *ldstr_list; /* used by AOT */
892         
893         MonoDomain      *domain;
894
895         guint            real_offset;
896         GHashTable      *cbb_hash;
897
898         /* The current virtual register number */
899         guint32 next_vreg;
900
901         MonoGenericSharingContext *generic_sharing_context;
902
903         unsigned char   *cil_start;
904         unsigned char   *native_code;
905         guint            code_size;
906         guint            code_len;
907         guint            prolog_end;
908         guint            epilog_begin;
909         regmask_t        used_int_regs;
910         guint32          opt;
911         guint32          prof_options;
912         guint32          flags;
913         guint32          comp_done;
914         guint32          verbose_level;
915         guint32          stack_usage;
916         guint32          param_area;
917         guint32          frame_reg;
918         gint32           sig_cookie;
919         guint            disable_aot : 1;
920         guint            disable_ssa : 1;
921         guint            enable_extended_bblocks : 1;
922         guint            run_cctors : 1;
923         guint            need_lmf_area : 1;
924         guint            compile_aot : 1;
925         guint            got_var_allocated : 1;
926         guint            ret_var_is_local : 1;
927         guint            ret_var_set : 1;
928         guint            new_ir : 1;
929         guint            globalra : 1;
930         guint            unverifiable : 1;
931         guint            skip_visibility : 1;
932         guint            disable_reuse_registers : 1;
933         guint            disable_reuse_stack_slots : 1;
934         guint            disable_initlocals_opt : 1;
935         guint            disable_omit_fp : 1;
936         guint            disable_vreg_to_lvreg : 1;
937         guint            has_got_slots : 1;
938         guint            uses_rgctx_reg : 1;
939         guint            uses_vtable_reg : 1;
940         guint            uses_simd_intrinsics : 1;
941         gpointer         debug_info;
942         guint32          lmf_offset;
943     guint16          *intvars;
944         MonoProfileCoverageInfo *coverage_info;
945         GHashTable       *token_info_hash;
946         MonoCompileArch  arch;
947         guint32          exception_type;        /* MONO_EXCEPTION_* */
948         guint32          exception_data;
949         char*            exception_message;
950         gpointer         exception_ptr;
951
952         /* Fields used by the local reg allocator */
953         void*            reginfo;
954         int              reginfo_len;
955
956         /* Maps vregs to their associated MonoInst's */
957         /* vregs with an associated MonoInst are 'global' while others are 'local' */
958         MonoInst **vreg_to_inst;
959
960         /* Size of above array */
961         guint32 vreg_to_inst_len;
962
963         /* 
964          * The original method to compile, differs from 'method' when doing generic
965          * sharing.
966          */
967         MonoMethod *orig_method;
968
969         /* Patches which describe absolute addresses embedded into the native code */
970         GHashTable *abs_patches;
971
972         /* If the arch passes valuetypes by address, then for methods
973            which use JMP the arch code should use these local
974            variables to store the addresses of incoming valuetypes.
975            The addresses should be stored in mono_arch_emit_prolog()
976            and can be used when emitting code for OP_JMP.  See
977            mini-ppc.c. */
978         MonoInst **tailcall_valuetype_addrs;
979
980         /* Used to implement iconv_to_r8_raw on archs that can't do raw
981         copy between an ireg and a freg*/
982         MonoInst *iconv_raw_var;
983 } MonoCompile;
984
985 typedef enum {
986         MONO_CFG_HAS_ALLOCA = 1 << 0,
987         MONO_CFG_HAS_CALLS  = 1 << 1,
988         MONO_CFG_HAS_LDELEMA  = 1 << 2,
989         MONO_CFG_HAS_VARARGS  = 1 << 3,
990         MONO_CFG_HAS_TAIL     = 1 << 4,
991         MONO_CFG_HAS_FPOUT    = 1 << 5, /* there are fp values passed in int registers */
992         MONO_CFG_HAS_SPILLUP  = 1 << 6, /* spill var slots are allocated from bottom to top */
993         MONO_CFG_HAS_CHECK_THIS  = 1 << 7,
994         MONO_CFG_HAS_ARRAY_ACCESS = 1 << 8
995 } MonoCompileFlags;
996
997 typedef struct {
998         gulong methods_compiled;
999         gulong methods_aot;
1000         gulong methods_lookups;
1001         gulong method_trampolines;
1002         gulong allocate_var;
1003         gulong cil_code_size;
1004         gulong native_code_size;
1005         gulong code_reallocs;
1006         gulong max_code_size_ratio;
1007         gulong biggest_method_size;
1008         gulong allocated_code_size;
1009         gulong inlineable_methods;
1010         gulong inlined_methods;
1011         gulong basic_blocks;
1012         gulong max_basic_blocks;
1013         gulong locals_stack_size;
1014         gulong regvars;
1015         gulong cas_declsec_check;
1016         gulong cas_linkdemand_icall;
1017         gulong cas_linkdemand_pinvoke;
1018         gulong cas_linkdemand_aptc;
1019         gulong cas_linkdemand;
1020         gulong cas_demand_generation;
1021         gulong generic_virtual_invocations;
1022         char *max_ratio_method;
1023         char *biggest_method;
1024         gboolean enabled;
1025 } MonoJitStats;
1026
1027 extern MonoJitStats mono_jit_stats;
1028
1029 /* values for MonoInst.ssa_op */
1030 enum {
1031         MONO_SSA_NOP = 0,
1032         MONO_SSA_ADDRESS_TAKEN = 1,
1033         MONO_SSA_LOAD = 2,
1034         MONO_SSA_STORE = 4,
1035         MONO_SSA_LOAD_STORE = MONO_SSA_LOAD|MONO_SSA_STORE,
1036         MONO_SSA_INDIRECT_LOAD = MONO_SSA_LOAD|MONO_SSA_ADDRESS_TAKEN,
1037         MONO_SSA_INDIRECT_STORE = MONO_SSA_STORE|MONO_SSA_ADDRESS_TAKEN,
1038         MONO_SSA_INDIRECT_LOAD_STORE =
1039         MONO_SSA_LOAD|MONO_SSA_STORE|MONO_SSA_ADDRESS_TAKEN
1040 };
1041
1042 /* opcodes: value assigned after all the CIL opcodes */
1043 #ifdef MINI_OP
1044 #undef MINI_OP
1045 #endif
1046 #define MINI_OP(a,b,dest,src1,src2) a,
1047 enum {
1048         OP_START = MONO_CEE_LAST - 1,
1049 #include "mini-ops.h"
1050         OP_LAST
1051 };
1052 #undef MINI_OP
1053
1054 /* Can't use the same with both JITs since that would break the burg rules */
1055 #if defined(NEW_IR)
1056
1057 #if SIZEOF_VOID_P == 8
1058 #define OP_PCONST OP_I8CONST
1059 #define OP_PADD OP_LADD
1060 #define OP_PADD_IMM OP_LADD_IMM
1061 #define OP_PSUB OP_LSUB
1062 #define OP_PMUL OP_LMUL
1063 #define OP_PMUL_IMM OP_LMUL_IMM
1064 #define OP_PNEG OP_LNEG
1065 #define OP_PCONV_TO_I1 OP_LCONV_TO_I1
1066 #define OP_PCONV_TO_U1 OP_LCONV_TO_U1
1067 #define OP_PCONV_TO_I2 OP_LCONV_TO_I2
1068 #define OP_PCONV_TO_U2 OP_LCONV_TO_U2
1069 #define OP_PCONV_TO_OVF_I1_UN OP_LCONV_TO_OVF_I1_UN
1070 #define OP_PCONV_TO_OVF_I1 OP_LCONV_TO_OVF_I1
1071 #define OP_PBEQ OP_LBEQ
1072 #define OP_PCEQ OP_LCEQ
1073 #define OP_PBNE_UN OP_LBNE_UN
1074 #define OP_PBGE_UN OP_LBGE_UN
1075 #define OP_PBLT_UN OP_LBLT_UN
1076 #define OP_PBGE OP_LBGE
1077 #define OP_STOREP_MEMBASE_REG OP_STOREI8_MEMBASE_REG
1078 #define OP_STOREP_MEMBASE_IMM OP_STOREI8_MEMBASE_IMM
1079 #else
1080 #define OP_PCONST OP_ICONST
1081 #define OP_PADD OP_IADD
1082 #define OP_PADD_IMM OP_IADD_IMM
1083 #define OP_PSUB OP_ISUB
1084 #define OP_PMUL OP_IMUL
1085 #define OP_PMUL_IMM OP_IMUL_IMM
1086 #define OP_PNEG OP_INEG
1087 #define OP_PCONV_TO_U2 OP_ICONV_TO_U2
1088 #define OP_PCONV_TO_OVF_I1_UN OP_ICONV_TO_OVF_I1_UN
1089 #define OP_PCONV_TO_OVF_I1 OP_ICONV_TO_OVF_I1
1090 #define OP_PBEQ OP_IBEQ
1091 #define OP_PCEQ OP_ICEQ
1092 #define OP_PBNE_UN OP_IBNE_UN
1093 #define OP_PBGE_UN OP_IBGE_UN
1094 #define OP_PBLT_UN OP_IBLT_UN
1095 #define OP_PBGE OP_IBGE
1096 #define OP_STOREP_MEMBASE_REG OP_STOREI4_MEMBASE_REG
1097 #define OP_STOREP_MEMBASE_IMM OP_STOREI4_MEMBASE_IMM
1098 #endif
1099
1100 #else
1101
1102 #if SIZEOF_VOID_P == 8
1103 #define OP_PCONST OP_I8CONST
1104 #define OP_PADD OP_LADD
1105 #define OP_PADD_IMM OP_LADD_IMM
1106 #define OP_PNEG OP_LNEG
1107 #define OP_PCONV_TO_I1 OP_LCONV_TO_I1
1108 #define OP_PCONV_TO_U1 OP_LCONV_TO_U1
1109 #define OP_PCONV_TO_I2 OP_LCONV_TO_I2
1110 #define OP_PCONV_TO_U2 OP_LCONV_TO_U2
1111 #define OP_PCONV_TO_OVF_I1_UN OP_LCONV_TO_OVF_I1_UN
1112 #define OP_PCONV_TO_OVF_I1 OP_LCONV_TO_OVF_I1
1113 #define OP_PBEQ OP_LBEQ
1114 #define OP_PCEQ CEE_CEQ
1115 #define OP_STOREP_MEMBASE_REG OP_STOREI8_MEMBASE_REG
1116 #define OP_STOREP_MEMBASE_IMM OP_STOREI8_MEMBASE_IMM
1117 #else
1118 #define OP_PCONST OP_ICONST
1119 #define OP_PADD CEE_ADD
1120 #define OP_PADD2 OP_IADD
1121 #define OP_PNEG CEE_NEG
1122 #define OP_PCONV_TO_I1 OP_ICONV_TO_I1
1123 #define OP_PCONV_TO_U1 OP_ICONV_TO_U1
1124 #define OP_PCONV_TO_I2 OP_ICONV_TO_I2
1125 #define OP_PCONV_TO_U2 CEE_CONV_U2
1126 #define OP_PCONV_TO_OVF_I1_UN CEE_CONV_OVF_I1_UN
1127 #define OP_PCONV_TO_OVF_I1 CEE_CONV_OVF_I1
1128 #define OP_PBEQ OP_IBEQ
1129 #define OP_PCEQ CEE_CEQ
1130 #define OP_STOREP_MEMBASE_REG OP_STOREI4_MEMBASE_REG
1131 #define OP_STOREP_MEMBASE_IMM OP_STOREI4_MEMBASE_IMM
1132 #endif
1133
1134 #endif
1135
1136 typedef enum {
1137         STACK_INV,
1138         STACK_I4,
1139         STACK_I8,
1140         STACK_PTR,
1141         STACK_R8,
1142         STACK_MP,
1143         STACK_OBJ,
1144         STACK_VTYPE,
1145         STACK_MAX
1146 } MonoStackType;
1147
1148 typedef struct {
1149         union {
1150                 double   r8;
1151                 gint32   i4;
1152                 gint64   i8;
1153                 gpointer p;
1154                 MonoClass *klass;
1155         } data;
1156         int type;
1157 } StackSlot;
1158
1159 #if HAVE_ARRAY_ELEM_INIT
1160 extern const guint8 mono_burg_arity [];
1161 #else
1162 extern guint8 mono_burg_arity [];
1163 #endif
1164
1165 extern const char MONO_ARCH_CPU_SPEC [] MONO_INTERNAL;
1166 #define MONO_ARCH_CPU_SPEC_IDX_COMBINE(a) a ## _idx
1167 #define MONO_ARCH_CPU_SPEC_IDX(a) MONO_ARCH_CPU_SPEC_IDX_COMBINE(a)
1168 extern const guint16 MONO_ARCH_CPU_SPEC_IDX(MONO_ARCH_CPU_SPEC) [] MONO_INTERNAL;
1169 #define ins_get_spec(op) ((const char*)&MONO_ARCH_CPU_SPEC + MONO_ARCH_CPU_SPEC_IDX(MONO_ARCH_CPU_SPEC)[(op)])
1170
1171 enum {
1172         MONO_COMP_DOM = 1,
1173         MONO_COMP_IDOM = 2,
1174         MONO_COMP_DFRONTIER = 4,
1175         MONO_COMP_DOM_REV = 8,
1176         MONO_COMP_LIVENESS = 16,
1177         MONO_COMP_SSA = 32,
1178         MONO_COMP_SSA_DEF_USE = 64,
1179         MONO_COMP_REACHABILITY = 128,
1180         MONO_COMP_LOOPS = 256
1181 };
1182
1183 typedef enum {
1184         MONO_GRAPH_CFG = 1,
1185         MONO_GRAPH_DTREE = 2,
1186         MONO_GRAPH_CFG_CODE = 4,
1187         MONO_GRAPH_CFG_SSA = 8,
1188         MONO_GRAPH_CFG_OPTCODE = 16
1189 } MonoGraphOptions;
1190
1191 typedef struct {
1192         guint16 size;
1193         guint16 offset;
1194         guint8  pad;
1195 } MonoJitArgumentInfo;
1196
1197 typedef struct {
1198         gboolean handle_sigint;
1199         gboolean keep_delegates;
1200         gboolean collect_pagefault_stats;
1201         gboolean break_on_unverified;
1202         gboolean better_cast_details;
1203         gboolean mdb_optimizations;
1204         gboolean no_gdb_backtrace;
1205 } MonoDebugOptions;
1206
1207 enum {
1208         BRANCH_NOT_TAKEN,
1209         BRANCH_TAKEN,
1210         BRANCH_UNDEF
1211 };
1212
1213 typedef enum {
1214         CMP_EQ,
1215         CMP_NE,
1216         CMP_LE,
1217         CMP_GE,
1218         CMP_LT,
1219         CMP_GT,
1220         CMP_LE_UN,
1221         CMP_GE_UN,
1222         CMP_LT_UN,
1223         CMP_GT_UN
1224 } CompRelation;
1225
1226 typedef enum {
1227         CMP_TYPE_L,
1228         CMP_TYPE_I,
1229         CMP_TYPE_F
1230 } CompType;
1231
1232 /* Implicit exceptions */
1233 enum {
1234         MONO_EXC_INDEX_OUT_OF_RANGE,
1235         MONO_EXC_OVERFLOW,
1236         MONO_EXC_ARITHMETIC,
1237         MONO_EXC_DIVIDE_BY_ZERO,
1238         MONO_EXC_INVALID_CAST,
1239         MONO_EXC_NULL_REF,
1240         MONO_EXC_ARRAY_TYPE_MISMATCH,
1241         MONO_EXC_INTRINS_NUM
1242 };
1243
1244 enum {
1245         MINI_TOKEN_SOURCE_CLASS,
1246         MINI_TOKEN_SOURCE_METHOD,
1247         MINI_TOKEN_SOURCE_FIELD
1248 };
1249
1250 typedef void (*MonoInstFunc) (MonoInst *tree, gpointer data);
1251
1252 /* main function */
1253 int         mono_main                      (int argc, char* argv[]);
1254 void        mono_set_defaults              (int verbose_level, guint32 opts);
1255 MonoDomain* mini_init                      (const char *filename, const char *runtime_version) MONO_INTERNAL;
1256 void        mini_cleanup                   (MonoDomain *domain) MONO_INTERNAL;
1257 MonoDebugOptions *mini_get_debug_options   (void) MONO_INTERNAL;
1258
1259 /* helper methods */
1260 MonoJumpInfoToken * mono_jump_info_token_new (MonoMemPool *mp, MonoImage *image, guint32 token) MONO_INTERNAL;
1261 MonoInst* mono_find_spvar_for_region        (MonoCompile *cfg, int region) MONO_INTERNAL;
1262 void      mono_precompile_assemblies        (void) MONO_INTERNAL;
1263 int       mono_parse_default_optimizations  (const char* p);
1264 void      mono_bblock_add_inst              (MonoBasicBlock *bb, MonoInst *inst) MONO_INTERNAL;
1265 void      mono_bblock_insert_after_ins      (MonoBasicBlock *bb, MonoInst *ins, MonoInst *ins_to_insert) MONO_INTERNAL;
1266 void      mono_bblock_insert_before_ins     (MonoBasicBlock *bb, MonoInst *ins, MonoInst *ins_to_insert) MONO_INTERNAL;
1267 void      mono_verify_bblock                (MonoBasicBlock *bb) MONO_INTERNAL;
1268 void      mono_verify_cfg                   (MonoCompile *cfg) MONO_INTERNAL;
1269 void      mono_constant_fold                (MonoCompile *cfg) MONO_INTERNAL;
1270 void      mono_constant_fold_inst           (MonoInst *inst, gpointer data) MONO_INTERNAL;
1271 MonoInst* mono_constant_fold_ins2           (MonoCompile *cfg, MonoInst *ins, MonoInst *arg1, MonoInst *arg2, gboolean overwrite) MONO_INTERNAL;
1272 int       mono_eval_cond_branch             (MonoInst *branch) MONO_INTERNAL;
1273 int       mono_is_power_of_two              (guint32 val) MONO_INTERNAL;
1274 void      mono_cprop_local                  (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst **acp, int acp_size) MONO_INTERNAL;
1275 MonoInst* mono_compile_create_var           (MonoCompile *cfg, MonoType *type, int opcode) MONO_INTERNAL;
1276 MonoInst* mono_compile_create_var_for_vreg  (MonoCompile *cfg, MonoType *type, int opcode, int vreg) MONO_INTERNAL;
1277 void      mono_compile_make_var_load        (MonoCompile *cfg, MonoInst *dest, gssize var_index) MONO_INTERNAL;
1278 MonoInst* mono_compile_create_var_load      (MonoCompile *cfg, gssize var_index) MONO_INTERNAL;
1279 MonoInst* mono_compile_create_var_store     (MonoCompile *cfg, gssize var_index, MonoInst *value) MONO_INTERNAL;
1280 MonoType* mono_type_from_stack_type         (MonoInst *ins) MONO_INTERNAL;
1281 guint32   mono_alloc_ireg                   (MonoCompile *cfg) MONO_INTERNAL;
1282 guint32   mono_alloc_freg                   (MonoCompile *cfg) MONO_INTERNAL;
1283 guint32   mono_alloc_preg                   (MonoCompile *cfg) MONO_INTERNAL;
1284 guint32   mono_alloc_dreg                   (MonoCompile *cfg, MonoStackType stack_type) MONO_INTERNAL;
1285
1286 void      mono_link_bblock                  (MonoCompile *cfg, MonoBasicBlock *from, MonoBasicBlock* to) MONO_INTERNAL;
1287 void      mono_unlink_bblock                (MonoCompile *cfg, MonoBasicBlock *from, MonoBasicBlock* to) MONO_INTERNAL;
1288 gboolean  mono_bblocks_linked               (MonoBasicBlock *bb1, MonoBasicBlock *bb2) MONO_INTERNAL;
1289 void      mono_remove_bblock                (MonoCompile *cfg, MonoBasicBlock *bb) MONO_INTERNAL;
1290 void      mono_nullify_basic_block          (MonoBasicBlock *bb) MONO_INTERNAL;
1291 void      mono_merge_basic_blocks           (MonoCompile *cfg, MonoBasicBlock *bb, MonoBasicBlock *bbn) MONO_INTERNAL;
1292 void      mono_optimize_branches            (MonoCompile *cfg) MONO_INTERNAL;
1293
1294 void      mono_blockset_print               (MonoCompile *cfg, MonoBitSet *set, const char *name, guint idom) MONO_INTERNAL;
1295 void      mono_print_tree                   (MonoInst *tree) MONO_INTERNAL;
1296 void      mono_print_tree_nl                (MonoInst *tree) MONO_INTERNAL;
1297 void      mono_print_ins_index              (int i, MonoInst *ins) MONO_INTERNAL;
1298 void      mono_print_ins                    (MonoInst *ins) MONO_INTERNAL;
1299 void      mono_print_bb                     (MonoBasicBlock *bb, const char *msg) MONO_INTERNAL;
1300 void      mono_print_code                   (MonoCompile *cfg, const char *msg) MONO_INTERNAL;
1301 void      mono_print_method_from_ip         (void *ip);
1302 char     *mono_pmip                         (void *ip);
1303 void      mono_select_instructions          (MonoCompile *cfg) MONO_INTERNAL;
1304 const char* mono_inst_name                  (int op);
1305 int       mono_op_to_op_imm                 (int opcode) MONO_INTERNAL;
1306 int       mono_op_imm_to_op                 (int opcode) MONO_INTERNAL;
1307 int       mono_load_membase_to_load_mem     (int opcode) MONO_INTERNAL;
1308 guint     mono_type_to_load_membase         (MonoCompile *cfg, MonoType *type) MONO_INTERNAL;
1309 guint     mono_type_to_store_membase        (MonoCompile *cfg, MonoType *type) MONO_INTERNAL;
1310 guint     mini_type_to_stind                (MonoCompile* cfg, MonoType *type) MONO_INTERNAL;
1311 guint32   mono_reverse_branch_op            (guint32 opcode) MONO_INTERNAL;
1312 void      mono_inst_foreach                 (MonoInst *tree, MonoInstFunc func, gpointer data) MONO_INTERNAL;
1313 void      mono_disassemble_code             (MonoCompile *cfg, guint8 *code, int size, char *id) MONO_INTERNAL;
1314 void      mono_add_patch_info               (MonoCompile *cfg, int ip, MonoJumpInfoType type, gconstpointer target) MONO_INTERNAL;
1315 void      mono_remove_patch_info            (MonoCompile *cfg, int ip) MONO_INTERNAL;
1316 MonoJumpInfo* mono_patch_info_dup_mp        (MonoMemPool *mp, MonoJumpInfo *patch_info) MONO_INTERNAL;
1317 guint     mono_patch_info_hash (gconstpointer data) MONO_INTERNAL;
1318 gint      mono_patch_info_equal (gconstpointer ka, gconstpointer kb) MONO_INTERNAL;
1319 MonoJumpInfo *mono_patch_info_list_prepend  (MonoJumpInfo *list, int ip, MonoJumpInfoType type, gconstpointer target) MONO_INTERNAL;
1320 gpointer  mono_resolve_patch_target         (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *patch_info, gboolean run_cctors) MONO_INTERNAL;
1321 gpointer  mono_jit_find_compiled_method     (MonoDomain *domain, MonoMethod *method) MONO_INTERNAL;
1322 MonoLMF * mono_get_lmf                      (void) MONO_INTERNAL;
1323 MonoLMF** mono_get_lmf_addr                 (void) MONO_INTERNAL;
1324 void      mono_jit_thread_attach            (MonoDomain *domain);
1325 guint32   mono_get_jit_tls_key              (void) MONO_INTERNAL;
1326 gint32    mono_get_jit_tls_offset           (void) MONO_INTERNAL;
1327 gint32    mono_get_lmf_tls_offset           (void) MONO_INTERNAL;
1328 gint32    mono_get_lmf_addr_tls_offset      (void) MONO_INTERNAL;
1329 MonoInst* mono_get_jit_tls_intrinsic        (MonoCompile *cfg) MONO_INTERNAL;
1330 GList    *mono_varlist_insert_sorted        (MonoCompile *cfg, GList *list, MonoMethodVar *mv, gboolean sort_end) MONO_INTERNAL;
1331 GList    *mono_varlist_sort                 (MonoCompile *cfg, GList *list, int sort_type) MONO_INTERNAL;
1332 void      mono_analyze_liveness             (MonoCompile *cfg) MONO_INTERNAL;
1333 void      mono_linear_scan                  (MonoCompile *cfg, GList *vars, GList *regs, regmask_t *used_mask) MONO_INTERNAL;
1334 void      mono_global_regalloc              (MonoCompile *cfg) MONO_INTERNAL;
1335 void      mono_create_jump_table            (MonoCompile *cfg, MonoInst *label, MonoBasicBlock **bbs, int num_blocks) MONO_INTERNAL;
1336 int       mono_compile_assembly             (MonoAssembly *ass, guint32 opts, const char *aot_options) MONO_INTERNAL;
1337 MonoCompile *mini_method_compile            (MonoMethod *method, guint32 opts, MonoDomain *domain, gboolean run_cctors, gboolean compile_aot, int parts) MONO_INTERNAL;
1338 void      mono_destroy_compile              (MonoCompile *cfg) MONO_INTERNAL;
1339 MonoJitICallInfo *mono_find_jit_opcode_emulation (int opcode) MONO_INTERNAL;
1340 void      mono_print_ins_index (int i, MonoInst *ins) MONO_INTERNAL;
1341 void      mono_print_ins (MonoInst *ins) MONO_INTERNAL;
1342 gboolean  mini_assembly_can_skip_verification (MonoDomain *domain, MonoMethod *method) MONO_INTERNAL;
1343 gboolean  mini_method_verify (MonoCompile *cfg, MonoMethod *method) MONO_INTERNAL;
1344
1345 gboolean  mini_class_is_system_array (MonoClass *klass) MONO_INTERNAL;
1346 MonoMethodSignature *mono_get_element_address_signature (int arity) MONO_INTERNAL;
1347 MonoJitICallInfo    *mono_get_element_address_icall (int rank) MONO_INTERNAL;
1348 MonoJitICallInfo    *mono_get_array_new_va_icall (int rank) MONO_INTERNAL;
1349
1350 void      mono_linterval_add_range          (MonoCompile *cfg, MonoLiveInterval *interval, int from, int to) MONO_INTERNAL;
1351 void      mono_linterval_print              (MonoLiveInterval *interval) MONO_INTERNAL;
1352 void      mono_linterval_print_nl (MonoLiveInterval *interval) MONO_INTERNAL;
1353 gboolean  mono_linterval_covers             (MonoLiveInterval *interval, int pos) MONO_INTERNAL;
1354 gint32    mono_linterval_get_intersect_pos  (MonoLiveInterval *i1, MonoLiveInterval *i2) MONO_INTERNAL;
1355 void      mono_linterval_split              (MonoCompile *cfg, MonoLiveInterval *interval, MonoLiveInterval **i1, MonoLiveInterval **i2, int pos) MONO_INTERNAL;
1356 void      mono_liveness_handle_exception_clauses (MonoCompile *cfg) MONO_INTERNAL;
1357
1358 /* AOT */
1359 void      mono_aot_init                     (void) MONO_INTERNAL;
1360 gpointer  mono_aot_get_method               (MonoDomain *domain,
1361                                                                                          MonoMethod *method) MONO_INTERNAL;
1362 gpointer  mono_aot_get_method_from_token    (MonoDomain *domain, MonoImage *image, guint32 token) MONO_INTERNAL;
1363 gboolean  mono_aot_is_got_entry             (guint8 *code, guint8 *addr) MONO_INTERNAL;
1364 guint8*   mono_aot_get_plt_entry            (guint8 *code) MONO_INTERNAL;
1365 guint32   mono_aot_get_plt_info_offset      (gssize *regs, guint8 *code) MONO_INTERNAL;
1366 gboolean  mono_aot_get_cached_class_info    (MonoClass *klass, MonoCachedClassInfo *res) MONO_INTERNAL;
1367 gboolean  mono_aot_get_class_from_name      (MonoImage *image, const char *name_space, const char *name, MonoClass **klass) MONO_INTERNAL;
1368 MonoJitInfo* mono_aot_find_jit_info         (MonoDomain *domain, MonoImage *image, gpointer addr) MONO_INTERNAL;
1369 void mono_aot_set_make_unreadable           (gboolean unreadable) MONO_INTERNAL;
1370 gboolean mono_aot_is_pagefault              (void *ptr) MONO_INTERNAL;
1371 void mono_aot_handle_pagefault              (void *ptr) MONO_INTERNAL;
1372 guint32 mono_aot_get_n_pagefaults           (void) MONO_INTERNAL;
1373 gpointer mono_aot_plt_resolve               (gpointer aot_module, guint32 plt_info_offset, guint8 *code) MONO_INTERNAL;
1374 gpointer mono_aot_get_method_from_vt_slot   (MonoDomain *domain, MonoVTable *vtable, int slot) MONO_INTERNAL;
1375 gpointer mono_aot_create_specific_trampoline   (MonoImage *image, gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len) MONO_INTERNAL;
1376 gpointer mono_aot_get_named_code            (const char *name) MONO_INTERNAL;
1377 gpointer mono_aot_get_unbox_trampoline      (MonoMethod *method) MONO_INTERNAL;
1378 gpointer mono_aot_get_lazy_fetch_trampoline (guint32 slot) MONO_INTERNAL;
1379 /* This is an exported function */
1380 void     mono_aot_register_globals          (gpointer *globals);
1381 /* This too */
1382 void     mono_aot_register_module           (gpointer *aot_info);
1383
1384 gboolean  mono_method_blittable             (MonoMethod *method) MONO_INTERNAL;
1385 gboolean  mono_method_same_domain           (MonoJitInfo *caller, MonoJitInfo *callee) MONO_INTERNAL;
1386
1387 void      mono_register_opcode_emulation    (int opcode, const char* name, const char *sigstr, gpointer func, gboolean no_throw) MONO_INTERNAL;
1388 void      mono_draw_graph                   (MonoCompile *cfg, MonoGraphOptions draw_options) MONO_INTERNAL;
1389 void      mono_add_varcopy_to_end           (MonoCompile *cfg, MonoBasicBlock *bb, int src, int dest) MONO_INTERNAL;
1390 void      mono_add_ins_to_end               (MonoBasicBlock *bb, MonoInst *inst) MONO_INTERNAL;
1391 gpointer  mono_create_ftnptr                (MonoDomain *domain, gpointer addr) MONO_INTERNAL;
1392
1393 void      mono_replace_ins                  (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins, MonoInst **prev, MonoBasicBlock *first_bb, MonoBasicBlock *last_bb);
1394
1395 int               mono_find_method_opcode      (MonoMethod *method) MONO_INTERNAL;
1396 MonoJitICallInfo *mono_find_jit_icall_by_name  (const char *name) MONO_INTERNAL;
1397 MonoJitICallInfo *mono_find_jit_icall_by_addr  (gconstpointer addr) MONO_INTERNAL;
1398 MonoJitICallInfo *mono_register_jit_icall      (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save) MONO_INTERNAL;
1399 gconstpointer     mono_icall_get_wrapper       (MonoJitICallInfo* callinfo) MONO_INTERNAL;
1400
1401 void              mono_trampolines_init (void) MONO_INTERNAL;
1402 void              mono_trampolines_cleanup (void) MONO_INTERNAL;
1403 guint8 *          mono_get_trampoline_code (MonoTrampolineType tramp_type) MONO_INTERNAL;
1404 gpointer          mono_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len) MONO_INTERNAL;
1405 gpointer          mono_create_jump_trampoline (MonoDomain *domain, 
1406                                                                                            MonoMethod *method, 
1407                                                                                            gboolean add_sync_wrapper) MONO_INTERNAL;
1408 gpointer          mono_create_class_init_trampoline (MonoVTable *vtable) MONO_INTERNAL;
1409 gpointer          mono_create_generic_class_init_trampoline (void) MONO_INTERNAL;
1410 gpointer          mono_create_jit_trampoline (MonoMethod *method) MONO_INTERNAL;
1411 gpointer          mono_create_jit_trampoline_from_token (MonoImage *image, guint32 token) MONO_INTERNAL;
1412 gpointer          mono_create_jit_trampoline_in_domain (MonoDomain *domain, MonoMethod *method) MONO_INTERNAL;
1413 gpointer          mono_create_delegate_trampoline (MonoClass *klass) MONO_INTERNAL;
1414 gpointer          mono_create_rgctx_lazy_fetch_trampoline (guint32 offset) MONO_INTERNAL;
1415 MonoVTable*       mono_find_class_init_trampoline_by_addr (gconstpointer addr) MONO_INTERNAL;
1416 MonoClass*        mono_find_delegate_trampoline_by_addr (gconstpointer addr) MONO_INTERNAL;
1417 guint32           mono_find_rgctx_lazy_fetch_trampoline_by_addr (gconstpointer addr) MONO_INTERNAL;
1418 gpointer          mono_magic_trampoline (gssize *regs, guint8 *code, MonoMethod *m, guint8* tramp) MONO_INTERNAL;
1419 gpointer          mono_delegate_trampoline (gssize *regs, guint8 *code, gpointer *tramp_data, guint8* tramp) MONO_INTERNAL;
1420 gpointer          mono_aot_trampoline (gssize *regs, guint8 *code, guint8 *token_info, 
1421                                                                            guint8* tramp) MONO_INTERNAL;
1422 gpointer          mono_aot_plt_trampoline (gssize *regs, guint8 *code, guint8 *token_info, 
1423                                                                                    guint8* tramp) MONO_INTERNAL;
1424 void              mono_class_init_trampoline (gssize *regs, guint8 *code, MonoVTable *vtable, guint8 *tramp) MONO_INTERNAL;
1425 void              mono_generic_class_init_trampoline (gssize *regs, guint8 *code, MonoVTable *vtable, guint8 *tramp) MONO_INTERNAL;
1426 gconstpointer     mono_get_trampoline_func (MonoTrampolineType tramp_type);
1427 gpointer          mini_get_vtable_trampoline (void) MONO_INTERNAL;
1428
1429 gboolean          mono_running_on_valgrind (void) MONO_INTERNAL;
1430 void*             mono_global_codeman_reserve (int size) MONO_INTERNAL;
1431 const char       *mono_regname_full (int reg, int bank) MONO_INTERNAL;
1432 gint32*           mono_allocate_stack_slots_full (MonoCompile *cfg, gboolean backward, guint32 *stack_size, guint32 *stack_align) MONO_INTERNAL;
1433 gint32*           mono_allocate_stack_slots (MonoCompile *cfg, guint32 *stack_size, guint32 *stack_align) MONO_INTERNAL;
1434 void              mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb) MONO_INTERNAL;
1435 MonoInst         *mono_branch_optimize_exception_target (MonoCompile *cfg, MonoBasicBlock *bb, const char * exname) MONO_INTERNAL;
1436 void              mono_remove_critical_edges (MonoCompile *cfg) MONO_INTERNAL;
1437 gboolean          mono_is_regsize_var (MonoType *t) MONO_INTERNAL;
1438 void              mini_emit_memcpy2 (MonoCompile *cfg, int destreg, int doffset, int srcreg, int soffset, int size, int align) MONO_INTERNAL;
1439 CompRelation      mono_opcode_to_cond (int opcode) MONO_INTERNAL;
1440 CompType          mono_opcode_to_type (int opcode, int cmp_opcode) MONO_INTERNAL;
1441 CompRelation      mono_negate_cond (CompRelation cond) MONO_INTERNAL;
1442 int               mono_op_imm_to_op (int opcode) MONO_INTERNAL;
1443 void              mono_decompose_op_imm (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins) MONO_INTERNAL;
1444 void              mono_peephole_ins (MonoBasicBlock *bb, MonoInst *ins) MONO_INTERNAL;
1445
1446 void              mono_decompose_opcode (MonoCompile *cfg, MonoInst *ins) MONO_INTERNAL;
1447 void              mono_decompose_long_opts (MonoCompile *cfg) MONO_INTERNAL;
1448 void              mono_decompose_vtype_opts (MonoCompile *cfg) MONO_INTERNAL;
1449 void              mono_decompose_array_access_opts (MonoCompile *cfg) MONO_INTERNAL;
1450 void              mono_decompose_soft_float (MonoCompile *cfg) MONO_INTERNAL;
1451 void              mono_handle_global_vregs (MonoCompile *cfg) MONO_INTERNAL;
1452 void              mono_spill_global_vars (MonoCompile *cfg, gboolean *need_local_opts) MONO_INTERNAL;
1453 void              mono_if_conversion (MonoCompile *cfg) MONO_INTERNAL;
1454
1455 /* methods that must be provided by the arch-specific port */
1456 void      mono_arch_init                        (void) MONO_INTERNAL;
1457 void      mono_arch_cleanup                     (void) MONO_INTERNAL;
1458 void      mono_arch_cpu_init                    (void) MONO_INTERNAL;
1459 guint32   mono_arch_cpu_optimizazions           (guint32 *exclude_mask) MONO_INTERNAL;
1460 void      mono_arch_instrument_mem_needs        (MonoMethod *method, int *stack, int *code) MONO_INTERNAL;
1461 void     *mono_arch_instrument_prolog           (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments) MONO_INTERNAL;
1462 void     *mono_arch_instrument_epilog           (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments) MONO_INTERNAL;
1463 MonoCallInst *mono_arch_call_opcode             (MonoCompile *cfg, MonoBasicBlock* bb, MonoCallInst *call, int is_virtual) MONO_INTERNAL;
1464 MonoInst *mono_arch_get_inst_for_method         (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args) MONO_INTERNAL;
1465 void      mono_codegen                          (MonoCompile *cfg) MONO_INTERNAL;
1466 void      mono_call_inst_add_outarg_reg         (MonoCompile *cfg, MonoCallInst *call, int vreg, int hreg, gboolean fp) MONO_INTERNAL;
1467 const char *mono_arch_regname                   (int reg) MONO_INTERNAL;
1468 const char *mono_arch_fregname                  (int reg) MONO_INTERNAL;
1469 gpointer  mono_arch_get_throw_exception         (void) MONO_INTERNAL;
1470 gpointer  mono_arch_get_rethrow_exception       (void) MONO_INTERNAL;
1471 gpointer  mono_arch_get_throw_exception_by_name (void) MONO_INTERNAL;
1472 gpointer  mono_arch_get_throw_corlib_exception  (void) MONO_INTERNAL;
1473 guchar*   mono_arch_create_trampoline_code      (MonoTrampolineType tramp_type) MONO_INTERNAL;
1474 guchar*   mono_arch_create_trampoline_code_full (MonoTrampolineType tramp_type, guint32 *code_size, MonoJumpInfo **ji, gboolean aot) MONO_INTERNAL;
1475 gpointer  mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot) MONO_INTERNAL;
1476 gpointer  mono_arch_create_rgctx_lazy_fetch_trampoline_full (guint32 slot, guint32 *code_size, MonoJumpInfo **ji, gboolean aot) MONO_INTERNAL;
1477 gpointer  mono_arch_create_generic_class_init_trampoline (void) MONO_INTERNAL;
1478 gpointer  mono_arch_get_nullified_class_init_trampoline (guint32 *code_len) MONO_INTERNAL;
1479 GList    *mono_arch_get_allocatable_int_vars    (MonoCompile *cfg) MONO_INTERNAL;
1480 GList    *mono_arch_get_global_int_regs         (MonoCompile *cfg) MONO_INTERNAL;
1481 GList    *mono_arch_get_global_fp_regs          (MonoCompile *cfg) MONO_INTERNAL;
1482 GList    *mono_arch_get_iregs_clobbered_by_call (MonoCallInst *call) MONO_INTERNAL;
1483 GList    *mono_arch_get_fregs_clobbered_by_call (MonoCallInst *call) MONO_INTERNAL;
1484 guint32   mono_arch_regalloc_cost               (MonoCompile *cfg, MonoMethodVar *vmv) MONO_INTERNAL;
1485 void      mono_arch_patch_code                  (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *ji, gboolean run_cctors) MONO_INTERNAL;
1486 void      mono_arch_flush_icache                (guint8 *code, gint size) MONO_INTERNAL;
1487 int       mono_arch_max_epilog_size             (MonoCompile *cfg) MONO_INTERNAL;
1488 guint8   *mono_arch_emit_prolog                 (MonoCompile *cfg) MONO_INTERNAL;
1489 void      mono_arch_emit_epilog                 (MonoCompile *cfg) MONO_INTERNAL;
1490 void      mono_arch_emit_exceptions             (MonoCompile *cfg) MONO_INTERNAL;
1491 void      mono_arch_lowering_pass               (MonoCompile *cfg, MonoBasicBlock *bb) MONO_INTERNAL;
1492 void      mono_arch_peephole_pass_1             (MonoCompile *cfg, MonoBasicBlock *bb) MONO_INTERNAL;
1493 void      mono_arch_peephole_pass_2             (MonoCompile *cfg, MonoBasicBlock *bb) MONO_INTERNAL;
1494 void      mono_arch_output_basic_block          (MonoCompile *cfg, MonoBasicBlock *bb) MONO_INTERNAL;
1495 gboolean  mono_arch_has_unwind_info             (gconstpointer addr) MONO_INTERNAL;
1496 void      mono_arch_setup_jit_tls_data          (MonoJitTlsData *tls) MONO_INTERNAL;
1497 void      mono_arch_free_jit_tls_data           (MonoJitTlsData *tls) MONO_INTERNAL;
1498 void      mono_arch_emit_this_vret_args         (MonoCompile *cfg, MonoCallInst *inst, int this_reg, int this_type, int vt_reg) MONO_INTERNAL;
1499 void      mono_arch_fill_argument_info          (MonoCompile *cfg) MONO_INTERNAL;
1500 void      mono_arch_allocate_vars               (MonoCompile *m) MONO_INTERNAL;
1501 int       mono_arch_get_argument_info           (MonoMethodSignature *csig, int param_count, MonoJitArgumentInfo *arg_info) MONO_INTERNAL;
1502 gboolean  mono_arch_print_tree                  (MonoInst *tree, int arity) MONO_INTERNAL;
1503 void      mono_arch_emit_call                   (MonoCompile *cfg, MonoCallInst *call) MONO_INTERNAL;
1504 void      mono_arch_emit_outarg_vt              (MonoCompile *cfg, MonoInst *ins, MonoInst *src) MONO_INTERNAL;
1505 void      mono_arch_emit_setret                 (MonoCompile *cfg, MonoMethod *method, MonoInst *val) MONO_INTERNAL;
1506 MonoInst *mono_arch_emit_inst_for_method        (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args) MONO_INTERNAL;
1507 void      mono_arch_decompose_opts              (MonoCompile *cfg, MonoInst *ins) MONO_INTERNAL;
1508 void      mono_arch_decompose_long_opts         (MonoCompile *cfg, MonoInst *ins) MONO_INTERNAL;
1509
1510 MonoJitInfo *mono_arch_find_jit_info            (MonoDomain *domain, 
1511                                                  MonoJitTlsData *jit_tls, 
1512                                                  MonoJitInfo *res, 
1513                                                  MonoJitInfo *prev_ji, 
1514                                                  MonoContext *ctx, 
1515                                                  MonoContext *new_ctx, 
1516                                                  MonoLMF **lmf, 
1517                                                  gboolean *managed) MONO_INTERNAL;
1518 gpointer mono_arch_get_call_filter              (void) MONO_INTERNAL;
1519 gpointer mono_arch_get_restore_context          (void) MONO_INTERNAL;
1520 gpointer mono_arch_get_call_filter_full         (guint32 *code_size, MonoJumpInfo **ji, gboolean aot) MONO_INTERNAL;
1521 gpointer mono_arch_get_restore_context_full     (guint32 *code_size, MonoJumpInfo **ji, gboolean aot) MONO_INTERNAL;
1522 gpointer  mono_arch_get_throw_exception_full    (guint32 *code_size, MonoJumpInfo **ji, gboolean aot) MONO_INTERNAL;
1523 gpointer  mono_arch_get_rethrow_exception_full  (guint32 *code_size, MonoJumpInfo **ji, gboolean aot) MONO_INTERNAL;
1524 gpointer  mono_arch_get_throw_exception_by_name_full (guint32 *code_size, MonoJumpInfo **ji, gboolean aot) MONO_INTERNAL;
1525 gpointer  mono_arch_get_throw_corlib_exception_full (guint32 *code_size, MonoJumpInfo **ji, gboolean aot) MONO_INTERNAL;
1526 gboolean mono_arch_handle_exception             (void *sigctx, gpointer obj, gboolean test_only) MONO_INTERNAL;
1527 void     mono_arch_handle_altstack_exception    (void *sigctx, gpointer fault_addr, gboolean stack_ovf) MONO_INTERNAL;
1528 gboolean mono_handle_soft_stack_ovf             (MonoJitTlsData *jit_tls, MonoJitInfo *ji, void *ctx, guint8* fault_addr) MONO_INTERNAL;
1529 gpointer mono_arch_ip_from_context              (void *sigctx) MONO_INTERNAL;
1530 void     mono_arch_sigctx_to_monoctx            (void *sigctx, MonoContext *ctx) MONO_INTERNAL;
1531 void     mono_arch_monoctx_to_sigctx            (MonoContext *mctx, void *ctx) MONO_INTERNAL;
1532 gpointer mono_arch_context_get_int_reg          (MonoContext *ctx, int reg) MONO_INTERNAL;
1533 void     mono_arch_flush_register_windows       (void) MONO_INTERNAL;
1534 gboolean mono_arch_is_inst_imm                  (gint64 imm) MONO_INTERNAL;
1535 MonoInst* mono_arch_get_domain_intrinsic        (MonoCompile* cfg) MONO_INTERNAL;
1536 MonoInst* mono_arch_get_thread_intrinsic        (MonoCompile* cfg) MONO_INTERNAL;
1537 gboolean mono_arch_is_int_overflow              (void *sigctx, void *info) MONO_INTERNAL;
1538 void     mono_arch_invalidate_method            (MonoJitInfo *ji, void *func, gpointer func_arg) MONO_INTERNAL;
1539 guint32  mono_arch_get_patch_offset             (guint8 *code) MONO_INTERNAL;
1540 gpointer*mono_arch_get_vcall_slot_addr          (guint8* code, gpointer *regs) MONO_INTERNAL;
1541 gpointer mono_arch_get_vcall_slot               (guint8 *code, gpointer *regs, int *displacement) MONO_INTERNAL;
1542 gpointer*mono_arch_get_delegate_method_ptr_addr (guint8* code, gpointer *regs) MONO_INTERNAL;
1543 void     mono_arch_create_vars                  (MonoCompile *cfg) MONO_INTERNAL;
1544 void     mono_arch_save_unwind_info             (MonoCompile *cfg) MONO_INTERNAL;
1545 void     mono_arch_register_lowlevel_calls      (void) MONO_INTERNAL;
1546 gpointer mono_arch_get_unbox_trampoline         (MonoGenericSharingContext *gsctx, MonoMethod *m, gpointer addr) MONO_INTERNAL;
1547 void     mono_arch_patch_callsite               (guint8 *method_start, guint8 *code, guint8 *addr) MONO_INTERNAL;
1548 void     mono_arch_patch_plt_entry              (guint8 *code, guint8 *addr) MONO_INTERNAL;
1549 void     mono_arch_nullify_class_init_trampoline(guint8 *code, gssize *regs) MONO_INTERNAL;
1550 void     mono_arch_nullify_plt_entry            (guint8 *code) MONO_INTERNAL;
1551 int      mono_arch_get_this_arg_reg             (MonoMethodSignature *sig, MonoGenericSharingContext *gsctx, guint8 *code) MONO_INTERNAL;
1552 gpointer mono_arch_get_this_arg_from_call       (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, gssize *regs, guint8 *code) MONO_INTERNAL;
1553 MonoObject* mono_arch_find_this_argument        (gpointer *regs, MonoMethod *method, MonoGenericSharingContext *gsctx) MONO_INTERNAL;
1554 gpointer mono_arch_get_delegate_invoke_impl     (MonoMethodSignature *sig, gboolean has_target) MONO_INTERNAL;
1555 gpointer mono_arch_create_specific_trampoline   (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len) MONO_INTERNAL;
1556 void        mono_arch_emit_imt_argument         (MonoCompile *cfg, MonoCallInst *call, MonoInst *imt_arg) MONO_INTERNAL;
1557 MonoMethod* mono_arch_find_imt_method           (gpointer *regs, guint8 *code) MONO_INTERNAL;
1558 MonoVTable* mono_arch_find_static_call_vtable   (gpointer *regs, guint8 *code) MONO_INTERNAL;
1559 gpointer    mono_arch_build_imt_thunk           (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckItem **imt_entries, int count, gpointer fail_tramp) MONO_INTERNAL;
1560 void    mono_arch_notify_pending_exc            (void) MONO_INTERNAL;
1561 void    mono_arch_fixup_jinfo                   (MonoCompile *cfg) MONO_INTERNAL;
1562
1563 /* Exception handling */
1564 void     mono_exceptions_init                   (void) MONO_INTERNAL;
1565 gboolean mono_handle_exception                  (MonoContext *ctx, gpointer obj,
1566                                                  gpointer original_ip, gboolean test_only) MONO_INTERNAL;
1567 void     mono_handle_native_sigsegv             (int signal, void *sigctx) MONO_INTERNAL;
1568 void     mono_print_thread_dump                 (void *sigctx);
1569 void     mono_jit_walk_stack                    (MonoStackWalk func, gboolean do_il_offset, gpointer user_data) MONO_INTERNAL;
1570 void     mono_jit_walk_stack_from_ctx           (MonoStackWalk func, MonoContext *ctx, gboolean do_il_offset, gpointer user_data) MONO_INTERNAL;
1571 void     mono_setup_altstack                    (MonoJitTlsData *tls) MONO_INTERNAL;
1572 void     mono_free_altstack                     (MonoJitTlsData *tls) MONO_INTERNAL;
1573 gpointer mono_altstack_restore_prot             (gssize *regs, guint8 *code, gpointer *tramp_data, guint8* tramp) MONO_INTERNAL;
1574
1575 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;
1576
1577 gpointer mono_get_throw_exception               (void) MONO_INTERNAL;
1578 gpointer mono_get_rethrow_exception             (void) MONO_INTERNAL;
1579 gpointer mono_get_call_filter                   (void) MONO_INTERNAL;
1580 gpointer mono_get_restore_context               (void) MONO_INTERNAL;
1581 gpointer mono_get_throw_exception_by_name       (void) MONO_INTERNAL;
1582 gpointer mono_get_throw_corlib_exception        (void) MONO_INTERNAL;
1583
1584 /* the new function to do stack walks */
1585 typedef gboolean (*MonoStackFrameWalk)          (MonoDomain *domain, MonoContext *ctx, MonoJitInfo *ji, gpointer data);
1586 void      mono_walk_stack                       (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoContext *start_ctx, MonoStackFrameWalk func, gpointer user_data);
1587
1588 MonoArray *ves_icall_get_trace                  (MonoException *exc, gint32 skip, MonoBoolean need_file_info) MONO_INTERNAL;
1589 MonoBoolean ves_icall_get_frame_info            (gint32 skip, MonoBoolean need_file_info, 
1590                                                  MonoReflectionMethod **method, 
1591                                                  gint32 *iloffset, gint32 *native_offset,
1592                                                  MonoString **file, gint32 *line, gint32 *column) MONO_INTERNAL;
1593 MonoString *ves_icall_System_Exception_get_trace (MonoException *exc) MONO_INTERNAL;
1594
1595 /* Dominator/SSA methods */
1596 void        mono_compile_dominator_info         (MonoCompile *cfg, int dom_flags) MONO_INTERNAL;
1597 void        mono_compute_natural_loops          (MonoCompile *cfg) MONO_INTERNAL;
1598 MonoBitSet* mono_compile_iterated_dfrontier     (MonoCompile *cfg, MonoBitSet *set) MONO_INTERNAL;
1599 void        mono_ssa_compute                    (MonoCompile *cfg) MONO_INTERNAL;
1600 void        mono_ssa_remove                     (MonoCompile *cfg) MONO_INTERNAL;
1601 void        mono_ssa_cprop                      (MonoCompile *cfg) MONO_INTERNAL;
1602 void        mono_ssa_deadce                     (MonoCompile *cfg) MONO_INTERNAL;
1603 void        mono_ssa_strength_reduction         (MonoCompile *cfg) MONO_INTERNAL;
1604 void        mono_free_loop_info                 (MonoCompile *cfg) MONO_INTERNAL;
1605
1606 void        mono_ssa_compute2                   (MonoCompile *cfg);
1607 void        mono_ssa_remove2                    (MonoCompile *cfg);
1608 void        mono_ssa_cprop2                     (MonoCompile *cfg);
1609 void        mono_ssa_deadce2                    (MonoCompile *cfg);
1610
1611 /* debugging support */
1612 void      mono_debug_init_method                (MonoCompile *cfg, MonoBasicBlock *start_block,
1613                                                  guint32 breakpoint_id) MONO_INTERNAL;
1614 void      mono_debug_open_method                (MonoCompile *cfg) MONO_INTERNAL;
1615 void      mono_debug_close_method               (MonoCompile *cfg) MONO_INTERNAL;
1616 void      mono_debug_open_block                 (MonoCompile *cfg, MonoBasicBlock *bb, guint32 address) MONO_INTERNAL;
1617 void      mono_debug_record_line_number         (MonoCompile *cfg, MonoInst *ins, guint32 address) MONO_INTERNAL;
1618 void      mono_debug_serialize_debug_info       (MonoCompile *cfg, guint8 **out_buf, guint32 *buf_len) MONO_INTERNAL;
1619 void      mono_debug_add_aot_method             (MonoDomain *domain,
1620                                                  MonoMethod *method, guint8 *code_start, 
1621                                                  guint8 *debug_info, guint32 debug_info_len) MONO_INTERNAL;
1622 void      mono_debug_add_icall_wrapper          (MonoMethod *method, MonoJitICallInfo* info) MONO_INTERNAL;
1623 void      mono_debug_print_vars                 (gpointer ip, gboolean only_arguments);
1624 void      mono_debugger_run_finally             (MonoContext *start_ctx);
1625
1626 extern gssize mono_breakpoint_info_index [MONO_BREAKPOINT_ARRAY_SIZE];
1627
1628 gboolean mono_breakpoint_clean_code (guint8 *method_start, guint8 *code, int offset, guint8 *buf, int size);
1629
1630 /* Mono Debugger support */
1631 void      mono_debugger_init                    (void);
1632 int       mono_debugger_main                    (MonoDomain *domain, MonoAssembly *assembly, int argc, char **argv);
1633
1634
1635 /* Tracing */
1636 MonoTraceSpec *mono_trace_parse_options         (const char *options) MONO_INTERNAL;
1637 void           mono_trace_set_assembly          (MonoAssembly *assembly) MONO_INTERNAL;
1638 gboolean       mono_trace_eval                  (MonoMethod *method) MONO_INTERNAL;
1639
1640 extern void
1641 mono_perform_abc_removal (MonoCompile *cfg) MONO_INTERNAL;
1642 extern void
1643 mono_perform_abc_removal2 (MonoCompile *cfg) MONO_INTERNAL;
1644 extern void
1645 mono_perform_ssapre (MonoCompile *cfg) MONO_INTERNAL;
1646 extern void
1647 mono_local_cprop (MonoCompile *cfg) MONO_INTERNAL;
1648 extern void
1649 mono_local_cprop2 (MonoCompile *cfg);
1650 extern void
1651 mono_local_deadce (MonoCompile *cfg);
1652
1653 /* CAS - stack walk */
1654 MonoSecurityFrame* ves_icall_System_Security_SecurityFrame_GetSecurityFrame (gint32 skip) MONO_INTERNAL;
1655 MonoArray* ves_icall_System_Security_SecurityFrame_GetSecurityStack (gint32 skip) MONO_INTERNAL;
1656
1657 /* Generic sharing */
1658
1659 MonoGenericSharingContext* mono_get_generic_context_from_code (guint8 *code) MONO_INTERNAL;
1660
1661 MonoGenericContext* mini_method_get_context (MonoMethod *method) MONO_INTERNAL;
1662
1663 int mono_method_check_context_used (MonoMethod *method) MONO_INTERNAL;
1664
1665 gboolean mono_generic_context_equal_deep (MonoGenericContext *context1, MonoGenericContext *context2) MONO_INTERNAL;
1666
1667 gpointer mono_helper_get_rgctx_other_ptr (MonoClass *caller_class, MonoVTable *vtable,
1668                                           guint32 token, guint32 token_source, guint32 rgctx_type,
1669                                           gint32 rgctx_index) MONO_INTERNAL;
1670
1671 void mono_generic_sharing_init (void) MONO_INTERNAL;
1672
1673 MonoClass* mini_class_get_container_class (MonoClass *class) MONO_INTERNAL;
1674 MonoGenericContext* mini_class_get_context (MonoClass *class) MONO_INTERNAL;
1675
1676 MonoType* mini_get_basic_type_from_generic (MonoGenericSharingContext *gsctx, MonoType *type) MONO_INTERNAL;
1677 MonoType* mini_type_get_underlying_type (MonoGenericSharingContext *gsctx, MonoType *type) MONO_INTERNAL;
1678
1679 int mini_type_stack_size (MonoGenericSharingContext *gsctx, MonoType *t, int *align) MONO_INTERNAL;
1680 int mini_type_stack_size_full (MonoGenericSharingContext *gsctx, MonoType *t, guint32 *align, gboolean pinvoke) MONO_INTERNAL;
1681 void type_to_eval_stack_type (MonoCompile *cfg, MonoType *type, MonoInst *inst) MONO_INTERNAL;
1682 guint mono_type_to_regmove (MonoCompile *cfg, MonoType *type) MONO_INTERNAL;
1683
1684 /* wapihandles.c */
1685 int mini_wapi_hps (int argc, char **argv) MONO_INTERNAL;
1686
1687 int mini_wapi_semdel (int argc, char **argv) MONO_INTERNAL;
1688
1689 int mini_wapi_seminfo (int argc, char **argv) MONO_INTERNAL;
1690
1691 /* SIMD support */
1692 const char *mono_arch_xregname (int reg) MONO_INTERNAL;
1693 void mono_simd_simplify_indirection (MonoCompile *cfg) MONO_INTERNAL;
1694 MonoInst* mono_emit_simd_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args) MONO_INTERNAL;
1695
1696
1697 #endif /* __MONO_MINI_H__ */