2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * (C) 2009 Novell, Inc.
8 #include <mono/metadata/debug-helpers.h>
9 #include <mono/metadata/mempool-internals.h>
11 #include "llvm-c/Core.h"
12 #include "llvm-c/ExecutionEngine.h"
14 #include "mini-llvm-cpp.h"
21 LLVMValueRef throw_corlib_exception;
23 /* Maps method names to the corresponding LLVMValueRef */
24 GHashTable *emitted_method_decls;
28 LLVMBasicBlockRef *bblocks, *end_bblocks;
29 int sindex, default_index, ex_index;
30 LLVMBuilderRef builder;
31 LLVMValueRef *values, *addresses;
41 * Instruction metadata
42 * This is the same as ins_info, but LREG != IREG.
50 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
51 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
58 /* keep in sync with the enum in mini.h */
66 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
68 #define LLVM_FAILURE(ctx, reason) do { \
69 (ctx)->cfg->exception_message = g_strdup (reason); \
70 (ctx)->cfg->disable_llvm = TRUE; \
74 #define CHECK_FAILURE(ctx) do { \
75 if ((ctx)->cfg->disable_llvm) \
79 static LLVMIntPredicate cond_to_llvm_cond [] = {
92 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
105 static LLVMModuleRef module;
106 static LLVMExecutionEngineRef ee;
107 static GHashTable *llvm_types;
108 static guint32 current_cfg_tls_id;
110 static void mono_llvm_init (void);
115 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
119 type_to_llvm_type (EmitContext *ctx, MonoType *t)
122 return IntPtrType ();
125 return LLVMVoidType ();
127 return LLVMInt8Type ();
129 return LLVMInt16Type ();
131 return LLVMInt32Type ();
133 return LLVMInt8Type ();
135 return LLVMInt16Type ();
137 return LLVMInt32Type ();
138 case MONO_TYPE_BOOLEAN:
139 return LLVMInt8Type ();
142 return LLVMInt64Type ();
144 return LLVMInt16Type ();
146 return LLVMFloatType ();
148 return LLVMDoubleType ();
151 return IntPtrType ();
152 case MONO_TYPE_OBJECT:
153 case MONO_TYPE_CLASS:
154 case MONO_TYPE_ARRAY:
155 case MONO_TYPE_SZARRAY:
156 case MONO_TYPE_STRING:
158 return IntPtrType ();
161 /* Because of generic sharing */
162 return IntPtrType ();
163 case MONO_TYPE_GENERICINST:
164 if (!mono_type_generic_inst_is_valuetype (t))
165 return IntPtrType ();
167 case MONO_TYPE_VALUETYPE: {
171 if (t->data.klass->enumtype)
172 return LLVMInt32Type ();
174 klass = mono_class_from_mono_type (t);
175 ltype = g_hash_table_lookup (llvm_types, klass);
177 ltype = LLVMArrayType (LLVMInt8Type (), mono_class_value_size (klass, NULL));
178 g_hash_table_insert (llvm_types, klass, ltype);
184 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
185 ctx->cfg->disable_llvm = TRUE;
190 static G_GNUC_UNUSED LLVMTypeRef
191 llvm_type_to_stack_type (LLVMTypeRef type)
195 if (type == LLVMInt8Type ())
196 return LLVMInt32Type ();
197 else if (type == LLVMInt16Type ())
198 return LLVMInt32Type ();
199 else if (type == LLVMFloatType ())
200 return LLVMDoubleType ();
206 regtype_to_llvm_type (char c)
210 return LLVMInt32Type ();
212 return LLVMInt64Type ();
214 return LLVMDoubleType ();
221 conv_to_llvm_type (int opcode)
226 return LLVMInt8Type ();
229 return LLVMInt8Type ();
232 return LLVMInt16Type ();
235 return LLVMInt16Type ();
238 return LLVMInt32Type ();
241 return LLVMInt32Type ();
243 return LLVMInt64Type ();
245 return LLVMFloatType ();
247 return LLVMDoubleType ();
249 return LLVMInt64Type ();
251 return LLVMInt32Type ();
253 return LLVMInt64Type ();
256 return LLVMInt8Type ();
259 return LLVMInt16Type ();
262 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
264 printf ("%s\n", mono_inst_name (opcode));
265 g_assert_not_reached ();
271 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
277 case OP_LOADI1_MEMBASE:
278 case OP_STOREI1_MEMBASE_REG:
279 case OP_STOREI1_MEMBASE_IMM:
282 return LLVMInt8Type ();
283 case OP_LOADU1_MEMBASE:
286 return LLVMInt8Type ();
287 case OP_LOADI2_MEMBASE:
288 case OP_STOREI2_MEMBASE_REG:
289 case OP_STOREI2_MEMBASE_IMM:
292 return LLVMInt16Type ();
293 case OP_LOADU2_MEMBASE:
296 return LLVMInt16Type ();
297 case OP_LOADI4_MEMBASE:
298 case OP_LOADU4_MEMBASE:
299 case OP_STOREI4_MEMBASE_REG:
300 case OP_STOREI4_MEMBASE_IMM:
302 return LLVMInt32Type ();
303 case OP_LOADI8_MEMBASE:
305 case OP_STOREI8_MEMBASE_REG:
306 case OP_STOREI8_MEMBASE_IMM:
308 return LLVMInt64Type ();
309 case OP_LOADR4_MEMBASE:
310 case OP_STORER4_MEMBASE_REG:
312 return LLVMFloatType ();
313 case OP_LOADR8_MEMBASE:
314 case OP_STORER8_MEMBASE_REG:
316 return LLVMDoubleType ();
317 case OP_LOAD_MEMBASE:
319 case OP_STORE_MEMBASE_REG:
320 case OP_STORE_MEMBASE_IMM:
321 *size = sizeof (gpointer);
322 return IntPtrType ();
324 g_assert_not_reached ();
330 ovf_op_to_intrins (int opcode)
334 return "llvm.sadd.with.overflow.i32";
336 return "llvm.uadd.with.overflow.i32";
338 return "llvm.ssub.with.overflow.i32";
340 return "llvm.usub.with.overflow.i32";
342 return "llvm.smul.with.overflow.i32";
344 return "llvm.umul.with.overflow.i32";
346 return "llvm.sadd.with.overflow.i64";
348 return "llvm.uadd.with.overflow.i64";
350 return "llvm.ssub.with.overflow.i64";
352 return "llvm.usub.with.overflow.i64";
354 return "llvm.smul.with.overflow.i64";
356 return "llvm.umul.with.overflow.i64";
358 g_assert_not_reached ();
363 static LLVMBasicBlockRef
364 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
368 if (ctx->bblocks [bb->block_num] == NULL) {
369 sprintf (bb_name, "BB%d", bb->block_num);
371 ctx->bblocks [bb->block_num] = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
372 ctx->end_bblocks [bb->block_num] = ctx->bblocks [bb->block_num];
375 return ctx->bblocks [bb->block_num];
378 /* Return the last LLVM bblock corresponding to BB */
379 static LLVMBasicBlockRef
380 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
383 return ctx->end_bblocks [bb->block_num];
387 get_tempname (EmitContext *ctx)
390 static char temp_name [128];
392 sprintf (temp_name, "s%d", ctx->sindex ++);
398 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
402 memset (&ji, 0, sizeof (ji));
404 ji.data.target = target;
406 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
410 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
412 LLVMTypeRef stype = LLVMTypeOf (v);
414 if (stype != dtype) {
416 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
417 return LLVMBuildSExt (ctx->builder, v, dtype, get_tempname (ctx));
418 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
419 return LLVMBuildSExt (ctx->builder, v, dtype, get_tempname (ctx));
420 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
421 return LLVMBuildSExt (ctx->builder, v, dtype, get_tempname (ctx));
422 else if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
423 return LLVMBuildFPExt (ctx->builder, v, dtype, get_tempname (ctx));
426 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
427 return LLVMBuildTrunc (ctx->builder, v, dtype, get_tempname (ctx));
428 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
429 return LLVMBuildTrunc (ctx->builder, v, dtype, get_tempname (ctx));
430 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
431 return LLVMBuildFPTrunc (ctx->builder, v, dtype, get_tempname (ctx));
433 g_assert_not_reached ();
440 /* Emit stores for volatile variables */
442 emit_volatile_store (EmitContext *ctx, int vreg)
444 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
446 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
447 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
452 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig, gboolean vretaddr)
454 LLVMTypeRef ret_type;
455 LLVMTypeRef *param_types = NULL;
459 ret_type = type_to_llvm_type (ctx, sig->ret);
462 if (MONO_TYPE_ISSTRUCT (sig->ret) && !vretaddr)
463 LLVM_FAILURE (ctx, "vtype ret");
465 param_types = g_new0 (LLVMTypeRef, sig->param_count + sig->hasthis + vretaddr);
468 ret_type = LLVMVoidType ();
469 param_types [pindex ++] = IntPtrType ();
472 param_types [pindex ++] = IntPtrType ();
473 for (i = 0; i < sig->param_count; ++i) {
474 if (MONO_TYPE_ISSTRUCT (sig->params [i]))
475 LLVM_FAILURE (ctx, "vtype param");
476 param_types [pindex ++] = type_to_llvm_type (ctx, sig->params [i]);
480 res = LLVMFunctionType (ret_type, param_types, sig->param_count + sig->hasthis + vretaddr, FALSE);
481 g_free (param_types);
486 g_free (param_types);
491 static G_GNUC_UNUSED LLVMTypeRef
492 LLVMFunctionType1(LLVMTypeRef ReturnType,
493 LLVMTypeRef ParamType1,
496 LLVMTypeRef param_types [1];
498 param_types [0] = ParamType1;
500 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
504 LLVMFunctionType2(LLVMTypeRef ReturnType,
505 LLVMTypeRef ParamType1,
506 LLVMTypeRef ParamType2,
509 LLVMTypeRef param_types [2];
511 param_types [0] = ParamType1;
512 param_types [1] = ParamType2;
514 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
518 LLVMFunctionType3(LLVMTypeRef ReturnType,
519 LLVMTypeRef ParamType1,
520 LLVMTypeRef ParamType2,
521 LLVMTypeRef ParamType3,
524 LLVMTypeRef param_types [3];
526 param_types [0] = ParamType1;
527 param_types [1] = ParamType2;
528 param_types [2] = ParamType3;
530 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
534 emit_cond_throw_pos (EmitContext *ctx)
539 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
542 LLVMBasicBlockRef ex_bb, noex_bb;
543 LLVMBuilderRef builder;
544 MonoClass *exc_class;
545 static LLVMValueRef throw;
547 sprintf (bb_name, "EX_BB%d", ctx->ex_index);
548 ex_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
550 sprintf (bb_name, "NOEX_BB%d", ctx->ex_index);
551 noex_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
553 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
555 ctx->builder = LLVMCreateBuilder ();
556 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
558 ctx->end_bblocks [bb->block_num] = noex_bb;
560 exc_class = mono_class_from_name (mono_defaults.corlib, "System", exc_type);
561 g_assert (exc_class);
563 /* Emit exception throwing code */
564 builder = LLVMCreateBuilder ();
565 LLVMPositionBuilderAtEnd (builder, ex_bb);
569 throw = LLVMAddFunction (module, "throw", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
571 LLVMAddGlobalMapping (ee, throw, &abort);
574 LLVMBuildCall (builder, throw, NULL, 0, "");
576 LLVMBuildUnreachable (builder);
582 mono_llvm_emit_method (MonoCompile *cfg)
585 MonoMethodSignature *sig;
587 LLVMTypeRef method_type;
588 LLVMValueRef method = NULL;
590 LLVMValueRef *values, *addresses;
591 LLVMTypeRef *vreg_types;
592 int i, max_block_num;
593 GHashTable *phi_nodes;
594 gboolean last = FALSE;
595 GPtrArray *phi_values;
597 /* The code below might acquire the loader lock, so use it for global locking */
603 /* Used to communicate with the callbacks */
604 TlsSetValue (current_cfg_tls_id, cfg);
606 ctx = g_new0 (EmitContext, 1);
608 ctx->mempool = cfg->mempool;
612 static int count = 0;
615 if (count == atoi (getenv ("COUNT"))) {
616 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
619 if (count > atoi (getenv ("COUNT")))
620 LLVM_FAILURE (ctx, "");
624 values = g_new0 (LLVMValueRef, cfg->next_vreg);
625 addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
626 vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
627 phi_nodes = g_hash_table_new (NULL, NULL);
628 phi_values = g_ptr_array_new ();
630 ctx->values = values;
631 ctx->addresses = addresses;
633 sig = mono_method_signature (cfg->method);
635 method_type = sig_to_llvm_sig (ctx, sig, cfg->vret_addr != NULL);
638 method_name = mono_method_full_name (cfg->method, TRUE);
639 method = LLVMAddFunction (module, method_name, method_type);
640 ctx->lmethod = method;
641 g_free (method_name);
643 if (cfg->method->save_lmf)
644 LLVM_FAILURE (ctx, "lmf");
646 if (cfg->vret_addr) {
647 values [cfg->vret_addr->dreg] = LLVMGetParam (method, 0);
648 for (i = 0; i < sig->param_count + sig->hasthis; ++i)
649 values [cfg->args [i]->dreg] = LLVMGetParam (method, i + 1);
651 for (i = 0; i < sig->param_count + sig->hasthis; ++i)
652 values [cfg->args [i]->dreg] = LLVMGetParam (method, i);
656 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
657 max_block_num = MAX (max_block_num, bb->block_num);
658 ctx->bblocks = g_new0 (LLVMBasicBlockRef, max_block_num + 1);
659 ctx->end_bblocks = g_new0 (LLVMBasicBlockRef, max_block_num + 1);
661 /* Add branches between non-consecutive bblocks */
662 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
663 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
664 bb->next_bb != bb->last_ins->inst_false_bb) {
666 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
667 inst->opcode = OP_BR;
668 inst->inst_target_bb = bb->last_ins->inst_false_bb;
669 mono_bblock_add_inst (bb, inst);
674 * Make a first pass over the code in dfn order to obtain the exact type of all
675 * vregs, and to create PHI nodes.
676 * This is needed because we only use iregs/fregs, while llvm uses many types,
677 * and requires precise types. Also, our IR is not precise in many places, like
678 * using i32 arguments to opcodes expecting an i64 etc.
680 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
682 LLVMBuilderRef builder;
686 builder = LLVMCreateBuilder ();
688 for (ins = bb->code; ins; ins = ins->next) {
689 switch (ins->opcode) {
692 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
697 * Have to precreate these, as they can be referenced by
698 * earlier instructions.
700 sprintf (dname_buf, "t%d", ins->dreg);
702 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
704 g_ptr_array_add (phi_values, values [ins->dreg]);
707 * Set the expected type of the incoming arguments since these have
708 * to have the same type.
710 for (i = 0; i < ins->inst_phi_args [0]; i++) {
711 int sreg1 = ins->inst_phi_args [i + 1];
714 vreg_types [sreg1] = phi_type;
725 * Second pass: generate code.
727 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
729 LLVMBasicBlockRef cbb;
730 LLVMBuilderRef builder;
731 gboolean has_terminator;
733 LLVMValueRef lhs, rhs;
735 if (!(bb == cfg->bb_entry || bb->in_count > 0))
738 cbb = get_bb (ctx, bb);
739 builder = LLVMCreateBuilder ();
740 ctx->builder = builder;
741 LLVMPositionBuilderAtEnd (builder, cbb);
743 if (bb == cfg->bb_entry) {
745 * Handle indirect/volatile variables by allocating memory for them
746 * using 'alloca', and storing their address in a temporary.
748 for (i = 0; i < cfg->num_varinfo; ++i) {
749 MonoInst *var = cfg->varinfo [i];
752 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || MONO_TYPE_ISSTRUCT (var->inst_vtype)) {
753 vtype = type_to_llvm_type (ctx, var->inst_vtype);
755 addresses [var->dreg] = LLVMBuildAlloca (builder, vtype, get_tempname (ctx));
759 /* Convert arguments */
760 for (i = 0; i < sig->param_count; ++i)
761 values [cfg->args [i + sig->hasthis]->dreg] = convert (ctx, values [cfg->args [i + sig->hasthis]->dreg], llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->params [i])));
763 for (i = 0; i < sig->param_count; ++i)
764 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
767 has_terminator = FALSE;
768 for (ins = bb->code; ins; ins = ins->next) {
769 const char *spec = LLVM_INS_INFO (ins->opcode);
771 char dname_buf [128];
774 /* There could be instructions after a terminator, skip them */
777 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
778 sprintf (dname_buf, "t%d", ins->dreg);
782 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
783 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
785 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
786 lhs = LLVMBuildLoad (builder, addresses [ins->sreg1], get_tempname (ctx));
788 /* It is ok for SETRET to have an uninitialized argument */
789 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
790 LLVM_FAILURE (ctx, "sreg1");
791 lhs = values [ins->sreg1];
797 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
798 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
799 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
800 rhs = LLVMBuildLoad (builder, addresses [ins->sreg2], get_tempname (ctx));
802 if (!values [ins->sreg2])
803 LLVM_FAILURE (ctx, "sreg2");
804 rhs = values [ins->sreg2];
810 //mono_print_ins (ins);
811 switch (ins->opcode) {
814 case OP_LIVERANGE_START:
815 case OP_LIVERANGE_END:
818 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
821 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
824 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
827 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
830 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
831 has_terminator = TRUE;
837 LLVMBasicBlockRef new_bb;
838 LLVMBuilderRef new_builder;
840 // The default branch is already handled
841 // FIXME: Handle it here
843 /* Start new bblock */
844 bb_name = g_strdup_printf ("SWITCH_DEFAULT_BB%d", ctx->default_index ++);
845 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
847 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
848 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
849 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
851 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
854 new_builder = LLVMCreateBuilder ();
855 LLVMPositionBuilderAtEnd (new_builder, new_bb);
856 LLVMBuildUnreachable (new_builder);
858 has_terminator = TRUE;
859 g_assert (!ins->next);
867 * The method did not set its return value, probably because it
871 LLVMBuildRetVoid (builder);
873 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
875 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
877 has_terminator = TRUE;
883 case OP_ICOMPARE_IMM:
884 case OP_LCOMPARE_IMM:
887 case OP_AMD64_ICOMPARE_MEMBASE_REG:
888 case OP_AMD64_ICOMPARE_MEMBASE_IMM:
894 if (ins->next->opcode == OP_NOP)
897 rel = mono_opcode_to_cond (ins->next->opcode);
899 /* Used for implementing bound checks */
901 if ((ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_REG) || (ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_IMM)) {
906 t = LLVMInt32Type ();
908 g_assert (ins->inst_offset % size == 0);
909 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
911 lhs = LLVMBuildLoad (builder, LLVMBuildGEP (builder, LLVMBuildIntToPtr (builder, values [ins->inst_basereg], LLVMPointerType (t, 0), get_tempname (ctx)), &index, 1, get_tempname (ctx)), get_tempname (ctx));
913 if (ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_IMM) {
914 lhs = convert (ctx, lhs, LLVMInt32Type ());
915 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
917 if (ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_REG)
918 rhs = convert (ctx, rhs, LLVMInt32Type ());
921 if (ins->opcode == OP_ICOMPARE_IMM) {
922 lhs = convert (ctx, lhs, LLVMInt32Type ());
923 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
925 if (ins->opcode == OP_LCOMPARE_IMM)
926 rhs = LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE);
927 if (ins->opcode == OP_ICOMPARE) {
928 lhs = convert (ctx, lhs, LLVMInt32Type ());
929 rhs = convert (ctx, rhs, LLVMInt32Type ());
932 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
933 if (ins->opcode == OP_FCOMPARE)
934 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), get_tempname (ctx));
935 else if (ins->opcode == OP_COMPARE_IMM)
936 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), get_tempname (ctx));
937 else if (ins->opcode == OP_COMPARE)
938 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), get_tempname (ctx));
940 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, get_tempname (ctx));
942 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
943 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
944 has_terminator = TRUE;
945 } else if (MONO_IS_SETCC (ins->next)) {
946 dname = g_strdup_printf ("t%d", ins->next->dreg);
947 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
948 } else if (MONO_IS_COND_EXC (ins->next)) {
949 //emit_cond_throw_pos (ctx);
950 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
951 builder = ctx->builder;
953 LLVM_FAILURE (ctx, "next");
967 rel = mono_opcode_to_cond (ins->opcode);
969 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], lhs, rhs, get_tempname (ctx));
970 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
977 /* Created earlier, insert it now */
978 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
980 /* Check that all input bblocks really branch to us */
981 for (i = 0; i < bb->in_count; ++i) {
982 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
983 ins->inst_phi_args [i + 1] = -1;
986 // FIXME: If a SWITCH statement branches to the same bblock in more
987 // than once case, the PHI should reference the bblock multiple times
988 for (i = 0; i < bb->in_count; ++i)
989 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
990 LLVM_FAILURE (ctx, "switch + phi");
994 for (i = 0; i < ins->inst_phi_args [0]; i++) {
995 int sreg1 = ins->inst_phi_args [i + 1];
996 LLVMBasicBlockRef in_bb;
1001 /* Add incoming values which are already defined */
1002 if (FALSE && values [sreg1]) {
1003 in_bb = get_end_bb (ctx, bb->in_bb [i]);
1005 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [ins->dreg]));
1006 LLVMAddIncoming (values [ins->dreg], &values [sreg1], &in_bb, 1);
1008 /* Remember for later */
1009 //LLVM_FAILURE (ctx, "phi incoming value");
1010 GSList *node_list = g_hash_table_lookup (phi_nodes, GUINT_TO_POINTER (bb->in_bb [i]));
1011 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
1015 node_list = g_slist_prepend_mempool (ctx->mempool, node_list, node);
1016 g_hash_table_insert (phi_nodes, GUINT_TO_POINTER (bb->in_bb [i]), node_list);
1024 values [ins->dreg] = lhs;
1056 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
1057 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
1059 switch (ins->opcode) {
1063 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
1068 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
1073 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
1077 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
1081 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
1085 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
1089 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
1092 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
1096 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
1100 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
1104 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
1108 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
1112 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
1116 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
1119 g_assert_not_reached ();
1127 case OP_IDIV_UN_IMM:
1133 case OP_ISHR_UN_IMM:
1142 case OP_LSHR_UN_IMM:
1149 if (spec [MONO_INST_SRC1] == 'l')
1150 imm = LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE);
1152 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
1153 imm = convert (ctx, imm, LLVMTypeOf (lhs));
1154 switch (ins->opcode) {
1158 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
1162 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
1166 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
1170 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
1172 case OP_IDIV_UN_IMM:
1173 case OP_LDIV_UN_IMM:
1174 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
1178 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
1183 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
1187 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
1191 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
1196 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
1200 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
1202 case OP_ISHR_UN_IMM:
1203 case OP_LSHR_UN_IMM:
1204 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
1207 g_assert_not_reached ();
1212 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
1215 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
1218 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
1221 guint32 v = 0xffffffff;
1222 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), lhs, dname);
1226 guint64 v = 0xffffffffffffffff;
1227 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
1231 LLVMValueRef v1, v2;
1233 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), get_tempname (ctx));
1234 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, get_tempname (ctx));
1235 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
1239 case OP_ICONV_TO_I1:
1240 case OP_ICONV_TO_I2:
1241 case OP_ICONV_TO_I4:
1242 case OP_ICONV_TO_U1:
1243 case OP_ICONV_TO_U2:
1244 case OP_ICONV_TO_U4:
1245 case OP_LCONV_TO_I1:
1246 case OP_LCONV_TO_I2:
1247 case OP_LCONV_TO_U1:
1248 case OP_LCONV_TO_U2:
1249 case OP_LCONV_TO_U4: {
1252 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);
1254 /* Have to do two casts since our vregs have type int */
1255 v = LLVMBuildTrunc (builder, lhs, conv_to_llvm_type (ins->opcode), get_tempname (ctx));
1257 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
1259 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
1262 case OP_FCONV_TO_I4:
1263 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
1265 case OP_FCONV_TO_I1:
1266 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), get_tempname (ctx));
1268 case OP_FCONV_TO_U1:
1269 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), get_tempname (ctx));
1271 case OP_FCONV_TO_I2:
1272 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), get_tempname (ctx));
1274 case OP_FCONV_TO_U2:
1275 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), get_tempname (ctx));
1277 case OP_FCONV_TO_I8:
1278 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
1281 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
1283 case OP_ICONV_TO_R8:
1284 case OP_LCONV_TO_R8:
1285 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
1287 case OP_LCONV_TO_R_UN:
1288 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
1290 case OP_ICONV_TO_R4:
1291 case OP_LCONV_TO_R4:
1292 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), get_tempname (ctx));
1293 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
1295 case OP_FCONV_TO_R4:
1296 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), get_tempname (ctx));
1297 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
1300 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
1303 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
1306 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
1308 case OP_LOCALLOC_IMM: {
1311 guint32 size = ins->inst_imm;
1312 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
1314 v = LLVMBuildArrayAlloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), get_tempname (ctx));
1316 if (ins->flags & MONO_INST_INIT) {
1317 LLVMValueRef args [4];
1320 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
1321 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
1322 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
1323 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memset.i32"), args, 4, "");
1326 values [ins->dreg] = LLVMBuildPtrToInt (builder, v, IntPtrType (), dname);
1329 case OP_LOADI1_MEMBASE:
1330 case OP_LOADU1_MEMBASE:
1331 case OP_LOADI2_MEMBASE:
1332 case OP_LOADU2_MEMBASE:
1333 case OP_LOADI4_MEMBASE:
1334 case OP_LOADU4_MEMBASE:
1335 case OP_LOADI8_MEMBASE:
1336 case OP_LOADR4_MEMBASE:
1337 case OP_LOADR8_MEMBASE:
1338 case OP_LOAD_MEMBASE:
1344 gboolean sext = FALSE, zext = FALSE;
1346 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
1349 dname = (char*)get_tempname (ctx);
1351 g_assert (ins->inst_offset % size == 0);
1352 if ((ins->opcode == OP_LOADI8_MEM) || (ins->opcode == OP_LOAD_MEM)) {
1353 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), LLVMPointerType (t, 0), get_tempname (ctx)), dname);
1354 } else if (ins->inst_offset == 0) {
1355 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, values [ins->inst_basereg], LLVMPointerType (t, 0), get_tempname (ctx)), dname);
1357 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1358 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildGEP (builder, LLVMBuildIntToPtr (builder, values [ins->inst_basereg], LLVMPointerType (t, 0), get_tempname (ctx)), &index, 1, get_tempname (ctx)), dname);
1361 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
1363 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
1364 else if (ins->opcode == OP_LOADR4_MEMBASE)
1365 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
1369 case OP_STOREI1_MEMBASE_REG:
1370 case OP_STOREI2_MEMBASE_REG:
1371 case OP_STOREI4_MEMBASE_REG:
1372 case OP_STOREI8_MEMBASE_REG:
1373 case OP_STORER4_MEMBASE_REG:
1374 case OP_STORER8_MEMBASE_REG:
1375 case OP_STORE_MEMBASE_REG: {
1379 gboolean sext = FALSE, zext = FALSE;
1381 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
1383 g_assert (ins->inst_offset % size == 0);
1384 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1385 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], t), LLVMBuildGEP (builder, LLVMBuildIntToPtr (builder, values [ins->inst_destbasereg], LLVMPointerType (t, 0), get_tempname (ctx)), &index, 1, get_tempname (ctx)));
1389 case OP_STOREI1_MEMBASE_IMM:
1390 case OP_STOREI2_MEMBASE_IMM:
1391 case OP_STOREI4_MEMBASE_IMM:
1392 case OP_STOREI8_MEMBASE_IMM:
1393 case OP_STORE_MEMBASE_IMM: {
1397 gboolean sext = FALSE, zext = FALSE;
1399 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
1401 g_assert (ins->inst_offset % size == 0);
1402 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1403 LLVMBuildStore (builder, convert (ctx, LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE), t), LLVMBuildGEP (builder, LLVMBuildIntToPtr (builder, values [ins->inst_destbasereg], LLVMPointerType (t, 0), get_tempname (ctx)), &index, 1, get_tempname (ctx)));
1407 LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, values [ins->sreg1], LLVMPointerType (IntPtrType (), 0), get_tempname (ctx)), get_tempname (ctx));
1409 case OP_OUTARG_VTRETADDR:
1416 case OP_VOIDCALL_MEMBASE:
1417 case OP_CALL_MEMBASE:
1418 case OP_LCALL_MEMBASE:
1419 case OP_FCALL_MEMBASE:
1420 case OP_VCALL_MEMBASE: {
1421 MonoCallInst *call = (MonoCallInst*)ins;
1422 MonoMethodSignature *sig = call->signature;
1423 LLVMValueRef callee;
1428 LLVMTypeRef llvm_sig;
1431 vretaddr = call->vret_var != NULL;
1433 llvm_sig = sig_to_llvm_sig (ctx, sig, vretaddr);
1434 CHECK_FAILURE (ctx);
1436 if (call->rgctx_reg) {
1437 LLVM_FAILURE (ctx, "rgctx reg");
1440 /* FIXME: Avoid creating duplicate methods */
1442 if (ins->flags & MONO_INST_HAS_METHOD) {
1443 callee = LLVMAddFunction (module, "", llvm_sig);
1446 mono_create_jit_trampoline_in_domain (mono_domain_get (),
1448 LLVMAddGlobalMapping (ee, callee, target);
1450 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
1452 callee = LLVMAddFunction (module, "", llvm_sig);
1457 memset (&ji, 0, sizeof (ji));
1458 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
1459 ji.data.target = info->name;
1461 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1462 LLVMAddGlobalMapping (ee, callee, target);
1465 if (cfg->abs_patches) {
1466 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1468 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
1469 LLVMAddGlobalMapping (ee, callee, target);
1473 LLVMAddGlobalMapping (ee, callee, (gpointer)call->fptr);
1477 if (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) {
1478 int size = sizeof (gpointer);
1481 g_assert (ins->inst_offset % size == 0);
1482 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1484 callee = LLVMBuildIntToPtr (builder, LLVMBuildLoad (builder, LLVMBuildGEP (builder, LLVMBuildIntToPtr (builder, values [ins->inst_basereg], LLVMPointerType (IntPtrType (), 0), get_tempname (ctx)), &index, 1, get_tempname (ctx)), get_tempname (ctx)), LLVMPointerType (llvm_sig, 0), get_tempname (ctx));
1486 // FIXME: mono_arch_get_vcall_slot () can't decode the code
1487 // generated by LLVM
1488 //LLVM_FAILURE (ctx, "virtual call");
1490 if (call->method && call->method->klass->flags & TYPE_ATTRIBUTE_INTERFACE)
1491 /* No support for passing the IMT argument */
1492 LLVM_FAILURE (ctx, "imt");
1494 if (ins->flags & MONO_INST_HAS_METHOD) {
1498 /* Collect and convert arguments */
1499 args = alloca (sizeof (LLVMValueRef) * (sig->param_count + sig->hasthis + vretaddr));
1500 l = call->out_ireg_args;
1503 MonoInst *var = call->vret_var->inst_p0;
1505 g_assert (addresses [var->dreg]);
1506 args [pindex ++] = LLVMBuildPtrToInt (builder, addresses [var->dreg], IntPtrType (), get_tempname (ctx));
1509 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
1513 regpair = (guint32)(gssize)(l->data);
1514 reg = regpair & 0xffffff;
1515 args [pindex] = values [reg];
1518 LLVM_FAILURE (ctx, "vtype arg");
1519 g_assert (args [pindex]);
1520 if (i == 0 && sig->hasthis)
1521 args [pindex] = convert (ctx, args [pindex], IntPtrType ());
1523 args [pindex] = convert (ctx, args [pindex], type_to_llvm_type (ctx, sig->params [i - sig->hasthis]));
1529 // FIXME: Align call sites
1531 if (sig->ret->type != MONO_TYPE_VOID && !vretaddr)
1532 /* FIXME: Convert res */
1533 values [ins->dreg] = convert (ctx, LLVMBuildCall (builder, callee, args, pindex, dname), llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->ret)));
1535 LLVMBuildCall (builder, callee, args, pindex, "");
1538 case OP_GOT_ENTRY: {
1539 LLVMValueRef indexes [2];
1541 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1542 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)ins->inst_p0, FALSE);
1543 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->got_var, indexes, 2, get_tempname (ctx)), dname);
1547 MonoMethodSignature *throw_sig;
1548 LLVMValueRef callee;
1550 throw_sig = mono_metadata_signature_alloc (mono_defaults.corlib, 1);
1551 throw_sig->ret = &mono_defaults.void_class->byval_arg;
1552 throw_sig->params [0] = &mono_defaults.int_class->byval_arg;
1553 // FIXME: Prevent duplicates
1554 callee = LLVMAddFunction (module, "mono_arch_throw_exception", sig_to_llvm_sig (ctx, throw_sig, FALSE));
1555 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_arch_throw_exception"));
1556 LLVMBuildCall (builder, callee, &values [ins->sreg1], 1, "");
1559 case OP_NOT_REACHED:
1560 LLVMBuildUnreachable (builder);
1561 has_terminator = TRUE;
1562 /* Might have instructions after this */
1564 MonoInst *next = ins->next;
1565 MONO_DELETE_INS (bb, next);
1569 MonoInst *var = ins->inst_p0;
1571 values [ins->dreg] = LLVMBuildPtrToInt (builder, addresses [var->dreg], IntPtrType (), dname);
1575 LLVMValueRef args [1];
1578 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
1582 LLVMValueRef args [1];
1585 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
1589 LLVMValueRef args [1];
1592 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
1598 LLVMValueRef v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, get_tempname (ctx));
1599 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
1604 LLVMValueRef v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, get_tempname (ctx));
1605 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
1610 LLVMValueRef v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, get_tempname (ctx));
1611 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
1616 LLVMValueRef v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, get_tempname (ctx));
1617 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
1620 case OP_ATOMIC_EXCHANGE_I4: {
1621 LLVMValueRef args [2];
1623 g_assert (ins->inst_offset == 0);
1625 args [0] = LLVMBuildIntToPtr (builder, lhs, LLVMPointerType (LLVMInt32Type (), 0), get_tempname (ctx));
1627 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.swap.i32.p0i32"), args, 2, dname);
1630 case OP_ATOMIC_EXCHANGE_I8: {
1631 LLVMValueRef args [2];
1633 g_assert (ins->inst_offset == 0);
1635 args [0] = LLVMBuildIntToPtr (builder, lhs, LLVMPointerType (LLVMInt64Type (), 0), get_tempname (ctx));
1637 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.swap.i64.p0i64"), args, 2, dname);
1640 case OP_ATOMIC_ADD_NEW_I4: {
1641 LLVMValueRef args [2];
1643 g_assert (ins->inst_offset == 0);
1645 args [0] = LLVMBuildIntToPtr (builder, lhs, LLVMPointerType (LLVMInt32Type (), 0), get_tempname (ctx));
1647 values [ins->dreg] = LLVMBuildAdd (builder, LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.load.add.i32.p0i32"), args, 2, get_tempname (ctx)), args [1], dname);
1650 case OP_ATOMIC_ADD_NEW_I8: {
1651 LLVMValueRef args [2];
1653 g_assert (ins->inst_offset == 0);
1655 args [0] = LLVMBuildIntToPtr (builder, lhs, LLVMPointerType (LLVMInt64Type (), 0), get_tempname (ctx));
1656 args [1] = convert (ctx, rhs, LLVMInt64Type ());
1657 values [ins->dreg] = LLVMBuildAdd (builder, LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.load.add.i64.p0i64"), args, 2, get_tempname (ctx)), args [1], dname);
1661 case OP_ATOMIC_CAS_IMM_I4: {
1662 LLVMValueRef args [3];
1664 args [0] = LLVMBuildIntToPtr (builder, lhs, LLVMPointerType (LLVMInt32Type (), 0), get_tempname (ctx));
1666 args [1] = LLVMConstInt (LLVMInt32Type (), GPOINTER_TO_INT (ins->backend.data), FALSE);
1669 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.cmp.swap.i32.p0i32"), args, 3, dname);
1673 case OP_MEMORY_BARRIER: {
1674 LLVMValueRef args [5];
1676 for (i = 0; i < 5; ++i)
1677 args [i] = LLVMConstInt (LLVMInt1Type (), TRUE, TRUE);
1679 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memory.barrier"), args, 5, "");
1686 // FIXME: LLVM can't handle mul_ovf_un yet
1688 case OP_IADD_OVF_UN:
1690 case OP_ISUB_OVF_UN:
1692 //case OP_IMUL_OVF_UN:
1695 case OP_LSUB_OVF_UN:
1697 //case OP_LMUL_OVF_UN: {
1698 LLVMValueRef args [2], val, ovf, func;
1700 emit_cond_throw_pos (ctx);
1704 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
1706 val = LLVMBuildCall (builder, func, args, 2, "");
1707 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
1708 ovf = LLVMBuildExtractValue (builder, val, 1, get_tempname (ctx));
1709 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
1710 builder = ctx->builder;
1716 * We currently model them using arrays. Promotion to local vregs is
1717 * disabled for them in mono_handle_global_vregs () in the LLVM case,
1718 * so we always have an entry in cfg->varinfo for them.
1719 * FIXME: Is this needed ?
1722 MonoClass *klass = ins->klass;
1723 LLVMValueRef args [4];
1727 LLVM_FAILURE (ctx, "!klass");
1731 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), get_tempname (ctx));
1732 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
1733 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
1735 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1736 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memset.i32"), args, 4, "");
1740 case OP_STOREV_MEMBASE:
1741 case OP_LOADV_MEMBASE:
1743 MonoClass *klass = ins->klass;
1744 LLVMValueRef src, dst, args [4];
1748 LLVM_FAILURE (ctx, "!klass");
1752 switch (ins->opcode) {
1753 case OP_STOREV_MEMBASE:
1754 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), get_tempname (ctx));
1755 dst = LLVMBuildIntToPtr (builder, LLVMBuildAdd (builder, values [ins->inst_destbasereg], LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), get_tempname (ctx)), LLVMPointerType (LLVMInt8Type (), 0), get_tempname (ctx));
1757 case OP_LOADV_MEMBASE:
1758 if (!addresses [ins->dreg])
1759 addresses [ins->dreg] = LLVMBuildAlloca (builder, type_to_llvm_type (ctx, &klass->byval_arg), get_tempname (ctx));
1760 src = LLVMBuildIntToPtr (builder, LLVMBuildAdd (builder, values [ins->inst_basereg], LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), get_tempname (ctx)), LLVMPointerType (LLVMInt8Type (), 0), get_tempname (ctx));
1761 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), get_tempname (ctx));
1764 if (!addresses [ins->dreg])
1765 addresses [ins->dreg] = LLVMBuildAlloca (builder, type_to_llvm_type (ctx, &klass->byval_arg), get_tempname (ctx));
1766 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), get_tempname (ctx));
1767 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), get_tempname (ctx));
1770 g_assert_not_reached ();
1775 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
1776 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1778 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1779 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memcpy.i32"), args, 4, "");
1784 char *reason = g_strdup_printf ("opcode %s", mono_inst_name (ins->opcode));
1785 LLVM_FAILURE (ctx, reason);
1790 /* Convert the value to the type required by phi nodes */
1791 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && vreg_types [ins->dreg])
1792 values [ins->dreg] = convert (ctx, values [ins->dreg], vreg_types [ins->dreg]);
1794 /* Add stores for volatile variables */
1795 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
1796 emit_volatile_store (ctx, ins->dreg);
1799 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
1800 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
1802 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
1803 LLVMBuildRetVoid (builder);
1806 /* Add incoming phi values */
1807 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1808 GSList *ins_list = g_hash_table_lookup (phi_nodes, GUINT_TO_POINTER (bb));
1811 PhiNode *node = ins_list->data;
1812 MonoInst *phi = node->phi;
1813 int sreg1 = phi->inst_phi_args [node->index + 1];
1814 LLVMBasicBlockRef in_bb;
1816 in_bb = get_end_bb (ctx, node->bb->in_bb [node->index]);
1818 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
1819 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
1821 ins_list = ins_list->next;
1826 LLVMDumpValue (method);
1828 //if (strstr (cfg->method->name, "test_0_ldfld_stfld_soft_float_remote"))
1829 //LLVMDumpValue (method);
1831 cfg->native_code = LLVMGetPointerToGlobal (ee, method);
1833 /* Set by emit_cb */
1834 g_assert (cfg->code_len);
1841 /* Need to add unused phi nodes as they can be referenced by other values */
1842 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
1843 LLVMBuilderRef builder;
1845 builder = LLVMCreateBuilder ();
1846 LLVMPositionBuilderAtEnd (builder, phi_bb);
1848 for (i = 0; i < phi_values->len; ++i) {
1849 LLVMValueRef v = g_ptr_array_index (phi_values, i);
1850 if (LLVMGetInstructionParent (v) == NULL)
1851 LLVMInsertIntoBuilder (builder, v);
1854 LLVMDeleteFunction (method);
1860 g_free (vreg_types);
1861 g_hash_table_destroy (phi_nodes);
1862 g_ptr_array_free (phi_values, TRUE);
1863 g_free (ctx->bblocks);
1864 g_free (ctx->end_bblocks);
1868 TlsSetValue (current_cfg_tls_id, NULL);
1870 mono_loader_unlock ();
1873 static unsigned char*
1874 alloc_cb (LLVMValueRef function, int size)
1878 cfg = TlsGetValue (current_cfg_tls_id);
1882 return mono_domain_code_reserve (cfg->domain, size);
1884 return mono_domain_code_reserve (mono_domain_get (), size);
1889 emitted_cb (LLVMValueRef function, void *start, void *end)
1893 cfg = TlsGetValue (current_cfg_tls_id);
1895 cfg->code_len = (guint8*)end - (guint8*)start;
1899 exception_cb (void *data)
1903 cfg = TlsGetValue (current_cfg_tls_id);
1907 * data points to a DWARF FDE structure, convert it to our unwind format and
1909 * An alternative would be to save it directly, and modify our unwinder to work
1912 cfg->encoded_unwind_ops = mono_unwind_get_ops_from_fde ((guint8*)data, &cfg->encoded_unwind_ops_len);
1916 mono_llvm_init (void)
1918 current_cfg_tls_id = TlsAlloc ();
1920 module = LLVMModuleCreateWithName ("mono");
1922 ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module), alloc_cb, emitted_cb, exception_cb);
1924 llvm_types = g_hash_table_new (NULL, NULL);
1926 /* Emit declarations of instrinsics */
1928 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type () };
1930 LLVMAddFunction (module, "llvm.memset.i32", LLVMFunctionType (LLVMVoidType (), memset_params, 4, FALSE));
1934 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type () };
1936 LLVMAddFunction (module, "llvm.memcpy.i32", LLVMFunctionType (LLVMVoidType (), memcpy_params, 4, FALSE));
1940 LLVMTypeRef params [] = { LLVMDoubleType () };
1942 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
1943 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
1944 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
1948 LLVMTypeRef membar_params [] = { LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type () };
1950 LLVMAddFunction (module, "llvm.atomic.swap.i32.p0i32", LLVMFunctionType2 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), FALSE));
1951 LLVMAddFunction (module, "llvm.atomic.swap.i64.p0i64", LLVMFunctionType2 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), FALSE));
1952 LLVMAddFunction (module, "llvm.atomic.load.add.i32.p0i32", LLVMFunctionType2 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), FALSE));
1953 LLVMAddFunction (module, "llvm.atomic.load.add.i64.p0i64", LLVMFunctionType2 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), FALSE));
1954 LLVMAddFunction (module, "llvm.atomic.cmp.swap.i32.p0i32", LLVMFunctionType3 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), LLVMInt32Type (), FALSE));
1955 LLVMAddFunction (module, "llvm.memory.barrier", LLVMFunctionType (LLVMVoidType (), membar_params, 5, FALSE));
1959 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
1960 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
1962 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
1963 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
1964 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
1965 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
1966 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
1967 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
1971 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
1972 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
1974 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
1975 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
1976 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
1977 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
1978 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
1979 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
1985 - Emit LLVM IR from the mono IR using the LLVM C API.
1986 - The original arch specific code remains, so we can fall back to it if we run
1987 into something we can't handle.
1989 - llvm's PrettyStackTrace class seems to register a signal handler which screws
1990 up our GC. Also, it calls sigaction () a _lot_ of times instead of just once.
1994 A partial list of issues:
1995 - Handling of opcodes which can throw exceptions.
1997 In the mono JIT, these are implemented using code like this:
2004 push throw_pos - method
2005 call <exception trampoline>
2007 The problematic part is push throw_pos - method, which cannot be represented
2008 in the LLVM IR, since it does not support label values.
2009 -> this can be implemented in AOT mode using inline asm + labels, but cannot
2010 be implemented in JIT mode ?
2011 -> a possible but slower implementation would use the normal exception
2012 throwing code but it would need to control the placement of the throw code
2013 (it needs to be exactly after the compare+branch).
2014 -> perhaps add a PC offset intrinsics ?
2016 - efficient implementation of .ovf opcodes.
2018 These are currently implemented as:
2019 <ins which sets the condition codes>
2022 Some overflow opcodes are now supported by LLVM SVN.
2024 - exception handling, unwinding.
2025 - SSA is disabled for methods with exception handlers
2026 - How to obtain unwind info for LLVM compiled methods ?
2027 -> this is now solved by converting the unwind info generated by LLVM
2029 - LLVM uses the c++ exception handling framework, while we use our home grown
2030 code, and couldn't use the c++ one:
2031 - its not supported under VC++, other exotic platforms.
2032 - it might be impossible to support filter clauses with it.
2036 The trampolines need a predictable call sequence, since they need to disasm
2037 the calling code to obtain register numbers / offsets.
2039 LLVM currently generates this code in non-JIT mode:
2040 mov -0x98(%rax),%eax
2042 Here, the vtable pointer is lost.
2043 -> solution: use one vtable trampoline per class.
2045 - passing/receiving the IMT pointer/RGCTX.
2046 -> solution: pass them as normal arguments ?
2050 LLVM does not allow the specification of argument registers etc. This means
2051 that all calls are made according to the platform ABI.
2055 Supported though alloca, we need to emit the load/store code.
2059 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
2060 typed registers, so we have to keep track of the precise LLVM type of each vreg.
2061 This is made easier because the IR is already in SSA form.
2062 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
2063 types are frequently used incorrectly.
2066 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
2067 * - each bblock should end with a branch
2068 * - setting the return value, making cfg->ret non-volatile
2069 * - merge some changes back to HEAD, to reduce the differences.
2070 * - avoid some transformations in the JIT which make it harder for us to generate
2072 * - fix memory leaks.
2073 * - use pointer types to help optimizations.