2010-06-02 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / mini / mini-llvm.c
blob9257c6006c6185e0d9c01cec53f0a9b854aee502
1 /*
2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * (C) 2009 Novell, Inc.
5 */
7 #include "mini.h"
8 #include <mono/metadata/debug-helpers.h>
9 #include <mono/metadata/mempool-internals.h>
11 #ifndef __STDC_LIMIT_MACROS
12 #define __STDC_LIMIT_MACROS
13 #endif
14 #ifndef __STDC_CONSTANT_MACROS
15 #define __STDC_CONSTANT_MACROS
16 #endif
18 #include "llvm-c/Core.h"
19 #include "llvm-c/ExecutionEngine.h"
20 #include "llvm-c/BitWriter.h"
21 #include "llvm-c/Analysis.h"
23 #include "mini-llvm-cpp.h"
26 * Information associated by mono with LLVM modules.
28 typedef struct {
29 LLVMModuleRef module;
30 LLVMValueRef throw, rethrow, throw_corlib_exception;
31 GHashTable *llvm_types;
32 LLVMValueRef got_var;
33 const char *got_symbol;
34 GHashTable *plt_entries;
35 } MonoLLVMModule;
38 * Information associated by the backend with mono basic blocks.
40 typedef struct {
41 LLVMBasicBlockRef bblock, end_bblock;
42 LLVMValueRef finally_ind;
43 gboolean added, invoke_target;
44 /*
45 * If this bblock is the start of a finally clause, this is a list of bblocks it
46 * needs to branch to in ENDFINALLY.
48 GSList *call_handler_return_bbs;
49 LLVMValueRef endfinally_switch;
50 GSList *phi_nodes;
51 } BBInfo;
54 * Structure containing emit state
56 typedef struct {
57 MonoMemPool *mempool;
59 /* Maps method names to the corresponding LLVMValueRef */
60 GHashTable *emitted_method_decls;
62 MonoCompile *cfg;
63 LLVMValueRef lmethod;
64 MonoLLVMModule *lmodule;
65 LLVMModuleRef module;
66 BBInfo *bblocks;
67 int sindex, default_index, ex_index;
68 LLVMBuilderRef builder;
69 LLVMValueRef *values, *addresses;
70 MonoType **vreg_cli_types;
71 LLVMCallInfo *linfo;
72 MonoMethodSignature *sig;
73 GSList *builders;
74 GHashTable *region_to_handler;
75 LLVMBuilderRef alloca_builder;
76 LLVMValueRef last_alloca;
77 LLVMValueRef rgctx_arg;
79 char temp_name [32];
80 } EmitContext;
82 typedef struct {
83 MonoBasicBlock *bb;
84 MonoInst *phi;
85 MonoBasicBlock *in_bb;
86 int sreg;
87 } PhiNode;
90 * Instruction metadata
91 * This is the same as ins_info, but LREG != IREG.
93 #ifdef MINI_OP
94 #undef MINI_OP
95 #endif
96 #ifdef MINI_OP3
97 #undef MINI_OP3
98 #endif
99 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
100 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
101 #define NONE ' '
102 #define IREG 'i'
103 #define FREG 'f'
104 #define VREG 'v'
105 #define XREG 'x'
106 #define LREG 'l'
107 /* keep in sync with the enum in mini.h */
108 const char
109 llvm_ins_info[] = {
110 #include "mini-ops.h"
112 #undef MINI_OP
113 #undef MINI_OP3
115 #if SIZEOF_VOID_P == 4
116 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
117 #else
118 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
119 #endif
121 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
123 #if 0
124 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
125 #else
126 #define TRACE_FAILURE(msg)
127 #endif
129 #define LLVM_FAILURE(ctx, reason) do { \
130 TRACE_FAILURE (reason); \
131 (ctx)->cfg->exception_message = g_strdup (reason); \
132 (ctx)->cfg->disable_llvm = TRUE; \
133 goto FAILURE; \
134 } while (0)
136 #define CHECK_FAILURE(ctx) do { \
137 if ((ctx)->cfg->disable_llvm) \
138 goto FAILURE; \
139 } while (0)
141 static LLVMIntPredicate cond_to_llvm_cond [] = {
142 LLVMIntEQ,
143 LLVMIntNE,
144 LLVMIntSLE,
145 LLVMIntSGE,
146 LLVMIntSLT,
147 LLVMIntSGT,
148 LLVMIntULE,
149 LLVMIntUGE,
150 LLVMIntULT,
151 LLVMIntUGT,
154 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
155 LLVMRealOEQ,
156 LLVMRealUNE,
157 LLVMRealOLE,
158 LLVMRealOGE,
159 LLVMRealOLT,
160 LLVMRealOGT,
161 LLVMRealULE,
162 LLVMRealUGE,
163 LLVMRealULT,
164 LLVMRealUGT,
167 static LLVMExecutionEngineRef ee;
168 static guint32 current_cfg_tls_id;
170 static MonoLLVMModule jit_module, aot_module;
171 static gboolean jit_module_inited;
172 static int memset_param_count, memcpy_param_count;
173 static const char *memset_func_name;
174 static const char *memcpy_func_name;
175 static const char *eh_selector_name;
177 static void init_jit_module (void);
180 * IntPtrType:
182 * The LLVM type with width == sizeof (gpointer)
184 static LLVMTypeRef
185 IntPtrType (void)
187 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
190 #if !LLVM_CHECK_VERSION(2, 8)
192 static LLVMValueRef LLVMBuildFAdd(LLVMBuilderRef Builder,
193 LLVMValueRef LHS, LLVMValueRef RHS,
194 const char *Name)
196 return LLVMBuildAdd (Builder, LHS, RHS, Name);
199 static LLVMValueRef LLVMBuildFSub(LLVMBuilderRef Builder,
200 LLVMValueRef LHS, LLVMValueRef RHS,
201 const char *Name)
203 return LLVMBuildSub (Builder, LHS, RHS, Name);
206 static LLVMValueRef LLVMBuildFMul(LLVMBuilderRef Builder,
207 LLVMValueRef LHS, LLVMValueRef RHS,
208 const char *Name)
210 return LLVMBuildMul (Builder, LHS, RHS, Name);
213 #endif
216 * get_vtype_size:
218 * Return the size of the LLVM representation of the vtype T.
220 static guint32
221 get_vtype_size (MonoType *t)
223 int size;
225 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
227 while (size < sizeof (gpointer) && mono_is_power_of_two (size) == -1)
228 size ++;
230 return size;
234 * simd_class_to_llvm_type:
236 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
238 static LLVMTypeRef
239 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
241 if (!strcmp (klass->name, "Vector2d")) {
242 return LLVMVectorType (LLVMDoubleType (), 2);
243 } else if (!strcmp (klass->name, "Vector2l")) {
244 return LLVMVectorType (LLVMInt64Type (), 2);
245 } else if (!strcmp (klass->name, "Vector2ul")) {
246 return LLVMVectorType (LLVMInt64Type (), 2);
247 } else if (!strcmp (klass->name, "Vector4i")) {
248 return LLVMVectorType (LLVMInt32Type (), 4);
249 } else if (!strcmp (klass->name, "Vector4ui")) {
250 return LLVMVectorType (LLVMInt32Type (), 4);
251 } else if (!strcmp (klass->name, "Vector4f")) {
252 return LLVMVectorType (LLVMFloatType (), 4);
253 } else if (!strcmp (klass->name, "Vector8s")) {
254 return LLVMVectorType (LLVMInt16Type (), 8);
255 } else if (!strcmp (klass->name, "Vector8us")) {
256 return LLVMVectorType (LLVMInt16Type (), 8);
257 } else if (!strcmp (klass->name, "Vector16sb")) {
258 return LLVMVectorType (LLVMInt8Type (), 16);
259 } else if (!strcmp (klass->name, "Vector16b")) {
260 return LLVMVectorType (LLVMInt8Type (), 16);
261 } else {
262 printf ("%s\n", klass->name);
263 NOT_IMPLEMENTED;
264 return NULL;
269 * type_to_llvm_type:
271 * Return the LLVM type corresponding to T.
273 static LLVMTypeRef
274 type_to_llvm_type (EmitContext *ctx, MonoType *t)
276 if (t->byref)
277 return LLVMPointerType (LLVMInt8Type (), 0);
278 switch (t->type) {
279 case MONO_TYPE_VOID:
280 return LLVMVoidType ();
281 case MONO_TYPE_I1:
282 return LLVMInt8Type ();
283 case MONO_TYPE_I2:
284 return LLVMInt16Type ();
285 case MONO_TYPE_I4:
286 return LLVMInt32Type ();
287 case MONO_TYPE_U1:
288 return LLVMInt8Type ();
289 case MONO_TYPE_U2:
290 return LLVMInt16Type ();
291 case MONO_TYPE_U4:
292 return LLVMInt32Type ();
293 case MONO_TYPE_BOOLEAN:
294 return LLVMInt8Type ();
295 case MONO_TYPE_I8:
296 case MONO_TYPE_U8:
297 return LLVMInt64Type ();
298 case MONO_TYPE_CHAR:
299 return LLVMInt16Type ();
300 case MONO_TYPE_R4:
301 return LLVMFloatType ();
302 case MONO_TYPE_R8:
303 return LLVMDoubleType ();
304 case MONO_TYPE_I:
305 case MONO_TYPE_U:
306 return IntPtrType ();
307 case MONO_TYPE_OBJECT:
308 case MONO_TYPE_CLASS:
309 case MONO_TYPE_ARRAY:
310 case MONO_TYPE_SZARRAY:
311 case MONO_TYPE_STRING:
312 case MONO_TYPE_PTR:
313 return LLVMPointerType (IntPtrType (), 0);
314 case MONO_TYPE_VAR:
315 case MONO_TYPE_MVAR:
316 /* Because of generic sharing */
317 return IntPtrType ();
318 case MONO_TYPE_GENERICINST:
319 if (!mono_type_generic_inst_is_valuetype (t))
320 return IntPtrType ();
321 /* Fall through */
322 case MONO_TYPE_VALUETYPE:
323 case MONO_TYPE_TYPEDBYREF: {
324 MonoClass *klass;
325 LLVMTypeRef ltype;
327 klass = mono_class_from_mono_type (t);
329 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
330 return simd_class_to_llvm_type (ctx, klass);
332 if (klass->enumtype)
333 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
334 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
335 if (!ltype) {
336 int i, size;
337 LLVMTypeRef *eltypes;
339 size = get_vtype_size (t);
341 eltypes = g_new (LLVMTypeRef, size);
342 for (i = 0; i < size; ++i)
343 eltypes [i] = LLVMInt8Type ();
345 ltype = LLVMStructType (eltypes, size, FALSE);
346 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
347 g_free (eltypes);
349 return ltype;
352 default:
353 printf ("X: %d\n", t->type);
354 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
355 ctx->cfg->disable_llvm = TRUE;
356 return NULL;
361 * type_is_unsigned:
363 * Return whenever T is an unsigned int type.
365 static gboolean
366 type_is_unsigned (EmitContext *ctx, MonoType *t)
368 if (t->byref)
369 return FALSE;
370 switch (t->type) {
371 case MONO_TYPE_U1:
372 case MONO_TYPE_U2:
373 case MONO_TYPE_U4:
374 case MONO_TYPE_U8:
375 return TRUE;
376 default:
377 return FALSE;
382 * type_to_llvm_arg_type:
384 * Same as type_to_llvm_type, but treat i8/i16 as i32.
386 static LLVMTypeRef
387 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
389 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
391 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
393 * LLVM generates code which only sets the lower bits, while JITted
394 * code expects all the bits to be set.
396 ptype = LLVMInt32Type ();
399 return ptype;
403 * llvm_type_to_stack_type:
405 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
406 * on the IL stack.
408 static G_GNUC_UNUSED LLVMTypeRef
409 llvm_type_to_stack_type (LLVMTypeRef type)
411 if (type == NULL)
412 return NULL;
413 if (type == LLVMInt8Type ())
414 return LLVMInt32Type ();
415 else if (type == LLVMInt16Type ())
416 return LLVMInt32Type ();
417 else if (type == LLVMFloatType ())
418 return LLVMDoubleType ();
419 else
420 return type;
424 * regtype_to_llvm_type:
426 * Return the LLVM type corresponding to the regtype C used in instruction
427 * descriptions.
429 static LLVMTypeRef
430 regtype_to_llvm_type (char c)
432 switch (c) {
433 case 'i':
434 return LLVMInt32Type ();
435 case 'l':
436 return LLVMInt64Type ();
437 case 'f':
438 return LLVMDoubleType ();
439 default:
440 return NULL;
445 * op_to_llvm_type:
447 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
449 static LLVMTypeRef
450 op_to_llvm_type (int opcode)
452 switch (opcode) {
453 case OP_ICONV_TO_I1:
454 case OP_LCONV_TO_I1:
455 return LLVMInt8Type ();
456 case OP_ICONV_TO_U1:
457 case OP_LCONV_TO_U1:
458 return LLVMInt8Type ();
459 case OP_ICONV_TO_I2:
460 case OP_LCONV_TO_I2:
461 return LLVMInt16Type ();
462 case OP_ICONV_TO_U2:
463 case OP_LCONV_TO_U2:
464 return LLVMInt16Type ();
465 case OP_ICONV_TO_I4:
466 case OP_LCONV_TO_I4:
467 return LLVMInt32Type ();
468 case OP_ICONV_TO_U4:
469 case OP_LCONV_TO_U4:
470 return LLVMInt32Type ();
471 case OP_ICONV_TO_I8:
472 return LLVMInt64Type ();
473 case OP_ICONV_TO_R4:
474 return LLVMFloatType ();
475 case OP_ICONV_TO_R8:
476 return LLVMDoubleType ();
477 case OP_ICONV_TO_U8:
478 return LLVMInt64Type ();
479 case OP_FCONV_TO_I4:
480 return LLVMInt32Type ();
481 case OP_FCONV_TO_I8:
482 return LLVMInt64Type ();
483 case OP_FCONV_TO_I1:
484 case OP_FCONV_TO_U1:
485 return LLVMInt8Type ();
486 case OP_FCONV_TO_I2:
487 case OP_FCONV_TO_U2:
488 return LLVMInt16Type ();
489 case OP_FCONV_TO_I:
490 case OP_FCONV_TO_U:
491 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
492 case OP_IADD_OVF:
493 case OP_IADD_OVF_UN:
494 case OP_ISUB_OVF:
495 case OP_ISUB_OVF_UN:
496 case OP_IMUL_OVF:
497 case OP_IMUL_OVF_UN:
498 return LLVMInt32Type ();
499 case OP_LADD_OVF:
500 case OP_LADD_OVF_UN:
501 case OP_LSUB_OVF:
502 case OP_LSUB_OVF_UN:
503 case OP_LMUL_OVF:
504 case OP_LMUL_OVF_UN:
505 return LLVMInt64Type ();
506 default:
507 printf ("%s\n", mono_inst_name (opcode));
508 g_assert_not_reached ();
509 return NULL;
514 * load_store_to_llvm_type:
516 * Return the size/sign/zero extension corresponding to the load/store opcode
517 * OPCODE.
519 static LLVMTypeRef
520 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
522 *sext = FALSE;
523 *zext = FALSE;
525 switch (opcode) {
526 case OP_LOADI1_MEMBASE:
527 case OP_STOREI1_MEMBASE_REG:
528 case OP_STOREI1_MEMBASE_IMM:
529 *size = 1;
530 *sext = TRUE;
531 return LLVMInt8Type ();
532 case OP_LOADU1_MEMBASE:
533 case OP_LOADU1_MEM:
534 *size = 1;
535 *zext = TRUE;
536 return LLVMInt8Type ();
537 case OP_LOADI2_MEMBASE:
538 case OP_STOREI2_MEMBASE_REG:
539 case OP_STOREI2_MEMBASE_IMM:
540 *size = 2;
541 *sext = TRUE;
542 return LLVMInt16Type ();
543 case OP_LOADU2_MEMBASE:
544 case OP_LOADU2_MEM:
545 *size = 2;
546 *zext = TRUE;
547 return LLVMInt16Type ();
548 case OP_LOADI4_MEMBASE:
549 case OP_LOADU4_MEMBASE:
550 case OP_LOADI4_MEM:
551 case OP_LOADU4_MEM:
552 case OP_STOREI4_MEMBASE_REG:
553 case OP_STOREI4_MEMBASE_IMM:
554 *size = 4;
555 return LLVMInt32Type ();
556 case OP_LOADI8_MEMBASE:
557 case OP_LOADI8_MEM:
558 case OP_STOREI8_MEMBASE_REG:
559 case OP_STOREI8_MEMBASE_IMM:
560 *size = 8;
561 return LLVMInt64Type ();
562 case OP_LOADR4_MEMBASE:
563 case OP_STORER4_MEMBASE_REG:
564 *size = 4;
565 return LLVMFloatType ();
566 case OP_LOADR8_MEMBASE:
567 case OP_STORER8_MEMBASE_REG:
568 *size = 8;
569 return LLVMDoubleType ();
570 case OP_LOAD_MEMBASE:
571 case OP_LOAD_MEM:
572 case OP_STORE_MEMBASE_REG:
573 case OP_STORE_MEMBASE_IMM:
574 *size = sizeof (gpointer);
575 return IntPtrType ();
576 default:
577 g_assert_not_reached ();
578 return NULL;
583 * ovf_op_to_intrins:
585 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
587 static const char*
588 ovf_op_to_intrins (int opcode)
590 switch (opcode) {
591 case OP_IADD_OVF:
592 return "llvm.sadd.with.overflow.i32";
593 case OP_IADD_OVF_UN:
594 return "llvm.uadd.with.overflow.i32";
595 case OP_ISUB_OVF:
596 return "llvm.ssub.with.overflow.i32";
597 case OP_ISUB_OVF_UN:
598 return "llvm.usub.with.overflow.i32";
599 case OP_IMUL_OVF:
600 return "llvm.smul.with.overflow.i32";
601 case OP_IMUL_OVF_UN:
602 return "llvm.umul.with.overflow.i32";
603 case OP_LADD_OVF:
604 return "llvm.sadd.with.overflow.i64";
605 case OP_LADD_OVF_UN:
606 return "llvm.uadd.with.overflow.i64";
607 case OP_LSUB_OVF:
608 return "llvm.ssub.with.overflow.i64";
609 case OP_LSUB_OVF_UN:
610 return "llvm.usub.with.overflow.i64";
611 case OP_LMUL_OVF:
612 return "llvm.smul.with.overflow.i64";
613 case OP_LMUL_OVF_UN:
614 return "llvm.umul.with.overflow.i64";
615 default:
616 g_assert_not_reached ();
617 return NULL;
621 static const char*
622 simd_op_to_intrins (int opcode)
624 switch (opcode) {
625 #if defined(TARGET_X86) || defined(TARGET_AMD64)
626 case OP_MINPD:
627 return "llvm.x86.sse2.min.pd";
628 case OP_MINPS:
629 return "llvm.x86.sse2.min.ps";
630 case OP_PMIND_UN:
631 return "llvm.x86.sse41.pminud";
632 case OP_PMINW_UN:
633 return "llvm.x86.sse41.pminuw";
634 case OP_PMINB_UN:
635 return "llvm.x86.sse2.pminu.b";
636 case OP_MAXPD:
637 return "llvm.x86.sse2.max.pd";
638 case OP_MAXPS:
639 return "llvm.x86.sse2.max.ps";
640 case OP_PMAXD_UN:
641 return "llvm.x86.sse41.pmaxud";
642 case OP_PMAXW_UN:
643 return "llvm.x86.sse41.pmaxuw";
644 case OP_PMAXB_UN:
645 return "llvm.x86.sse2.pmaxu.b";
646 #endif
647 default:
648 g_assert_not_reached ();
649 return NULL;
654 * get_bb:
656 * Return the LLVM basic block corresponding to BB.
658 static LLVMBasicBlockRef
659 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
661 char bb_name [128];
663 if (ctx->bblocks [bb->block_num].bblock == NULL) {
664 sprintf (bb_name, "BB%d", bb->block_num);
666 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
667 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
670 return ctx->bblocks [bb->block_num].bblock;
674 * get_end_bb:
676 * Return the last LLVM bblock corresponding to BB.
677 * This might not be equal to the bb returned by get_bb () since we need to generate
678 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
680 static LLVMBasicBlockRef
681 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
683 get_bb (ctx, bb);
684 return ctx->bblocks [bb->block_num].end_bblock;
687 static LLVMBasicBlockRef
688 gen_bb (EmitContext *ctx, const char *prefix)
690 char bb_name [128];
692 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
693 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
697 * resolve_patch:
699 * Return the target of the patch identified by TYPE and TARGET.
701 static gpointer
702 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
704 MonoJumpInfo ji;
706 memset (&ji, 0, sizeof (ji));
707 ji.type = type;
708 ji.data.target = target;
710 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
714 * convert_full:
716 * Emit code to convert the LLVM value V to DTYPE.
718 static LLVMValueRef
719 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
721 LLVMTypeRef stype = LLVMTypeOf (v);
723 if (stype != dtype) {
724 gboolean ext = FALSE;
726 /* Extend */
727 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
728 ext = TRUE;
729 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
730 ext = TRUE;
731 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
732 ext = TRUE;
734 if (ext)
735 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
737 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
738 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
740 /* Trunc */
741 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
742 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
743 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
744 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
745 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
746 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
748 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
749 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
750 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
751 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
752 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
753 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
755 #ifdef MONO_ARCH_SOFT_FLOAT
756 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
757 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
758 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
759 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
760 #endif
762 LLVMDumpValue (v);
763 LLVMDumpValue (LLVMConstNull (dtype));
764 g_assert_not_reached ();
765 return NULL;
766 } else {
767 return v;
771 static LLVMValueRef
772 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
774 return convert_full (ctx, v, dtype, FALSE);
778 * emit_volatile_load:
780 * If vreg is volatile, emit a load from its address.
782 static LLVMValueRef
783 emit_volatile_load (EmitContext *ctx, int vreg)
785 MonoType *t;
787 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
788 t = ctx->vreg_cli_types [vreg];
789 if (t && !t->byref) {
791 * Might have to zero extend since llvm doesn't have
792 * unsigned types.
794 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2)
795 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
796 else if (t->type == MONO_TYPE_U8)
797 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
800 return v;
804 * emit_volatile_store:
806 * If VREG is volatile, emit a store from its value to its address.
808 static void
809 emit_volatile_store (EmitContext *ctx, int vreg)
811 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
813 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
814 g_assert (ctx->addresses [vreg]);
815 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
820 * sig_to_llvm_sig:
822 * Return the LLVM signature corresponding to the mono signature SIG using the
823 * calling convention information in CINFO.
825 static LLVMTypeRef
826 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
828 LLVMTypeRef ret_type;
829 LLVMTypeRef *param_types = NULL;
830 LLVMTypeRef res;
831 int i, j, pindex;
832 gboolean vretaddr = FALSE;
834 ret_type = type_to_llvm_type (ctx, sig->ret);
835 CHECK_FAILURE (ctx);
837 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
838 /* LLVM models this by returning an aggregate value */
839 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
840 LLVMTypeRef members [2];
842 members [0] = IntPtrType ();
843 ret_type = LLVMStructType (members, 1, FALSE);
844 } else {
845 g_assert_not_reached ();
847 } else if (cinfo && MONO_TYPE_ISSTRUCT (sig->ret)) {
848 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
849 vretaddr = TRUE;
852 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 2) + 2);
853 pindex = 0;
854 if (cinfo && cinfo->rgctx_arg) {
855 param_types [pindex] = IntPtrType ();
856 pindex ++;
858 if (cinfo && cinfo->imt_arg) {
859 param_types [pindex] = IntPtrType ();
860 pindex ++;
862 if (vretaddr) {
863 ret_type = LLVMVoidType ();
864 param_types [pindex ++] = IntPtrType ();
866 if (sig->hasthis)
867 param_types [pindex ++] = IntPtrType ();
868 for (i = 0; i < sig->param_count; ++i) {
869 if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeInReg) {
870 for (j = 0; j < 2; ++j) {
871 switch (cinfo->args [i + sig->hasthis].pair_storage [j]) {
872 case LLVMArgInIReg:
873 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
874 break;
875 case LLVMArgNone:
876 break;
877 default:
878 g_assert_not_reached ();
881 } else if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal) {
882 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
883 CHECK_FAILURE (ctx);
884 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
885 pindex ++;
886 } else {
887 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
890 CHECK_FAILURE (ctx);
892 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
893 g_free (param_types);
895 return res;
897 FAILURE:
898 g_free (param_types);
900 return NULL;
904 * LLVMFunctionType1:
906 * Create an LLVM function type from the arguments.
908 static G_GNUC_UNUSED LLVMTypeRef
909 LLVMFunctionType1(LLVMTypeRef ReturnType,
910 LLVMTypeRef ParamType1,
911 int IsVarArg)
913 LLVMTypeRef param_types [1];
915 param_types [0] = ParamType1;
917 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
921 * LLVMFunctionType2:
923 * Create an LLVM function type from the arguments.
925 static LLVMTypeRef
926 LLVMFunctionType2(LLVMTypeRef ReturnType,
927 LLVMTypeRef ParamType1,
928 LLVMTypeRef ParamType2,
929 int IsVarArg)
931 LLVMTypeRef param_types [2];
933 param_types [0] = ParamType1;
934 param_types [1] = ParamType2;
936 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
940 * LLVMFunctionType3:
942 * Create an LLVM function type from the arguments.
944 static LLVMTypeRef
945 LLVMFunctionType3(LLVMTypeRef ReturnType,
946 LLVMTypeRef ParamType1,
947 LLVMTypeRef ParamType2,
948 LLVMTypeRef ParamType3,
949 int IsVarArg)
951 LLVMTypeRef param_types [3];
953 param_types [0] = ParamType1;
954 param_types [1] = ParamType2;
955 param_types [2] = ParamType3;
957 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
961 * create_builder:
963 * Create an LLVM builder and remember it so it can be freed later.
965 static LLVMBuilderRef
966 create_builder (EmitContext *ctx)
968 LLVMBuilderRef builder = LLVMCreateBuilder ();
970 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
972 return builder;
975 static LLVMValueRef
976 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
978 char *callee_name = mono_aot_get_plt_symbol (type, data);
979 LLVMValueRef callee;
981 if (!callee_name)
982 return NULL;
984 // FIXME: Locking
985 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
986 if (!callee) {
987 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
989 LLVMSetVisibility (callee, LLVMHiddenVisibility);
991 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
994 return callee;
997 static void
998 emit_cond_throw_pos (EmitContext *ctx)
1002 static int
1003 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1005 MonoMethodHeader *header = cfg->header;
1006 MonoExceptionClause *clause;
1007 int i;
1009 /* Directly */
1010 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1011 return (bb->region >> 8) - 1;
1013 /* Indirectly */
1014 for (i = 0; i < header->num_clauses; ++i) {
1015 clause = &header->clauses [i];
1017 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1018 return i;
1021 return -1;
1025 * emit_call:
1027 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1028 * a try region.
1030 static LLVMValueRef
1031 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1033 MonoCompile *cfg = ctx->cfg;
1034 LLVMValueRef lcall;
1035 LLVMBuilderRef builder = *builder_ref;
1036 int clause_index;
1038 clause_index = get_handler_clause (cfg, bb);
1040 if (clause_index != -1) {
1041 MonoMethodHeader *header = cfg->header;
1042 MonoExceptionClause *ec = &header->clauses [clause_index];
1043 MonoBasicBlock *tblock;
1044 LLVMBasicBlockRef ex_bb, noex_bb;
1047 * Have to use an invoke instead of a call, branching to the
1048 * handler bblock of the clause containing this bblock.
1051 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1053 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1054 g_assert (tblock);
1056 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1058 ex_bb = get_bb (ctx, tblock);
1060 noex_bb = gen_bb (ctx, "NOEX_BB");
1062 /* Use an invoke */
1063 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1065 builder = ctx->builder = create_builder (ctx);
1066 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1068 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1069 } else {
1070 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1071 ctx->builder = builder;
1074 *builder_ref = ctx->builder;
1076 return lcall;
1080 * emit_cond_system_exception:
1082 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1083 * Might set the ctx exception.
1085 static void
1086 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1088 LLVMBasicBlockRef ex_bb, noex_bb;
1089 LLVMBuilderRef builder;
1090 MonoClass *exc_class;
1091 LLVMValueRef args [2];
1093 ex_bb = gen_bb (ctx, "EX_BB");
1094 noex_bb = gen_bb (ctx, "NOEX_BB");
1096 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1098 exc_class = mono_class_from_name (mono_defaults.corlib, "System", exc_type);
1099 g_assert (exc_class);
1101 /* Emit exception throwing code */
1102 builder = create_builder (ctx);
1103 LLVMPositionBuilderAtEnd (builder, ex_bb);
1105 if (!ctx->lmodule->throw_corlib_exception) {
1106 LLVMValueRef callee;
1107 LLVMTypeRef sig;
1109 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_defaults.corlib, 2);
1110 throw_sig->ret = &mono_defaults.void_class->byval_arg;
1111 throw_sig->params [0] = &mono_defaults.int32_class->byval_arg;
1112 throw_sig->params [1] = &mono_defaults.int32_class->byval_arg;
1113 sig = sig_to_llvm_sig (ctx, throw_sig, NULL);
1115 if (ctx->cfg->compile_aot) {
1116 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_arch_throw_corlib_exception");
1117 } else {
1118 callee = LLVMAddFunction (ctx->module, "throw_corlib_exception", sig_to_llvm_sig (ctx, throw_sig, NULL));
1120 #ifdef TARGET_X86
1122 * LLVM generated code doesn't push the arguments, so we need another
1123 * throw trampoline.
1125 LLVMAddGlobalMapping (ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_arch_llvm_throw_corlib_exception"));
1126 #else
1127 LLVMAddGlobalMapping (ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_arch_throw_corlib_exception"));
1128 #endif
1131 mono_memory_barrier ();
1132 ctx->lmodule->throw_corlib_exception = callee;
1135 #ifdef TARGET_X86
1136 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1137 #else
1138 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1139 #endif
1142 * FIXME: The offset is 0, this is only a problem if the code is inside a clause,
1143 * otherwise only the line numbers in stack traces are incorrect.
1145 if (bb->region != -1)
1146 LLVM_FAILURE (ctx, "system-ex-in-region");
1148 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1149 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1151 LLVMBuildUnreachable (builder);
1153 ctx->builder = create_builder (ctx);
1154 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1156 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1158 ctx->ex_index ++;
1159 return;
1161 FAILURE:
1162 return;
1166 * emit_reg_to_vtype:
1168 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
1170 static void
1171 emit_reg_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs)
1173 int j, size;
1175 size = get_vtype_size (t);
1177 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1178 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1181 for (j = 0; j < 2; ++j) {
1182 LLVMValueRef index [2], addr;
1183 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1184 LLVMTypeRef part_type;
1186 if (ainfo->pair_storage [j] == LLVMArgNone)
1187 continue;
1189 part_type = LLVMIntType (part_size * 8);
1190 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1191 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1192 addr = LLVMBuildGEP (builder, address, index, 1, "");
1193 } else {
1194 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1195 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1196 addr = LLVMBuildGEP (builder, address, index, 2, "");
1198 switch (ainfo->pair_storage [j]) {
1199 case LLVMArgInIReg:
1200 LLVMBuildStore (builder, convert (ctx, regs [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1201 break;
1202 case LLVMArgNone:
1203 break;
1204 default:
1205 g_assert_not_reached ();
1208 size -= sizeof (gpointer);
1213 * emit_vtype_to_reg:
1215 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
1216 * into REGS, and the number of registers into NREGS.
1218 static void
1219 emit_vtype_to_reg (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs, guint32 *nregs)
1221 int pindex = 0;
1222 int j, size;
1224 size = get_vtype_size (t);
1226 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1227 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1230 for (j = 0; j < 2; ++j) {
1231 LLVMValueRef index [2], addr;
1232 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1234 if (ainfo->pair_storage [j] == LLVMArgNone)
1235 continue;
1237 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1238 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1239 addr = LLVMBuildGEP (builder, address, index, 1, "");
1240 } else {
1241 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1242 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1243 addr = LLVMBuildGEP (builder, address, index, 2, "");
1245 switch (ainfo->pair_storage [j]) {
1246 case LLVMArgInIReg:
1247 regs [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1248 break;
1249 case LLVMArgNone:
1250 break;
1251 default:
1252 g_assert_not_reached ();
1254 size -= sizeof (gpointer);
1257 *nregs = pindex;
1260 static LLVMValueRef
1261 build_alloca (EmitContext *ctx, MonoType *t)
1263 MonoClass *k = mono_class_from_mono_type (t);
1264 int align;
1266 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1267 align = 16;
1268 else
1269 align = mono_class_min_align (k);
1271 /* Sometimes align is not a power of 2 */
1272 while (mono_is_power_of_two (align) == -1)
1273 align ++;
1276 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1277 * get executed every time control reaches them.
1279 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1281 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, type_to_llvm_type (ctx, t), NULL, align, "");
1282 return ctx->last_alloca;
1286 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1288 static void
1289 mark_as_used (LLVMModuleRef module, LLVMValueRef global)
1291 LLVMTypeRef used_type;
1292 LLVMValueRef used, used_elem;
1294 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), 1);
1295 used = LLVMAddGlobal (module, used_type, "llvm.used");
1296 used_elem = LLVMConstBitCast (global, LLVMPointerType (LLVMInt8Type (), 0));
1297 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), &used_elem, 1));
1298 LLVMSetLinkage (used, LLVMAppendingLinkage);
1299 LLVMSetSection (used, "llvm.metadata");
1303 * emit_entry_bb:
1305 * Emit code to load/convert arguments.
1307 static void
1308 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder, int *pindexes)
1310 int i, pindex;
1311 MonoCompile *cfg = ctx->cfg;
1312 MonoMethodSignature *sig = ctx->sig;
1313 LLVMCallInfo *linfo = ctx->linfo;
1314 MonoBasicBlock *bb;
1316 ctx->alloca_builder = create_builder (ctx);
1319 * Handle indirect/volatile variables by allocating memory for them
1320 * using 'alloca', and storing their address in a temporary.
1322 for (i = 0; i < cfg->num_varinfo; ++i) {
1323 MonoInst *var = cfg->varinfo [i];
1324 LLVMTypeRef vtype;
1326 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || MONO_TYPE_ISSTRUCT (var->inst_vtype)) {
1327 vtype = type_to_llvm_type (ctx, var->inst_vtype);
1328 CHECK_FAILURE (ctx);
1329 /* Could be already created by an OP_VPHI */
1330 if (!ctx->addresses [var->dreg])
1331 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
1332 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
1336 for (i = 0; i < sig->param_count; ++i) {
1337 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
1338 int reg = cfg->args [i + sig->hasthis]->dreg;
1340 if (ainfo->storage == LLVMArgVtypeInReg) {
1341 LLVMValueRef regs [2];
1344 * Emit code to save the argument from the registers to
1345 * the real argument.
1347 pindex = pindexes [i];
1348 regs [0] = LLVMGetParam (ctx->lmethod, pindex);
1349 if (ainfo->pair_storage [1] != LLVMArgNone)
1350 regs [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
1351 else
1352 regs [1] = NULL;
1354 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
1356 emit_reg_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, regs);
1358 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1359 /* Treat these as normal values */
1360 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1362 } else if (ainfo->storage == LLVMArgVtypeByVal) {
1363 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindexes [i]);
1365 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1366 /* Treat these as normal values */
1367 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1369 } else {
1370 ctx->values [reg] = convert (ctx, ctx->values [reg], llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->params [i])));
1374 if (cfg->vret_addr)
1375 emit_volatile_store (ctx, cfg->vret_addr->dreg);
1376 if (sig->hasthis)
1377 emit_volatile_store (ctx, cfg->args [0]->dreg);
1378 for (i = 0; i < sig->param_count; ++i)
1379 if (!MONO_TYPE_ISSTRUCT (sig->params [i]))
1380 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
1382 if (sig->hasthis && !cfg->rgctx_var) {
1383 #if LLVM_CHECK_VERSION (2, 8)
1384 LLVMValueRef this_alloc, md_arg;
1385 int md_kind;
1388 * The exception handling code needs the location where the this argument was
1389 * stored for gshared methods. We create a separate alloca to hold it, and mark it
1390 * with the "mono.this" custom metadata to tell llvm that it needs to save its
1391 * location into the LSDA.
1393 // FIXME: Do this for gshared only
1394 this_alloc = mono_llvm_build_alloca (builder, IntPtrType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
1395 /* This volatile store will keep the alloca alive */
1396 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE);
1398 md_kind = LLVMGetMDKindID ("mono.this", strlen ("mono.this"));
1399 md_arg = LLVMMDString ("this", 4);
1400 LLVMSetMetadata (this_alloc, md_kind, LLVMMDNode (&md_arg, 1));
1401 #endif
1404 if (cfg->rgctx_var) {
1405 LLVMValueRef rgctx_alloc, store, md_arg;
1406 int md_kind;
1409 * We handle the rgctx arg similarly to the this pointer.
1411 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
1412 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
1413 /* This volatile store will keep the alloca alive */
1414 store = mono_llvm_build_store (builder, ctx->rgctx_arg, rgctx_alloc, TRUE);
1416 md_kind = LLVMGetMDKindID ("mono.this", strlen ("mono.this"));
1417 md_arg = LLVMMDString ("this", 4);
1418 LLVMSetMetadata (rgctx_alloc, md_kind, LLVMMDNode (&md_arg, 1));
1422 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
1423 * it needs to continue normally, or return back to the exception handling system.
1425 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1426 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER))
1427 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
1428 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER) && bb->in_scount == 0) {
1429 LLVMValueRef val = LLVMBuildAlloca (builder, LLVMInt32Type (), "");
1430 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
1432 ctx->bblocks [bb->block_num].finally_ind = val;
1436 FAILURE:
1440 /* Have to export this for AOT */
1441 void
1442 mono_personality (void);
1444 void
1445 mono_personality (void)
1447 /* Not used */
1448 g_assert_not_reached ();
1452 * mono_llvm_emit_method:
1454 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
1456 void
1457 mono_llvm_emit_method (MonoCompile *cfg)
1459 EmitContext *ctx;
1460 MonoMethodSignature *sig;
1461 MonoBasicBlock *bb;
1462 LLVMTypeRef method_type;
1463 LLVMValueRef method = NULL, debug_alias = NULL;
1464 char *method_name, *debug_name = NULL;
1465 LLVMValueRef *values, *addresses;
1466 LLVMTypeRef *vreg_types;
1467 MonoType **vreg_cli_types;
1468 int i, max_block_num, pindex, bb_index;
1469 int *pindexes = NULL;
1470 gboolean last = FALSE;
1471 GPtrArray *phi_values;
1472 LLVMCallInfo *linfo;
1473 GSList *l;
1474 LLVMModuleRef module;
1475 gboolean *is_dead;
1476 gboolean *unreachable;
1477 BBInfo *bblocks;
1478 GPtrArray *bblock_list;
1479 MonoMethodHeader *header;
1480 MonoExceptionClause *clause;
1482 /* The code below might acquire the loader lock, so use it for global locking */
1483 mono_loader_lock ();
1485 /* Used to communicate with the callbacks */
1486 TlsSetValue (current_cfg_tls_id, cfg);
1488 ctx = g_new0 (EmitContext, 1);
1489 ctx->cfg = cfg;
1490 ctx->mempool = cfg->mempool;
1493 * This maps vregs to the LLVM instruction defining them
1495 values = g_new0 (LLVMValueRef, cfg->next_vreg);
1497 * This maps vregs for volatile variables to the LLVM instruction defining their
1498 * address.
1500 addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
1501 vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
1502 vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
1503 phi_values = g_ptr_array_new ();
1505 * This signals whenever the vreg was defined by a phi node with no input vars
1506 * (i.e. all its input bblocks end with NOT_REACHABLE).
1508 is_dead = g_new0 (gboolean, cfg->next_vreg);
1509 /* Whenever the bblock is unreachable */
1510 unreachable = g_new0 (gboolean, cfg->max_block_num);
1512 bblock_list = g_ptr_array_new ();
1514 ctx->values = values;
1515 ctx->addresses = addresses;
1516 ctx->vreg_cli_types = vreg_cli_types;
1517 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
1519 if (cfg->compile_aot) {
1520 ctx->lmodule = &aot_module;
1521 method_name = mono_aot_get_method_name (cfg);
1522 debug_name = mono_aot_get_method_debug_name (cfg);
1523 } else {
1524 init_jit_module ();
1525 ctx->lmodule = &jit_module;
1526 method_name = mono_method_full_name (cfg->method, TRUE);
1527 debug_name = NULL;
1530 module = ctx->module = ctx->lmodule->module;
1532 #if 1
1534 static int count = 0;
1535 count ++;
1537 if (getenv ("LLVM_COUNT")) {
1538 if (count == atoi (getenv ("LLVM_COUNT"))) {
1539 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
1540 last = TRUE;
1542 if (count > atoi (getenv ("LLVM_COUNT")))
1543 LLVM_FAILURE (ctx, "");
1546 #endif
1548 sig = mono_method_signature (cfg->method);
1549 ctx->sig = sig;
1551 linfo = mono_arch_get_llvm_call_info (cfg, sig);
1552 ctx->linfo = linfo;
1553 CHECK_FAILURE (ctx);
1555 if (cfg->rgctx_var) {
1556 if (IS_LLVM_MONO_BRANCH)
1557 linfo->rgctx_arg = TRUE;
1558 else
1559 LLVM_FAILURE (ctx, "rgctx arg");
1561 method_type = sig_to_llvm_sig (ctx, sig, linfo);
1562 CHECK_FAILURE (ctx);
1564 method = LLVMAddFunction (module, method_name, method_type);
1565 ctx->lmethod = method;
1567 if (linfo->rgctx_arg)
1568 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
1569 LLVMSetLinkage (method, LLVMPrivateLinkage);
1571 if (cfg->method->save_lmf)
1572 LLVM_FAILURE (ctx, "lmf");
1574 if (sig->pinvoke)
1575 LLVM_FAILURE (ctx, "pinvoke signature");
1577 header = cfg->header;
1578 for (i = 0; i < header->num_clauses; ++i) {
1579 clause = &header->clauses [i];
1580 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
1581 LLVM_FAILURE (ctx, "non-finally/catch clause.");
1585 * This maps parameter indexes in the original signature to the indexes in
1586 * the LLVM signature.
1588 pindexes = g_new0 (int, sig->param_count);
1589 pindex = 0;
1590 if (linfo->rgctx_arg) {
1591 ctx->rgctx_arg = LLVMGetParam (method, pindex);
1593 * We mark the rgctx parameter with the inreg attribute, which is mapped to
1594 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
1595 * CC_X86_64_Mono in X86CallingConv.td.
1597 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
1598 pindex ++;
1600 if (cfg->vret_addr) {
1601 values [cfg->vret_addr->dreg] = LLVMGetParam (method, pindex);
1602 pindex ++;
1604 if (sig->hasthis) {
1605 values [cfg->args [0]->dreg] = LLVMGetParam (method, pindex);
1606 pindex ++;
1608 for (i = 0; i < sig->param_count; ++i) {
1609 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
1610 pindexes [i] = pindex;
1611 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeInReg) {
1612 if (linfo->args [i + sig->hasthis].pair_storage [0] != LLVMArgNone)
1613 pindex ++;
1614 if (linfo->args [i + sig->hasthis].pair_storage [1] != LLVMArgNone)
1615 pindex ++;
1616 } else if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal) {
1617 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
1618 pindex ++;
1619 } else {
1620 pindex ++;
1624 max_block_num = 0;
1625 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
1626 max_block_num = MAX (max_block_num, bb->block_num);
1627 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
1629 /* Add branches between non-consecutive bblocks */
1630 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1631 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
1632 bb->next_bb != bb->last_ins->inst_false_bb) {
1634 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
1635 inst->opcode = OP_BR;
1636 inst->inst_target_bb = bb->last_ins->inst_false_bb;
1637 mono_bblock_add_inst (bb, inst);
1642 * Make a first pass over the code to precreate PHI nodes.
1644 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1645 MonoInst *ins;
1646 LLVMBuilderRef builder;
1647 char *dname;
1648 char dname_buf[128];
1650 builder = create_builder (ctx);
1652 for (ins = bb->code; ins; ins = ins->next) {
1653 switch (ins->opcode) {
1654 case OP_PHI:
1655 case OP_FPHI:
1656 case OP_VPHI:
1657 case OP_XPHI: {
1658 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
1660 CHECK_FAILURE (ctx);
1662 if (ins->opcode == OP_VPHI) {
1663 /* Treat valuetype PHI nodes as operating on the address itself */
1664 g_assert (ins->klass);
1665 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
1669 * Have to precreate these, as they can be referenced by
1670 * earlier instructions.
1672 sprintf (dname_buf, "t%d", ins->dreg);
1673 dname = dname_buf;
1674 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
1676 if (ins->opcode == OP_VPHI)
1677 addresses [ins->dreg] = values [ins->dreg];
1679 g_ptr_array_add (phi_values, values [ins->dreg]);
1682 * Set the expected type of the incoming arguments since these have
1683 * to have the same type.
1685 for (i = 0; i < ins->inst_phi_args [0]; i++) {
1686 int sreg1 = ins->inst_phi_args [i + 1];
1688 if (sreg1 != -1)
1689 vreg_types [sreg1] = phi_type;
1691 break;
1693 default:
1694 break;
1700 * Create an ordering for bblocks, use the depth first order first, then
1701 * put the exception handling bblocks last.
1703 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
1704 bb = cfg->bblocks [bb_index];
1705 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
1706 g_ptr_array_add (bblock_list, bb);
1707 bblocks [bb->block_num].added = TRUE;
1711 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1712 if (!bblocks [bb->block_num].added)
1713 g_ptr_array_add (bblock_list, bb);
1717 * Second pass: generate code.
1719 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
1720 MonoInst *ins;
1721 LLVMBasicBlockRef cbb;
1722 LLVMBuilderRef builder;
1723 gboolean has_terminator;
1724 LLVMValueRef v;
1725 LLVMValueRef lhs, rhs;
1727 bb = g_ptr_array_index (bblock_list, bb_index);
1729 if (!(bb == cfg->bb_entry || bb->in_count > 0))
1730 continue;
1732 cbb = get_bb (ctx, bb);
1733 builder = create_builder (ctx);
1734 ctx->builder = builder;
1735 LLVMPositionBuilderAtEnd (builder, cbb);
1737 if (bb == cfg->bb_entry)
1738 emit_entry_bb (ctx, builder, pindexes);
1739 CHECK_FAILURE (ctx);
1741 if (bb->flags & BB_EXCEPTION_HANDLER) {
1742 LLVMTypeRef i8ptr;
1743 LLVMValueRef eh_selector, eh_exception, personality, args [4];
1744 MonoInst *exvar;
1745 static gint32 mapping_inited;
1746 static int ti_generator;
1747 char ti_name [128];
1748 MonoClass **ti;
1749 LLVMValueRef type_info;
1750 int clause_index;
1752 if (!bblocks [bb->block_num].invoke_target) {
1754 * LLVM asserts if llvm.eh.selector is called from a bblock which
1755 * doesn't have an invoke pointing at it.
1757 LLVM_FAILURE (ctx, "handler without invokes");
1760 eh_selector = LLVMGetNamedFunction (module, eh_selector_name);
1762 if (cfg->compile_aot) {
1763 /* Use a dummy personality function */
1764 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
1765 g_assert (personality);
1766 } else {
1767 personality = LLVMGetNamedFunction (module, "mono_personality");
1768 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
1769 LLVMAddGlobalMapping (ee, personality, mono_personality);
1772 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
1774 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
1777 * Create the type info
1779 sprintf (ti_name, "type_info_%d", ti_generator);
1780 ti_generator ++;
1782 if (cfg->compile_aot) {
1783 /* decode_eh_frame () in aot-runtime.c will decode this */
1784 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
1785 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
1787 LLVMSetLinkage (type_info, LLVMPrivateLinkage);
1788 LLVMSetVisibility (type_info, LLVMHiddenVisibility);
1791 * Enabling this causes llc to crash:
1792 * http://llvm.org/bugs/show_bug.cgi?id=6102
1794 LLVM_FAILURE (ctx, "aot+clauses");
1795 } else {
1796 /* exception_cb will decode this */
1797 ti = g_malloc (sizeof (gint32));
1798 *(gint32*)ti = clause_index;
1800 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
1802 LLVMAddGlobalMapping (ee, type_info, ti);
1805 args [0] = LLVMConstNull (i8ptr);
1806 args [1] = LLVMConstBitCast (personality, i8ptr);
1807 args [2] = type_info;
1808 LLVMBuildCall (builder, eh_selector, args, 3, "");
1810 /* Store the exception into the exvar */
1811 if (bb->in_scount == 1) {
1812 g_assert (bb->in_scount == 1);
1813 exvar = bb->in_stack [0];
1815 eh_exception = LLVMGetNamedFunction (module, "llvm.eh.exception");
1817 // FIXME: This is shared with filter clauses ?
1818 g_assert (!values [exvar->dreg]);
1819 values [exvar->dreg] = LLVMBuildCall (builder, eh_exception, NULL, 0, "");
1820 emit_volatile_store (ctx, exvar->dreg);
1824 has_terminator = FALSE;
1825 for (ins = bb->code; ins; ins = ins->next) {
1826 const char *spec = LLVM_INS_INFO (ins->opcode);
1827 char *dname = NULL;
1828 char dname_buf [128];
1830 if (has_terminator)
1831 /* There could be instructions after a terminator, skip them */
1832 break;
1834 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
1835 sprintf (dname_buf, "t%d", ins->dreg);
1836 dname = dname_buf;
1839 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
1840 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
1842 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1843 lhs = emit_volatile_load (ctx, ins->sreg1);
1844 } else {
1845 /* It is ok for SETRET to have an uninitialized argument */
1846 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
1847 LLVM_FAILURE (ctx, "sreg1");
1848 lhs = values [ins->sreg1];
1850 } else {
1851 lhs = NULL;
1854 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
1855 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
1856 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1857 rhs = emit_volatile_load (ctx, ins->sreg2);
1858 } else {
1859 if (!values [ins->sreg2])
1860 LLVM_FAILURE (ctx, "sreg2");
1861 rhs = values [ins->sreg2];
1863 } else {
1864 rhs = NULL;
1867 //mono_print_ins (ins);
1868 switch (ins->opcode) {
1869 case OP_NOP:
1870 case OP_NOT_NULL:
1871 case OP_LIVERANGE_START:
1872 case OP_LIVERANGE_END:
1873 break;
1874 case OP_ICONST:
1875 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
1876 break;
1877 case OP_I8CONST:
1878 #if SIZEOF_VOID_P == 4
1879 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
1880 #else
1881 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
1882 #endif
1883 break;
1884 case OP_R8CONST:
1885 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
1886 break;
1887 case OP_R4CONST:
1888 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
1889 break;
1890 case OP_BR:
1891 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
1892 has_terminator = TRUE;
1893 break;
1894 case OP_SWITCH: {
1895 int i;
1896 LLVMValueRef v;
1897 char bb_name [128];
1898 LLVMBasicBlockRef new_bb;
1899 LLVMBuilderRef new_builder;
1901 // The default branch is already handled
1902 // FIXME: Handle it here
1904 /* Start new bblock */
1905 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
1906 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1908 lhs = convert (ctx, lhs, LLVMInt32Type ());
1909 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
1910 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
1911 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
1913 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
1916 new_builder = create_builder (ctx);
1917 LLVMPositionBuilderAtEnd (new_builder, new_bb);
1918 LLVMBuildUnreachable (new_builder);
1920 has_terminator = TRUE;
1921 g_assert (!ins->next);
1923 break;
1926 case OP_SETRET:
1927 if (linfo->ret.storage == LLVMArgVtypeInReg) {
1928 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
1929 LLVMValueRef part1, retval;
1930 int size;
1932 size = get_vtype_size (sig->ret);
1934 g_assert (addresses [ins->sreg1]);
1936 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
1937 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
1939 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
1941 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
1943 LLVMBuildRet (builder, retval);
1944 break;
1947 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
1948 LLVMBuildRetVoid (builder);
1949 break;
1952 if (!lhs || is_dead [ins->sreg1]) {
1954 * The method did not set its return value, probably because it
1955 * ends with a throw.
1957 if (cfg->vret_addr)
1958 LLVMBuildRetVoid (builder);
1959 else
1960 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
1961 } else {
1962 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
1964 has_terminator = TRUE;
1965 break;
1966 case OP_ICOMPARE:
1967 case OP_FCOMPARE:
1968 case OP_LCOMPARE:
1969 case OP_COMPARE:
1970 case OP_ICOMPARE_IMM:
1971 case OP_LCOMPARE_IMM:
1972 case OP_COMPARE_IMM:
1973 #ifdef TARGET_AMD64
1974 case OP_AMD64_ICOMPARE_MEMBASE_REG:
1975 case OP_AMD64_ICOMPARE_MEMBASE_IMM:
1976 #endif
1977 #ifdef TARGET_X86
1978 case OP_X86_COMPARE_MEMBASE_REG:
1979 case OP_X86_COMPARE_MEMBASE_IMM:
1980 #endif
1982 CompRelation rel;
1983 LLVMValueRef cmp;
1985 if (ins->next->opcode == OP_NOP)
1986 break;
1988 if (ins->next->opcode == OP_BR)
1989 /* The comparison result is not needed */
1990 continue;
1992 rel = mono_opcode_to_cond (ins->next->opcode);
1994 /* Used for implementing bound checks */
1995 #ifdef TARGET_AMD64
1996 if ((ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_REG) || (ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_IMM)) {
1997 int size = 4;
1998 LLVMValueRef index;
1999 LLVMTypeRef t;
2001 t = LLVMInt32Type ();
2003 g_assert (ins->inst_offset % size == 0);
2004 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2006 lhs = LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (t, 0)), &index, 1, ""), "");
2008 if (ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_IMM) {
2009 lhs = convert (ctx, lhs, LLVMInt32Type ());
2010 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2012 if (ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_REG)
2013 rhs = convert (ctx, rhs, LLVMInt32Type ());
2014 #endif
2016 #ifdef TARGET_X86
2017 if ((ins->opcode == OP_X86_COMPARE_MEMBASE_REG) || (ins->opcode == OP_X86_COMPARE_MEMBASE_IMM)) {
2018 int size = 4;
2019 LLVMValueRef index;
2020 LLVMTypeRef t;
2022 t = LLVMInt32Type ();
2024 g_assert (ins->inst_offset % size == 0);
2025 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2027 lhs = LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (t, 0)), &index, 1, ""), "");
2029 if (ins->opcode == OP_X86_COMPARE_MEMBASE_IMM) {
2030 lhs = convert (ctx, lhs, LLVMInt32Type ());
2031 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2033 if (ins->opcode == OP_X86_COMPARE_MEMBASE_REG)
2034 rhs = convert (ctx, rhs, LLVMInt32Type ());
2035 #endif
2037 if (ins->opcode == OP_ICOMPARE_IMM) {
2038 lhs = convert (ctx, lhs, LLVMInt32Type ());
2039 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2041 if (ins->opcode == OP_LCOMPARE_IMM) {
2042 lhs = convert (ctx, lhs, LLVMInt64Type ());
2043 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2045 if (ins->opcode == OP_LCOMPARE) {
2046 lhs = convert (ctx, lhs, LLVMInt64Type ());
2047 rhs = convert (ctx, rhs, LLVMInt64Type ());
2049 if (ins->opcode == OP_ICOMPARE) {
2050 lhs = convert (ctx, lhs, LLVMInt32Type ());
2051 rhs = convert (ctx, rhs, LLVMInt32Type ());
2054 if (lhs && rhs) {
2055 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2056 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2057 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2058 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2061 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2062 if (ins->opcode == OP_FCOMPARE)
2063 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2064 else if (ins->opcode == OP_COMPARE_IMM)
2065 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2066 else if (ins->opcode == OP_COMPARE)
2067 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2068 else
2069 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2071 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2072 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2073 has_terminator = TRUE;
2074 } else if (MONO_IS_SETCC (ins->next)) {
2075 sprintf (dname_buf, "t%d", ins->next->dreg);
2076 dname = dname_buf;
2077 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2079 /* Add stores for volatile variables */
2080 emit_volatile_store (ctx, ins->next->dreg);
2081 } else if (MONO_IS_COND_EXC (ins->next)) {
2082 //emit_cond_throw_pos (ctx);
2083 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2084 CHECK_FAILURE (ctx);
2085 builder = ctx->builder;
2086 } else {
2087 LLVM_FAILURE (ctx, "next");
2090 ins = ins->next;
2091 break;
2093 case OP_FCEQ:
2094 case OP_FCLT:
2095 case OP_FCLT_UN:
2096 case OP_FCGT:
2097 case OP_FCGT_UN: {
2098 CompRelation rel;
2099 LLVMValueRef cmp;
2101 rel = mono_opcode_to_cond (ins->opcode);
2103 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2104 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2105 break;
2107 case OP_PHI:
2108 case OP_FPHI:
2109 case OP_VPHI:
2110 case OP_XPHI: {
2111 int i;
2112 gboolean empty = TRUE;
2114 /* Check that all input bblocks really branch to us */
2115 for (i = 0; i < bb->in_count; ++i) {
2116 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
2117 ins->inst_phi_args [i + 1] = -1;
2118 else
2119 empty = FALSE;
2122 if (empty) {
2123 /* LLVM doesn't like phi instructions with zero operands */
2124 is_dead [ins->dreg] = TRUE;
2125 break;
2128 /* Created earlier, insert it now */
2129 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
2131 for (i = 0; i < ins->inst_phi_args [0]; i++) {
2132 int sreg1 = ins->inst_phi_args [i + 1];
2133 int count, j;
2136 * Count the number of times the incoming bblock branches to us,
2137 * since llvm requires a separate entry for each.
2139 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
2140 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
2142 count = 0;
2143 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
2144 if (switch_ins->inst_many_bb [j] == bb)
2145 count ++;
2147 } else {
2148 count = 1;
2151 /* Remember for later */
2152 for (j = 0; j < count; ++j) {
2153 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
2154 node->bb = bb;
2155 node->phi = ins;
2156 node->in_bb = bb->in_bb [i];
2157 node->sreg = sreg1;
2158 bblocks [bb->in_bb [i]->block_num].phi_nodes = g_slist_prepend_mempool (ctx->mempool, bblocks [bb->in_bb [i]->block_num].phi_nodes, node);
2161 break;
2163 case OP_MOVE:
2164 case OP_LMOVE:
2165 case OP_XMOVE:
2166 g_assert (lhs);
2167 values [ins->dreg] = lhs;
2168 break;
2169 case OP_FMOVE: {
2170 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
2172 g_assert (lhs);
2173 values [ins->dreg] = lhs;
2175 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
2177 * This is added by the spilling pass in case of the JIT,
2178 * but we have to do it ourselves.
2180 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
2182 break;
2184 case OP_IADD:
2185 case OP_ISUB:
2186 case OP_IAND:
2187 case OP_IMUL:
2188 case OP_IDIV:
2189 case OP_IDIV_UN:
2190 case OP_IREM:
2191 case OP_IREM_UN:
2192 case OP_IOR:
2193 case OP_IXOR:
2194 case OP_ISHL:
2195 case OP_ISHR:
2196 case OP_ISHR_UN:
2197 case OP_FADD:
2198 case OP_FSUB:
2199 case OP_FMUL:
2200 case OP_FDIV:
2201 case OP_LADD:
2202 case OP_LSUB:
2203 case OP_LMUL:
2204 case OP_LDIV:
2205 case OP_LDIV_UN:
2206 case OP_LREM:
2207 case OP_LREM_UN:
2208 case OP_LAND:
2209 case OP_LOR:
2210 case OP_LXOR:
2211 case OP_LSHL:
2212 case OP_LSHR:
2213 case OP_LSHR_UN:
2214 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2215 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2217 switch (ins->opcode) {
2218 case OP_IADD:
2219 case OP_LADD:
2220 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
2221 break;
2222 case OP_ISUB:
2223 case OP_LSUB:
2224 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
2225 break;
2226 case OP_IMUL:
2227 case OP_LMUL:
2228 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
2229 break;
2230 case OP_IREM:
2231 case OP_LREM:
2232 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
2233 break;
2234 case OP_IREM_UN:
2235 case OP_LREM_UN:
2236 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
2237 break;
2238 case OP_IDIV:
2239 case OP_LDIV:
2240 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
2241 break;
2242 case OP_IDIV_UN:
2243 case OP_LDIV_UN:
2244 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
2245 break;
2246 case OP_FDIV:
2247 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
2248 break;
2249 case OP_IAND:
2250 case OP_LAND:
2251 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
2252 break;
2253 case OP_IOR:
2254 case OP_LOR:
2255 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
2256 break;
2257 case OP_IXOR:
2258 case OP_LXOR:
2259 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
2260 break;
2261 case OP_ISHL:
2262 case OP_LSHL:
2263 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
2264 break;
2265 case OP_ISHR:
2266 case OP_LSHR:
2267 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
2268 break;
2269 case OP_ISHR_UN:
2270 case OP_LSHR_UN:
2271 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
2272 break;
2274 case OP_FADD:
2275 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
2276 break;
2277 case OP_FSUB:
2278 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
2279 break;
2280 case OP_FMUL:
2281 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
2282 break;
2284 default:
2285 g_assert_not_reached ();
2287 break;
2288 case OP_IADD_IMM:
2289 case OP_ISUB_IMM:
2290 case OP_IMUL_IMM:
2291 case OP_IREM_IMM:
2292 case OP_IREM_UN_IMM:
2293 case OP_IDIV_IMM:
2294 case OP_IDIV_UN_IMM:
2295 case OP_IAND_IMM:
2296 case OP_IOR_IMM:
2297 case OP_IXOR_IMM:
2298 case OP_ISHL_IMM:
2299 case OP_ISHR_IMM:
2300 case OP_ISHR_UN_IMM:
2301 case OP_LADD_IMM:
2302 case OP_LSUB_IMM:
2303 case OP_LREM_IMM:
2304 case OP_LAND_IMM:
2305 case OP_LOR_IMM:
2306 case OP_LXOR_IMM:
2307 case OP_LSHL_IMM:
2308 case OP_LSHR_IMM:
2309 case OP_LSHR_UN_IMM:
2310 case OP_ADD_IMM:
2311 case OP_AND_IMM:
2312 case OP_MUL_IMM:
2313 case OP_SHL_IMM:
2314 case OP_SHR_IMM: {
2315 LLVMValueRef imm;
2317 if (spec [MONO_INST_SRC1] == 'l') {
2318 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2319 } else {
2320 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2323 #if SIZEOF_VOID_P == 4
2324 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
2325 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2326 #endif
2328 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2329 lhs = convert (ctx, lhs, IntPtrType ());
2330 imm = convert (ctx, imm, LLVMTypeOf (lhs));
2331 switch (ins->opcode) {
2332 case OP_IADD_IMM:
2333 case OP_LADD_IMM:
2334 case OP_ADD_IMM:
2335 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
2336 break;
2337 case OP_ISUB_IMM:
2338 case OP_LSUB_IMM:
2339 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
2340 break;
2341 case OP_IMUL_IMM:
2342 case OP_MUL_IMM:
2343 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
2344 break;
2345 case OP_IDIV_IMM:
2346 case OP_LDIV_IMM:
2347 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
2348 break;
2349 case OP_IDIV_UN_IMM:
2350 case OP_LDIV_UN_IMM:
2351 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
2352 break;
2353 case OP_IREM_IMM:
2354 case OP_LREM_IMM:
2355 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
2356 break;
2357 case OP_IREM_UN_IMM:
2358 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
2359 break;
2360 case OP_IAND_IMM:
2361 case OP_LAND_IMM:
2362 case OP_AND_IMM:
2363 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
2364 break;
2365 case OP_IOR_IMM:
2366 case OP_LOR_IMM:
2367 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
2368 break;
2369 case OP_IXOR_IMM:
2370 case OP_LXOR_IMM:
2371 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
2372 break;
2373 case OP_ISHL_IMM:
2374 case OP_LSHL_IMM:
2375 case OP_SHL_IMM:
2376 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
2377 break;
2378 case OP_ISHR_IMM:
2379 case OP_LSHR_IMM:
2380 case OP_SHR_IMM:
2381 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
2382 break;
2383 case OP_ISHR_UN_IMM:
2384 /* This is used to implement conv.u4, so the lhs could be an i8 */
2385 lhs = convert (ctx, lhs, LLVMInt32Type ());
2386 imm = convert (ctx, imm, LLVMInt32Type ());
2387 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2388 break;
2389 case OP_LSHR_UN_IMM:
2390 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2391 break;
2392 default:
2393 g_assert_not_reached ();
2395 break;
2397 case OP_INEG:
2398 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2399 break;
2400 case OP_LNEG:
2401 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
2402 break;
2403 case OP_FNEG:
2404 lhs = convert (ctx, lhs, LLVMDoubleType ());
2405 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
2406 break;
2407 case OP_INOT: {
2408 guint32 v = 0xffffffff;
2409 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), lhs, dname);
2410 break;
2412 case OP_LNOT: {
2413 guint64 v = 0xffffffffffffffffLL;
2414 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
2415 break;
2417 #if defined(TARGET_X86) || defined(TARGET_AMD64)
2418 case OP_X86_LEA: {
2419 LLVMValueRef v1, v2;
2421 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
2422 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
2423 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
2424 break;
2426 #endif
2428 case OP_ICONV_TO_I1:
2429 case OP_ICONV_TO_I2:
2430 case OP_ICONV_TO_I4:
2431 case OP_ICONV_TO_U1:
2432 case OP_ICONV_TO_U2:
2433 case OP_ICONV_TO_U4:
2434 case OP_LCONV_TO_I1:
2435 case OP_LCONV_TO_I2:
2436 case OP_LCONV_TO_U1:
2437 case OP_LCONV_TO_U2:
2438 case OP_LCONV_TO_U4: {
2439 gboolean sign;
2441 sign = (ins->opcode == OP_ICONV_TO_I1) || (ins->opcode == OP_ICONV_TO_I2) || (ins->opcode == OP_ICONV_TO_I4) || (ins->opcode == OP_LCONV_TO_I1) || (ins->opcode == OP_LCONV_TO_I2);
2443 /* Have to do two casts since our vregs have type int */
2444 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
2445 if (sign)
2446 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
2447 else
2448 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
2449 break;
2451 case OP_ICONV_TO_I8:
2452 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2453 break;
2454 case OP_ICONV_TO_U8:
2455 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2456 break;
2457 case OP_FCONV_TO_I4:
2458 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
2459 break;
2460 case OP_FCONV_TO_I1:
2461 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2462 break;
2463 case OP_FCONV_TO_U1:
2464 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2465 break;
2466 case OP_FCONV_TO_I2:
2467 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2468 break;
2469 case OP_FCONV_TO_U2:
2470 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2471 break;
2472 case OP_FCONV_TO_I8:
2473 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
2474 break;
2475 case OP_FCONV_TO_I:
2476 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
2477 break;
2478 case OP_ICONV_TO_R8:
2479 case OP_LCONV_TO_R8:
2480 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
2481 break;
2482 case OP_LCONV_TO_R_UN:
2483 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
2484 break;
2485 #if SIZEOF_VOID_P == 4
2486 case OP_LCONV_TO_U:
2487 #endif
2488 case OP_LCONV_TO_I4:
2489 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2490 break;
2491 case OP_ICONV_TO_R4:
2492 case OP_LCONV_TO_R4:
2493 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
2494 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2495 break;
2496 case OP_FCONV_TO_R4:
2497 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
2498 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2499 break;
2500 case OP_SEXT_I4:
2501 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2502 break;
2503 case OP_ZEXT_I4:
2504 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2505 break;
2506 case OP_TRUNC_I4:
2507 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2508 break;
2509 case OP_LOCALLOC_IMM: {
2510 LLVMValueRef v;
2512 guint32 size = ins->inst_imm;
2513 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
2515 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
2517 if (ins->flags & MONO_INST_INIT) {
2518 LLVMValueRef args [5];
2520 args [0] = v;
2521 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2522 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
2523 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2524 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2525 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2528 values [ins->dreg] = v;
2529 break;
2531 case OP_LOCALLOC: {
2532 LLVMValueRef v, size;
2534 size = LLVMBuildAnd (builder, LLVMBuildAdd (builder, lhs, LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT - 1, FALSE), ""), LLVMConstInt (LLVMInt32Type (), ~ (MONO_ARCH_FRAME_ALIGNMENT - 1), FALSE), "");
2536 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
2538 if (ins->flags & MONO_INST_INIT) {
2539 LLVMValueRef args [5];
2541 args [0] = v;
2542 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2543 args [2] = size;
2544 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2545 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2546 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2548 values [ins->dreg] = v;
2549 break;
2552 case OP_LOADI1_MEMBASE:
2553 case OP_LOADU1_MEMBASE:
2554 case OP_LOADI2_MEMBASE:
2555 case OP_LOADU2_MEMBASE:
2556 case OP_LOADI4_MEMBASE:
2557 case OP_LOADU4_MEMBASE:
2558 case OP_LOADI8_MEMBASE:
2559 case OP_LOADR4_MEMBASE:
2560 case OP_LOADR8_MEMBASE:
2561 case OP_LOAD_MEMBASE:
2562 case OP_LOADI8_MEM:
2563 case OP_LOADU1_MEM:
2564 case OP_LOADU2_MEM:
2565 case OP_LOADI4_MEM:
2566 case OP_LOADU4_MEM:
2567 case OP_LOAD_MEM: {
2568 int size = 8;
2569 LLVMValueRef index, addr;
2570 LLVMTypeRef t;
2571 gboolean sext = FALSE, zext = FALSE;
2572 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
2574 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
2576 if (sext || zext)
2577 dname = (char*)"";
2580 * We emit volatile loads for loads which can fault, because otherwise
2581 * LLVM will generate invalid code when encountering a load from a
2582 * NULL address.
2584 if ((ins->opcode == OP_LOADI8_MEM) || (ins->opcode == OP_LOAD_MEM) || (ins->opcode == OP_LOADI4_MEM) || (ins->opcode == OP_LOADU4_MEM) || (ins->opcode == OP_LOADU1_MEM) || (ins->opcode == OP_LOADU2_MEM)) {
2585 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
2586 } else if (ins->inst_offset == 0) {
2587 addr = values [ins->inst_basereg];
2588 } else if (ins->inst_offset % size != 0) {
2589 /* Unaligned load */
2590 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
2591 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
2592 } else {
2593 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2594 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (t, 0)), &index, 1, "");
2597 addr = convert (ctx, addr, LLVMPointerType (t, 0));
2599 values [ins->dreg] = mono_llvm_build_load (builder, addr, dname, is_volatile);
2601 if (sext)
2602 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
2603 else if (zext)
2604 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
2605 else if (ins->opcode == OP_LOADR4_MEMBASE)
2606 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
2607 break;
2610 case OP_STOREI1_MEMBASE_REG:
2611 case OP_STOREI2_MEMBASE_REG:
2612 case OP_STOREI4_MEMBASE_REG:
2613 case OP_STOREI8_MEMBASE_REG:
2614 case OP_STORER4_MEMBASE_REG:
2615 case OP_STORER8_MEMBASE_REG:
2616 case OP_STORE_MEMBASE_REG: {
2617 int size = 8;
2618 LLVMValueRef index, addr;
2619 LLVMTypeRef t;
2620 gboolean sext = FALSE, zext = FALSE;
2622 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
2624 if (ins->inst_offset % size != 0) {
2625 /* Unaligned store */
2626 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
2627 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
2628 } else {
2629 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2630 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
2632 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)));
2633 break;
2636 case OP_STOREI1_MEMBASE_IMM:
2637 case OP_STOREI2_MEMBASE_IMM:
2638 case OP_STOREI4_MEMBASE_IMM:
2639 case OP_STOREI8_MEMBASE_IMM:
2640 case OP_STORE_MEMBASE_IMM: {
2641 int size = 8;
2642 LLVMValueRef index, addr;
2643 LLVMTypeRef t;
2644 gboolean sext = FALSE, zext = FALSE;
2646 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
2648 if (ins->inst_offset % size != 0) {
2649 /* Unaligned store */
2650 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
2651 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
2652 } else {
2653 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2654 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
2656 LLVMBuildStore (builder, convert (ctx, LLVMConstInt (t, ins->inst_imm, FALSE), t), addr);
2657 break;
2660 case OP_CHECK_THIS:
2661 mono_llvm_build_load (builder, convert (ctx, values [ins->sreg1], LLVMPointerType (IntPtrType (), 0)), "", TRUE);
2662 break;
2663 case OP_OUTARG_VTRETADDR:
2664 break;
2665 case OP_VOIDCALL:
2666 case OP_CALL:
2667 case OP_LCALL:
2668 case OP_FCALL:
2669 case OP_VCALL:
2670 case OP_VOIDCALL_MEMBASE:
2671 case OP_CALL_MEMBASE:
2672 case OP_LCALL_MEMBASE:
2673 case OP_FCALL_MEMBASE:
2674 case OP_VCALL_MEMBASE:
2675 case OP_VOIDCALL_REG:
2676 case OP_CALL_REG:
2677 case OP_LCALL_REG:
2678 case OP_FCALL_REG:
2679 case OP_VCALL_REG: {
2680 MonoCallInst *call = (MonoCallInst*)ins;
2681 MonoMethodSignature *sig = call->signature;
2682 LLVMValueRef callee, lcall;
2683 LLVMValueRef *args;
2684 LLVMCallInfo *cinfo;
2685 GSList *l;
2686 int i, pindex;
2687 gboolean vretaddr;
2688 LLVMTypeRef llvm_sig;
2689 gpointer target;
2690 int *pindexes;
2691 gboolean virtual, calli;
2693 if (call->signature->call_convention != MONO_CALL_DEFAULT)
2694 LLVM_FAILURE (ctx, "non-default callconv");
2696 if (call->rgctx_arg_reg && !IS_LLVM_MONO_BRANCH)
2697 LLVM_FAILURE (ctx, "rgctx reg in call");
2699 cinfo = call->cinfo;
2700 if (call->rgctx_arg_reg)
2701 cinfo->rgctx_arg = TRUE;
2702 if (call->imt_arg_reg)
2703 cinfo->imt_arg = TRUE;
2705 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
2707 llvm_sig = sig_to_llvm_sig (ctx, sig, cinfo);
2708 CHECK_FAILURE (ctx);
2710 virtual = (ins->opcode == OP_VOIDCALL_MEMBASE || ins->opcode == OP_CALL_MEMBASE || ins->opcode == OP_VCALL_MEMBASE || ins->opcode == OP_LCALL_MEMBASE || ins->opcode == OP_FCALL_MEMBASE);
2711 calli = (ins->opcode == OP_VOIDCALL_REG || ins->opcode == OP_CALL_REG || ins->opcode == OP_VCALL_REG || ins->opcode == OP_LCALL_REG || ins->opcode == OP_FCALL_REG);
2713 /* FIXME: Avoid creating duplicate methods */
2715 if (ins->flags & MONO_INST_HAS_METHOD) {
2716 if (virtual) {
2717 callee = NULL;
2718 } else {
2719 if (cfg->compile_aot) {
2720 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
2721 if (!callee)
2722 LLVM_FAILURE (ctx, "can't encode patch");
2723 } else {
2724 callee = LLVMAddFunction (module, "", llvm_sig);
2726 target =
2727 mono_create_jit_trampoline_in_domain (mono_domain_get (),
2728 call->method);
2729 LLVMAddGlobalMapping (ee, callee, target);
2732 } else if (calli) {
2733 } else {
2734 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
2736 if (info) {
2738 MonoJumpInfo ji;
2740 memset (&ji, 0, sizeof (ji));
2741 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
2742 ji.data.target = info->name;
2744 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
2746 if (cfg->compile_aot) {
2747 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
2748 if (!callee)
2749 LLVM_FAILURE (ctx, "can't encode patch");
2750 } else {
2751 callee = LLVMAddFunction (module, "", llvm_sig);
2752 target = (gpointer)mono_icall_get_wrapper (info);
2753 LLVMAddGlobalMapping (ee, callee, target);
2755 } else {
2756 if (cfg->compile_aot) {
2757 callee = NULL;
2758 if (cfg->abs_patches) {
2759 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2760 if (abs_ji) {
2761 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
2762 if (!callee)
2763 LLVM_FAILURE (ctx, "can't encode patch");
2766 if (!callee)
2767 LLVM_FAILURE (ctx, "aot");
2768 } else {
2769 callee = LLVMAddFunction (module, "", llvm_sig);
2770 target = NULL;
2771 if (cfg->abs_patches) {
2772 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2773 if (abs_ji) {
2775 * The monitor entry/exit trampolines might have
2776 * their own calling convention on some platforms.
2778 #ifndef TARGET_AMD64
2779 if (abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER || abs_ji->type == MONO_PATCH_INFO_MONITOR_EXIT)
2780 LLVM_FAILURE (ctx, "monitor enter/exit");
2781 #endif
2782 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
2783 LLVMAddGlobalMapping (ee, callee, target);
2786 if (!target)
2787 LLVMAddGlobalMapping (ee, callee, (gpointer)call->fptr);
2792 if (virtual) {
2793 int size = sizeof (gpointer);
2794 LLVMValueRef index;
2796 g_assert (ins->inst_offset % size == 0);
2797 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2799 // FIXME: mono_arch_get_vcall_slot () can't decode the code
2800 // generated by LLVM
2801 //LLVM_FAILURE (ctx, "virtual call");
2804 * When using the llvm mono branch, we can support IMT directly, otherwise
2805 * we need to call a trampoline.
2807 if (call->method && call->method->klass->flags & TYPE_ATTRIBUTE_INTERFACE && !IS_LLVM_MONO_BRANCH) {
2808 #ifdef MONO_ARCH_HAVE_LLVM_IMT_TRAMPOLINE
2809 if (cfg->compile_aot) {
2810 MonoJumpInfoImtTramp *imt_tramp = g_new0 (MonoJumpInfoImtTramp, 1);
2811 imt_tramp->method = call->method;
2812 imt_tramp->vt_offset = call->inst.inst_offset;
2814 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_LLVM_IMT_TRAMPOLINE, imt_tramp);
2815 } else {
2816 callee = LLVMAddFunction (module, "", llvm_sig);
2817 target = mono_create_llvm_imt_trampoline (cfg->domain, call->method, call->inst.inst_offset);
2818 LLVMAddGlobalMapping (ee, callee, target);
2820 #else
2821 /* No support for passing the IMT argument */
2822 LLVM_FAILURE (ctx, "imt");
2823 #endif
2824 } else {
2825 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
2827 } else if (calli) {
2828 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
2829 } else {
2830 if (ins->flags & MONO_INST_HAS_METHOD) {
2835 * Collect and convert arguments
2837 pindexes = mono_mempool_alloc0 (cfg->mempool, (sig->param_count + 2) * sizeof (guint32));
2838 args = alloca (sizeof (LLVMValueRef) * ((sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg));
2839 l = call->out_ireg_args;
2840 pindex = 0;
2842 if (IS_LLVM_MONO_BRANCH) {
2843 if (call->rgctx_arg_reg)
2844 args [pindex ++] = values [call->rgctx_arg_reg];
2845 if (call->imt_arg_reg)
2846 args [pindex ++] = values [call->imt_arg_reg];
2849 if (vretaddr) {
2850 if (!addresses [call->inst.dreg])
2851 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2852 args [pindex ++] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2855 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2856 guint32 regpair;
2857 int reg;
2858 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2860 regpair = (guint32)(gssize)(l->data);
2861 reg = regpair & 0xffffff;
2862 args [pindex] = values [reg];
2863 if (ainfo->storage == LLVMArgVtypeInReg) {
2864 int j;
2865 LLVMValueRef regs [2];
2866 guint32 nregs;
2868 g_assert (ainfo);
2870 g_assert (addresses [reg]);
2872 emit_vtype_to_reg (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, regs, &nregs);
2873 for (j = 0; j < nregs; ++j)
2874 args [pindex ++] = regs [j];
2876 // FIXME: alignment
2877 // FIXME: Get rid of the VMOVE
2878 } else if (ainfo->storage == LLVMArgVtypeByVal) {
2879 g_assert (addresses [reg]);
2880 args [pindex] = addresses [reg];
2881 pindexes [i] = pindex;
2882 pindex ++;
2883 } else {
2884 g_assert (args [pindex]);
2885 if (i == 0 && sig->hasthis)
2886 args [pindex] = convert (ctx, args [pindex], IntPtrType ());
2887 else
2888 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2889 pindex ++;
2892 l = l->next;
2895 // FIXME: Align call sites
2898 * Emit the call
2901 lcall = emit_call (ctx, bb, &builder, callee, args, pindex);
2903 #ifdef LLVM_MONO_BRANCH
2905 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2907 if (call->rgctx_arg_reg)
2908 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2909 else if (call->imt_arg_reg)
2910 LLVMSetInstructionCallConv (lcall, LLVMMono2CallConv);
2912 if (call->rgctx_arg_reg)
2913 LLVMAddInstrAttribute (lcall, 1, LLVMInRegAttribute);
2914 if (call->imt_arg_reg)
2915 LLVMAddInstrAttribute (lcall, 1 + (call->rgctx_arg_reg ? 1 : 0), LLVMInRegAttribute);
2916 #endif
2918 /* Add byval attributes if needed */
2919 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2920 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2922 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2923 LLVMAddInstrAttribute (lcall, pindexes [i] + 1, LLVMByValAttribute);
2928 * Convert the result
2930 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
2931 LLVMValueRef regs [2];
2933 if (!addresses [ins->dreg])
2934 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2936 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2937 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2938 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2940 emit_reg_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2941 } else if (sig->ret->type != MONO_TYPE_VOID && !vretaddr) {
2942 /* If the method returns an unsigned value, need to zext it */
2944 values [ins->dreg] = convert_full (ctx, lcall, llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->ret)), type_is_unsigned (ctx, sig->ret));
2946 break;
2948 case OP_AOTCONST: {
2949 guint32 got_offset;
2950 LLVMValueRef indexes [2];
2951 MonoJumpInfo *ji;
2952 LLVMValueRef got_entry_addr;
2955 * FIXME: Can't allocate from the cfg mempool since that is freed if
2956 * the LLVM compile fails.
2958 ji = g_new0 (MonoJumpInfo, 1);
2959 ji->type = (MonoJumpInfoType)ins->inst_i1;
2960 ji->data.target = ins->inst_p0;
2962 ji = mono_aot_patch_info_dup (ji);
2964 ji->next = cfg->patch_info;
2965 cfg->patch_info = ji;
2967 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
2968 got_offset = mono_aot_get_got_offset (cfg->patch_info);
2970 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2971 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
2972 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
2974 // FIXME: This doesn't work right now, because it must be
2975 // paired with an invariant.end, and even then, its only in effect
2976 // inside its basic block
2977 #if 0
2979 LLVMValueRef args [3];
2980 LLVMValueRef ptr, val;
2982 ptr = LLVMBuildBitCast (builder, got_entry_addr, LLVMPointerType (LLVMInt8Type (), 0), "ptr");
2984 args [0] = LLVMConstInt (LLVMInt64Type (), sizeof (gpointer), FALSE);
2985 args [1] = ptr;
2986 val = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.invariant.start"), args, 2, "");
2988 #endif
2990 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
2991 break;
2993 case OP_NOT_REACHED:
2994 LLVMBuildUnreachable (builder);
2995 has_terminator = TRUE;
2996 g_assert (bb->block_num < cfg->max_block_num);
2997 unreachable [bb->block_num] = TRUE;
2998 /* Might have instructions after this */
2999 while (ins->next) {
3000 MonoInst *next = ins->next;
3001 MONO_DELETE_INS (bb, next);
3003 break;
3004 case OP_LDADDR: {
3005 MonoInst *var = ins->inst_p0;
3007 values [ins->dreg] = addresses [var->dreg];
3008 break;
3010 case OP_SIN: {
3011 LLVMValueRef args [1];
3013 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3014 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3015 break;
3017 case OP_COS: {
3018 LLVMValueRef args [1];
3020 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3021 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3022 break;
3024 /* test_0_sqrt_nan fails with LLVM */
3026 case OP_SQRT: {
3027 LLVMValueRef args [1];
3029 args [0] = lhs;
3030 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3031 break;
3035 case OP_ABS: {
3036 LLVMValueRef args [1];
3038 args [0] = lhs;
3039 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3040 break;
3043 case OP_IMIN:
3044 case OP_LMIN: {
3045 LLVMValueRef v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3046 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3047 break;
3049 case OP_IMAX:
3050 case OP_LMAX: {
3051 LLVMValueRef v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3052 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3053 break;
3055 case OP_IMIN_UN:
3056 case OP_LMIN_UN: {
3057 LLVMValueRef v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3058 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3059 break;
3061 case OP_IMAX_UN:
3062 case OP_LMAX_UN: {
3063 LLVMValueRef v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3064 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3065 break;
3067 case OP_ATOMIC_EXCHANGE_I4: {
3068 LLVMValueRef args [2];
3070 g_assert (ins->inst_offset == 0);
3072 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3073 args [1] = rhs;
3074 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.swap.i32.p0i32"), args, 2, dname);
3075 break;
3077 case OP_ATOMIC_EXCHANGE_I8: {
3078 LLVMValueRef args [2];
3080 g_assert (ins->inst_offset == 0);
3082 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3083 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3084 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.swap.i64.p0i64"), args, 2, dname);
3085 break;
3087 case OP_ATOMIC_ADD_NEW_I4: {
3088 LLVMValueRef args [2];
3090 g_assert (ins->inst_offset == 0);
3092 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3093 args [1] = rhs;
3094 values [ins->dreg] = LLVMBuildAdd (builder, LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.load.add.i32.p0i32"), args, 2, ""), args [1], dname);
3095 break;
3097 case OP_ATOMIC_ADD_NEW_I8: {
3098 LLVMValueRef args [2];
3100 g_assert (ins->inst_offset == 0);
3102 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3103 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3104 values [ins->dreg] = LLVMBuildAdd (builder, LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.load.add.i64.p0i64"), args, 2, ""), args [1], dname);
3105 break;
3107 case OP_ATOMIC_CAS_I4:
3108 case OP_ATOMIC_CAS_I8: {
3109 LLVMValueRef args [3];
3110 LLVMTypeRef t;
3111 const char *intrins;
3113 if (ins->opcode == OP_ATOMIC_CAS_I4) {
3114 t = LLVMInt32Type ();
3115 intrins = "llvm.atomic.cmp.swap.i32.p0i32";
3116 } else {
3117 t = LLVMInt64Type ();
3118 intrins = "llvm.atomic.cmp.swap.i64.p0i64";
3121 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3122 /* comparand */
3123 args [1] = convert (ctx, values [ins->sreg3], t);
3124 /* new value */
3125 args [2] = convert (ctx, values [ins->sreg2], t);
3126 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, intrins), args, 3, dname);
3127 break;
3129 case OP_MEMORY_BARRIER: {
3130 LLVMValueRef args [5];
3132 for (i = 0; i < 5; ++i)
3133 args [i] = LLVMConstInt (LLVMInt1Type (), TRUE, TRUE);
3135 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memory.barrier"), args, 5, "");
3136 break;
3138 case OP_RELAXED_NOP: {
3139 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3140 /* No way to get LLVM to emit this */
3141 LLVM_FAILURE (ctx, "relaxed_nop");
3142 #else
3143 break;
3144 #endif
3146 case OP_TLS_GET: {
3147 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3148 #ifdef TARGET_AMD64
3149 // 257 == FS segment register
3150 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3151 #else
3152 // 256 == GS segment register
3153 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3154 #endif
3156 // FIXME: XEN
3157 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3158 #else
3159 LLVM_FAILURE (ctx, "opcode tls-get");
3160 #endif
3162 break;
3166 * Overflow opcodes.
3168 case OP_IADD_OVF:
3169 case OP_IADD_OVF_UN:
3170 case OP_ISUB_OVF:
3171 case OP_ISUB_OVF_UN:
3172 case OP_IMUL_OVF:
3173 case OP_IMUL_OVF_UN:
3174 #if SIZEOF_VOID_P == 8
3175 case OP_LADD_OVF:
3176 case OP_LADD_OVF_UN:
3177 case OP_LSUB_OVF:
3178 case OP_LSUB_OVF_UN:
3179 case OP_LMUL_OVF:
3180 case OP_LMUL_OVF_UN:
3181 #endif
3183 LLVMValueRef args [2], val, ovf, func;
3185 emit_cond_throw_pos (ctx);
3187 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
3188 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
3189 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
3190 g_assert (func);
3191 val = LLVMBuildCall (builder, func, args, 2, "");
3192 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
3193 ovf = LLVMBuildExtractValue (builder, val, 1, "");
3194 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
3195 CHECK_FAILURE (ctx);
3196 builder = ctx->builder;
3197 break;
3201 * Valuetypes.
3202 * We currently model them using arrays. Promotion to local vregs is
3203 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3204 * so we always have an entry in cfg->varinfo for them.
3205 * FIXME: Is this needed ?
3207 case OP_VZERO: {
3208 MonoClass *klass = ins->klass;
3209 LLVMValueRef args [5];
3211 if (!klass) {
3212 // FIXME:
3213 LLVM_FAILURE (ctx, "!klass");
3214 break;
3217 if (!addresses [ins->dreg])
3218 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3219 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3220 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3221 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3222 // FIXME: Alignment
3223 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3224 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3225 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3226 break;
3229 case OP_STOREV_MEMBASE:
3230 case OP_LOADV_MEMBASE:
3231 case OP_VMOVE: {
3232 MonoClass *klass = ins->klass;
3233 LLVMValueRef src, dst, args [5];
3234 gboolean done = FALSE;
3236 if (!klass) {
3237 // FIXME:
3238 LLVM_FAILURE (ctx, "!klass");
3239 break;
3242 switch (ins->opcode) {
3243 case OP_STOREV_MEMBASE:
3244 if (!addresses [ins->sreg1]) {
3245 /* SIMD */
3246 g_assert (values [ins->sreg1]);
3247 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (type_to_llvm_type (ctx, &klass->byval_arg), 0));
3248 LLVMBuildStore (builder, values [ins->sreg1], dst);
3249 done = TRUE;
3250 } else {
3251 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3252 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3254 break;
3255 case OP_LOADV_MEMBASE:
3256 if (!addresses [ins->dreg])
3257 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3258 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3259 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3260 break;
3261 case OP_VMOVE:
3262 if (!addresses [ins->sreg1])
3263 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
3264 if (!addresses [ins->dreg])
3265 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3266 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3267 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3268 break;
3269 default:
3270 g_assert_not_reached ();
3273 if (done)
3274 break;
3276 args [0] = dst;
3277 args [1] = src;
3278 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3279 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3280 // FIXME: Alignment
3281 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3282 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3283 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
3284 break;
3286 case OP_LLVM_OUTARG_VT:
3287 if (!addresses [ins->sreg1]) {
3288 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
3289 g_assert (values [ins->sreg1]);
3290 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
3292 addresses [ins->dreg] = addresses [ins->sreg1];
3293 break;
3296 * SIMD
3298 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3299 case OP_XZERO: {
3300 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
3301 break;
3303 case OP_LOADX_MEMBASE: {
3304 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
3305 LLVMValueRef src;
3307 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3308 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
3309 break;
3311 case OP_PADDB:
3312 case OP_PADDW:
3313 case OP_PADDD:
3314 case OP_PADDQ:
3315 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
3316 break;
3317 case OP_ADDPD:
3318 case OP_ADDPS:
3319 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
3320 break;
3321 case OP_PSUBB:
3322 case OP_PSUBW:
3323 case OP_PSUBD:
3324 case OP_PSUBQ:
3325 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
3326 break;
3327 case OP_SUBPD:
3328 case OP_SUBPS:
3329 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
3330 break;
3331 case OP_MULPD:
3332 case OP_MULPS:
3333 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
3334 break;
3335 case OP_DIVPD:
3336 case OP_DIVPS:
3337 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
3338 break;
3339 case OP_PAND:
3340 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
3341 break;
3342 case OP_POR:
3343 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
3344 break;
3345 case OP_PXOR:
3346 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
3347 break;
3348 case OP_ANDPS:
3349 case OP_ANDNPS:
3350 case OP_ORPS:
3351 case OP_XORPS:
3352 case OP_ANDPD:
3353 case OP_ANDNPD:
3354 case OP_ORPD:
3355 case OP_XORPD: {
3356 LLVMTypeRef t, rt;
3357 LLVMValueRef v;
3359 switch (ins->opcode) {
3360 case OP_ANDPS:
3361 case OP_ANDNPS:
3362 case OP_ORPS:
3363 case OP_XORPS:
3364 t = LLVMVectorType (LLVMInt32Type (), 4);
3365 rt = LLVMVectorType (LLVMFloatType (), 4);
3366 break;
3367 case OP_ANDPD:
3368 case OP_ANDNPD:
3369 case OP_ORPD:
3370 case OP_XORPD:
3371 t = LLVMVectorType (LLVMInt64Type (), 2);
3372 rt = LLVMVectorType (LLVMDoubleType (), 2);
3373 break;
3374 default:
3375 t = LLVMInt32Type ();
3376 rt = LLVMInt32Type ();
3377 g_assert_not_reached ();
3380 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3381 rhs = LLVMBuildBitCast (builder, rhs, t, "");
3382 switch (ins->opcode) {
3383 case OP_ANDPS:
3384 case OP_ANDPD:
3385 v = LLVMBuildAnd (builder, lhs, rhs, "");
3386 break;
3387 case OP_ORPS:
3388 case OP_ORPD:
3389 v = LLVMBuildOr (builder, lhs, rhs, "");
3390 break;
3391 case OP_XORPS:
3392 case OP_XORPD:
3393 v = LLVMBuildXor (builder, lhs, rhs, "");
3394 break;
3395 case OP_ANDNPS:
3396 case OP_ANDNPD:
3397 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
3398 break;
3400 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
3401 break;
3403 case OP_MINPD:
3404 case OP_MINPS:
3405 case OP_MAXPD:
3406 case OP_MAXPS:
3407 case OP_PMIND_UN:
3408 case OP_PMINW_UN:
3409 case OP_PMINB_UN:
3410 case OP_PMAXD_UN:
3411 case OP_PMAXW_UN:
3412 case OP_PMAXB_UN: {
3413 LLVMValueRef args [2];
3415 args [0] = lhs;
3416 args [1] = rhs;
3418 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3419 break;
3421 case OP_EXTRACT_R8:
3422 case OP_EXTRACT_I8:
3423 case OP_EXTRACT_I4:
3424 case OP_EXTRACT_I2:
3425 case OP_EXTRACT_U2:
3426 case OP_EXTRACT_I1:
3427 case OP_EXTRACT_U1: {
3428 LLVMTypeRef t;
3429 gboolean zext = FALSE;
3431 switch (ins->opcode) {
3432 case OP_EXTRACT_R8:
3433 t = LLVMVectorType (LLVMDoubleType (), 2);
3434 break;
3435 case OP_EXTRACT_I8:
3436 t = LLVMVectorType (LLVMInt64Type (), 2);
3437 break;
3438 case OP_EXTRACT_I4:
3439 t = LLVMVectorType (LLVMInt32Type (), 4);
3440 break;
3441 case OP_EXTRACT_I2:
3442 t = LLVMVectorType (LLVMInt16Type (), 8);
3443 break;
3444 case OP_EXTRACT_U2:
3445 t = LLVMVectorType (LLVMInt16Type (), 8);
3446 zext = TRUE;
3447 break;
3448 case OP_EXTRACT_I1:
3449 t = LLVMVectorType (LLVMInt8Type (), 16);
3450 break;
3451 case OP_EXTRACT_U1:
3452 t = LLVMVectorType (LLVMInt8Type (), 16);
3453 zext = TRUE;
3454 break;
3455 default:
3456 t = LLVMInt32Type ();
3457 g_assert_not_reached ();
3460 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3461 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
3462 if (zext)
3463 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
3464 break;
3466 #endif
3468 case OP_DUMMY_USE:
3469 break;
3472 * EXCEPTION HANDLING
3474 case OP_IMPLICIT_EXCEPTION:
3475 /* This marks a place where an implicit exception can happen */
3476 if (bb->region != -1)
3477 LLVM_FAILURE (ctx, "implicit-exception");
3478 break;
3479 case OP_THROW:
3480 case OP_RETHROW: {
3481 MonoMethodSignature *throw_sig;
3482 LLVMValueRef callee, arg;
3483 gboolean rethrow = (ins->opcode == OP_RETHROW);
3484 const char *icall_name;
3486 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
3487 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3489 if (!callee) {
3490 throw_sig = mono_metadata_signature_alloc (mono_defaults.corlib, 1);
3491 throw_sig->ret = &mono_defaults.void_class->byval_arg;
3492 throw_sig->params [0] = &mono_defaults.object_class->byval_arg;
3493 if (cfg->compile_aot) {
3494 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig, NULL), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3495 } else {
3496 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig, NULL));
3498 #ifdef TARGET_X86
3500 * LLVM doesn't push the exception argument, so we need a different
3501 * trampoline.
3503 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "mono_arch_llvm_rethrow_exception" : "mono_arch_llvm_throw_exception"));
3504 #else
3505 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3506 #endif
3509 mono_memory_barrier ();
3510 if (rethrow)
3511 ctx->lmodule->rethrow = callee;
3512 else
3513 ctx->lmodule->throw = callee;
3515 arg = convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, &mono_defaults.object_class->byval_arg));
3516 emit_call (ctx, bb, &builder, callee, &arg, 1);
3517 break;
3519 case OP_CALL_HANDLER: {
3521 * We don't 'call' handlers, but instead simply branch to them.
3522 * The code generated by ENDFINALLY will branch back to us.
3524 LLVMBasicBlockRef finally_bb, noex_bb;
3525 GSList *bb_list;
3527 finally_bb = get_bb (ctx, ins->inst_target_bb);
3529 bb_list = bblocks [ins->inst_target_bb->block_num].call_handler_return_bbs;
3532 * Set the indicator variable for the finally clause.
3534 lhs = bblocks [ins->inst_target_bb->block_num].finally_ind;
3535 g_assert (lhs);
3536 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
3538 /* Branch to the finally clause */
3539 LLVMBuildBr (builder, finally_bb);
3541 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
3542 // FIXME: Use a mempool
3543 bblocks [ins->inst_target_bb->block_num].call_handler_return_bbs = g_slist_append (bblocks [ins->inst_target_bb->block_num].call_handler_return_bbs, noex_bb);
3545 builder = ctx->builder = create_builder (ctx);
3546 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
3548 bblocks [bb->block_num].end_bblock = noex_bb;
3549 break;
3551 case OP_START_HANDLER: {
3552 break;
3554 case OP_ENDFINALLY: {
3555 LLVMBasicBlockRef resume_bb;
3556 MonoBasicBlock *handler_bb;
3557 LLVMValueRef val, switch_ins;
3558 GSList *bb_list;
3560 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
3561 g_assert (handler_bb);
3562 lhs = bblocks [handler_bb->block_num].finally_ind;
3563 g_assert (lhs);
3565 bb_list = bblocks [handler_bb->block_num].call_handler_return_bbs;
3567 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
3569 /* Load the finally variable */
3570 val = LLVMBuildLoad (builder, lhs, "");
3572 /* Reset the variable */
3573 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
3575 /* Branch to either resume_bb, or to the bblocks in bb_list */
3576 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
3578 * The other targets are added at the end to handle OP_CALL_HANDLER
3579 * opcodes processed later.
3581 bblocks [handler_bb->block_num].endfinally_switch = switch_ins;
3583 for (i = 0; i < g_slist_length (bb_list); ++i)
3584 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
3587 builder = ctx->builder = create_builder (ctx);
3588 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
3590 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "mono_resume_unwind"), NULL, 0, "");
3591 LLVMBuildUnreachable (builder);
3592 has_terminator = TRUE;
3593 break;
3595 default: {
3596 char reason [128];
3598 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
3599 LLVM_FAILURE (ctx, reason);
3600 break;
3604 /* Convert the value to the type required by phi nodes */
3605 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && vreg_types [ins->dreg]) {
3606 if (!values [ins->dreg])
3607 /* vtypes */
3608 values [ins->dreg] = addresses [ins->dreg];
3609 else
3610 values [ins->dreg] = convert (ctx, values [ins->dreg], vreg_types [ins->dreg]);
3613 /* Add stores for volatile variables */
3614 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
3615 emit_volatile_store (ctx, ins->dreg);
3618 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
3619 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
3621 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
3622 LLVMBuildRetVoid (builder);
3624 if (bb == cfg->bb_entry)
3625 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
3628 /* Add incoming phi values */
3629 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3630 GSList *l, *ins_list;
3632 ins_list = bblocks [bb->block_num].phi_nodes;
3634 for (l = ins_list; l; l = l->next) {
3635 PhiNode *node = l->data;
3636 MonoInst *phi = node->phi;
3637 int sreg1 = node->sreg;
3638 LLVMBasicBlockRef in_bb;
3640 if (sreg1 == -1)
3641 continue;
3643 in_bb = get_end_bb (ctx, node->in_bb);
3645 if (unreachable [node->in_bb->block_num])
3646 continue;
3648 g_assert (values [sreg1]);
3650 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
3651 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
3655 /* Create the SWITCH statements for ENDFINALLY instructions */
3656 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3657 if (bblocks [bb->block_num].endfinally_switch) {
3658 LLVMValueRef switch_ins = bblocks [bb->block_num].endfinally_switch;
3659 GSList *bb_list = bblocks [bb->block_num].call_handler_return_bbs;
3661 for (i = 0; i < g_slist_length (bb_list); ++i)
3662 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
3666 if (cfg->verbose_level > 1)
3667 mono_llvm_dump_value (method);
3669 mark_as_used (module, method);
3671 if (cfg->compile_aot) {
3672 /* Don't generate native code, keep the LLVM IR */
3674 /* Can't delete the method if it has an alias, so only add it if successful */
3675 if (debug_name) {
3676 debug_alias = LLVMAddAlias (module, LLVMTypeOf (method), method, debug_name);
3677 LLVMSetLinkage (debug_alias, LLVMInternalLinkage);
3678 LLVMSetVisibility (debug_alias, LLVMHiddenVisibility);
3681 if (cfg->compile_aot && cfg->verbose_level)
3682 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
3684 //LLVMVerifyFunction(method, 0);
3685 } else {
3686 mono_llvm_optimize_method (method);
3688 if (cfg->verbose_level > 1)
3689 mono_llvm_dump_value (method);
3691 cfg->native_code = LLVMGetPointerToGlobal (ee, method);
3693 /* Set by emit_cb */
3694 g_assert (cfg->code_len);
3696 /* FIXME: Free the LLVM IL for the function */
3699 goto CLEANUP;
3701 FAILURE:
3703 if (method) {
3704 /* Need to add unused phi nodes as they can be referenced by other values */
3705 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
3706 LLVMBuilderRef builder;
3708 builder = create_builder (ctx);
3709 LLVMPositionBuilderAtEnd (builder, phi_bb);
3711 for (i = 0; i < phi_values->len; ++i) {
3712 LLVMValueRef v = g_ptr_array_index (phi_values, i);
3713 if (LLVMGetInstructionParent (v) == NULL)
3714 LLVMInsertIntoBuilder (builder, v);
3717 LLVMDeleteFunction (method);
3720 CLEANUP:
3721 g_free (values);
3722 g_free (addresses);
3723 g_free (vreg_types);
3724 g_free (vreg_cli_types);
3725 g_free (pindexes);
3726 g_free (debug_name);
3727 g_ptr_array_free (phi_values, TRUE);
3728 g_free (ctx->bblocks);
3729 g_hash_table_destroy (ctx->region_to_handler);
3730 g_free (method_name);
3731 g_ptr_array_free (bblock_list, TRUE);
3733 for (l = ctx->builders; l; l = l->next) {
3734 LLVMBuilderRef builder = l->data;
3735 LLVMDisposeBuilder (builder);
3738 g_free (ctx);
3740 TlsSetValue (current_cfg_tls_id, NULL);
3742 mono_loader_unlock ();
3746 * mono_llvm_emit_call:
3748 * Same as mono_arch_emit_call () for LLVM.
3750 void
3751 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
3753 MonoInst *in;
3754 MonoMethodSignature *sig;
3755 int i, n, stack_size;
3756 LLVMArgInfo *ainfo;
3758 stack_size = 0;
3760 sig = call->signature;
3761 n = sig->param_count + sig->hasthis;
3763 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
3765 if (cfg->disable_llvm)
3766 return;
3768 if (sig->call_convention == MONO_CALL_VARARG) {
3769 cfg->exception_message = g_strdup ("varargs");
3770 cfg->disable_llvm = TRUE;
3773 for (i = 0; i < n; ++i) {
3774 MonoInst *ins;
3776 ainfo = call->cinfo->args + i;
3778 in = call->args [i];
3780 /* Simply remember the arguments */
3781 switch (ainfo->storage) {
3782 case LLVMArgInIReg:
3783 MONO_INST_NEW (cfg, ins, OP_MOVE);
3784 ins->dreg = mono_alloc_ireg (cfg);
3785 ins->sreg1 = in->dreg;
3786 break;
3787 case LLVMArgInFPReg:
3788 MONO_INST_NEW (cfg, ins, OP_FMOVE);
3789 ins->dreg = mono_alloc_freg (cfg);
3790 ins->sreg1 = in->dreg;
3791 break;
3792 case LLVMArgVtypeByVal:
3793 case LLVMArgVtypeInReg:
3794 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
3795 ins->dreg = mono_alloc_ireg (cfg);
3796 ins->sreg1 = in->dreg;
3797 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
3798 break;
3799 default:
3800 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
3801 cfg->exception_message = g_strdup ("ainfo->storage");
3802 cfg->disable_llvm = TRUE;
3803 return;
3806 if (!cfg->disable_llvm) {
3807 MONO_ADD_INS (cfg->cbb, ins);
3808 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
3813 static unsigned char*
3814 alloc_cb (LLVMValueRef function, int size)
3816 MonoCompile *cfg;
3818 cfg = TlsGetValue (current_cfg_tls_id);
3820 if (cfg) {
3821 // FIXME: dynamic
3822 return mono_domain_code_reserve (cfg->domain, size);
3823 } else {
3824 return mono_domain_code_reserve (mono_domain_get (), size);
3828 static void
3829 emitted_cb (LLVMValueRef function, void *start, void *end)
3831 MonoCompile *cfg;
3833 cfg = TlsGetValue (current_cfg_tls_id);
3834 g_assert (cfg);
3835 cfg->code_len = (guint8*)end - (guint8*)start;
3838 static void
3839 exception_cb (void *data)
3841 MonoCompile *cfg;
3842 MonoJitExceptionInfo *ei;
3843 guint32 ei_len, i;
3844 gpointer *type_info;
3845 int this_reg, this_offset;
3847 cfg = TlsGetValue (current_cfg_tls_id);
3848 g_assert (cfg);
3851 * data points to a DWARF FDE structure, convert it to our unwind format and
3852 * save it.
3853 * An alternative would be to save it directly, and modify our unwinder to work
3854 * with it.
3856 cfg->encoded_unwind_ops = mono_unwind_decode_fde ((guint8*)data, &cfg->encoded_unwind_ops_len, NULL, &ei, &ei_len, &type_info, &this_reg, &this_offset);
3858 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, ei_len * sizeof (MonoJitExceptionInfo));
3859 cfg->llvm_ex_info_len = ei_len;
3860 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
3861 /* Fill the rest of the information from the type info */
3862 for (i = 0; i < ei_len; ++i) {
3863 gint32 clause_index = *(gint32*)type_info [i];
3864 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
3866 cfg->llvm_ex_info [i].flags = clause->flags;
3867 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
3869 cfg->llvm_this_reg = this_reg;
3870 cfg->llvm_this_offset = this_offset;
3872 g_free (ei);
3875 static void
3876 add_intrinsics (LLVMModuleRef module)
3878 /* Emit declarations of instrinsics */
3880 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
3882 #if LLVM_CHECK_VERSION(2, 8)
3883 memset_param_count = 5;
3884 memset_func_name = "llvm.memset.p0i8.i32";
3885 #else
3886 memset_param_count = 4;
3887 memset_func_name = "llvm.memset.i32";
3888 #endif
3889 LLVMAddFunction (module, memset_func_name, LLVMFunctionType (LLVMVoidType (), memset_params, memset_param_count, FALSE));
3893 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
3895 #if LLVM_CHECK_VERSION(2, 8)
3896 memcpy_param_count = 5;
3897 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
3898 #else
3899 memcpy_param_count = 4;
3900 memcpy_func_name = "llvm.memcpy.i32";
3901 #endif
3903 LLVMAddFunction (module, memcpy_func_name, LLVMFunctionType (LLVMVoidType (), memcpy_params, memcpy_param_count, FALSE));
3907 LLVMTypeRef params [] = { LLVMDoubleType () };
3909 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
3910 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
3911 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
3913 /* This isn't an intrinsic, instead llvm seems to special case it by name */
3914 LLVMAddFunction (module, "fabs", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
3918 LLVMTypeRef membar_params [] = { LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type () };
3920 LLVMAddFunction (module, "llvm.atomic.swap.i32.p0i32", LLVMFunctionType2 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), FALSE));
3921 LLVMAddFunction (module, "llvm.atomic.swap.i64.p0i64", LLVMFunctionType2 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), FALSE));
3922 LLVMAddFunction (module, "llvm.atomic.load.add.i32.p0i32", LLVMFunctionType2 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), FALSE));
3923 LLVMAddFunction (module, "llvm.atomic.load.add.i64.p0i64", LLVMFunctionType2 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), FALSE));
3924 LLVMAddFunction (module, "llvm.atomic.cmp.swap.i32.p0i32", LLVMFunctionType3 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), LLVMInt32Type (), FALSE));
3925 LLVMAddFunction (module, "llvm.atomic.cmp.swap.i64.p0i64", LLVMFunctionType3 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), LLVMInt64Type (), FALSE));
3926 LLVMAddFunction (module, "llvm.memory.barrier", LLVMFunctionType (LLVMVoidType (), membar_params, 5, FALSE));
3930 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
3931 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
3933 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
3934 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
3935 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
3936 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
3937 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
3938 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
3942 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
3943 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
3945 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
3946 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
3947 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
3948 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
3949 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
3950 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
3954 LLVMTypeRef struct_ptr = LLVMPointerType (LLVMStructType (NULL, 0, FALSE), 0);
3955 LLVMTypeRef invariant_start_params [] = { LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
3956 LLVMTypeRef invariant_end_params [] = { struct_ptr, LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
3958 LLVMAddFunction (module, "llvm.invariant.start", LLVMFunctionType (struct_ptr, invariant_start_params, 2, FALSE));
3960 LLVMAddFunction (module, "llvm.invariant.end", LLVMFunctionType (LLVMVoidType (), invariant_end_params, 3, FALSE));
3963 /* EH intrinsics */
3965 LLVMTypeRef arg_types [2];
3966 LLVMTypeRef ret_type;
3968 arg_types [0] = LLVMPointerType (LLVMInt8Type (), 0);
3969 arg_types [1] = LLVMPointerType (LLVMInt8Type (), 0);
3970 #if LLVM_CHECK_VERSION(2, 8)
3971 eh_selector_name = "llvm.eh.selector";
3972 ret_type = LLVMInt32Type ();
3973 #else
3974 #if SIZEOF_VOID_P == 8
3975 eh_selector_name = "llvm.eh.selector.i64";
3976 ret_type = LLVMInt64Type ();
3977 #else
3978 eh_selector_name = "llvm.eh.selector.i32";
3979 ret_type = LLVMInt32Type ();
3980 #endif
3981 #endif
3982 LLVMAddFunction (module, eh_selector_name, LLVMFunctionType (ret_type, arg_types, 2, TRUE));
3984 LLVMAddFunction (module, "llvm.eh.exception", LLVMFunctionType (LLVMPointerType (LLVMInt8Type (), 0), NULL, 0, FALSE));
3986 LLVMAddFunction (module, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
3988 LLVMAddFunction (module, "mono_resume_unwind", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
3991 /* SSE intrinsics */
3993 LLVMTypeRef vector_type, arg_types [2];
3995 vector_type = LLVMVectorType (LLVMInt32Type (), 4);
3996 arg_types [0] = vector_type;
3997 arg_types [1] = vector_type;
3998 LLVMAddFunction (module, "llvm.x86.sse41.pminud", LLVMFunctionType (vector_type, arg_types, 2, FALSE));
3999 LLVMAddFunction (module, "llvm.x86.sse41.pmaxud", LLVMFunctionType (vector_type, arg_types, 2, FALSE));
4001 vector_type = LLVMVectorType (LLVMInt16Type (), 8);
4002 arg_types [0] = vector_type;
4003 arg_types [1] = vector_type;
4004 LLVMAddFunction (module, "llvm.x86.sse41.pminuw", LLVMFunctionType (vector_type, arg_types, 2, FALSE));
4005 LLVMAddFunction (module, "llvm.x86.sse41.pmaxuw", LLVMFunctionType (vector_type, arg_types, 2, FALSE));
4007 vector_type = LLVMVectorType (LLVMInt8Type (), 16);
4008 arg_types [0] = vector_type;
4009 arg_types [1] = vector_type;
4010 LLVMAddFunction (module, "llvm.x86.sse2.pminu.b", LLVMFunctionType (vector_type, arg_types, 2, FALSE));
4011 LLVMAddFunction (module, "llvm.x86.sse2.pmaxu.b", LLVMFunctionType (vector_type, arg_types, 2, FALSE));
4013 vector_type = LLVMVectorType (LLVMDoubleType (), 2);
4014 arg_types [0] = vector_type;
4015 arg_types [1] = vector_type;
4016 LLVMAddFunction (module, "llvm.x86.sse2.min.pd", LLVMFunctionType (vector_type, arg_types, 2, FALSE));
4017 LLVMAddFunction (module, "llvm.x86.sse2.max.pd", LLVMFunctionType (vector_type, arg_types, 2, FALSE));
4019 vector_type = LLVMVectorType (LLVMFloatType (), 4);
4020 arg_types [0] = vector_type;
4021 arg_types [1] = vector_type;
4022 LLVMAddFunction (module, "llvm.x86.sse2.min.ps", LLVMFunctionType (vector_type, arg_types, 2, FALSE));
4023 LLVMAddFunction (module, "llvm.x86.sse2.max.ps", LLVMFunctionType (vector_type, arg_types, 2, FALSE));
4027 void
4028 mono_llvm_init (void)
4030 current_cfg_tls_id = TlsAlloc ();
4033 static void
4034 init_jit_module (void)
4036 if (jit_module_inited)
4037 return;
4039 mono_loader_lock ();
4041 if (jit_module_inited) {
4042 mono_loader_unlock ();
4043 return;
4046 jit_module.module = LLVMModuleCreateWithName ("mono");
4048 ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module.module), alloc_cb, emitted_cb, exception_cb);
4050 add_intrinsics (jit_module.module);
4052 jit_module.llvm_types = g_hash_table_new (NULL, NULL);
4054 LLVMAddGlobalMapping (ee, LLVMGetNamedFunction (jit_module.module, "mono_resume_unwind"), mono_resume_unwind);
4056 jit_module_inited = TRUE;
4058 mono_loader_unlock ();
4061 void
4062 mono_llvm_cleanup (void)
4064 if (ee)
4065 mono_llvm_dispose_ee (ee);
4067 if (jit_module.llvm_types)
4068 g_hash_table_destroy (jit_module.llvm_types);
4071 void
4072 mono_llvm_create_aot_module (const char *got_symbol)
4074 /* Delete previous module */
4075 if (aot_module.plt_entries)
4076 g_hash_table_destroy (aot_module.plt_entries);
4078 memset (&aot_module, 0, sizeof (aot_module));
4080 aot_module.module = LLVMModuleCreateWithName ("aot");
4081 aot_module.got_symbol = got_symbol;
4083 add_intrinsics (aot_module.module);
4085 /* Add GOT */
4087 * We couldn't compute the type of the LLVM global representing the got because
4088 * its size is only known after all the methods have been emitted. So create
4089 * a dummy variable, and replace all uses it with the real got variable when
4090 * its size is known in mono_llvm_emit_aot_module ().
4093 LLVMTypeRef got_type = LLVMArrayType (IntPtrType (), 0);
4095 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
4096 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
4099 /* Add a dummy personality function */
4101 LLVMBasicBlockRef lbb;
4102 LLVMBuilderRef lbuilder;
4103 LLVMValueRef personality;
4105 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4106 LLVMSetLinkage (personality, LLVMPrivateLinkage);
4107 lbb = LLVMAppendBasicBlock (personality, "BB0");
4108 lbuilder = LLVMCreateBuilder ();
4109 LLVMPositionBuilderAtEnd (lbuilder, lbb);
4110 LLVMBuildRetVoid (lbuilder);
4113 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
4114 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
4118 * Emit the aot module into the LLVM bitcode file FILENAME.
4120 void
4121 mono_llvm_emit_aot_module (const char *filename, int got_size)
4123 LLVMTypeRef got_type;
4124 LLVMValueRef real_got;
4127 * Create the real got variable and replace all uses of the dummy variable with
4128 * the real one.
4130 got_type = LLVMArrayType (IntPtrType (), got_size);
4131 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
4132 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
4133 LLVMSetLinkage (real_got, LLVMInternalLinkage);
4135 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
4137 mark_as_used (aot_module.module, real_got);
4139 /* Delete the dummy got so it doesn't become a global */
4140 LLVMDeleteGlobal (aot_module.got_var);
4142 #if 0
4144 char *verifier_err;
4146 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
4147 g_assert_not_reached ();
4150 #endif
4152 LLVMWriteBitcodeToFile (aot_module.module, filename);
4156 DESIGN:
4157 - Emit LLVM IR from the mono IR using the LLVM C API.
4158 - The original arch specific code remains, so we can fall back to it if we run
4159 into something we can't handle.
4160 FIXME:
4161 - llvm's PrettyStackTrace class seems to register a signal handler which screws
4162 up our GC. Also, it calls sigaction () a _lot_ of times instead of just once.
4166 A partial list of issues:
4167 - Handling of opcodes which can throw exceptions.
4169 In the mono JIT, these are implemented using code like this:
4170 method:
4171 <compare>
4172 throw_pos:
4173 b<cond> ex_label
4174 <rest of code>
4175 ex_label:
4176 push throw_pos - method
4177 call <exception trampoline>
4179 The problematic part is push throw_pos - method, which cannot be represented
4180 in the LLVM IR, since it does not support label values.
4181 -> this can be implemented in AOT mode using inline asm + labels, but cannot
4182 be implemented in JIT mode ?
4183 -> a possible but slower implementation would use the normal exception
4184 throwing code but it would need to control the placement of the throw code
4185 (it needs to be exactly after the compare+branch).
4186 -> perhaps add a PC offset intrinsics ?
4188 - efficient implementation of .ovf opcodes.
4190 These are currently implemented as:
4191 <ins which sets the condition codes>
4192 b<cond> ex_label
4194 Some overflow opcodes are now supported by LLVM SVN.
4196 - exception handling, unwinding.
4197 - SSA is disabled for methods with exception handlers
4198 - How to obtain unwind info for LLVM compiled methods ?
4199 -> this is now solved by converting the unwind info generated by LLVM
4200 into our format.
4201 - LLVM uses the c++ exception handling framework, while we use our home grown
4202 code, and couldn't use the c++ one:
4203 - its not supported under VC++, other exotic platforms.
4204 - it might be impossible to support filter clauses with it.
4206 - trampolines.
4208 The trampolines need a predictable call sequence, since they need to disasm
4209 the calling code to obtain register numbers / offsets.
4211 LLVM currently generates this code in non-JIT mode:
4212 mov -0x98(%rax),%eax
4213 callq *%rax
4214 Here, the vtable pointer is lost.
4215 -> solution: use one vtable trampoline per class.
4217 - passing/receiving the IMT pointer/RGCTX.
4218 -> solution: pass them as normal arguments ?
4220 - argument passing.
4222 LLVM does not allow the specification of argument registers etc. This means
4223 that all calls are made according to the platform ABI.
4225 - passing/receiving vtypes.
4227 Vtypes passed/received in registers are handled by the front end by using
4228 a signature with scalar arguments, and loading the parts of the vtype into those
4229 arguments.
4231 Vtypes passed on the stack are handled using the 'byval' attribute.
4233 - ldaddr.
4235 Supported though alloca, we need to emit the load/store code.
4237 - types.
4239 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
4240 typed registers, so we have to keep track of the precise LLVM type of each vreg.
4241 This is made easier because the IR is already in SSA form.
4242 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
4243 types are frequently used incorrectly.
4247 AOT SUPPORT:
4248 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
4249 append the AOT data structures to that file. For methods which cannot be
4250 handled by LLVM, the normal JIT compiled versions are used.
4253 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
4254 * - each bblock should end with a branch
4255 * - setting the return value, making cfg->ret non-volatile
4256 * - merge some changes back to HEAD, to reduce the differences.
4257 * - avoid some transformations in the JIT which make it harder for us to generate
4258 * code.
4259 * - fix memory leaks.
4260 * - use pointer types to help optimizations.