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"
17 * Information associated by mono with LLVM modules.
21 LLVMValueRef throw, throw_corlib_exception;
22 GHashTable *llvm_types;
27 * Structure containing emit state
32 /* Maps method names to the corresponding LLVMValueRef */
33 GHashTable *emitted_method_decls;
37 MonoLLVMModule *lmodule;
39 LLVMBasicBlockRef *bblocks, *end_bblocks;
40 int sindex, default_index, ex_index;
41 LLVMBuilderRef builder;
42 LLVMValueRef *values, *addresses;
44 MonoMethodSignature *sig;
57 * Instruction metadata
58 * This is the same as ins_info, but LREG != IREG.
66 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
67 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
74 /* keep in sync with the enum in mini.h */
82 #if SIZEOF_VOID_P == 4
83 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
85 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
88 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
90 #define LLVM_FAILURE(ctx, reason) do { \
91 (ctx)->cfg->exception_message = g_strdup (reason); \
92 (ctx)->cfg->disable_llvm = TRUE; \
96 #define CHECK_FAILURE(ctx) do { \
97 if ((ctx)->cfg->disable_llvm) \
101 static LLVMIntPredicate cond_to_llvm_cond [] = {
114 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
127 static LLVMExecutionEngineRef ee;
128 static guint32 current_cfg_tls_id;
130 static MonoLLVMModule jit_module, aot_module;
131 static GHashTable *plt_entries;
136 * The LLVM type with width == sizeof (gpointer)
141 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
147 * Return the size of the LLVM representation of the vtype T.
150 get_vtype_size (MonoType *t)
154 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
156 while (size < sizeof (gpointer) && mono_is_power_of_two (size) == -1)
165 * Return the LLVM type corresponding to T.
168 type_to_llvm_type (EmitContext *ctx, MonoType *t)
171 return LLVMPointerType (LLVMInt8Type (), 0);
174 return LLVMVoidType ();
176 return LLVMInt8Type ();
178 return LLVMInt16Type ();
180 return LLVMInt32Type ();
182 return LLVMInt8Type ();
184 return LLVMInt16Type ();
186 return LLVMInt32Type ();
187 case MONO_TYPE_BOOLEAN:
188 return LLVMInt8Type ();
191 return LLVMInt64Type ();
193 return LLVMInt16Type ();
195 return LLVMFloatType ();
197 return LLVMDoubleType ();
200 return IntPtrType ();
201 case MONO_TYPE_OBJECT:
202 case MONO_TYPE_CLASS:
203 case MONO_TYPE_ARRAY:
204 case MONO_TYPE_SZARRAY:
205 case MONO_TYPE_STRING:
207 return LLVMPointerType (IntPtrType (), 0);
210 /* Because of generic sharing */
211 return IntPtrType ();
212 case MONO_TYPE_GENERICINST:
213 if (!mono_type_generic_inst_is_valuetype (t))
214 return IntPtrType ();
216 case MONO_TYPE_VALUETYPE: {
220 klass = mono_class_from_mono_type (t);
223 return type_to_llvm_type (ctx, mono_class_enum_basetype (t->data.klass));
224 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
227 LLVMTypeRef *eltypes;
229 size = get_vtype_size (t);
231 eltypes = g_new (LLVMTypeRef, size);
232 for (i = 0; i < size; ++i)
233 eltypes [i] = LLVMInt8Type ();
235 ltype = LLVMStructType (eltypes, size, FALSE);
236 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
243 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
244 ctx->cfg->disable_llvm = TRUE;
250 * type_to_llvm_arg_type:
252 * Same as type_to_llvm_type, but treat i8/i16 as i32.
255 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
257 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
259 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
261 * LLVM generates code which only sets the lower bits, while JITted
262 * code expects all the bits to be set.
264 ptype = LLVMInt32Type ();
271 * llvm_type_to_stack_type:
273 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
276 static G_GNUC_UNUSED LLVMTypeRef
277 llvm_type_to_stack_type (LLVMTypeRef type)
281 if (type == LLVMInt8Type ())
282 return LLVMInt32Type ();
283 else if (type == LLVMInt16Type ())
284 return LLVMInt32Type ();
285 else if (type == LLVMFloatType ())
286 return LLVMDoubleType ();
292 * regtype_to_llvm_type:
294 * Return the LLVM type corresponding to the regtype C used in instruction
298 regtype_to_llvm_type (char c)
302 return LLVMInt32Type ();
304 return LLVMInt64Type ();
306 return LLVMDoubleType ();
315 * Return the LLVM type corresponding to the conversion opcode OPCODE.
318 conv_to_llvm_type (int opcode)
323 return LLVMInt8Type ();
326 return LLVMInt8Type ();
329 return LLVMInt16Type ();
332 return LLVMInt16Type ();
335 return LLVMInt32Type ();
338 return LLVMInt32Type ();
340 return LLVMInt64Type ();
342 return LLVMFloatType ();
344 return LLVMDoubleType ();
346 return LLVMInt64Type ();
348 return LLVMInt32Type ();
350 return LLVMInt64Type ();
353 return LLVMInt8Type ();
356 return LLVMInt16Type ();
359 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
361 printf ("%s\n", mono_inst_name (opcode));
362 g_assert_not_reached ();
368 * load_store_to_llvm_type:
370 * Return the size/sign/zero extension corresponding to the load/store opcode
374 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
380 case OP_LOADI1_MEMBASE:
381 case OP_STOREI1_MEMBASE_REG:
382 case OP_STOREI1_MEMBASE_IMM:
385 return LLVMInt8Type ();
386 case OP_LOADU1_MEMBASE:
390 return LLVMInt8Type ();
391 case OP_LOADI2_MEMBASE:
392 case OP_STOREI2_MEMBASE_REG:
393 case OP_STOREI2_MEMBASE_IMM:
396 return LLVMInt16Type ();
397 case OP_LOADU2_MEMBASE:
401 return LLVMInt16Type ();
402 case OP_LOADI4_MEMBASE:
403 case OP_LOADU4_MEMBASE:
406 case OP_STOREI4_MEMBASE_REG:
407 case OP_STOREI4_MEMBASE_IMM:
409 return LLVMInt32Type ();
410 case OP_LOADI8_MEMBASE:
412 case OP_STOREI8_MEMBASE_REG:
413 case OP_STOREI8_MEMBASE_IMM:
415 return LLVMInt64Type ();
416 case OP_LOADR4_MEMBASE:
417 case OP_STORER4_MEMBASE_REG:
419 return LLVMFloatType ();
420 case OP_LOADR8_MEMBASE:
421 case OP_STORER8_MEMBASE_REG:
423 return LLVMDoubleType ();
424 case OP_LOAD_MEMBASE:
426 case OP_STORE_MEMBASE_REG:
427 case OP_STORE_MEMBASE_IMM:
428 *size = sizeof (gpointer);
429 return IntPtrType ();
431 g_assert_not_reached ();
439 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
442 ovf_op_to_intrins (int opcode)
446 return "llvm.sadd.with.overflow.i32";
448 return "llvm.uadd.with.overflow.i32";
450 return "llvm.ssub.with.overflow.i32";
452 return "llvm.usub.with.overflow.i32";
454 return "llvm.smul.with.overflow.i32";
456 return "llvm.umul.with.overflow.i32";
458 return "llvm.sadd.with.overflow.i64";
460 return "llvm.uadd.with.overflow.i64";
462 return "llvm.ssub.with.overflow.i64";
464 return "llvm.usub.with.overflow.i64";
466 return "llvm.smul.with.overflow.i64";
468 return "llvm.umul.with.overflow.i64";
470 g_assert_not_reached ();
478 * Return the LLVM basic block corresponding to BB.
480 static LLVMBasicBlockRef
481 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
485 if (ctx->bblocks [bb->block_num] == NULL) {
486 sprintf (bb_name, "BB%d", bb->block_num);
488 ctx->bblocks [bb->block_num] = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
489 ctx->end_bblocks [bb->block_num] = ctx->bblocks [bb->block_num];
492 return ctx->bblocks [bb->block_num];
498 * Return the last LLVM bblock corresponding to BB.
499 * This might not be equal to the bb returned by get_bb () since we need to generate
500 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
502 static LLVMBasicBlockRef
503 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
506 return ctx->end_bblocks [bb->block_num];
512 * Return the target of the patch identified by TYPE and TARGET.
515 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
519 memset (&ji, 0, sizeof (ji));
521 ji.data.target = target;
523 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
529 * Emit code to convert the LLVM value V to DTYPE.
532 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
534 LLVMTypeRef stype = LLVMTypeOf (v);
536 if (stype != dtype) {
538 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
539 return LLVMBuildSExt (ctx->builder, v, dtype, "");
540 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
541 return LLVMBuildSExt (ctx->builder, v, dtype, "");
542 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
543 return LLVMBuildSExt (ctx->builder, v, dtype, "");
544 else if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
545 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
548 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
549 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
550 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
551 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
552 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
553 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
555 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
556 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
557 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
558 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
559 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
560 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
563 LLVMDumpValue (LLVMConstNull (dtype));
564 g_assert_not_reached ();
572 * emit_volatile_store:
574 * If VREG is volatile, emit a store from its value to its address.
577 emit_volatile_store (EmitContext *ctx, int vreg)
579 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
581 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
582 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
589 * Return the LLVM signature corresponding to the mono signature SIG using the
590 * calling convention information in CINFO.
593 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
595 LLVMTypeRef ret_type;
596 LLVMTypeRef *param_types = NULL;
599 gboolean vretaddr = FALSE;
601 ret_type = type_to_llvm_type (ctx, sig->ret);
604 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
605 /* LLVM models this by returning an aggregate value */
606 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
607 LLVMTypeRef members [2];
609 members [0] = IntPtrType ();
610 ret_type = LLVMStructType (members, 1, FALSE);
612 g_assert_not_reached ();
614 } else if (cinfo && MONO_TYPE_ISSTRUCT (sig->ret)) {
615 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
619 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 2) + 2);
622 ret_type = LLVMVoidType ();
623 param_types [pindex ++] = IntPtrType ();
626 param_types [pindex ++] = IntPtrType ();
627 for (i = 0; i < sig->param_count; ++i) {
628 if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeInReg) {
629 for (j = 0; j < 2; ++j) {
630 switch (cinfo->args [i + sig->hasthis].pair_storage [j]) {
632 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
637 g_assert_not_reached ();
640 } else if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal) {
641 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
643 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
646 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
651 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
652 g_free (param_types);
657 g_free (param_types);
665 * Create an LLVM function type from the arguments.
667 static G_GNUC_UNUSED LLVMTypeRef
668 LLVMFunctionType1(LLVMTypeRef ReturnType,
669 LLVMTypeRef ParamType1,
672 LLVMTypeRef param_types [1];
674 param_types [0] = ParamType1;
676 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
682 * Create an LLVM function type from the arguments.
685 LLVMFunctionType2(LLVMTypeRef ReturnType,
686 LLVMTypeRef ParamType1,
687 LLVMTypeRef ParamType2,
690 LLVMTypeRef param_types [2];
692 param_types [0] = ParamType1;
693 param_types [1] = ParamType2;
695 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
701 * Create an LLVM function type from the arguments.
704 LLVMFunctionType3(LLVMTypeRef ReturnType,
705 LLVMTypeRef ParamType1,
706 LLVMTypeRef ParamType2,
707 LLVMTypeRef ParamType3,
710 LLVMTypeRef param_types [3];
712 param_types [0] = ParamType1;
713 param_types [1] = ParamType2;
714 param_types [2] = ParamType3;
716 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
722 * Create an LLVM builder and remember it so it can be freed later.
724 static LLVMBuilderRef
725 create_builder (EmitContext *ctx)
727 LLVMBuilderRef builder = LLVMCreateBuilder ();
729 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
735 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
742 emit_cond_throw_pos (EmitContext *ctx)
747 * emit_cond_system_exception:
749 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
752 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
755 LLVMBasicBlockRef ex_bb, noex_bb;
756 LLVMBuilderRef builder;
757 MonoClass *exc_class;
758 LLVMValueRef args [2];
760 sprintf (bb_name, "EX_BB%d", ctx->ex_index);
761 ex_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
763 sprintf (bb_name, "NOEX_BB%d", ctx->ex_index);
764 noex_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
766 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
768 ctx->builder = create_builder (ctx);
769 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
771 ctx->end_bblocks [bb->block_num] = noex_bb;
773 exc_class = mono_class_from_name (mono_defaults.corlib, "System", exc_type);
774 g_assert (exc_class);
776 /* Emit exception throwing code */
777 builder = create_builder (ctx);
778 LLVMPositionBuilderAtEnd (builder, ex_bb);
780 if (!ctx->lmodule->throw_corlib_exception) {
784 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_defaults.corlib, 2);
785 throw_sig->ret = &mono_defaults.void_class->byval_arg;
786 throw_sig->params [0] = &mono_defaults.int32_class->byval_arg;
787 throw_sig->params [1] = &mono_defaults.int32_class->byval_arg;
788 sig = sig_to_llvm_sig (ctx, throw_sig, NULL);
790 if (ctx->cfg->compile_aot) {
791 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_arch_throw_corlib_exception");
793 callee = LLVMAddFunction (ctx->module, "throw_corlib_exception", sig_to_llvm_sig (ctx, throw_sig, NULL));
795 LLVMAddGlobalMapping (ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_arch_throw_corlib_exception"));
798 mono_memory_barrier ();
799 ctx->lmodule->throw_corlib_exception = callee;
802 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
804 * FIXME: The offset is 0, this is not a problem for exception handling
805 * in general, because we don't llvm compile methods with handlers, its only
806 * a problem for line numbers in stack traces.
808 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
809 LLVMBuildCall (builder, ctx->lmodule->throw_corlib_exception, args, 2, "");
811 LLVMBuildUnreachable (builder);
819 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
822 emit_reg_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs)
826 size = get_vtype_size (t);
828 for (j = 0; j < 2; ++j) {
829 LLVMValueRef index [2], addr;
830 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
831 LLVMTypeRef part_type;
833 if (ainfo->pair_storage [j] == LLVMArgNone)
836 part_type = LLVMIntType (part_size * 8);
837 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
838 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
839 addr = LLVMBuildGEP (builder, address, index, 2, "");
840 switch (ainfo->pair_storage [j]) {
842 LLVMBuildStore (builder, convert (ctx, regs [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
847 g_assert_not_reached ();
850 size -= sizeof (gpointer);
857 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
858 * into REGS, and the number of registers into NREGS.
861 emit_vtype_to_reg (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs, guint32 *nregs)
866 size = get_vtype_size (t);
868 for (j = 0; j < 2; ++j) {
869 LLVMValueRef index [2], addr;
870 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
872 if (ainfo->pair_storage [j] == LLVMArgNone)
875 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
876 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
877 addr = LLVMBuildGEP (builder, address, index, 2, "");
878 switch (ainfo->pair_storage [j]) {
880 regs [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
885 g_assert_not_reached ();
887 size -= sizeof (gpointer);
896 * Emit code to load/convert arguments.
899 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder, int *pindexes)
902 MonoCompile *cfg = ctx->cfg;
903 MonoMethodSignature *sig = ctx->sig;
904 LLVMCallInfo *linfo = ctx->linfo;
907 * Handle indirect/volatile variables by allocating memory for them
908 * using 'alloca', and storing their address in a temporary.
910 for (i = 0; i < cfg->num_varinfo; ++i) {
911 MonoInst *var = cfg->varinfo [i];
914 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || MONO_TYPE_ISSTRUCT (var->inst_vtype)) {
915 vtype = type_to_llvm_type (ctx, var->inst_vtype);
917 ctx->addresses [var->dreg] = LLVMBuildAlloca (builder, vtype, "");
921 for (i = 0; i < sig->param_count; ++i) {
922 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
923 int reg = cfg->args [i + sig->hasthis]->dreg;
925 if (ainfo->storage == LLVMArgVtypeInReg) {
926 LLVMValueRef regs [2];
929 * Emit code to save the argument from the registers to
932 pindex = pindexes [i];
933 regs [0] = LLVMGetParam (ctx->lmethod, pindex);
934 if (ainfo->pair_storage [1] != LLVMArgNone)
935 regs [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
939 ctx->addresses [reg] = LLVMBuildAlloca (builder, type_to_llvm_type (ctx, &(mono_class_from_mono_type (sig->params [i])->byval_arg)), "");
941 emit_reg_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, regs);
942 } else if (ainfo->storage == LLVMArgVtypeByVal) {
943 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindexes [i]);
945 ctx->values [reg] = convert (ctx, ctx->values [reg], llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->params [i])));
949 for (i = 0; i < sig->param_count; ++i)
950 if (!MONO_TYPE_ISSTRUCT (sig->params [i]))
951 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
958 * mono_llvm_emit_method:
960 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
963 mono_llvm_emit_method (MonoCompile *cfg)
966 MonoMethodSignature *sig;
968 LLVMTypeRef method_type;
969 LLVMValueRef method = NULL;
970 char *method_name, *debug_name;
971 LLVMValueRef *values, *addresses;
972 LLVMTypeRef *vreg_types;
973 int i, max_block_num, pindex;
974 int *pindexes = NULL;
975 GHashTable *phi_nodes;
976 gboolean last = FALSE;
977 GPtrArray *phi_values;
980 LLVMModuleRef module;
982 /* The code below might acquire the loader lock, so use it for global locking */
985 /* Used to communicate with the callbacks */
986 TlsSetValue (current_cfg_tls_id, cfg);
988 ctx = g_new0 (EmitContext, 1);
990 ctx->mempool = cfg->mempool;
993 * This maps vregs to the LLVM instruction defining them
995 values = g_new0 (LLVMValueRef, cfg->next_vreg);
997 * This maps vregs for volatile variables to the LLVM instruction defining their
1000 addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
1001 vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
1002 phi_nodes = g_hash_table_new (NULL, NULL);
1003 phi_values = g_ptr_array_new ();
1005 ctx->values = values;
1006 ctx->addresses = addresses;
1008 if (cfg->compile_aot) {
1009 ctx->lmodule = &aot_module;
1012 ctx->lmodule = &jit_module;
1013 method_name = mono_method_full_name (cfg->method, TRUE);
1017 module = ctx->module = ctx->lmodule->module;
1021 static int count = 0;
1024 if (getenv ("LLVM_COUNT")) {
1025 if (count == atoi (getenv ("LLVM_COUNT"))) {
1026 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
1029 if (count > atoi (getenv ("LLVM_COUNT")))
1030 LLVM_FAILURE (ctx, "");
1035 sig = mono_method_signature (cfg->method);
1038 linfo = mono_arch_get_llvm_call_info (cfg, sig);
1040 CHECK_FAILURE (ctx);
1042 method_type = sig_to_llvm_sig (ctx, sig, linfo);
1043 CHECK_FAILURE (ctx);
1045 method = LLVMAddFunction (module, method_name, method_type);
1046 ctx->lmethod = method;
1047 g_free (method_name);
1049 LLVMSetLinkage (method, LLVMPrivateLinkage);
1051 if (cfg->method->save_lmf)
1052 LLVM_FAILURE (ctx, "lmf");
1055 LLVM_FAILURE (ctx, "pinvoke signature");
1058 * This maps parameter indexes in the original signature to the indexes in
1059 * the LLVM signature.
1061 pindexes = g_new0 (int, sig->param_count);
1063 if (cfg->vret_addr) {
1064 values [cfg->vret_addr->dreg] = LLVMGetParam (method, pindex);
1068 values [cfg->args [0]->dreg] = LLVMGetParam (method, pindex);
1071 for (i = 0; i < sig->param_count; ++i) {
1072 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
1073 pindexes [i] = pindex;
1074 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeInReg) {
1075 if (linfo->args [i + sig->hasthis].pair_storage [0] != LLVMArgNone)
1077 if (linfo->args [i + sig->hasthis].pair_storage [1] != LLVMArgNone)
1079 } else if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal) {
1080 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
1088 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
1089 max_block_num = MAX (max_block_num, bb->block_num);
1090 ctx->bblocks = g_new0 (LLVMBasicBlockRef, max_block_num + 1);
1091 ctx->end_bblocks = g_new0 (LLVMBasicBlockRef, max_block_num + 1);
1093 /* Add branches between non-consecutive bblocks */
1094 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1095 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
1096 bb->next_bb != bb->last_ins->inst_false_bb) {
1098 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
1099 inst->opcode = OP_BR;
1100 inst->inst_target_bb = bb->last_ins->inst_false_bb;
1101 mono_bblock_add_inst (bb, inst);
1106 * Make a first pass over the code to precreate PHI nodes.
1108 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1110 LLVMBuilderRef builder;
1112 char dname_buf[128];
1114 builder = create_builder (ctx);
1116 for (ins = bb->code; ins; ins = ins->next) {
1117 switch (ins->opcode) {
1120 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
1122 CHECK_FAILURE (ctx);
1125 * Have to precreate these, as they can be referenced by
1126 * earlier instructions.
1128 sprintf (dname_buf, "t%d", ins->dreg);
1130 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
1132 g_ptr_array_add (phi_values, values [ins->dreg]);
1135 * Set the expected type of the incoming arguments since these have
1136 * to have the same type.
1138 for (i = 0; i < ins->inst_phi_args [0]; i++) {
1139 int sreg1 = ins->inst_phi_args [i + 1];
1142 vreg_types [sreg1] = phi_type;
1153 * Second pass: generate code.
1155 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1157 LLVMBasicBlockRef cbb;
1158 LLVMBuilderRef builder;
1159 gboolean has_terminator;
1161 LLVMValueRef lhs, rhs;
1163 if (!(bb == cfg->bb_entry || bb->in_count > 0))
1166 cbb = get_bb (ctx, bb);
1167 builder = create_builder (ctx);
1168 ctx->builder = builder;
1169 LLVMPositionBuilderAtEnd (builder, cbb);
1171 if (bb == cfg->bb_entry)
1172 emit_entry_bb (ctx, builder, pindexes);
1173 CHECK_FAILURE (ctx);
1175 has_terminator = FALSE;
1176 for (ins = bb->code; ins; ins = ins->next) {
1177 const char *spec = LLVM_INS_INFO (ins->opcode);
1179 char dname_buf [128];
1182 /* There could be instructions after a terminator, skip them */
1185 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
1186 sprintf (dname_buf, "t%d", ins->dreg);
1190 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
1191 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
1193 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1194 lhs = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
1196 /* It is ok for SETRET to have an uninitialized argument */
1197 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
1198 LLVM_FAILURE (ctx, "sreg1");
1199 lhs = values [ins->sreg1];
1205 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
1206 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
1207 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1208 rhs = LLVMBuildLoad (builder, addresses [ins->sreg2], "");
1210 if (!values [ins->sreg2])
1211 LLVM_FAILURE (ctx, "sreg2");
1212 rhs = values [ins->sreg2];
1218 //mono_print_ins (ins);
1219 switch (ins->opcode) {
1222 case OP_LIVERANGE_START:
1223 case OP_LIVERANGE_END:
1226 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
1229 #if SIZEOF_VOID_P == 4
1230 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
1232 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
1236 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
1239 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
1242 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
1243 has_terminator = TRUE;
1249 LLVMBasicBlockRef new_bb;
1250 LLVMBuilderRef new_builder;
1252 // The default branch is already handled
1253 // FIXME: Handle it here
1255 /* Start new bblock */
1256 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
1257 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1259 lhs = convert (ctx, lhs, LLVMInt32Type ());
1260 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
1261 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
1262 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
1264 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
1267 new_builder = create_builder (ctx);
1268 LLVMPositionBuilderAtEnd (new_builder, new_bb);
1269 LLVMBuildUnreachable (new_builder);
1271 has_terminator = TRUE;
1272 g_assert (!ins->next);
1278 if (linfo->ret.storage == LLVMArgVtypeInReg) {
1279 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
1280 LLVMValueRef part1, retval;
1283 size = get_vtype_size (sig->ret);
1285 g_assert (addresses [ins->sreg1]);
1287 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
1288 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
1290 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
1292 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
1294 LLVMBuildRet (builder, retval);
1300 * The method did not set its return value, probably because it
1301 * ends with a throw.
1304 LLVMBuildRetVoid (builder);
1306 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
1308 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
1310 has_terminator = TRUE;
1316 case OP_ICOMPARE_IMM:
1317 case OP_LCOMPARE_IMM:
1318 case OP_COMPARE_IMM:
1320 case OP_AMD64_ICOMPARE_MEMBASE_REG:
1321 case OP_AMD64_ICOMPARE_MEMBASE_IMM:
1324 case OP_X86_COMPARE_MEMBASE_REG:
1325 case OP_X86_COMPARE_MEMBASE_IMM:
1331 if (ins->next->opcode == OP_NOP)
1334 if (ins->next->opcode == OP_BR)
1335 /* The comparison result is not needed */
1338 rel = mono_opcode_to_cond (ins->next->opcode);
1340 /* Used for implementing bound checks */
1342 if ((ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_REG) || (ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_IMM)) {
1347 t = LLVMInt32Type ();
1349 g_assert (ins->inst_offset % size == 0);
1350 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1352 lhs = LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (t, 0)), &index, 1, ""), "");
1354 if (ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_IMM) {
1355 lhs = convert (ctx, lhs, LLVMInt32Type ());
1356 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
1358 if (ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_REG)
1359 rhs = convert (ctx, rhs, LLVMInt32Type ());
1363 if ((ins->opcode == OP_X86_COMPARE_MEMBASE_REG) || (ins->opcode == OP_X86_COMPARE_MEMBASE_IMM)) {
1368 t = LLVMInt32Type ();
1370 g_assert (ins->inst_offset % size == 0);
1371 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1373 lhs = LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (t, 0)), &index, 1, ""), "");
1375 if (ins->opcode == OP_X86_COMPARE_MEMBASE_IMM) {
1376 lhs = convert (ctx, lhs, LLVMInt32Type ());
1377 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
1379 if (ins->opcode == OP_X86_COMPARE_MEMBASE_REG)
1380 rhs = convert (ctx, rhs, LLVMInt32Type ());
1383 if (ins->opcode == OP_ICOMPARE_IMM) {
1384 lhs = convert (ctx, lhs, LLVMInt32Type ());
1385 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
1387 if (ins->opcode == OP_LCOMPARE_IMM)
1388 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
1389 if (ins->opcode == OP_LCOMPARE) {
1390 lhs = convert (ctx, lhs, LLVMInt64Type ());
1391 rhs = convert (ctx, rhs, LLVMInt64Type ());
1393 if (ins->opcode == OP_ICOMPARE) {
1394 lhs = convert (ctx, lhs, LLVMInt32Type ());
1395 rhs = convert (ctx, rhs, LLVMInt32Type ());
1399 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
1400 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
1401 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
1402 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
1405 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
1406 if (ins->opcode == OP_FCOMPARE)
1407 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
1408 else if (ins->opcode == OP_COMPARE_IMM)
1409 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
1410 else if (ins->opcode == OP_COMPARE)
1411 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
1413 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
1415 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
1416 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
1417 has_terminator = TRUE;
1418 } else if (MONO_IS_SETCC (ins->next)) {
1419 sprintf (dname_buf, "t%d", ins->next->dreg);
1421 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
1423 /* Add stores for volatile variables */
1424 emit_volatile_store (ctx, ins->next->dreg);
1425 } else if (MONO_IS_COND_EXC (ins->next)) {
1426 //emit_cond_throw_pos (ctx);
1427 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
1428 builder = ctx->builder;
1430 LLVM_FAILURE (ctx, "next");
1444 rel = mono_opcode_to_cond (ins->opcode);
1446 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
1447 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
1454 /* Created earlier, insert it now */
1455 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
1457 /* Check that all input bblocks really branch to us */
1458 for (i = 0; i < bb->in_count; ++i) {
1459 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
1460 ins->inst_phi_args [i + 1] = -1;
1463 // FIXME: If a SWITCH statement branches to the same bblock in more
1464 // than once case, the PHI should reference the bblock multiple times
1465 for (i = 0; i < bb->in_count; ++i)
1466 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
1467 LLVM_FAILURE (ctx, "switch + phi");
1471 for (i = 0; i < ins->inst_phi_args [0]; i++) {
1472 int sreg1 = ins->inst_phi_args [i + 1];
1473 LLVMBasicBlockRef in_bb;
1478 /* Add incoming values which are already defined */
1479 if (FALSE && values [sreg1]) {
1480 in_bb = get_end_bb (ctx, bb->in_bb [i]);
1482 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [ins->dreg]));
1483 LLVMAddIncoming (values [ins->dreg], &values [sreg1], &in_bb, 1);
1485 /* Remember for later */
1486 //LLVM_FAILURE (ctx, "phi incoming value");
1487 GSList *node_list = g_hash_table_lookup (phi_nodes, GUINT_TO_POINTER (bb->in_bb [i]));
1488 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
1492 node_list = g_slist_prepend_mempool (ctx->mempool, node_list, node);
1493 g_hash_table_insert (phi_nodes, GUINT_TO_POINTER (bb->in_bb [i]), node_list);
1501 values [ins->dreg] = lhs;
1504 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
1507 values [ins->dreg] = lhs;
1509 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
1511 * This is added by the spilling pass in case of the JIT,
1512 * but we have to do it ourselves.
1514 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
1548 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
1549 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
1551 switch (ins->opcode) {
1555 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
1560 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
1565 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
1569 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
1573 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
1577 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
1581 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
1584 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
1588 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
1592 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
1596 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
1600 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
1604 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
1608 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
1611 g_assert_not_reached ();
1618 case OP_IREM_UN_IMM:
1620 case OP_IDIV_UN_IMM:
1626 case OP_ISHR_UN_IMM:
1635 case OP_LSHR_UN_IMM:
1642 if (spec [MONO_INST_SRC1] == 'l')
1643 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
1645 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
1647 #if SIZEOF_VOID_P == 4
1648 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
1649 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
1652 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
1653 lhs = convert (ctx, lhs, IntPtrType ());
1654 imm = convert (ctx, imm, LLVMTypeOf (lhs));
1655 switch (ins->opcode) {
1659 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
1663 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
1667 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
1671 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
1673 case OP_IDIV_UN_IMM:
1674 case OP_LDIV_UN_IMM:
1675 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
1679 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
1681 case OP_IREM_UN_IMM:
1682 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
1687 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
1691 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
1695 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
1700 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
1704 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
1706 case OP_ISHR_UN_IMM:
1707 case OP_LSHR_UN_IMM:
1708 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
1711 g_assert_not_reached ();
1716 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
1719 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
1722 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
1725 guint32 v = 0xffffffff;
1726 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), lhs, dname);
1730 guint64 v = 0xffffffffffffffffLL;
1731 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
1735 LLVMValueRef v1, v2;
1737 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
1738 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
1739 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
1743 case OP_ICONV_TO_I1:
1744 case OP_ICONV_TO_I2:
1745 case OP_ICONV_TO_I4:
1746 case OP_ICONV_TO_U1:
1747 case OP_ICONV_TO_U2:
1748 case OP_ICONV_TO_U4:
1749 case OP_LCONV_TO_I1:
1750 case OP_LCONV_TO_I2:
1751 case OP_LCONV_TO_U1:
1752 case OP_LCONV_TO_U2:
1753 case OP_LCONV_TO_U4: {
1756 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);
1758 /* Have to do two casts since our vregs have type int */
1759 v = LLVMBuildTrunc (builder, lhs, conv_to_llvm_type (ins->opcode), "");
1761 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
1763 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
1766 case OP_ICONV_TO_I8:
1767 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
1769 case OP_ICONV_TO_U8:
1770 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
1772 case OP_FCONV_TO_I4:
1773 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
1775 case OP_FCONV_TO_I1:
1776 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
1778 case OP_FCONV_TO_U1:
1779 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
1781 case OP_FCONV_TO_I2:
1782 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
1784 case OP_FCONV_TO_U2:
1785 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
1787 case OP_FCONV_TO_I8:
1788 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
1791 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
1793 case OP_ICONV_TO_R8:
1794 case OP_LCONV_TO_R8:
1795 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
1797 case OP_LCONV_TO_R_UN:
1798 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
1800 #if SIZEOF_VOID_P == 4
1803 case OP_LCONV_TO_I4:
1804 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
1806 case OP_ICONV_TO_R4:
1807 case OP_LCONV_TO_R4:
1808 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
1809 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
1811 case OP_FCONV_TO_R4:
1812 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
1813 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
1816 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
1819 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
1822 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
1824 case OP_LOCALLOC_IMM: {
1827 guint32 size = ins->inst_imm;
1828 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
1830 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
1832 if (ins->flags & MONO_INST_INIT) {
1833 LLVMValueRef args [4];
1836 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
1837 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
1838 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
1839 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memset.i32"), args, 4, "");
1842 values [ins->dreg] = v;
1845 case OP_LOADI1_MEMBASE:
1846 case OP_LOADU1_MEMBASE:
1847 case OP_LOADI2_MEMBASE:
1848 case OP_LOADU2_MEMBASE:
1849 case OP_LOADI4_MEMBASE:
1850 case OP_LOADU4_MEMBASE:
1851 case OP_LOADI8_MEMBASE:
1852 case OP_LOADR4_MEMBASE:
1853 case OP_LOADR8_MEMBASE:
1854 case OP_LOAD_MEMBASE:
1864 gboolean sext = FALSE, zext = FALSE;
1866 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
1871 g_assert (ins->inst_offset % size == 0);
1872 if ((ins->opcode == OP_LOADI8_MEM) || (ins->opcode == OP_LOAD_MEM) || (ins->opcode == OP_LOADI4_MEM) || (ins->opcode == OP_LOADU4_MEM) || (ins->opcode == OP_LOADU1_MEM) || (ins->opcode == OP_LOADU2_MEM)) {
1873 values [ins->dreg] = LLVMBuildLoad (builder, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), LLVMPointerType (t, 0)), dname);
1874 } else if (ins->inst_offset == 0) {
1875 values [ins->dreg] = LLVMBuildLoad (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (t, 0)), dname);
1877 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1878 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (t, 0)), &index, 1, ""), dname);
1881 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
1883 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
1884 else if (ins->opcode == OP_LOADR4_MEMBASE)
1885 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
1889 case OP_STOREI1_MEMBASE_REG:
1890 case OP_STOREI2_MEMBASE_REG:
1891 case OP_STOREI4_MEMBASE_REG:
1892 case OP_STOREI8_MEMBASE_REG:
1893 case OP_STORER4_MEMBASE_REG:
1894 case OP_STORER8_MEMBASE_REG:
1895 case OP_STORE_MEMBASE_REG: {
1899 gboolean sext = FALSE, zext = FALSE;
1901 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
1903 g_assert (ins->inst_offset % size == 0);
1904 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1905 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], t), LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, ""));
1909 case OP_STOREI1_MEMBASE_IMM:
1910 case OP_STOREI2_MEMBASE_IMM:
1911 case OP_STOREI4_MEMBASE_IMM:
1912 case OP_STOREI8_MEMBASE_IMM:
1913 case OP_STORE_MEMBASE_IMM: {
1917 gboolean sext = FALSE, zext = FALSE;
1919 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
1921 g_assert (ins->inst_offset % size == 0);
1922 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1923 LLVMBuildStore (builder, convert (ctx, LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE), t), LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, ""));
1928 mono_llvm_build_volatile_load (builder, convert (ctx, values [ins->sreg1], LLVMPointerType (IntPtrType (), 0)), "");
1930 case OP_OUTARG_VTRETADDR:
1937 case OP_VOIDCALL_MEMBASE:
1938 case OP_CALL_MEMBASE:
1939 case OP_LCALL_MEMBASE:
1940 case OP_FCALL_MEMBASE:
1941 case OP_VCALL_MEMBASE: {
1942 MonoCallInst *call = (MonoCallInst*)ins;
1943 MonoMethodSignature *sig = call->signature;
1944 LLVMValueRef callee, lcall;
1946 LLVMCallInfo *cinfo;
1950 LLVMTypeRef llvm_sig;
1954 cinfo = call->cinfo;
1956 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
1958 llvm_sig = sig_to_llvm_sig (ctx, sig, cinfo);
1959 CHECK_FAILURE (ctx);
1961 if (call->rgctx_reg) {
1962 LLVM_FAILURE (ctx, "rgctx reg");
1965 pindexes = mono_mempool_alloc0 (cfg->mempool, sig->param_count + 2);
1967 /* FIXME: Avoid creating duplicate methods */
1969 if (ins->flags & MONO_INST_HAS_METHOD) {
1970 if (cfg->compile_aot) {
1971 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
1973 callee = LLVMAddFunction (module, "", llvm_sig);
1976 mono_create_jit_trampoline_in_domain (mono_domain_get (),
1978 LLVMAddGlobalMapping (ee, callee, target);
1981 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
1987 memset (&ji, 0, sizeof (ji));
1988 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
1989 ji.data.target = info->name;
1991 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1993 if (cfg->compile_aot) {
1994 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
1996 callee = LLVMAddFunction (module, "", llvm_sig);
1997 target = (gpointer)mono_icall_get_wrapper (info);
1998 LLVMAddGlobalMapping (ee, callee, target);
2001 if (cfg->compile_aot) {
2003 if (cfg->abs_patches) {
2004 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2006 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
2010 LLVM_FAILURE (ctx, "aot");
2012 callee = LLVMAddFunction (module, "", llvm_sig);
2014 if (cfg->abs_patches) {
2015 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2017 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
2018 LLVMAddGlobalMapping (ee, callee, target);
2022 LLVMAddGlobalMapping (ee, callee, (gpointer)call->fptr);
2027 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) {
2028 int size = sizeof (gpointer);
2031 g_assert (ins->inst_offset % size == 0);
2032 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2034 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
2036 // FIXME: mono_arch_get_vcall_slot () can't decode the code
2037 // generated by LLVM
2038 //LLVM_FAILURE (ctx, "virtual call");
2040 if (call->method && call->method->klass->flags & TYPE_ATTRIBUTE_INTERFACE)
2041 /* No support for passing the IMT argument */
2042 LLVM_FAILURE (ctx, "imt");
2044 if (ins->flags & MONO_INST_HAS_METHOD) {
2049 * Collect and convert arguments
2052 args = alloca (sizeof (LLVMValueRef) * ((sig->param_count * 2) + sig->hasthis + vretaddr));
2053 l = call->out_ireg_args;
2056 if (!addresses [call->inst.dreg])
2057 addresses [call->inst.dreg] = LLVMBuildAlloca (builder, type_to_llvm_type (ctx, &(mono_class_from_mono_type (sig->ret)->byval_arg)), "");
2058 args [pindex ++] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2061 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2064 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2066 regpair = (guint32)(gssize)(l->data);
2067 reg = regpair & 0xffffff;
2068 args [pindex] = values [reg];
2069 if (ainfo->storage == LLVMArgVtypeInReg) {
2071 LLVMValueRef regs [2];
2076 g_assert (addresses [reg]);
2078 emit_vtype_to_reg (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, regs, &nregs);
2079 for (j = 0; j < nregs; ++j)
2080 args [pindex ++] = regs [j];
2083 // FIXME: Get rid of the VMOVE
2084 } else if (ainfo->storage == LLVMArgVtypeByVal) {
2085 g_assert (addresses [reg]);
2086 args [pindex] = addresses [reg];
2087 pindexes [i] = pindex;
2090 g_assert (args [pindex]);
2091 if (i == 0 && sig->hasthis)
2092 args [pindex] = convert (ctx, args [pindex], IntPtrType ());
2094 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2101 // FIXME: Align call sites
2106 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
2108 /* Add byval attributes if needed */
2109 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2110 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2112 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2113 LLVMAddInstrAttribute (lcall, pindexes [i] + 1, LLVMByValAttribute);
2118 * Convert the result
2120 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
2121 LLVMValueRef regs [2];
2123 if (!addresses [ins->dreg])
2124 addresses [ins->dreg] = LLVMBuildAlloca (builder, type_to_llvm_type (ctx, &(mono_class_from_mono_type (sig->ret)->byval_arg)), "");
2126 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2127 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2128 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2130 emit_reg_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2131 } else if (sig->ret->type != MONO_TYPE_VOID && !vretaddr) {
2132 values [ins->dreg] = convert (ctx, lcall, llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->ret)));
2136 case OP_GOT_ENTRY: {
2137 LLVMValueRef indexes [2];
2139 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2140 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)ins->inst_p0, FALSE);
2141 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, ""), dname);
2145 MonoMethodSignature *throw_sig;
2146 LLVMValueRef callee, arg;
2148 if (!ctx->lmodule->throw) {
2149 throw_sig = mono_metadata_signature_alloc (mono_defaults.corlib, 1);
2150 throw_sig->ret = &mono_defaults.void_class->byval_arg;
2151 throw_sig->params [0] = &mono_defaults.object_class->byval_arg;
2152 if (cfg->compile_aot) {
2153 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig, NULL), MONO_PATCH_INFO_INTERNAL_METHOD, "mono_arch_throw_exception");
2155 callee = LLVMAddFunction (module, "mono_arch_throw_exception", sig_to_llvm_sig (ctx, throw_sig, NULL));
2156 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_arch_throw_exception"));
2159 mono_memory_barrier ();
2160 ctx->lmodule->throw = callee;
2162 arg = convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, &mono_defaults.object_class->byval_arg));
2163 LLVMBuildCall (builder, ctx->lmodule->throw, &arg, 1, "");
2166 case OP_NOT_REACHED:
2167 LLVMBuildUnreachable (builder);
2168 has_terminator = TRUE;
2169 /* Might have instructions after this */
2171 MonoInst *next = ins->next;
2172 MONO_DELETE_INS (bb, next);
2176 MonoInst *var = ins->inst_p0;
2178 values [ins->dreg] = addresses [var->dreg];
2182 LLVMValueRef args [1];
2185 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
2189 LLVMValueRef args [1];
2192 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
2195 /* test_0_sqrt_nan fails with LLVM */
2198 LLVMValueRef args [1];
2201 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
2208 LLVMValueRef v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
2209 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
2214 LLVMValueRef v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
2215 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
2220 LLVMValueRef v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
2221 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
2226 LLVMValueRef v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
2227 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
2230 case OP_ATOMIC_EXCHANGE_I4: {
2231 LLVMValueRef args [2];
2233 g_assert (ins->inst_offset == 0);
2235 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
2237 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.swap.i32.p0i32"), args, 2, dname);
2240 case OP_ATOMIC_EXCHANGE_I8: {
2241 LLVMValueRef args [2];
2243 g_assert (ins->inst_offset == 0);
2245 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
2247 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.swap.i64.p0i64"), args, 2, dname);
2250 case OP_ATOMIC_ADD_NEW_I4: {
2251 LLVMValueRef args [2];
2253 g_assert (ins->inst_offset == 0);
2255 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
2257 values [ins->dreg] = LLVMBuildAdd (builder, LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.load.add.i32.p0i32"), args, 2, ""), args [1], dname);
2260 case OP_ATOMIC_ADD_NEW_I8: {
2261 LLVMValueRef args [2];
2263 g_assert (ins->inst_offset == 0);
2265 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
2266 args [1] = convert (ctx, rhs, LLVMInt64Type ());
2267 values [ins->dreg] = LLVMBuildAdd (builder, LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.load.add.i64.p0i64"), args, 2, ""), args [1], dname);
2270 case OP_ATOMIC_CAS_I4:
2271 case OP_ATOMIC_CAS_I8: {
2272 LLVMValueRef args [3];
2274 const char *intrins;
2276 if (ins->opcode == OP_ATOMIC_CAS_I4) {
2277 t = LLVMInt32Type ();
2278 intrins = "llvm.atomic.cmp.swap.i32.p0i32";
2280 t = LLVMInt64Type ();
2281 intrins = "llvm.atomic.cmp.swap.i64.p0i64";
2284 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
2286 args [1] = convert (ctx, values [ins->sreg3], t);
2288 args [2] = convert (ctx, values [ins->sreg2], t);
2289 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, intrins), args, 3, dname);
2292 case OP_MEMORY_BARRIER: {
2293 LLVMValueRef args [5];
2295 for (i = 0; i < 5; ++i)
2296 args [i] = LLVMConstInt (LLVMInt1Type (), TRUE, TRUE);
2298 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memory.barrier"), args, 5, "");
2303 #if defined(TARGET_AMD64) || defined(TARGET_X86)
2305 // 257 == FS segment register
2306 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
2308 // 256 == GS segment register
2309 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
2313 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
2315 LLVM_FAILURE (ctx, "opcode tls-get");
2325 case OP_IADD_OVF_UN:
2327 case OP_ISUB_OVF_UN:
2329 case OP_IMUL_OVF_UN:
2330 #if SIZEOF_VOID_P == 8
2333 case OP_LSUB_OVF_UN:
2335 case OP_LMUL_OVF_UN:
2338 LLVMValueRef args [2], val, ovf, func;
2340 emit_cond_throw_pos (ctx);
2344 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
2346 val = LLVMBuildCall (builder, func, args, 2, "");
2347 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
2348 ovf = LLVMBuildExtractValue (builder, val, 1, "");
2349 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
2350 builder = ctx->builder;
2356 * We currently model them using arrays. Promotion to local vregs is
2357 * disabled for them in mono_handle_global_vregs () in the LLVM case,
2358 * so we always have an entry in cfg->varinfo for them.
2359 * FIXME: Is this needed ?
2362 MonoClass *klass = ins->klass;
2363 LLVMValueRef args [4];
2367 LLVM_FAILURE (ctx, "!klass");
2371 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
2372 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2373 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
2375 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2376 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memset.i32"), args, 4, "");
2380 case OP_STOREV_MEMBASE:
2381 case OP_LOADV_MEMBASE:
2383 MonoClass *klass = ins->klass;
2384 LLVMValueRef src, dst, args [4];
2388 LLVM_FAILURE (ctx, "!klass");
2392 switch (ins->opcode) {
2393 case OP_STOREV_MEMBASE:
2394 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
2395 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
2397 case OP_LOADV_MEMBASE:
2398 if (!addresses [ins->dreg])
2399 addresses [ins->dreg] = LLVMBuildAlloca (builder, type_to_llvm_type (ctx, &klass->byval_arg), "");
2400 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
2401 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
2404 if (!addresses [ins->sreg1])
2405 addresses [ins->sreg1] = LLVMBuildAlloca (builder, type_to_llvm_type (ctx, &klass->byval_arg), "");
2406 if (!addresses [ins->dreg])
2407 addresses [ins->dreg] = LLVMBuildAlloca (builder, type_to_llvm_type (ctx, &klass->byval_arg), "");
2408 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
2409 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
2412 g_assert_not_reached ();
2417 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
2418 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2420 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2421 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memcpy.i32"), args, 4, "");
2424 case OP_LLVM_OUTARG_VT:
2425 g_assert (addresses [ins->sreg1]);
2426 addresses [ins->dreg] = addresses [ins->sreg1];
2432 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
2433 LLVM_FAILURE (ctx, reason);
2438 /* Convert the value to the type required by phi nodes */
2439 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && vreg_types [ins->dreg])
2440 values [ins->dreg] = convert (ctx, values [ins->dreg], vreg_types [ins->dreg]);
2442 /* Add stores for volatile variables */
2443 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
2444 emit_volatile_store (ctx, ins->dreg);
2447 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
2448 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
2450 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
2451 LLVMBuildRetVoid (builder);
2454 /* Add incoming phi values */
2455 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
2456 GSList *ins_list = g_hash_table_lookup (phi_nodes, GUINT_TO_POINTER (bb));
2459 PhiNode *node = ins_list->data;
2460 MonoInst *phi = node->phi;
2461 int sreg1 = phi->inst_phi_args [node->index + 1];
2462 LLVMBasicBlockRef in_bb;
2464 in_bb = get_end_bb (ctx, node->bb->in_bb [node->index]);
2466 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
2467 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
2469 ins_list = ins_list->next;
2473 if (cfg->verbose_level > 1)
2474 mono_llvm_dump_value (method);
2476 if (cfg->compile_aot) {
2477 /* Don't generate native code, keep the LLVM IR */
2480 mono_llvm_optimize_method (method);
2482 if (cfg->verbose_level > 1)
2483 mono_llvm_dump_value (method);
2485 cfg->native_code = LLVMGetPointerToGlobal (ee, method);
2487 /* Set by emit_cb */
2488 g_assert (cfg->code_len);
2490 /* FIXME: Free the LLVM IL for the function */
2498 /* Need to add unused phi nodes as they can be referenced by other values */
2499 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
2500 LLVMBuilderRef builder;
2502 builder = create_builder (ctx);
2503 LLVMPositionBuilderAtEnd (builder, phi_bb);
2505 for (i = 0; i < phi_values->len; ++i) {
2506 LLVMValueRef v = g_ptr_array_index (phi_values, i);
2507 if (LLVMGetInstructionParent (v) == NULL)
2508 LLVMInsertIntoBuilder (builder, v);
2511 LLVMDeleteFunction (method);
2517 g_free (vreg_types);
2519 g_hash_table_destroy (phi_nodes);
2520 g_ptr_array_free (phi_values, TRUE);
2521 g_free (ctx->bblocks);
2522 g_free (ctx->end_bblocks);
2524 for (l = ctx->builders; l; l = l->next) {
2525 LLVMBuilderRef builder = l->data;
2526 LLVMDisposeBuilder (builder);
2531 TlsSetValue (current_cfg_tls_id, NULL);
2533 mono_loader_unlock ();
2537 * mono_llvm_emit_call:
2539 * Same as mono_arch_emit_call () for LLVM.
2542 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
2545 MonoMethodSignature *sig;
2546 int i, n, stack_size;
2551 sig = call->signature;
2552 n = sig->param_count + sig->hasthis;
2554 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
2556 if (sig->call_convention == MONO_CALL_VARARG) {
2557 cfg->exception_message = g_strdup ("varargs");
2558 cfg->disable_llvm = TRUE;
2561 for (i = 0; i < n; ++i) {
2564 ainfo = call->cinfo->args + i;
2566 in = call->args [i];
2568 /* Simply remember the arguments */
2569 switch (ainfo->storage) {
2571 MONO_INST_NEW (cfg, ins, OP_MOVE);
2572 ins->dreg = mono_alloc_ireg (cfg);
2573 ins->sreg1 = in->dreg;
2575 case LLVMArgInFPReg:
2576 MONO_INST_NEW (cfg, ins, OP_FMOVE);
2577 ins->dreg = mono_alloc_freg (cfg);
2578 ins->sreg1 = in->dreg;
2580 case LLVMArgVtypeByVal:
2581 case LLVMArgVtypeInReg:
2582 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
2583 ins->dreg = mono_alloc_ireg (cfg);
2584 ins->sreg1 = in->dreg;
2585 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
2588 cfg->exception_message = g_strdup ("ainfo->storage");
2589 cfg->disable_llvm = TRUE;
2593 if (!cfg->disable_llvm) {
2594 MONO_ADD_INS (cfg->cbb, ins);
2595 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
2600 static unsigned char*
2601 alloc_cb (LLVMValueRef function, int size)
2605 cfg = TlsGetValue (current_cfg_tls_id);
2609 return mono_domain_code_reserve (cfg->domain, size);
2611 return mono_domain_code_reserve (mono_domain_get (), size);
2616 emitted_cb (LLVMValueRef function, void *start, void *end)
2620 cfg = TlsGetValue (current_cfg_tls_id);
2622 cfg->code_len = (guint8*)end - (guint8*)start;
2626 exception_cb (void *data)
2630 cfg = TlsGetValue (current_cfg_tls_id);
2634 * data points to a DWARF FDE structure, convert it to our unwind format and
2636 * An alternative would be to save it directly, and modify our unwinder to work
2639 cfg->encoded_unwind_ops = mono_unwind_get_ops_from_fde ((guint8*)data, &cfg->encoded_unwind_ops_len, NULL);
2643 add_intrinsics (LLVMModuleRef module)
2645 /* Emit declarations of instrinsics */
2647 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type () };
2649 LLVMAddFunction (module, "llvm.memset.i32", LLVMFunctionType (LLVMVoidType (), memset_params, 4, FALSE));
2653 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type () };
2655 LLVMAddFunction (module, "llvm.memcpy.i32", LLVMFunctionType (LLVMVoidType (), memcpy_params, 4, FALSE));
2659 LLVMTypeRef params [] = { LLVMDoubleType () };
2661 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
2662 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
2663 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
2667 LLVMTypeRef membar_params [] = { LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type () };
2669 LLVMAddFunction (module, "llvm.atomic.swap.i32.p0i32", LLVMFunctionType2 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), FALSE));
2670 LLVMAddFunction (module, "llvm.atomic.swap.i64.p0i64", LLVMFunctionType2 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), FALSE));
2671 LLVMAddFunction (module, "llvm.atomic.load.add.i32.p0i32", LLVMFunctionType2 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), FALSE));
2672 LLVMAddFunction (module, "llvm.atomic.load.add.i64.p0i64", LLVMFunctionType2 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), FALSE));
2673 LLVMAddFunction (module, "llvm.atomic.cmp.swap.i32.p0i32", LLVMFunctionType3 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), LLVMInt32Type (), FALSE));
2674 LLVMAddFunction (module, "llvm.atomic.cmp.swap.i64.p0i64", LLVMFunctionType3 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), LLVMInt64Type (), FALSE));
2675 LLVMAddFunction (module, "llvm.memory.barrier", LLVMFunctionType (LLVMVoidType (), membar_params, 5, FALSE));
2679 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
2680 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
2682 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
2683 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
2684 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
2685 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
2686 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
2687 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
2691 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
2692 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
2694 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
2695 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
2696 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
2697 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
2698 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
2699 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
2704 mono_llvm_init (void)
2706 current_cfg_tls_id = TlsAlloc ();
2708 jit_module.module = LLVMModuleCreateWithName ("mono");
2710 ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module.module), alloc_cb, emitted_cb, exception_cb);
2712 add_intrinsics (jit_module.module);
2714 jit_module.llvm_types = g_hash_table_new (NULL, NULL);
2718 mono_llvm_cleanup (void)
2720 mono_llvm_dispose_ee (ee);
2722 g_hash_table_destroy (jit_module.llvm_types);
2727 - Emit LLVM IR from the mono IR using the LLVM C API.
2728 - The original arch specific code remains, so we can fall back to it if we run
2729 into something we can't handle.
2731 - llvm's PrettyStackTrace class seems to register a signal handler which screws
2732 up our GC. Also, it calls sigaction () a _lot_ of times instead of just once.
2736 A partial list of issues:
2737 - Handling of opcodes which can throw exceptions.
2739 In the mono JIT, these are implemented using code like this:
2746 push throw_pos - method
2747 call <exception trampoline>
2749 The problematic part is push throw_pos - method, which cannot be represented
2750 in the LLVM IR, since it does not support label values.
2751 -> this can be implemented in AOT mode using inline asm + labels, but cannot
2752 be implemented in JIT mode ?
2753 -> a possible but slower implementation would use the normal exception
2754 throwing code but it would need to control the placement of the throw code
2755 (it needs to be exactly after the compare+branch).
2756 -> perhaps add a PC offset intrinsics ?
2758 - efficient implementation of .ovf opcodes.
2760 These are currently implemented as:
2761 <ins which sets the condition codes>
2764 Some overflow opcodes are now supported by LLVM SVN.
2766 - exception handling, unwinding.
2767 - SSA is disabled for methods with exception handlers
2768 - How to obtain unwind info for LLVM compiled methods ?
2769 -> this is now solved by converting the unwind info generated by LLVM
2771 - LLVM uses the c++ exception handling framework, while we use our home grown
2772 code, and couldn't use the c++ one:
2773 - its not supported under VC++, other exotic platforms.
2774 - it might be impossible to support filter clauses with it.
2778 The trampolines need a predictable call sequence, since they need to disasm
2779 the calling code to obtain register numbers / offsets.
2781 LLVM currently generates this code in non-JIT mode:
2782 mov -0x98(%rax),%eax
2784 Here, the vtable pointer is lost.
2785 -> solution: use one vtable trampoline per class.
2787 - passing/receiving the IMT pointer/RGCTX.
2788 -> solution: pass them as normal arguments ?
2792 LLVM does not allow the specification of argument registers etc. This means
2793 that all calls are made according to the platform ABI.
2795 - passing/receiving vtypes.
2797 Vtypes passed/received in registers are handled by the front end by using
2798 a signature with scalar arguments, and loading the parts of the vtype into those
2801 Vtypes passed on the stack are handled using the 'byval' attribute.
2805 Supported though alloca, we need to emit the load/store code.
2809 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
2810 typed registers, so we have to keep track of the precise LLVM type of each vreg.
2811 This is made easier because the IR is already in SSA form.
2812 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
2813 types are frequently used incorrectly.
2816 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
2817 * - each bblock should end with a branch
2818 * - setting the return value, making cfg->ret non-volatile
2819 * - merge some changes back to HEAD, to reduce the differences.
2820 * - avoid some transformations in the JIT which make it harder for us to generate
2822 * - fix memory leaks.
2823 * - use pointer types to help optimizations.