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 LLVMPointerType (IntPtrType (), 0);
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;
191 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
193 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
195 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
197 * LLVM generates code which only sets the lower bits, while JITted
198 * code expects all the bits to be set.
200 ptype = LLVMInt32Type ();
206 static G_GNUC_UNUSED LLVMTypeRef
207 llvm_type_to_stack_type (LLVMTypeRef type)
211 if (type == LLVMInt8Type ())
212 return LLVMInt32Type ();
213 else if (type == LLVMInt16Type ())
214 return LLVMInt32Type ();
215 else if (type == LLVMFloatType ())
216 return LLVMDoubleType ();
222 regtype_to_llvm_type (char c)
226 return LLVMInt32Type ();
228 return LLVMInt64Type ();
230 return LLVMDoubleType ();
237 conv_to_llvm_type (int opcode)
242 return LLVMInt8Type ();
245 return LLVMInt8Type ();
248 return LLVMInt16Type ();
251 return LLVMInt16Type ();
254 return LLVMInt32Type ();
257 return LLVMInt32Type ();
259 return LLVMInt64Type ();
261 return LLVMFloatType ();
263 return LLVMDoubleType ();
265 return LLVMInt64Type ();
267 return LLVMInt32Type ();
269 return LLVMInt64Type ();
272 return LLVMInt8Type ();
275 return LLVMInt16Type ();
278 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
280 printf ("%s\n", mono_inst_name (opcode));
281 g_assert_not_reached ();
287 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
293 case OP_LOADI1_MEMBASE:
294 case OP_STOREI1_MEMBASE_REG:
295 case OP_STOREI1_MEMBASE_IMM:
298 return LLVMInt8Type ();
299 case OP_LOADU1_MEMBASE:
302 return LLVMInt8Type ();
303 case OP_LOADI2_MEMBASE:
304 case OP_STOREI2_MEMBASE_REG:
305 case OP_STOREI2_MEMBASE_IMM:
308 return LLVMInt16Type ();
309 case OP_LOADU2_MEMBASE:
312 return LLVMInt16Type ();
313 case OP_LOADI4_MEMBASE:
314 case OP_LOADU4_MEMBASE:
315 case OP_STOREI4_MEMBASE_REG:
316 case OP_STOREI4_MEMBASE_IMM:
318 return LLVMInt32Type ();
319 case OP_LOADI8_MEMBASE:
321 case OP_STOREI8_MEMBASE_REG:
322 case OP_STOREI8_MEMBASE_IMM:
324 return LLVMInt64Type ();
325 case OP_LOADR4_MEMBASE:
326 case OP_STORER4_MEMBASE_REG:
328 return LLVMFloatType ();
329 case OP_LOADR8_MEMBASE:
330 case OP_STORER8_MEMBASE_REG:
332 return LLVMDoubleType ();
333 case OP_LOAD_MEMBASE:
335 case OP_STORE_MEMBASE_REG:
336 case OP_STORE_MEMBASE_IMM:
337 *size = sizeof (gpointer);
338 return IntPtrType ();
340 g_assert_not_reached ();
346 ovf_op_to_intrins (int opcode)
350 return "llvm.sadd.with.overflow.i32";
352 return "llvm.uadd.with.overflow.i32";
354 return "llvm.ssub.with.overflow.i32";
356 return "llvm.usub.with.overflow.i32";
358 return "llvm.smul.with.overflow.i32";
360 return "llvm.umul.with.overflow.i32";
362 return "llvm.sadd.with.overflow.i64";
364 return "llvm.uadd.with.overflow.i64";
366 return "llvm.ssub.with.overflow.i64";
368 return "llvm.usub.with.overflow.i64";
370 return "llvm.smul.with.overflow.i64";
372 return "llvm.umul.with.overflow.i64";
374 g_assert_not_reached ();
379 static LLVMBasicBlockRef
380 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
384 if (ctx->bblocks [bb->block_num] == NULL) {
385 sprintf (bb_name, "BB%d", bb->block_num);
387 ctx->bblocks [bb->block_num] = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
388 ctx->end_bblocks [bb->block_num] = ctx->bblocks [bb->block_num];
391 return ctx->bblocks [bb->block_num];
394 /* Return the last LLVM bblock corresponding to BB */
395 static LLVMBasicBlockRef
396 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
399 return ctx->end_bblocks [bb->block_num];
403 get_tempname (EmitContext *ctx)
406 static char temp_name [128];
408 sprintf (temp_name, "s%d", ctx->sindex ++);
414 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
418 memset (&ji, 0, sizeof (ji));
420 ji.data.target = target;
422 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
426 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
428 LLVMTypeRef stype = LLVMTypeOf (v);
430 if (stype != dtype) {
432 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
433 return LLVMBuildSExt (ctx->builder, v, dtype, get_tempname (ctx));
434 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
435 return LLVMBuildSExt (ctx->builder, v, dtype, get_tempname (ctx));
436 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
437 return LLVMBuildSExt (ctx->builder, v, dtype, get_tempname (ctx));
438 else if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
439 return LLVMBuildFPExt (ctx->builder, v, dtype, get_tempname (ctx));
442 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
443 return LLVMBuildTrunc (ctx->builder, v, dtype, get_tempname (ctx));
444 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
445 return LLVMBuildTrunc (ctx->builder, v, dtype, get_tempname (ctx));
446 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
447 return LLVMBuildFPTrunc (ctx->builder, v, dtype, get_tempname (ctx));
449 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
450 return LLVMBuildBitCast (ctx->builder, v, dtype, get_tempname (ctx));
451 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
452 return LLVMBuildIntToPtr (ctx->builder, v, dtype, get_tempname (ctx));
453 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
454 return LLVMBuildPtrToInt (ctx->builder, v, dtype, get_tempname (ctx));
457 LLVMDumpValue (LLVMConstNull (dtype));
458 g_assert_not_reached ();
465 /* Emit stores for volatile variables */
467 emit_volatile_store (EmitContext *ctx, int vreg)
469 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
471 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
472 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
477 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig, gboolean vretaddr)
479 LLVMTypeRef ret_type;
480 LLVMTypeRef *param_types = NULL;
484 ret_type = type_to_llvm_type (ctx, sig->ret);
487 if (MONO_TYPE_ISSTRUCT (sig->ret) && !vretaddr)
488 LLVM_FAILURE (ctx, "vtype ret");
490 param_types = g_new0 (LLVMTypeRef, sig->param_count + sig->hasthis + vretaddr);
493 ret_type = LLVMVoidType ();
494 param_types [pindex ++] = IntPtrType ();
497 param_types [pindex ++] = IntPtrType ();
498 for (i = 0; i < sig->param_count; ++i) {
499 if (MONO_TYPE_ISSTRUCT (sig->params [i]))
500 LLVM_FAILURE (ctx, "vtype param");
501 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
505 res = LLVMFunctionType (ret_type, param_types, sig->param_count + sig->hasthis + vretaddr, FALSE);
506 g_free (param_types);
511 g_free (param_types);
516 static G_GNUC_UNUSED LLVMTypeRef
517 LLVMFunctionType1(LLVMTypeRef ReturnType,
518 LLVMTypeRef ParamType1,
521 LLVMTypeRef param_types [1];
523 param_types [0] = ParamType1;
525 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
529 LLVMFunctionType2(LLVMTypeRef ReturnType,
530 LLVMTypeRef ParamType1,
531 LLVMTypeRef ParamType2,
534 LLVMTypeRef param_types [2];
536 param_types [0] = ParamType1;
537 param_types [1] = ParamType2;
539 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
543 LLVMFunctionType3(LLVMTypeRef ReturnType,
544 LLVMTypeRef ParamType1,
545 LLVMTypeRef ParamType2,
546 LLVMTypeRef ParamType3,
549 LLVMTypeRef param_types [3];
551 param_types [0] = ParamType1;
552 param_types [1] = ParamType2;
553 param_types [2] = ParamType3;
555 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
559 emit_cond_throw_pos (EmitContext *ctx)
564 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
567 LLVMBasicBlockRef ex_bb, noex_bb;
568 LLVMBuilderRef builder;
569 MonoClass *exc_class;
570 static LLVMValueRef throw;
572 sprintf (bb_name, "EX_BB%d", ctx->ex_index);
573 ex_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
575 sprintf (bb_name, "NOEX_BB%d", ctx->ex_index);
576 noex_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
578 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
580 ctx->builder = LLVMCreateBuilder ();
581 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
583 ctx->end_bblocks [bb->block_num] = noex_bb;
585 exc_class = mono_class_from_name (mono_defaults.corlib, "System", exc_type);
586 g_assert (exc_class);
588 /* Emit exception throwing code */
589 builder = LLVMCreateBuilder ();
590 LLVMPositionBuilderAtEnd (builder, ex_bb);
594 throw = LLVMAddFunction (module, "throw", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
596 LLVMAddGlobalMapping (ee, throw, &abort);
599 LLVMBuildCall (builder, throw, NULL, 0, "");
601 LLVMBuildUnreachable (builder);
607 mono_llvm_emit_method (MonoCompile *cfg)
610 MonoMethodSignature *sig;
612 LLVMTypeRef method_type;
613 LLVMValueRef method = NULL;
615 LLVMValueRef *values, *addresses;
616 LLVMTypeRef *vreg_types;
617 int i, max_block_num;
618 GHashTable *phi_nodes;
619 gboolean last = FALSE;
620 GPtrArray *phi_values;
622 /* The code below might acquire the loader lock, so use it for global locking */
628 /* Used to communicate with the callbacks */
629 TlsSetValue (current_cfg_tls_id, cfg);
631 ctx = g_new0 (EmitContext, 1);
633 ctx->mempool = cfg->mempool;
635 values = g_new0 (LLVMValueRef, cfg->next_vreg);
636 addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
637 vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
638 phi_nodes = g_hash_table_new (NULL, NULL);
639 phi_values = g_ptr_array_new ();
641 ctx->values = values;
642 ctx->addresses = addresses;
646 static int count = 0;
649 if (getenv ("LLVM_COUNT")) {
650 if (count == atoi (getenv ("LLVM_COUNT"))) {
651 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
654 if (count > atoi (getenv ("LLVM_COUNT")))
655 LLVM_FAILURE (ctx, "");
660 sig = mono_method_signature (cfg->method);
662 method_type = sig_to_llvm_sig (ctx, sig, cfg->vret_addr != NULL);
665 method_name = mono_method_full_name (cfg->method, TRUE);
666 method = LLVMAddFunction (module, method_name, method_type);
667 ctx->lmethod = method;
668 g_free (method_name);
670 if (cfg->method->save_lmf)
671 LLVM_FAILURE (ctx, "lmf");
673 if (cfg->vret_addr) {
674 values [cfg->vret_addr->dreg] = LLVMGetParam (method, 0);
675 for (i = 0; i < sig->param_count + sig->hasthis; ++i)
676 values [cfg->args [i]->dreg] = LLVMGetParam (method, i + 1);
678 for (i = 0; i < sig->param_count + sig->hasthis; ++i)
679 values [cfg->args [i]->dreg] = LLVMGetParam (method, i);
683 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
684 max_block_num = MAX (max_block_num, bb->block_num);
685 ctx->bblocks = g_new0 (LLVMBasicBlockRef, max_block_num + 1);
686 ctx->end_bblocks = g_new0 (LLVMBasicBlockRef, max_block_num + 1);
688 /* Add branches between non-consecutive bblocks */
689 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
690 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
691 bb->next_bb != bb->last_ins->inst_false_bb) {
693 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
694 inst->opcode = OP_BR;
695 inst->inst_target_bb = bb->last_ins->inst_false_bb;
696 mono_bblock_add_inst (bb, inst);
701 * Make a first pass over the code in dfn order to obtain the exact type of all
702 * vregs, and to create PHI nodes.
703 * This is needed because we only use iregs/fregs, while llvm uses many types,
704 * and requires precise types. Also, our IR is not precise in many places, like
705 * using i32 arguments to opcodes expecting an i64 etc.
707 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
709 LLVMBuilderRef builder;
713 builder = LLVMCreateBuilder ();
715 for (ins = bb->code; ins; ins = ins->next) {
716 switch (ins->opcode) {
719 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
724 * Have to precreate these, as they can be referenced by
725 * earlier instructions.
727 sprintf (dname_buf, "t%d", ins->dreg);
729 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
731 g_ptr_array_add (phi_values, values [ins->dreg]);
734 * Set the expected type of the incoming arguments since these have
735 * to have the same type.
737 for (i = 0; i < ins->inst_phi_args [0]; i++) {
738 int sreg1 = ins->inst_phi_args [i + 1];
741 vreg_types [sreg1] = phi_type;
752 * Second pass: generate code.
754 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
756 LLVMBasicBlockRef cbb;
757 LLVMBuilderRef builder;
758 gboolean has_terminator;
760 LLVMValueRef lhs, rhs;
762 if (!(bb == cfg->bb_entry || bb->in_count > 0))
765 cbb = get_bb (ctx, bb);
766 builder = LLVMCreateBuilder ();
767 ctx->builder = builder;
768 LLVMPositionBuilderAtEnd (builder, cbb);
770 if (bb == cfg->bb_entry) {
772 * Handle indirect/volatile variables by allocating memory for them
773 * using 'alloca', and storing their address in a temporary.
775 for (i = 0; i < cfg->num_varinfo; ++i) {
776 MonoInst *var = cfg->varinfo [i];
779 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || MONO_TYPE_ISSTRUCT (var->inst_vtype)) {
780 vtype = type_to_llvm_type (ctx, var->inst_vtype);
782 addresses [var->dreg] = LLVMBuildAlloca (builder, vtype, get_tempname (ctx));
786 /* Convert arguments */
787 for (i = 0; i < sig->param_count; ++i)
788 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])));
790 for (i = 0; i < sig->param_count; ++i)
791 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
794 has_terminator = FALSE;
795 for (ins = bb->code; ins; ins = ins->next) {
796 const char *spec = LLVM_INS_INFO (ins->opcode);
798 char dname_buf [128];
801 /* There could be instructions after a terminator, skip them */
804 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
805 sprintf (dname_buf, "t%d", ins->dreg);
809 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
810 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
812 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
813 lhs = LLVMBuildLoad (builder, addresses [ins->sreg1], get_tempname (ctx));
815 /* It is ok for SETRET to have an uninitialized argument */
816 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
817 LLVM_FAILURE (ctx, "sreg1");
818 lhs = values [ins->sreg1];
824 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
825 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
826 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
827 rhs = LLVMBuildLoad (builder, addresses [ins->sreg2], get_tempname (ctx));
829 if (!values [ins->sreg2])
830 LLVM_FAILURE (ctx, "sreg2");
831 rhs = values [ins->sreg2];
837 //mono_print_ins (ins);
838 switch (ins->opcode) {
841 case OP_LIVERANGE_START:
842 case OP_LIVERANGE_END:
845 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
848 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
851 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
854 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
857 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
858 has_terminator = TRUE;
864 LLVMBasicBlockRef new_bb;
865 LLVMBuilderRef new_builder;
867 // The default branch is already handled
868 // FIXME: Handle it here
870 /* Start new bblock */
871 bb_name = g_strdup_printf ("SWITCH_DEFAULT_BB%d", ctx->default_index ++);
872 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
874 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
875 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
876 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
878 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
881 new_builder = LLVMCreateBuilder ();
882 LLVMPositionBuilderAtEnd (new_builder, new_bb);
883 LLVMBuildUnreachable (new_builder);
885 has_terminator = TRUE;
886 g_assert (!ins->next);
894 * The method did not set its return value, probably because it
898 LLVMBuildRetVoid (builder);
900 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
902 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
904 has_terminator = TRUE;
910 case OP_ICOMPARE_IMM:
911 case OP_LCOMPARE_IMM:
914 case OP_AMD64_ICOMPARE_MEMBASE_REG:
915 case OP_AMD64_ICOMPARE_MEMBASE_IMM:
921 if (ins->next->opcode == OP_NOP)
924 rel = mono_opcode_to_cond (ins->next->opcode);
926 /* Used for implementing bound checks */
928 if ((ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_REG) || (ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_IMM)) {
933 t = LLVMInt32Type ();
935 g_assert (ins->inst_offset % size == 0);
936 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
938 lhs = LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (t, 0)), &index, 1, get_tempname (ctx)), get_tempname (ctx));
940 if (ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_IMM) {
941 lhs = convert (ctx, lhs, LLVMInt32Type ());
942 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
944 if (ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_REG)
945 rhs = convert (ctx, rhs, LLVMInt32Type ());
948 if (ins->opcode == OP_ICOMPARE_IMM) {
949 lhs = convert (ctx, lhs, LLVMInt32Type ());
950 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
952 if (ins->opcode == OP_LCOMPARE_IMM)
953 rhs = LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE);
954 if (ins->opcode == OP_LCOMPARE)
955 rhs = convert (ctx, rhs, LLVMInt64Type ());
956 if (ins->opcode == OP_ICOMPARE) {
957 lhs = convert (ctx, lhs, LLVMInt32Type ());
958 rhs = convert (ctx, rhs, LLVMInt32Type ());
962 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
963 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
964 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
965 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
968 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
969 if (ins->opcode == OP_FCOMPARE)
970 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), get_tempname (ctx));
971 else if (ins->opcode == OP_COMPARE_IMM)
972 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), get_tempname (ctx));
973 else if (ins->opcode == OP_COMPARE)
974 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), get_tempname (ctx));
976 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, get_tempname (ctx));
978 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
979 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
980 has_terminator = TRUE;
981 } else if (MONO_IS_SETCC (ins->next)) {
982 dname = g_strdup_printf ("t%d", ins->next->dreg);
983 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
984 } else if (MONO_IS_COND_EXC (ins->next)) {
985 //emit_cond_throw_pos (ctx);
986 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
987 builder = ctx->builder;
989 LLVM_FAILURE (ctx, "next");
1003 rel = mono_opcode_to_cond (ins->opcode);
1005 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], lhs, rhs, get_tempname (ctx));
1006 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
1013 /* Created earlier, insert it now */
1014 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
1016 /* Check that all input bblocks really branch to us */
1017 for (i = 0; i < bb->in_count; ++i) {
1018 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
1019 ins->inst_phi_args [i + 1] = -1;
1022 // FIXME: If a SWITCH statement branches to the same bblock in more
1023 // than once case, the PHI should reference the bblock multiple times
1024 for (i = 0; i < bb->in_count; ++i)
1025 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
1026 LLVM_FAILURE (ctx, "switch + phi");
1030 for (i = 0; i < ins->inst_phi_args [0]; i++) {
1031 int sreg1 = ins->inst_phi_args [i + 1];
1032 LLVMBasicBlockRef in_bb;
1037 /* Add incoming values which are already defined */
1038 if (FALSE && values [sreg1]) {
1039 in_bb = get_end_bb (ctx, bb->in_bb [i]);
1041 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [ins->dreg]));
1042 LLVMAddIncoming (values [ins->dreg], &values [sreg1], &in_bb, 1);
1044 /* Remember for later */
1045 //LLVM_FAILURE (ctx, "phi incoming value");
1046 GSList *node_list = g_hash_table_lookup (phi_nodes, GUINT_TO_POINTER (bb->in_bb [i]));
1047 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
1051 node_list = g_slist_prepend_mempool (ctx->mempool, node_list, node);
1052 g_hash_table_insert (phi_nodes, GUINT_TO_POINTER (bb->in_bb [i]), node_list);
1060 values [ins->dreg] = lhs;
1092 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
1093 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
1095 switch (ins->opcode) {
1099 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
1104 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
1109 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
1113 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
1117 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
1121 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
1125 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
1128 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
1132 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
1136 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
1140 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
1144 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
1148 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
1152 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
1155 g_assert_not_reached ();
1163 case OP_IDIV_UN_IMM:
1169 case OP_ISHR_UN_IMM:
1178 case OP_LSHR_UN_IMM:
1185 if (spec [MONO_INST_SRC1] == 'l')
1186 imm = LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE);
1188 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
1189 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
1190 lhs = convert (ctx, lhs, IntPtrType ());
1191 imm = convert (ctx, imm, LLVMTypeOf (lhs));
1192 switch (ins->opcode) {
1196 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
1200 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
1204 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
1208 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
1210 case OP_IDIV_UN_IMM:
1211 case OP_LDIV_UN_IMM:
1212 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
1216 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
1221 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
1225 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
1229 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
1234 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
1238 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
1240 case OP_ISHR_UN_IMM:
1241 case OP_LSHR_UN_IMM:
1242 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
1245 g_assert_not_reached ();
1250 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
1253 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
1256 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
1259 guint32 v = 0xffffffff;
1260 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), lhs, dname);
1264 guint64 v = 0xffffffffffffffff;
1265 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
1269 LLVMValueRef v1, v2;
1271 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), get_tempname (ctx));
1272 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, get_tempname (ctx));
1273 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
1277 case OP_ICONV_TO_I1:
1278 case OP_ICONV_TO_I2:
1279 case OP_ICONV_TO_I4:
1280 case OP_ICONV_TO_U1:
1281 case OP_ICONV_TO_U2:
1282 case OP_ICONV_TO_U4:
1283 case OP_LCONV_TO_I1:
1284 case OP_LCONV_TO_I2:
1285 case OP_LCONV_TO_U1:
1286 case OP_LCONV_TO_U2:
1287 case OP_LCONV_TO_U4: {
1290 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);
1292 /* Have to do two casts since our vregs have type int */
1293 v = LLVMBuildTrunc (builder, lhs, conv_to_llvm_type (ins->opcode), get_tempname (ctx));
1295 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
1297 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
1300 case OP_FCONV_TO_I4:
1301 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
1303 case OP_FCONV_TO_I1:
1304 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), get_tempname (ctx));
1306 case OP_FCONV_TO_U1:
1307 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), get_tempname (ctx));
1309 case OP_FCONV_TO_I2:
1310 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), get_tempname (ctx));
1312 case OP_FCONV_TO_U2:
1313 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), get_tempname (ctx));
1315 case OP_FCONV_TO_I8:
1316 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
1319 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
1321 case OP_ICONV_TO_R8:
1322 case OP_LCONV_TO_R8:
1323 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
1325 case OP_LCONV_TO_R_UN:
1326 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
1328 case OP_ICONV_TO_R4:
1329 case OP_LCONV_TO_R4:
1330 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), get_tempname (ctx));
1331 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
1333 case OP_FCONV_TO_R4:
1334 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), get_tempname (ctx));
1335 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
1338 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
1341 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
1344 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
1346 case OP_LOCALLOC_IMM: {
1349 guint32 size = ins->inst_imm;
1350 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
1352 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, get_tempname (ctx));
1354 if (ins->flags & MONO_INST_INIT) {
1355 LLVMValueRef args [4];
1358 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
1359 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
1360 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
1361 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memset.i32"), args, 4, "");
1364 values [ins->dreg] = v;
1367 case OP_LOADI1_MEMBASE:
1368 case OP_LOADU1_MEMBASE:
1369 case OP_LOADI2_MEMBASE:
1370 case OP_LOADU2_MEMBASE:
1371 case OP_LOADI4_MEMBASE:
1372 case OP_LOADU4_MEMBASE:
1373 case OP_LOADI8_MEMBASE:
1374 case OP_LOADR4_MEMBASE:
1375 case OP_LOADR8_MEMBASE:
1376 case OP_LOAD_MEMBASE:
1382 gboolean sext = FALSE, zext = FALSE;
1384 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
1387 dname = (char*)get_tempname (ctx);
1389 g_assert (ins->inst_offset % size == 0);
1390 if ((ins->opcode == OP_LOADI8_MEM) || (ins->opcode == OP_LOAD_MEM)) {
1391 values [ins->dreg] = LLVMBuildLoad (builder, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), LLVMPointerType (t, 0)), dname);
1392 } else if (ins->inst_offset == 0) {
1393 values [ins->dreg] = LLVMBuildLoad (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (t, 0)), dname);
1395 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1396 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (t, 0)), &index, 1, get_tempname (ctx)), dname);
1399 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
1401 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
1402 else if (ins->opcode == OP_LOADR4_MEMBASE)
1403 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
1407 case OP_STOREI1_MEMBASE_REG:
1408 case OP_STOREI2_MEMBASE_REG:
1409 case OP_STOREI4_MEMBASE_REG:
1410 case OP_STOREI8_MEMBASE_REG:
1411 case OP_STORER4_MEMBASE_REG:
1412 case OP_STORER8_MEMBASE_REG:
1413 case OP_STORE_MEMBASE_REG: {
1417 gboolean sext = FALSE, zext = FALSE;
1419 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
1421 g_assert (ins->inst_offset % size == 0);
1422 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1423 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], t), LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, get_tempname (ctx)));
1427 case OP_STOREI1_MEMBASE_IMM:
1428 case OP_STOREI2_MEMBASE_IMM:
1429 case OP_STOREI4_MEMBASE_IMM:
1430 case OP_STOREI8_MEMBASE_IMM:
1431 case OP_STORE_MEMBASE_IMM: {
1435 gboolean sext = FALSE, zext = FALSE;
1437 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
1439 g_assert (ins->inst_offset % size == 0);
1440 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1441 LLVMBuildStore (builder, convert (ctx, LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE), t), LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, get_tempname (ctx)));
1446 LLVMBuildLoad (builder, convert (ctx, values [ins->sreg1], LLVMPointerType (IntPtrType (), 0)), get_tempname (ctx));
1448 case OP_OUTARG_VTRETADDR:
1455 case OP_VOIDCALL_MEMBASE:
1456 case OP_CALL_MEMBASE:
1457 case OP_LCALL_MEMBASE:
1458 case OP_FCALL_MEMBASE:
1459 case OP_VCALL_MEMBASE: {
1460 MonoCallInst *call = (MonoCallInst*)ins;
1461 MonoMethodSignature *sig = call->signature;
1462 LLVMValueRef callee;
1467 LLVMTypeRef llvm_sig;
1470 vretaddr = call->vret_var != NULL;
1472 llvm_sig = sig_to_llvm_sig (ctx, sig, vretaddr);
1473 CHECK_FAILURE (ctx);
1475 if (call->rgctx_reg) {
1476 LLVM_FAILURE (ctx, "rgctx reg");
1479 /* FIXME: Avoid creating duplicate methods */
1481 if (ins->flags & MONO_INST_HAS_METHOD) {
1482 callee = LLVMAddFunction (module, "", llvm_sig);
1485 mono_create_jit_trampoline_in_domain (mono_domain_get (),
1487 LLVMAddGlobalMapping (ee, callee, target);
1489 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
1491 callee = LLVMAddFunction (module, "", llvm_sig);
1496 memset (&ji, 0, sizeof (ji));
1497 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
1498 ji.data.target = info->name;
1500 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1501 LLVMAddGlobalMapping (ee, callee, target);
1504 if (cfg->abs_patches) {
1505 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1507 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
1508 LLVMAddGlobalMapping (ee, callee, target);
1512 LLVMAddGlobalMapping (ee, callee, (gpointer)call->fptr);
1516 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) {
1517 int size = sizeof (gpointer);
1520 g_assert (ins->inst_offset % size == 0);
1521 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1523 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (IntPtrType (), 0)), &index, 1, get_tempname (ctx)), get_tempname (ctx)), LLVMPointerType (llvm_sig, 0));
1525 // FIXME: mono_arch_get_vcall_slot () can't decode the code
1526 // generated by LLVM
1527 //LLVM_FAILURE (ctx, "virtual call");
1529 if (call->method && call->method->klass->flags & TYPE_ATTRIBUTE_INTERFACE)
1530 /* No support for passing the IMT argument */
1531 LLVM_FAILURE (ctx, "imt");
1533 if (ins->flags & MONO_INST_HAS_METHOD) {
1537 /* Collect and convert arguments */
1538 args = alloca (sizeof (LLVMValueRef) * (sig->param_count + sig->hasthis + vretaddr));
1539 l = call->out_ireg_args;
1542 MonoInst *var = call->vret_var->inst_p0;
1544 g_assert (addresses [var->dreg]);
1545 args [pindex ++] = LLVMBuildPtrToInt (builder, addresses [var->dreg], IntPtrType (), get_tempname (ctx));
1548 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
1552 regpair = (guint32)(gssize)(l->data);
1553 reg = regpair & 0xffffff;
1554 args [pindex] = values [reg];
1557 LLVM_FAILURE (ctx, "vtype arg");
1558 g_assert (args [pindex]);
1559 if (i == 0 && sig->hasthis)
1560 args [pindex] = convert (ctx, args [pindex], IntPtrType ());
1562 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
1568 // FIXME: Align call sites
1570 if (sig->ret->type != MONO_TYPE_VOID && !vretaddr)
1571 /* FIXME: Convert res */
1572 values [ins->dreg] = convert (ctx, LLVMBuildCall (builder, callee, args, pindex, dname), llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->ret)));
1574 LLVMBuildCall (builder, callee, args, pindex, "");
1577 case OP_GOT_ENTRY: {
1578 LLVMValueRef indexes [2];
1580 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1581 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)ins->inst_p0, FALSE);
1582 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->got_var, indexes, 2, get_tempname (ctx)), dname);
1586 MonoMethodSignature *throw_sig;
1587 LLVMValueRef callee;
1589 throw_sig = mono_metadata_signature_alloc (mono_defaults.corlib, 1);
1590 throw_sig->ret = &mono_defaults.void_class->byval_arg;
1591 throw_sig->params [0] = &mono_defaults.object_class->byval_arg;
1592 // FIXME: Prevent duplicates
1593 callee = LLVMAddFunction (module, "mono_arch_throw_exception", sig_to_llvm_sig (ctx, throw_sig, FALSE));
1594 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_arch_throw_exception"));
1595 LLVMBuildCall (builder, callee, &values [ins->sreg1], 1, "");
1598 case OP_NOT_REACHED:
1599 LLVMBuildUnreachable (builder);
1600 has_terminator = TRUE;
1601 /* Might have instructions after this */
1603 MonoInst *next = ins->next;
1604 MONO_DELETE_INS (bb, next);
1608 MonoInst *var = ins->inst_p0;
1610 values [ins->dreg] = addresses [var->dreg];
1614 LLVMValueRef args [1];
1617 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
1621 LLVMValueRef args [1];
1624 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
1627 /* test_0_sqrt_nan fails with LLVM */
1630 LLVMValueRef args [1];
1633 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
1640 LLVMValueRef v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, get_tempname (ctx));
1641 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
1646 LLVMValueRef v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, get_tempname (ctx));
1647 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
1652 LLVMValueRef v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, get_tempname (ctx));
1653 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
1658 LLVMValueRef v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, get_tempname (ctx));
1659 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
1662 case OP_ATOMIC_EXCHANGE_I4: {
1663 LLVMValueRef args [2];
1665 g_assert (ins->inst_offset == 0);
1667 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
1669 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.swap.i32.p0i32"), args, 2, dname);
1672 case OP_ATOMIC_EXCHANGE_I8: {
1673 LLVMValueRef args [2];
1675 g_assert (ins->inst_offset == 0);
1677 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
1679 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.swap.i64.p0i64"), args, 2, dname);
1682 case OP_ATOMIC_ADD_NEW_I4: {
1683 LLVMValueRef args [2];
1685 g_assert (ins->inst_offset == 0);
1687 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
1689 values [ins->dreg] = LLVMBuildAdd (builder, LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.load.add.i32.p0i32"), args, 2, get_tempname (ctx)), args [1], dname);
1692 case OP_ATOMIC_ADD_NEW_I8: {
1693 LLVMValueRef args [2];
1695 g_assert (ins->inst_offset == 0);
1697 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
1698 args [1] = convert (ctx, rhs, LLVMInt64Type ());
1699 values [ins->dreg] = LLVMBuildAdd (builder, LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.load.add.i64.p0i64"), args, 2, get_tempname (ctx)), args [1], dname);
1703 case OP_ATOMIC_CAS_IMM_I4: {
1704 LLVMValueRef args [3];
1706 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
1708 args [1] = LLVMConstInt (LLVMInt32Type (), GPOINTER_TO_INT (ins->backend.data), FALSE);
1711 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.cmp.swap.i32.p0i32"), args, 3, dname);
1715 case OP_MEMORY_BARRIER: {
1716 LLVMValueRef args [5];
1718 for (i = 0; i < 5; ++i)
1719 args [i] = LLVMConstInt (LLVMInt1Type (), TRUE, TRUE);
1721 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memory.barrier"), args, 5, "");
1728 // FIXME: LLVM can't handle mul_ovf_un yet
1730 case OP_IADD_OVF_UN:
1732 case OP_ISUB_OVF_UN:
1734 //case OP_IMUL_OVF_UN:
1737 case OP_LSUB_OVF_UN:
1739 //case OP_LMUL_OVF_UN: {
1740 LLVMValueRef args [2], val, ovf, func;
1742 emit_cond_throw_pos (ctx);
1746 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
1748 val = LLVMBuildCall (builder, func, args, 2, "");
1749 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
1750 ovf = LLVMBuildExtractValue (builder, val, 1, get_tempname (ctx));
1751 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
1752 builder = ctx->builder;
1758 * We currently model them using arrays. Promotion to local vregs is
1759 * disabled for them in mono_handle_global_vregs () in the LLVM case,
1760 * so we always have an entry in cfg->varinfo for them.
1761 * FIXME: Is this needed ?
1764 MonoClass *klass = ins->klass;
1765 LLVMValueRef args [4];
1769 LLVM_FAILURE (ctx, "!klass");
1773 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), get_tempname (ctx));
1774 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
1775 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
1777 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1778 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memset.i32"), args, 4, "");
1782 case OP_STOREV_MEMBASE:
1783 case OP_LOADV_MEMBASE:
1785 MonoClass *klass = ins->klass;
1786 LLVMValueRef src, dst, args [4];
1790 LLVM_FAILURE (ctx, "!klass");
1794 switch (ins->opcode) {
1795 case OP_STOREV_MEMBASE:
1796 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), get_tempname (ctx));
1797 dst = convert (ctx, LLVMBuildAdd (builder, values [ins->inst_destbasereg], LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), get_tempname (ctx)), LLVMPointerType (LLVMInt8Type (), 0));
1799 case OP_LOADV_MEMBASE:
1800 if (!addresses [ins->dreg])
1801 addresses [ins->dreg] = LLVMBuildAlloca (builder, type_to_llvm_type (ctx, &klass->byval_arg), get_tempname (ctx));
1802 src = convert (ctx, LLVMBuildAdd (builder, values [ins->inst_basereg], LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), get_tempname (ctx)), LLVMPointerType (LLVMInt8Type (), 0));
1803 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), get_tempname (ctx));
1806 if (!addresses [ins->dreg])
1807 addresses [ins->dreg] = LLVMBuildAlloca (builder, type_to_llvm_type (ctx, &klass->byval_arg), get_tempname (ctx));
1808 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), get_tempname (ctx));
1809 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), get_tempname (ctx));
1812 g_assert_not_reached ();
1817 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
1818 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1820 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1821 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memcpy.i32"), args, 4, "");
1826 char *reason = g_strdup_printf ("opcode %s", mono_inst_name (ins->opcode));
1827 LLVM_FAILURE (ctx, reason);
1832 /* Convert the value to the type required by phi nodes */
1833 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && vreg_types [ins->dreg])
1834 values [ins->dreg] = convert (ctx, values [ins->dreg], vreg_types [ins->dreg]);
1836 /* Add stores for volatile variables */
1837 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
1838 emit_volatile_store (ctx, ins->dreg);
1841 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
1842 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
1844 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
1845 LLVMBuildRetVoid (builder);
1848 /* Add incoming phi values */
1849 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1850 GSList *ins_list = g_hash_table_lookup (phi_nodes, GUINT_TO_POINTER (bb));
1853 PhiNode *node = ins_list->data;
1854 MonoInst *phi = node->phi;
1855 int sreg1 = phi->inst_phi_args [node->index + 1];
1856 LLVMBasicBlockRef in_bb;
1858 in_bb = get_end_bb (ctx, node->bb->in_bb [node->index]);
1860 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
1861 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
1863 ins_list = ins_list->next;
1868 LLVMDumpValue (method);
1870 mono_llvm_optimize_method (method);
1872 if (cfg->verbose_level > 1)
1873 LLVMDumpValue (method);
1875 cfg->native_code = LLVMGetPointerToGlobal (ee, method);
1877 /* Set by emit_cb */
1878 g_assert (cfg->code_len);
1885 /* Need to add unused phi nodes as they can be referenced by other values */
1886 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
1887 LLVMBuilderRef builder;
1889 builder = LLVMCreateBuilder ();
1890 LLVMPositionBuilderAtEnd (builder, phi_bb);
1892 for (i = 0; i < phi_values->len; ++i) {
1893 LLVMValueRef v = g_ptr_array_index (phi_values, i);
1894 if (LLVMGetInstructionParent (v) == NULL)
1895 LLVMInsertIntoBuilder (builder, v);
1898 LLVMDeleteFunction (method);
1904 g_free (vreg_types);
1905 g_hash_table_destroy (phi_nodes);
1906 g_ptr_array_free (phi_values, TRUE);
1907 g_free (ctx->bblocks);
1908 g_free (ctx->end_bblocks);
1912 TlsSetValue (current_cfg_tls_id, NULL);
1914 mono_loader_unlock ();
1917 static unsigned char*
1918 alloc_cb (LLVMValueRef function, int size)
1922 cfg = TlsGetValue (current_cfg_tls_id);
1926 return mono_domain_code_reserve (cfg->domain, size);
1928 return mono_domain_code_reserve (mono_domain_get (), size);
1933 emitted_cb (LLVMValueRef function, void *start, void *end)
1937 cfg = TlsGetValue (current_cfg_tls_id);
1939 cfg->code_len = (guint8*)end - (guint8*)start;
1943 exception_cb (void *data)
1947 cfg = TlsGetValue (current_cfg_tls_id);
1951 * data points to a DWARF FDE structure, convert it to our unwind format and
1953 * An alternative would be to save it directly, and modify our unwinder to work
1956 cfg->encoded_unwind_ops = mono_unwind_get_ops_from_fde ((guint8*)data, &cfg->encoded_unwind_ops_len);
1960 mono_llvm_init (void)
1962 current_cfg_tls_id = TlsAlloc ();
1964 module = LLVMModuleCreateWithName ("mono");
1966 ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module), alloc_cb, emitted_cb, exception_cb);
1968 llvm_types = g_hash_table_new (NULL, NULL);
1970 /* Emit declarations of instrinsics */
1972 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type () };
1974 LLVMAddFunction (module, "llvm.memset.i32", LLVMFunctionType (LLVMVoidType (), memset_params, 4, FALSE));
1978 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type () };
1980 LLVMAddFunction (module, "llvm.memcpy.i32", LLVMFunctionType (LLVMVoidType (), memcpy_params, 4, FALSE));
1984 LLVMTypeRef params [] = { LLVMDoubleType () };
1986 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
1987 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
1988 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
1992 LLVMTypeRef membar_params [] = { LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type () };
1994 LLVMAddFunction (module, "llvm.atomic.swap.i32.p0i32", LLVMFunctionType2 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), FALSE));
1995 LLVMAddFunction (module, "llvm.atomic.swap.i64.p0i64", LLVMFunctionType2 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), FALSE));
1996 LLVMAddFunction (module, "llvm.atomic.load.add.i32.p0i32", LLVMFunctionType2 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), FALSE));
1997 LLVMAddFunction (module, "llvm.atomic.load.add.i64.p0i64", LLVMFunctionType2 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), FALSE));
1998 LLVMAddFunction (module, "llvm.atomic.cmp.swap.i32.p0i32", LLVMFunctionType3 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), LLVMInt32Type (), FALSE));
1999 LLVMAddFunction (module, "llvm.memory.barrier", LLVMFunctionType (LLVMVoidType (), membar_params, 5, FALSE));
2003 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
2004 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
2006 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
2007 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
2008 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
2009 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
2010 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
2011 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
2015 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
2016 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
2018 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
2019 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
2020 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
2021 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
2022 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
2023 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
2029 - Emit LLVM IR from the mono IR using the LLVM C API.
2030 - The original arch specific code remains, so we can fall back to it if we run
2031 into something we can't handle.
2033 - llvm's PrettyStackTrace class seems to register a signal handler which screws
2034 up our GC. Also, it calls sigaction () a _lot_ of times instead of just once.
2038 A partial list of issues:
2039 - Handling of opcodes which can throw exceptions.
2041 In the mono JIT, these are implemented using code like this:
2048 push throw_pos - method
2049 call <exception trampoline>
2051 The problematic part is push throw_pos - method, which cannot be represented
2052 in the LLVM IR, since it does not support label values.
2053 -> this can be implemented in AOT mode using inline asm + labels, but cannot
2054 be implemented in JIT mode ?
2055 -> a possible but slower implementation would use the normal exception
2056 throwing code but it would need to control the placement of the throw code
2057 (it needs to be exactly after the compare+branch).
2058 -> perhaps add a PC offset intrinsics ?
2060 - efficient implementation of .ovf opcodes.
2062 These are currently implemented as:
2063 <ins which sets the condition codes>
2066 Some overflow opcodes are now supported by LLVM SVN.
2068 - exception handling, unwinding.
2069 - SSA is disabled for methods with exception handlers
2070 - How to obtain unwind info for LLVM compiled methods ?
2071 -> this is now solved by converting the unwind info generated by LLVM
2073 - LLVM uses the c++ exception handling framework, while we use our home grown
2074 code, and couldn't use the c++ one:
2075 - its not supported under VC++, other exotic platforms.
2076 - it might be impossible to support filter clauses with it.
2080 The trampolines need a predictable call sequence, since they need to disasm
2081 the calling code to obtain register numbers / offsets.
2083 LLVM currently generates this code in non-JIT mode:
2084 mov -0x98(%rax),%eax
2086 Here, the vtable pointer is lost.
2087 -> solution: use one vtable trampoline per class.
2089 - passing/receiving the IMT pointer/RGCTX.
2090 -> solution: pass them as normal arguments ?
2094 LLVM does not allow the specification of argument registers etc. This means
2095 that all calls are made according to the platform ABI.
2099 Supported though alloca, we need to emit the load/store code.
2103 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
2104 typed registers, so we have to keep track of the precise LLVM type of each vreg.
2105 This is made easier because the IR is already in SSA form.
2106 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
2107 types are frequently used incorrectly.
2110 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
2111 * - each bblock should end with a branch
2112 * - setting the return value, making cfg->ret non-volatile
2113 * - merge some changes back to HEAD, to reduce the differences.
2114 * - avoid some transformations in the JIT which make it harder for us to generate
2116 * - fix memory leaks.
2117 * - use pointer types to help optimizations.